From 28347bb7c10eaf99a437c3b00fcbd88abc92900c Mon Sep 17 00:00:00 2001 From: HuyNguyen Date: Wed, 5 Apr 2023 02:20:43 +0700 Subject: [PATCH] TF-1679: Hide cursor of bcc when focus to html editor (cherry picked from commit 588c9b4873ea40b75dd6e6cffbe80af21a4b287c) --- .../identity_creator_controller.dart | 22 ++++- .../presentation/identity_creator_view.dart | 99 ++++++++++--------- ...ty_input_with_drop_list_field_builder.dart | 19 ++-- .../identities/identities_controller.dart | 23 ----- .../identities_radio_list_builder.dart | 2 +- 5 files changed, 85 insertions(+), 80 deletions(-) diff --git a/lib/features/identity_creator/presentation/identity_creator_controller.dart b/lib/features/identity_creator/presentation/identity_creator_controller.dart index 0d263e2fb..5256a18d3 100644 --- a/lib/features/identity_creator/presentation/identity_creator_controller.dart +++ b/lib/features/identity_creator/presentation/identity_creator_controller.dart @@ -2,6 +2,7 @@ import 'package:core/utils/app_logger.dart'; import 'package:core/utils/build_utils.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter/services.dart'; import 'package:get/get_core/get_core.dart'; import 'package:get/get_instance/get_instance.dart'; import 'package:get/get_rx/get_rx.dart'; @@ -63,6 +64,7 @@ class IdentityCreatorController extends BaseController { TextEditingController? inputNameIdentityController; TextEditingController? inputBccIdentityController; FocusNode? inputNameIdentityFocusNode; + FocusNode? inputBccIdentityFocusNode; String? _nameIdentity; String? _contentHtmlEditor; @@ -109,6 +111,7 @@ class IdentityCreatorController extends BaseController { inputNameIdentityController = TextEditingController(); inputBccIdentityController = TextEditingController(); inputNameIdentityFocusNode = FocusNode(); + inputBccIdentityFocusNode = FocusNode(); scrollController = ScrollController(); } @@ -422,6 +425,7 @@ class IdentityCreatorController extends BaseController { if (!BuildUtils.isWeb) { keyboardRichTextController.htmlEditorApi?.unfocus(); } + SystemChannels.textInput.invokeMethod('TextInput.hide'); FocusScope.of(context).unfocus(); } @@ -437,6 +441,8 @@ class IdentityCreatorController extends BaseController { keyboardRichTextController.dispose(); inputNameIdentityFocusNode?.dispose(); inputNameIdentityFocusNode = null; + inputBccIdentityFocusNode?.dispose(); + inputBccIdentityFocusNode = null; inputNameIdentityController?.dispose(); inputNameIdentityController = null; inputBccIdentityController?.dispose(); @@ -444,7 +450,19 @@ class IdentityCreatorController extends BaseController { scrollController?.dispose(); } - void onFocusHTMLEditorOnMobile() async { + void initRichTextForMobile(BuildContext context, HtmlEditorApi editorApi) { + keyboardRichTextController.htmlEditorApi = editorApi; + keyboardRichTextController.onCreateHTMLEditor( + editorApi, + onEnterKeyDown: _onEnterKeyDownOnMobile, + onFocus: _onFocusHTMLEditorOnMobile, + context: context + ); + } + + void _onFocusHTMLEditorOnMobile() async { + inputBccIdentityFocusNode?.unfocus(); + inputNameIdentityFocusNode?.unfocus(); if (scrollController != null) { if (htmlKey.currentContext != null) { await Scrollable.ensureVisible(htmlKey.currentContext!); @@ -462,7 +480,7 @@ class IdentityCreatorController extends BaseController { } } - void onEnterKeyDownOnMobile() { + void _onEnterKeyDownOnMobile() { if (scrollController != null && scrollController!.position.pixels < scrollController!.position.maxScrollExtent) { scrollController!.animateTo( scrollController!.position.pixels + 20, diff --git a/lib/features/identity_creator/presentation/identity_creator_view.dart b/lib/features/identity_creator/presentation/identity_creator_view.dart index 5c598a744..d9d6a7221 100644 --- a/lib/features/identity_creator/presentation/identity_creator_view.dart +++ b/lib/features/identity_creator/presentation/identity_creator_view.dart @@ -237,7 +237,8 @@ class IdentityCreatorView extends GetWidget { Obx(() => (IdentityInputWithDropListFieldBuilder( AppLocalizations.of(context).bcc_to, controller.errorBccIdentity.value, - controller.inputBccIdentityController) + controller.inputBccIdentityController, + focusNode: controller.inputBccIdentityFocusNode) ..addOnSelectedSuggestionAction((newEmailAddress) { controller.inputBccIdentityController?.text = newEmailAddress?.email ?? ''; controller.updateBccOfIdentity(newEmailAddress); @@ -337,7 +338,9 @@ class IdentityCreatorView extends GetWidget { ), ] ), - )] else ...[ + ), + const SizedBox(height: 35), + ] else ...[ _buildActionBottomDesktop(context) ] ]), @@ -346,48 +349,57 @@ class IdentityCreatorView extends GetWidget { return GestureDetector( onTap: () => controller.clearFocusEditor(context), - child: Stack( - children: [ - Column(children: [ + child: Column(children: [ + SizedBox( + width: double.infinity, + child: Stack( + children: [ + Positioned(right: 8, top: 2, + child: buildIconWeb( + iconSize: 24, + icon: SvgPicture.asset( + _imagePaths.icComposerClose, + fit: BoxFit.fill, + colorFilter: AppColor.colorDeleteContactIcon.asFilter() + ), + tooltip: AppLocalizations.of(context).close, + onTap: () => controller.closeView(context)), + ), Padding( - padding: const EdgeInsets.only(top: 14), + padding: const EdgeInsets.only(top: 14), + child: Align( + alignment: Alignment.center, child: Obx(() { return Text(controller.actionType.value == IdentityActionType.create - ? AppLocalizations.of(context).createNewIdentity.inCaps - : AppLocalizations.of(context).edit_identity.inCaps, + ? AppLocalizations.of(context).createNewIdentity.inCaps + : AppLocalizations.of(context).edit_identity.inCaps, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: Colors.black)); - })), - const SizedBox(height: 8), - Expanded( - child: BuildUtils.isWeb - ? PointerInterceptor(child: bodyCreatorView) - : KeyboardRichText( - keyBroadToolbar: RichTextKeyboardToolBar( - titleBack: AppLocalizations.of(context).titleFormat, - backgroundKeyboardToolBarColor: AppColor.colorBackgroundKeyboard, - isLandScapeMode: _responsiveUtils.isLandscapeMobile(context), - richTextController: controller.keyboardRichTextController, - titleQuickStyleBottomSheet: AppLocalizations.of(context).titleQuickStyles, - titleBackgroundBottomSheet: AppLocalizations.of(context).titleBackground, - titleForegroundBottomSheet: AppLocalizations.of(context).titleForeground, - titleFormatBottomSheet: AppLocalizations.of(context).titleFormat, - ), - richTextController: controller.keyboardRichTextController, - child: bodyCreatorView), + }), + ), ), - ]), - Positioned(top: 2, right: 8, - child: buildIconWeb( - iconSize: 24, - icon: SvgPicture.asset( - _imagePaths.icComposerClose, - fit: BoxFit.fill, - colorFilter: AppColor.colorDeleteContactIcon.asFilter() - ), - tooltip: AppLocalizations.of(context).close, - onTap: () => controller.closeView(context))) - ] - ), + ], + ), + ), + const SizedBox(height: 8), + Expanded( + child: BuildUtils.isWeb + ? PointerInterceptor(child: bodyCreatorView) + : KeyboardRichText( + keyBroadToolbar: RichTextKeyboardToolBar( + titleBack: AppLocalizations.of(context).titleFormat, + backgroundKeyboardToolBarColor: AppColor.colorBackgroundKeyboard, + isLandScapeMode: _responsiveUtils.isLandscapeMobile(context), + richTextController: controller.keyboardRichTextController, + titleQuickStyleBottomSheet: AppLocalizations.of(context).titleQuickStyles, + titleBackgroundBottomSheet: AppLocalizations.of(context).titleBackground, + titleForegroundBottomSheet: AppLocalizations.of(context).titleForeground, + titleFormatBottomSheet: AppLocalizations.of(context).titleFormat, + ), + richTextController: controller.keyboardRichTextController, + paddingChild: EdgeInsets.zero, + child: bodyCreatorView), + ), + ]), ); } @@ -458,14 +470,7 @@ class IdentityCreatorView extends GetWidget { minHeight: controller.htmlEditorMinHeight, addDefaultSelectionMenuItems: false, initialContent: initialContent ?? '', - onCreated: (editorApi) { - controller.keyboardRichTextController.onCreateHTMLEditor( - editorApi, - onEnterKeyDown: controller.onEnterKeyDownOnMobile, - onFocus: controller.onFocusHTMLEditorOnMobile, - context: context - ); - }, + onCreated: (editorApi) => controller.initRichTextForMobile(context, editorApi), ), ); } diff --git a/lib/features/identity_creator/presentation/widgets/identity_input_with_drop_list_field_builder.dart b/lib/features/identity_creator/presentation/widgets/identity_input_with_drop_list_field_builder.dart index e597f26c6..a0abbe175 100644 --- a/lib/features/identity_creator/presentation/widgets/identity_input_with_drop_list_field_builder.dart +++ b/lib/features/identity_creator/presentation/widgets/identity_input_with_drop_list_field_builder.dart @@ -14,6 +14,7 @@ class IdentityInputWithDropListFieldBuilder { final String _label; final String? _error; final TextEditingController? editingController; + final FocusNode? focusNode; OnSelectedSuggestionAction? _onSelectedSuggestionAction; OnSuggestionCallbackAction? _onSuggestionCallbackAction; @@ -23,6 +24,9 @@ class IdentityInputWithDropListFieldBuilder { this._label, this._error, this.editingController, + { + this.focusNode, + } ); void addOnSelectedSuggestionAction(OnSelectedSuggestionAction action) { @@ -46,13 +50,14 @@ class IdentityInputWithDropListFieldBuilder { const SizedBox(height: 8), TypeAheadFormField( textFieldConfiguration: TextFieldConfiguration( - controller: editingController, - textInputAction: TextInputAction.done, - decoration: (IdentityInputDecorationBuilder() - ..setContentPadding(const EdgeInsets.symmetric( - vertical: BuildUtils.isWeb ? 16 : 12, - horizontal: 12)) - ..setErrorText(_error)) + focusNode: focusNode, + controller: editingController, + textInputAction: TextInputAction.done, + decoration: (IdentityInputDecorationBuilder() + ..setContentPadding(const EdgeInsets.symmetric( + vertical: BuildUtils.isWeb ? 16 : 12, + horizontal: 12)) + ..setErrorText(_error)) .build() ), debounceDuration: const Duration(milliseconds: 500), diff --git a/lib/features/manage_account/presentation/profiles/identities/identities_controller.dart b/lib/features/manage_account/presentation/profiles/identities/identities_controller.dart index bb2ae09e3..2238eb471 100644 --- a/lib/features/manage_account/presentation/profiles/identities/identities_controller.dart +++ b/lib/features/manage_account/presentation/profiles/identities/identities_controller.dart @@ -53,7 +53,6 @@ class IdentitiesController extends BaseController { final identitySelected = Rxn(); final signatureSelected = Rxn(); - final _htmlSignature = Rxn(); final listAllIdentities = [].obs; IdentitiesController( @@ -163,15 +162,10 @@ class IdentitiesController extends BaseController { } }); } else { - _hideHtmlSignature(); final newIdentityArguments = await push( AppRoutes.identityCreator, arguments: arguments); - if(newIdentityArguments == true) { - _showHtmlSignature(); - } - if (newIdentityArguments is CreateNewIdentityRequest) { _createNewIdentityAction(session, accountId, newIdentityArguments); } else if (newIdentityArguments is EditIdentityRequest) { @@ -199,7 +193,6 @@ class IdentitiesController extends BaseController { currentOverlayContext!, AppLocalizations.of(currentContext!).you_have_created_a_new_identity); } - _showHtmlSignature(); _refreshAllIdentities(); } @@ -210,7 +203,6 @@ class IdentitiesController extends BaseController { currentOverlayContext!, AppLocalizations.of(currentContext!).you_have_created_a_new_default_identity); } - _showHtmlSignature(); _refreshAllIdentities(); } @@ -295,15 +287,10 @@ class IdentitiesController extends BaseController { } }); } else { - _hideHtmlSignature(); final newIdentityArguments = await push( AppRoutes.identityCreator, arguments: arguments); - if(newIdentityArguments == true) { - _showHtmlSignature(); - } - if (newIdentityArguments is CreateNewIdentityRequest) { _createNewIdentityAction(session, accountId, newIdentityArguments); } else if (newIdentityArguments is EditIdentityRequest) { @@ -331,7 +318,6 @@ class IdentitiesController extends BaseController { currentOverlayContext!, AppLocalizations.of(currentContext!).you_are_changed_your_identity_successfully); } - _showHtmlSignature(); _refreshAllIdentities(); } @@ -339,13 +325,4 @@ class IdentitiesController extends BaseController { ImagePaths get imagePaths => _imagePaths; bool get isSignatureShow => identitySelected.value != null; - - bool get isShowHtmlSignature => _htmlSignature.value ?? true; - - void _hideHtmlSignature() async { - await Future.delayed(const Duration(milliseconds: 100)); - _htmlSignature.value = false; - } - - void _showHtmlSignature() => _htmlSignature.value = true; } \ No newline at end of file diff --git a/lib/features/manage_account/presentation/profiles/identities/widgets/identities_radio_list_builder.dart b/lib/features/manage_account/presentation/profiles/identities/widgets/identities_radio_list_builder.dart index 3d5dcf291..7801b6a5b 100644 --- a/lib/features/manage_account/presentation/profiles/identities/widgets/identities_radio_list_builder.dart +++ b/lib/features/manage_account/presentation/profiles/identities/widgets/identities_radio_list_builder.dart @@ -49,7 +49,7 @@ class IdentitiesRadioListBuilder extends StatelessWidget { _buildListIdentityView(context), Container(height: 1, color: AppColor.attachmentFileBorderColor), Obx(() { - if (controller.isShowHtmlSignature) { + if (controller.isSignatureShow) { return SignatureBuilder(controller.signatureSelected.value!); } else { return _buildLoadingView();