fix: keyboard close on modal opens
This commit is contained in:
@@ -36,6 +36,9 @@ final prefilledInputTextProvider = StateProvider<String?>((ref) => null);
|
||||
// Trigger to request focus on the chat input (increment to signal)
|
||||
final inputFocusTriggerProvider = StateProvider<int>((ref) => 0);
|
||||
|
||||
// Whether the chat composer currently has focus
|
||||
final composerHasFocusProvider = StateProvider<bool>((ref) => false);
|
||||
|
||||
class ChatMessagesNotifier extends StateNotifier<List<ChatMessage>> {
|
||||
final Ref _ref;
|
||||
StreamSubscription? _messageStream;
|
||||
|
||||
@@ -1533,12 +1533,25 @@ class _ChatPageState extends ConsumerState<ChatPage> {
|
||||
WidgetRef ref,
|
||||
List<Model> models,
|
||||
) {
|
||||
// Ensure keyboard is closed before presenting modal
|
||||
final hadFocus = ref.read(composerHasFocusProvider);
|
||||
try {
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
SystemChannels.textInput.invokeMethod('TextInput.hide');
|
||||
} catch (_) {}
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (context) => _ModelSelectorSheet(models: models, ref: ref),
|
||||
);
|
||||
).whenComplete(() {
|
||||
if (!mounted) return;
|
||||
if (hadFocus) {
|
||||
// Bump focus trigger to restore composer focus + IME
|
||||
final cur = ref.read(inputFocusTriggerProvider);
|
||||
ref.read(inputFocusTriggerProvider.notifier).state = cur + 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: Implement chat options when needed
|
||||
|
||||
@@ -250,6 +250,10 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (!mounted || _isDeactivated) return;
|
||||
final hasFocus = _focusNode.hasFocus;
|
||||
// Publish composer focus state
|
||||
try {
|
||||
ref.read(composerHasFocusProvider.notifier).state = hasFocus;
|
||||
} catch (_) {}
|
||||
if (hasFocus) {
|
||||
if (!_isExpanded) _setExpanded(true);
|
||||
} else {
|
||||
@@ -277,6 +281,9 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
try {
|
||||
ref.read(composerHasFocusProvider.notifier).state = false;
|
||||
} catch (_) {}
|
||||
_controller.dispose();
|
||||
_focusNode.dispose();
|
||||
_expandController.dispose();
|
||||
@@ -1286,7 +1293,13 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
|
||||
void _showAttachmentOptions() {
|
||||
HapticFeedback.selectionClick();
|
||||
final prevCanRequest = _focusNode.canRequestFocus;
|
||||
final wasFocused = _focusNode.hasFocus;
|
||||
_focusNode.canRequestFocus = false;
|
||||
// Ensure keyboard is closed before presenting modal
|
||||
try {
|
||||
FocusScope.of(context).unfocus();
|
||||
SystemChannels.textInput.invokeMethod('TextInput.hide');
|
||||
} catch (_) {}
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
backgroundColor: Colors.transparent,
|
||||
@@ -1361,6 +1374,16 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
|
||||
).whenComplete(() {
|
||||
if (mounted) {
|
||||
_focusNode.canRequestFocus = prevCanRequest;
|
||||
if (wasFocused && widget.enabled) {
|
||||
if (!_isExpanded) _setExpanded(true);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (!mounted) return;
|
||||
_ensureFocusedIfEnabled();
|
||||
try {
|
||||
SystemChannels.textInput.invokeMethod('TextInput.show');
|
||||
} catch (_) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1368,7 +1391,13 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
|
||||
void _showUnifiedToolsModal() {
|
||||
HapticFeedback.selectionClick();
|
||||
final prevCanRequest = _focusNode.canRequestFocus;
|
||||
final wasFocused = _focusNode.hasFocus;
|
||||
_focusNode.canRequestFocus = false;
|
||||
// Ensure keyboard is closed before presenting modal
|
||||
try {
|
||||
FocusScope.of(context).unfocus();
|
||||
SystemChannels.textInput.invokeMethod('TextInput.hide');
|
||||
} catch (_) {}
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
backgroundColor: Colors.transparent,
|
||||
@@ -1376,6 +1405,16 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
|
||||
).whenComplete(() {
|
||||
if (mounted) {
|
||||
_focusNode.canRequestFocus = prevCanRequest;
|
||||
if (wasFocused && widget.enabled) {
|
||||
if (!_isExpanded) _setExpanded(true);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (!mounted) return;
|
||||
_ensureFocusedIfEnabled();
|
||||
try {
|
||||
SystemChannels.textInput.invokeMethod('TextInput.show');
|
||||
} catch (_) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user