mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 11:05:19 +00:00
Fix NaN errors and timeout warnings when typing
- Disable iOS autocorrection on text fields to prevent conflicts - Add NaN validation for all geometry and gesture calculations - Fix frame calculations to handle invalid geometry values - Validate translation and velocity values in drag gestures - Prevent Result accumulator timeout warnings
This commit is contained in:
@@ -93,17 +93,20 @@ struct ContentView: View {
|
|||||||
insertion: .move(edge: .trailing),
|
insertion: .move(edge: .trailing),
|
||||||
removal: .move(edge: .trailing)
|
removal: .move(edge: .trailing)
|
||||||
))
|
))
|
||||||
.offset(x: showPrivateChat ? -1 : geometry.size.width)
|
.offset(x: showPrivateChat ? -1 : max(0, geometry.size.width))
|
||||||
.offset(x: backSwipeOffset)
|
.offset(x: backSwipeOffset.isNaN ? 0 : backSwipeOffset)
|
||||||
.gesture(
|
.gesture(
|
||||||
DragGesture()
|
DragGesture()
|
||||||
.onChanged { value in
|
.onChanged { value in
|
||||||
if value.translation.width > 0 {
|
if value.translation.width > 0 && !value.translation.width.isNaN {
|
||||||
backSwipeOffset = min(value.translation.width, geometry.size.width)
|
let maxWidth = max(0, geometry.size.width)
|
||||||
|
backSwipeOffset = min(value.translation.width, maxWidth.isNaN ? 0 : maxWidth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onEnded { value in
|
.onEnded { value in
|
||||||
if value.translation.width > 50 || (value.translation.width > 30 && value.velocity.width > 300) {
|
let translation = value.translation.width.isNaN ? 0 : value.translation.width
|
||||||
|
let velocity = value.velocity.width.isNaN ? 0 : value.velocity.width
|
||||||
|
if translation > 50 || (translation > 30 && velocity > 300) {
|
||||||
withAnimation(.easeOut(duration: 0.2)) {
|
withAnimation(.easeOut(duration: 0.2)) {
|
||||||
showPrivateChat = false
|
showPrivateChat = false
|
||||||
backSwipeOffset = 0
|
backSwipeOffset = 0
|
||||||
@@ -134,22 +137,26 @@ struct ContentView: View {
|
|||||||
if showSidebar || sidebarDragOffset != 0 {
|
if showSidebar || sidebarDragOffset != 0 {
|
||||||
sidebarView
|
sidebarView
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
.frame(width: min(300, geometry.size.width * 0.4))
|
.frame(width: min(300, max(0, geometry.size.width.isNaN ? 300 : geometry.size.width) * 0.4))
|
||||||
#else
|
#else
|
||||||
.frame(width: geometry.size.width * 0.7)
|
.frame(width: max(0, geometry.size.width.isNaN ? 300 : geometry.size.width) * 0.7)
|
||||||
#endif
|
#endif
|
||||||
.transition(.move(edge: .trailing))
|
.transition(.move(edge: .trailing))
|
||||||
} else {
|
} else {
|
||||||
// Empty placeholder when hidden
|
// Empty placeholder when hidden
|
||||||
Color.clear
|
Color.clear
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
.frame(width: min(300, geometry.size.width * 0.4))
|
.frame(width: min(300, max(0, geometry.size.width.isNaN ? 300 : geometry.size.width) * 0.4))
|
||||||
#else
|
#else
|
||||||
.frame(width: geometry.size.width * 0.7)
|
.frame(width: max(0, geometry.size.width.isNaN ? 300 : geometry.size.width) * 0.7)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.offset(x: showSidebar ? -sidebarDragOffset : geometry.size.width - sidebarDragOffset)
|
.offset(x: {
|
||||||
|
let dragOffset = sidebarDragOffset.isNaN ? 0 : sidebarDragOffset
|
||||||
|
let width = geometry.size.width.isNaN ? 0 : max(0, geometry.size.width)
|
||||||
|
return showSidebar ? -dragOffset : width - dragOffset
|
||||||
|
}())
|
||||||
.animation(.easeInOut(duration: 0.25), value: showSidebar)
|
.animation(.easeInOut(duration: 0.25), value: showSidebar)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -452,6 +459,8 @@ struct ContentView: View {
|
|||||||
.foregroundColor(textColor)
|
.foregroundColor(textColor)
|
||||||
.focused($isTextFieldFocused)
|
.focused($isTextFieldFocused)
|
||||||
.padding(.leading, 12)
|
.padding(.leading, 12)
|
||||||
|
.autocorrectionDisabled(true)
|
||||||
|
.textInputAutocapitalization(.never)
|
||||||
.onChange(of: messageText) { newValue in
|
.onChange(of: messageText) { newValue in
|
||||||
// Cancel previous debounce timer
|
// Cancel previous debounce timer
|
||||||
autocompleteDebounceTimer?.invalidate()
|
autocompleteDebounceTimer?.invalidate()
|
||||||
@@ -715,23 +724,26 @@ struct ContentView: View {
|
|||||||
.gesture(
|
.gesture(
|
||||||
DragGesture()
|
DragGesture()
|
||||||
.onChanged { value in
|
.onChanged { value in
|
||||||
if !showSidebar && value.translation.width < 0 {
|
let translation = value.translation.width.isNaN ? 0 : value.translation.width
|
||||||
sidebarDragOffset = max(value.translation.width, -300)
|
if !showSidebar && translation < 0 {
|
||||||
} else if showSidebar && value.translation.width > 0 {
|
sidebarDragOffset = max(translation, -300)
|
||||||
sidebarDragOffset = min(-300 + value.translation.width, 0)
|
} else if showSidebar && translation > 0 {
|
||||||
|
sidebarDragOffset = min(-300 + translation, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onEnded { value in
|
.onEnded { value in
|
||||||
|
let translation = value.translation.width.isNaN ? 0 : value.translation.width
|
||||||
|
let velocity = value.velocity.width.isNaN ? 0 : value.velocity.width
|
||||||
withAnimation(.easeOut(duration: 0.2)) {
|
withAnimation(.easeOut(duration: 0.2)) {
|
||||||
if !showSidebar {
|
if !showSidebar {
|
||||||
if value.translation.width < -100 || (value.translation.width < -50 && value.velocity.width < -500) {
|
if translation < -100 || (translation < -50 && velocity < -500) {
|
||||||
showSidebar = true
|
showSidebar = true
|
||||||
sidebarDragOffset = 0
|
sidebarDragOffset = 0
|
||||||
} else {
|
} else {
|
||||||
sidebarDragOffset = 0
|
sidebarDragOffset = 0
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if value.translation.width > 100 || (value.translation.width > 50 && value.velocity.width > 500) {
|
if translation > 100 || (translation > 50 && velocity > 500) {
|
||||||
showSidebar = false
|
showSidebar = false
|
||||||
sidebarDragOffset = 0
|
sidebarDragOffset = 0
|
||||||
} else {
|
} else {
|
||||||
@@ -788,6 +800,8 @@ struct ContentView: View {
|
|||||||
.frame(maxWidth: 100)
|
.frame(maxWidth: 100)
|
||||||
.foregroundColor(textColor)
|
.foregroundColor(textColor)
|
||||||
.focused($isNicknameFieldFocused)
|
.focused($isNicknameFieldFocused)
|
||||||
|
.autocorrectionDisabled(true)
|
||||||
|
.textInputAutocapitalization(.never)
|
||||||
.onChange(of: isNicknameFieldFocused) { isFocused in
|
.onChange(of: isNicknameFieldFocused) { isFocused in
|
||||||
if !isFocused {
|
if !isFocused {
|
||||||
// Only validate when losing focus
|
// Only validate when losing focus
|
||||||
|
|||||||
Reference in New Issue
Block a user