diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index 2ee37dabae..04c8740d14 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -104,6 +104,12 @@ class ChatController extends State PinnedEventsController pinnedEventsController = PinnedEventsController(); + final ValueKey chatComposerTypeAheadKey = + const ValueKey('chatComposerTypeAheadKey'); + + final ValueKey _chatMediaPickerTypeAheadKey = + const ValueKey('chatMediaPickerTypeAheadKey'); + @override Room? room; @@ -1308,6 +1314,7 @@ class ChatController extends State onCameraPicked: (_) => sendMedia(imagePickerController, room: room), captionController: _captionsController, focusSuggestionController: _focusSuggestionController, + typeAheadKey: _chatMediaPickerTypeAheadKey, ); } diff --git a/lib/pages/chat/chat_input_row.dart b/lib/pages/chat/chat_input_row.dart index 4e1bca1d71..cdb412d52f 100644 --- a/lib/pages/chat/chat_input_row.dart +++ b/lib/pages/chat/chat_input_row.dart @@ -165,6 +165,7 @@ class ChatInputRow extends StatelessWidget { InputBar _buildInputBar(BuildContext context) { return InputBar( + typeAheadKey: controller.chatComposerTypeAheadKey, room: controller.room!, minLines: 1, maxLines: 8, diff --git a/lib/pages/chat/input_bar/input_bar.dart b/lib/pages/chat/input_bar/input_bar.dart index e5da9fe280..564de8a203 100644 --- a/lib/pages/chat/input_bar/input_bar.dart +++ b/lib/pages/chat/input_bar/input_bar.dart @@ -32,7 +32,7 @@ class InputBar extends StatelessWidget with PasteImageMixin { final InputDecoration decoration; final ValueChanged? onChanged; final bool autofocus; - final bool enablePasteImage; + final ValueKey? typeAheadKey; InputBar({ this.room, @@ -47,8 +47,8 @@ class InputBar extends StatelessWidget with PasteImageMixin { this.autofocus = false, this.textInputAction, this.suggestionScrollController, - this.enablePasteImage = true, required this.focusSuggestionController, + this.typeAheadKey, Key? key, }) : super(key: key); @@ -340,6 +340,7 @@ class InputBar extends StatelessWidget with PasteImageMixin { room: room, onEnter: _onEnter, child: TypeAheadField>( + key: typeAheadKey, direction: AxisDirection.up, hideOnEmpty: true, hideOnLoading: true, diff --git a/lib/pages/chat/send_file_dialog.dart b/lib/pages/chat/send_file_dialog.dart index 092b01ac2b..84d104a183 100644 --- a/lib/pages/chat/send_file_dialog.dart +++ b/lib/pages/chat/send_file_dialog.dart @@ -33,6 +33,11 @@ class SendFileDialogController extends State { final TextEditingController textEditingController = TextEditingController(); + final FocusNode captionsFocusNode = FocusNode(); + + final ValueKey sendFileDialogTypeAheadKey = + const ValueKey('sendFileDialogTypeAhead'); + bool isSendMediaWithCaption = true; List get files => widget.files; @@ -41,6 +46,7 @@ class SendFileDialogController extends State { void initState() { super.initState(); isSendMediaWithCaption = _isShowSendMediaDialog(widget.files, widget.room); + requestFocusCaptions(); } @override @@ -49,6 +55,10 @@ class SendFileDialogController extends State { super.dispose(); } + void requestFocusCaptions() { + captionsFocusNode.requestFocus(); + } + void sendMediaWithCaption() { if (widget.room == null) { Logs().e("sendMediaWithCaption:: room is null"); diff --git a/lib/pages/chat/send_file_dialog_view.dart b/lib/pages/chat/send_file_dialog_view.dart index 7d93ba6e56..6b1b78d210 100644 --- a/lib/pages/chat/send_file_dialog_view.dart +++ b/lib/pages/chat/send_file_dialog_view.dart @@ -58,16 +58,27 @@ class SendFileDialogView extends StatelessWidget { room: controller.widget.room, ), const SizedBox(height: 16.0), - InputBar( - maxLines: 5, - minLines: 1, - focusSuggestionController: controller.focusSuggestionController, - room: controller.widget.room, - controller: controller.textEditingController, - decoration: - SendFileDialogStyle.bottomBarInputDecoration(context), - keyboardType: TextInputType.multiline, - enablePasteImage: false, + InkWell( + hoverColor: Colors.transparent, + highlightColor: Colors.transparent, + focusColor: Colors.transparent, + onTap: controller.requestFocusCaptions, + child: InputBar( + typeAheadKey: controller.sendFileDialogTypeAheadKey, + maxLines: 5, + minLines: 1, + focusSuggestionController: + controller.focusSuggestionController, + room: controller.widget.room, + controller: controller.textEditingController, + textInputAction: null, + decoration: + SendFileDialogStyle.bottomBarInputDecoration(context), + keyboardType: TextInputType.multiline, + focusNode: controller.captionsFocusNode, + autofocus: !PlatformInfos.isMobile, + onSubmitted: (_) => controller.send(), + ), ), SendFileDialogStyle.spaceBwInputBarAndButton, Row( diff --git a/lib/pages/chat_draft/draft_chat.dart b/lib/pages/chat_draft/draft_chat.dart index 0bdf353db7..9a364e4573 100644 --- a/lib/pages/chat_draft/draft_chat.dart +++ b/lib/pages/chat_draft/draft_chat.dart @@ -68,6 +68,12 @@ class DraftChatController extends State final FocusSuggestionController focusSuggestionController = FocusSuggestionController(); + final ValueKey draftChatComposerTypeAheadKey = + const ValueKey('draftChatComposerTypeAheadKey'); + + final ValueKey _draftChatMediaPickerTypeAheadKey = + const ValueKey('draftChatMediaPickerTypeAheadKey'); + FocusNode inputFocus = FocusNode(); FocusNode keyboardFocus = FocusNode(); @@ -296,6 +302,7 @@ class DraftChatController extends State ), onSendTap: () => sendMedia(imagePickerController), onCameraPicked: (_) => sendMedia(imagePickerController), + typeAheadKey: _draftChatMediaPickerTypeAheadKey, ); } diff --git a/lib/pages/chat_draft/draft_chat_view.dart b/lib/pages/chat_draft/draft_chat_view.dart index 7bfb17c95c..efb0b6d482 100644 --- a/lib/pages/chat_draft/draft_chat_view.dart +++ b/lib/pages/chat_draft/draft_chat_view.dart @@ -164,6 +164,8 @@ class DraftChatView extends StatelessWidget { children: [ Expanded( child: InputBar( + typeAheadKey: controller + .draftChatComposerTypeAheadKey, minLines: DraftChatViewStyle .minLinesInputBar, diff --git a/lib/presentation/mixins/media_picker_mixin.dart b/lib/presentation/mixins/media_picker_mixin.dart index 6eb8a8615b..ef5d5e5837 100644 --- a/lib/presentation/mixins/media_picker_mixin.dart +++ b/lib/presentation/mixins/media_picker_mixin.dart @@ -4,6 +4,7 @@ import 'package:fluffychat/pages/chat/input_bar/input_bar.dart'; import 'package:fluffychat/pages/chat/item_actions_bottom_widget.dart'; import 'package:fluffychat/pages/chat/send_file_dialog_style.dart'; import 'package:fluffychat/resource/image_paths.dart'; +import 'package:fluffychat/utils/platform_infos.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -38,6 +39,7 @@ mixin MediaPickerMixin on CommonMediaPickerMixin { OnCameraPicked? onCameraPicked, FocusSuggestionController? focusSuggestionController, TextEditingController? captionController, + ValueKey? typeAheadKey, }) async { final currentPermissionPhotos = await getCurrentMediaPermission(); final currentPermissionCamera = await getCurrentCameraPermission(); @@ -53,6 +55,7 @@ mixin MediaPickerMixin on CommonMediaPickerMixin { onCameraPicked: onCameraPicked, focusSuggestionController: focusSuggestionController, captionController: captionController, + typeAheadKey: typeAheadKey, ); } } @@ -69,6 +72,7 @@ mixin MediaPickerMixin on CommonMediaPickerMixin { Widget? inputBar, FocusSuggestionController? focusSuggestionController, TextEditingController? captionController, + ValueKey? typeAheadKey, }) async { final numberSelectedImagesNotifier = ValueNotifier(0); imagePickerController.addListener(() { @@ -182,8 +186,10 @@ mixin MediaPickerMixin on CommonMediaPickerMixin { children: [ Expanded( child: InputBar( + typeAheadKey: typeAheadKey, maxLines: 5, minLines: 1, + textInputAction: null, focusSuggestionController: focusSuggestionController ?? FocusSuggestionController(), @@ -194,7 +200,13 @@ mixin MediaPickerMixin on CommonMediaPickerMixin { context, ), keyboardType: TextInputType.multiline, - enablePasteImage: false, + autofocus: !PlatformInfos.isMobile, + onSubmitted: (_) { + if (onSendTap != null) { + onSendTap(); + } + Navigator.of(context).pop(); + }, ), ), Padding(