fix: remove one tap to open keyboard which is causing issues
This commit is contained in:
@@ -199,13 +199,9 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
|
|||||||
_pendingFocusAfterExpand = false;
|
_pendingFocusAfterExpand = false;
|
||||||
// Focus and ensure IME shows reliably after expansion finishes
|
// Focus and ensure IME shows reliably after expansion finishes
|
||||||
_ensureFocusedIfEnabled();
|
_ensureFocusedIfEnabled();
|
||||||
Future.microtask(() {
|
// Let platform show IME naturally when focus is active. Avoid manual
|
||||||
try {
|
// TextInput.show here to prevent race conditions on Android.
|
||||||
if (_focusNode.hasFocus) {
|
// If a device/IME requires a nudge, the TextField's onTap path covers it.
|
||||||
SystemChannels.textInput.invokeMethod('TextInput.show');
|
|
||||||
}
|
|
||||||
} catch (_) {}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
_pulseController = AnimationController(
|
_pulseController = AnimationController(
|
||||||
@@ -426,14 +422,6 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
|
|||||||
// Explicit request: always try to focus and show the keyboard
|
// Explicit request: always try to focus and show the keyboard
|
||||||
_ensureFocusedIfEnabled();
|
_ensureFocusedIfEnabled();
|
||||||
if (!_isExpanded) _setExpanded(true);
|
if (!_isExpanded) _setExpanded(true);
|
||||||
// Nudge the platform text input to show reliably on iOS/Android
|
|
||||||
Future.microtask(() {
|
|
||||||
try {
|
|
||||||
if (_focusNode.hasFocus) {
|
|
||||||
SystemChannels.textInput.invokeMethod('TextInput.show');
|
|
||||||
}
|
|
||||||
} catch (_) {}
|
|
||||||
});
|
|
||||||
_lastHandledFocusTick = focusTick;
|
_lastHandledFocusTick = focusTick;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -487,6 +475,13 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
|
|||||||
.fast, // Faster for better responsiveness
|
.fast, // Faster for better responsiveness
|
||||||
curve: Curves.fastOutSlowIn, // More efficient curve
|
curve: Curves.fastOutSlowIn, // More efficient curve
|
||||||
alignment: Alignment.topCenter,
|
alignment: Alignment.topCenter,
|
||||||
|
onEnd: () {
|
||||||
|
if (!mounted || _isDeactivated) return;
|
||||||
|
if (_pendingFocusAfterExpand) {
|
||||||
|
_pendingFocusAfterExpand = false;
|
||||||
|
_ensureFocusedIfEnabled();
|
||||||
|
}
|
||||||
|
},
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
physics: const ClampingScrollPhysics(),
|
physics: const ClampingScrollPhysics(),
|
||||||
child: RepaintBoundary(
|
child: RepaintBoundary(
|
||||||
@@ -502,22 +497,16 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
|
|||||||
bottom: Spacing.inputPadding,
|
bottom: Spacing.inputPadding,
|
||||||
),
|
),
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
behavior: HitTestBehavior.opaque,
|
// Defer taps to the TextField so it can gain focus immediately.
|
||||||
|
// This prevents the first tap from being consumed by the wrapper,
|
||||||
|
// which previously opened the keyboard without focusing the field.
|
||||||
|
behavior: HitTestBehavior.deferToChild,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (!_isExpanded && widget.enabled) {
|
if (!_isExpanded && widget.enabled) {
|
||||||
_pendingFocusAfterExpand = true;
|
_pendingFocusAfterExpand = true;
|
||||||
_setExpanded(true);
|
_setExpanded(true);
|
||||||
WidgetsBinding.instance
|
// Defer focus until AnimatedSize finishes changing layout
|
||||||
.addPostFrameCallback((_) {
|
// to avoid IME/client race conditions.
|
||||||
if (!mounted) return;
|
|
||||||
if (_pendingFocusAfterExpand) {
|
|
||||||
_ensureFocusedIfEnabled();
|
|
||||||
try {
|
|
||||||
SystemChannels.textInput
|
|
||||||
.invokeMethod('TextInput.show');
|
|
||||||
} catch (_) {}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
@@ -652,18 +641,12 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
|
|||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
if (_pendingFocusAfterExpand) {
|
if (_pendingFocusAfterExpand) {
|
||||||
_ensureFocusedIfEnabled();
|
_ensureFocusedIfEnabled();
|
||||||
try {
|
// Focus alone should bring up IME.
|
||||||
SystemChannels.textInput
|
|
||||||
.invokeMethod('TextInput.show');
|
|
||||||
} catch (_) {}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
_ensureFocusedIfEnabled();
|
_ensureFocusedIfEnabled();
|
||||||
try {
|
// Focus alone should bring up IME.
|
||||||
SystemChannels.textInput
|
|
||||||
.invokeMethod('TextInput.show');
|
|
||||||
} catch (_) {}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -1379,9 +1362,7 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
|
|||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
_ensureFocusedIfEnabled();
|
_ensureFocusedIfEnabled();
|
||||||
try {
|
// Let focus naturally reopen the IME.
|
||||||
SystemChannels.textInput.invokeMethod('TextInput.show');
|
|
||||||
} catch (_) {}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1410,9 +1391,7 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
|
|||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
_ensureFocusedIfEnabled();
|
_ensureFocusedIfEnabled();
|
||||||
try {
|
// Let focus naturally reopen the IME.
|
||||||
SystemChannels.textInput.invokeMethod('TextInput.show');
|
|
||||||
} catch (_) {}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user