mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-08-22 07:16:03 +00:00
fix: debounce autocorrect trait flips across token boundaries
Avoid thrashing UIKit keyboard traits on every keystroke when the caret crosses / @ # tokens (#969 review). Signed-off-by: Taksh <takshkothari09@gmail.com>
This commit is contained in:
parent
22386a42b8
commit
d43440d79e
@ -19,6 +19,12 @@ struct ContentComposerView: View {
|
||||
@ObservedObject var voiceRecordingVM: VoiceRecordingViewModel
|
||||
@Binding var autocompleteDebounceTimer: Timer?
|
||||
|
||||
/// Applied autocorrect gate — updated on a short debounce so crossing a
|
||||
/// `/` `@` `#` boundary doesn't thrash UIKit text-input traits on every
|
||||
/// keystroke (can flicker the keyboard on some iOS versions).
|
||||
@State private var appliedAutocorrectDisabled = false
|
||||
@State private var autocorrectTraitTimer: Timer?
|
||||
|
||||
let onSendMessage: () -> Void
|
||||
|
||||
#if os(iOS)
|
||||
@ -79,9 +85,9 @@ struct ContentComposerView: View {
|
||||
// Token-aware (#969): autocorrect for prose, off while the
|
||||
// current token is a /command, @mention, or #channel so the
|
||||
// keyboard doesn't fight exact tokens (or learn them).
|
||||
.autocorrectionDisabled(shouldDisableAutocorrect)
|
||||
.autocorrectionDisabled(appliedAutocorrectDisabled)
|
||||
#if os(iOS)
|
||||
.textInputAutocapitalization(shouldDisableAutocorrect ? .never : .sentences)
|
||||
.textInputAutocapitalization(appliedAutocorrectDisabled ? .never : .sentences)
|
||||
#endif
|
||||
.submitLabel(.send)
|
||||
.modifier(AutocompleteKeyboardNavigationModifier(
|
||||
@ -126,6 +132,13 @@ struct ContentComposerView: View {
|
||||
conversationUIModel.updateAutocomplete(for: newValue, cursorPosition: cursorPosition)
|
||||
}
|
||||
}
|
||||
scheduleAutocorrectTraitUpdate(for: newValue)
|
||||
}
|
||||
.onAppear {
|
||||
appliedAutocorrectDisabled = ComposerAutocorrect.shouldDisable(
|
||||
for: messageText,
|
||||
cursorPosition: messageText.count
|
||||
)
|
||||
}
|
||||
|
||||
HStack(alignment: .center, spacing: 4) {
|
||||
@ -158,6 +171,27 @@ private extension ContentComposerView {
|
||||
ComposerAutocorrect.shouldDisable(for: messageText, cursorPosition: messageText.count)
|
||||
}
|
||||
|
||||
/// Debounce trait flips so UIKit isn't asked to reload the keyboard on
|
||||
/// every character while the user is still deciding the token.
|
||||
func scheduleAutocorrectTraitUpdate(for text: String) {
|
||||
let desired = ComposerAutocorrect.shouldDisable(for: text, cursorPosition: text.count)
|
||||
guard desired != appliedAutocorrectDisabled else {
|
||||
autocorrectTraitTimer?.invalidate()
|
||||
return
|
||||
}
|
||||
autocorrectTraitTimer?.invalidate()
|
||||
autocorrectTraitTimer = Timer.scheduledTimer(withTimeInterval: 0.12, repeats: false) { _ in
|
||||
Task { @MainActor in
|
||||
let latest = ComposerAutocorrect.shouldDisable(
|
||||
for: messageText,
|
||||
cursorPosition: messageText.count
|
||||
)
|
||||
guard latest != appliedAutocorrectDisabled else { return }
|
||||
appliedAutocorrectDisabled = latest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The nearby-only scope toggle appears only where it means something:
|
||||
/// the public mesh channel with the bridge on.
|
||||
var showsNearbyOnlyToggle: Bool {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user