From fc4ca58d4e73acfb56acd9defaf6b9660fd42ef7 Mon Sep 17 00:00:00 2001 From: dab246 Date: Mon, 1 Jul 2024 14:59:30 +0700 Subject: [PATCH] TF-2475 Add onSubjectTextListener for subject focus node --- .../presentation/composer_controller.dart | 64 ++++++++++--------- .../composer/presentation/composer_view.dart | 2 - .../presentation/composer_view_web.dart | 3 - .../rich_text_mobile_tablet_controller.dart | 17 ++--- .../widgets/subject_composer_widget.dart | 3 - .../menu/settings/settings_view.dart | 8 ++- .../vacation/vacation_controller.dart | 15 +++-- pubspec.lock | 12 ++-- pubspec.yaml | 4 +- 9 files changed, 66 insertions(+), 62 deletions(-) diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart index 74e4ea7ec..4bbf61c6c 100644 --- a/lib/features/composer/presentation/composer_controller.dart +++ b/lib/features/composer/presentation/composer_controller.dart @@ -430,8 +430,10 @@ class ComposerController extends BaseController with DragDropFileMixin { void _subjectEmailInputFocusListener() { if (subjectEmailInputFocusNode?.hasFocus == true) { - if (PlatformInfo.isMobile) { - htmlEditorApi?.unfocus(); + if (PlatformInfo.isMobile + && currentContext != null + && !responsiveUtils.isScreenWithShortestSide(currentContext!)) { + richTextMobileTabletController?.richTextController.hideRichTextView(); } _collapseAllRecipient(); _autoCreateEmailTag(); @@ -454,17 +456,13 @@ class ComposerController extends BaseController with DragDropFileMixin { richTextMobileTabletController?.richTextController.onCreateHTMLEditor( editorApi, onEnterKeyDown: _onEnterKeyDown, - onFocus: () => _onEditorFocusOnMobile(context), + onFocus: _onEditorFocusOnMobile, onChangeCursor: (coordinates) { _onChangeCursorOnMobile(coordinates, context); }, ); } - void onTapOutsideSubject(PointerDownEvent event) { - subjectEmailInputFocusNode?.unfocus(); - } - void onLoadCompletedMobileEditorAction(HtmlEditorApi editorApi, WebUri? url) async { _isEmailBodyLoaded = true; if (identitySelected.value == null) { @@ -1379,13 +1377,6 @@ class ComposerController extends BaseController with DragDropFileMixin { } } - void onEditorFocusChange(bool isFocus) { - if (isFocus) { - _collapseAllRecipient(); - _autoCreateEmailTag(); - } - } - void _collapseAllRecipient() { toAddressExpandMode.value = ExpandMode.COLLAPSE; ccAddressExpandMode.value = ExpandMode.COLLAPSE; @@ -1505,7 +1496,9 @@ class ComposerController extends BaseController with DragDropFileMixin { break; } _closeSuggestionBox(); - if (PlatformInfo.isMobile) { + if (PlatformInfo.isMobile + && currentContext != null + && !responsiveUtils.isScreenWithShortestSide(currentContext!)) { richTextMobileTabletController?.richTextController.hideRichTextView(); } } else { @@ -1645,9 +1638,11 @@ class ComposerController extends BaseController with DragDropFileMixin { _closeComposerAction(); } - Future _onEditorFocusOnMobile(BuildContext context) async { + Future _onEditorFocusOnMobile() async { if (PlatformInfo.isAndroid) { - FocusScope.of(context).unfocus(); + if (FocusManager.instance.primaryFocus?.hasFocus == true) { + FocusManager.instance.primaryFocus?.unfocus(); + } await Future.delayed( const Duration(milliseconds: 300), richTextMobileTabletController?.richTextController.showDeviceKeyboard); @@ -1709,8 +1704,8 @@ class ComposerController extends BaseController with DragDropFileMixin { hasRequestReadReceipt.toggle(); } - void _autoFocusFieldWhenLauncher() { - if (_hasInputFieldFocused) { + Future _autoFocusFieldWhenLauncher() async { + if (await _hasInputFieldFocused()) { log('ComposerController::_autoFocusFieldWhenLauncher: INPUT_FIELD_FOCUS = true'); return; } @@ -1725,14 +1720,28 @@ class ComposerController extends BaseController with DragDropFileMixin { subjectEmailInputFocusNode?.requestFocus(); } else if (PlatformInfo.isWeb) { richTextWebController?.editorController.setFocus(); + } else if (PlatformInfo.isIOS) { + await richTextMobileTabletController?.htmlEditorApi?.requestFocus(); } } - bool get _hasInputFieldFocused => - toAddressFocusNode?.hasFocus == true || - ccAddressFocusNode?.hasFocus == true || - bccAddressFocusNode?.hasFocus == true || - subjectEmailInputFocusNode?.hasFocus == true; + Future _hasInputFieldFocused() async { + if (PlatformInfo.isWeb) { + return toAddressFocusNode?.hasFocus == true || + ccAddressFocusNode?.hasFocus == true || + bccAddressFocusNode?.hasFocus == true || + subjectEmailInputFocusNode?.hasFocus == true; + } else if (PlatformInfo.isMobile) { + final isEditorFocused = (await richTextMobileTabletController?.isEditorFocused) ?? false; + return toAddressFocusNode?.hasFocus == true || + ccAddressFocusNode?.hasFocus == true || + bccAddressFocusNode?.hasFocus == true || + subjectEmailInputFocusNode?.hasFocus == true || + isEditorFocused; + } + return false; + } + void handleInitHtmlEditorWeb(String initContent) async { log('ComposerController::handleInitHtmlEditorWeb:'); @@ -1755,14 +1764,11 @@ class ComposerController extends BaseController with DragDropFileMixin { richTextWebController?.closeAllMenuPopup(); } - void handleOnUnFocusHtmlEditorWeb() { - onEditorFocusChange(false); - } - void handleOnMouseDownHtmlEditorWeb(BuildContext context) { Navigator.maybePop(context); FocusScope.of(context).unfocus(); - onEditorFocusChange(true); + _collapseAllRecipient(); + _autoCreateEmailTag(); } FocusNode? getNextFocusOfToEmailAddress() { diff --git a/lib/features/composer/presentation/composer_view.dart b/lib/features/composer/presentation/composer_view.dart index a805c443f..ab1ee1c05 100644 --- a/lib/features/composer/presentation/composer_view.dart +++ b/lib/features/composer/presentation/composer_view.dart @@ -201,7 +201,6 @@ class ComposerView extends GetWidget { onTextChange: controller.setSubjectEmail, padding: ComposerStyle.mobileSubjectPadding, margin: ComposerStyle.mobileSubjectMargin, - onTapOutside: controller.onTapOutsideSubject, ), Obx(() { if (controller.uploadController.listUploadAttachments.isNotEmpty) { @@ -350,7 +349,6 @@ class ComposerView extends GetWidget { onTextChange: controller.setSubjectEmail, padding: ComposerStyle.mobileSubjectPadding, margin: ComposerStyle.mobileSubjectMargin, - onTapOutside: controller.onTapOutsideSubject, ), Obx(() { if (controller.uploadController.listUploadAttachments.isNotEmpty) { diff --git a/lib/features/composer/presentation/composer_view_web.dart b/lib/features/composer/presentation/composer_view_web.dart index efe72a168..d992b0caa 100644 --- a/lib/features/composer/presentation/composer_view_web.dart +++ b/lib/features/composer/presentation/composer_view_web.dart @@ -184,7 +184,6 @@ class ComposerView extends GetWidget { onInitial: controller.handleInitHtmlEditorWeb, onChangeContent: controller.onChangeTextEditorWeb, onFocus: controller.handleOnFocusHtmlEditorWeb, - onUnFocus: controller.handleOnUnFocusHtmlEditorWeb, onMouseDown: controller.handleOnMouseDownHtmlEditorWeb, onEditorSettings: controller.richTextWebController!.onEditorSettingsChange, onEditorTextSizeChanged: controller.richTextWebController!.onEditorTextSizeChanged, @@ -425,7 +424,6 @@ class ComposerView extends GetWidget { onInitial: controller.handleInitHtmlEditorWeb, onChangeContent: controller.onChangeTextEditorWeb, onFocus: controller.handleOnFocusHtmlEditorWeb, - onUnFocus: controller.handleOnUnFocusHtmlEditorWeb, onMouseDown: controller.handleOnMouseDownHtmlEditorWeb, onEditorSettings: controller.richTextWebController?.onEditorSettingsChange, onEditorTextSizeChanged: controller.richTextWebController?.onEditorTextSizeChanged, @@ -687,7 +685,6 @@ class ComposerView extends GetWidget { onInitial: controller.handleInitHtmlEditorWeb, onChangeContent: controller.onChangeTextEditorWeb, onFocus: controller.handleOnFocusHtmlEditorWeb, - onUnFocus: controller.handleOnUnFocusHtmlEditorWeb, onMouseDown: controller.handleOnMouseDownHtmlEditorWeb, onEditorSettings: controller.richTextWebController!.onEditorSettingsChange, onEditorTextSizeChanged: controller.richTextWebController!.onEditorTextSizeChanged, diff --git a/lib/features/composer/presentation/controller/rich_text_mobile_tablet_controller.dart b/lib/features/composer/presentation/controller/rich_text_mobile_tablet_controller.dart index 75c626c69..0501ab12a 100644 --- a/lib/features/composer/presentation/controller/rich_text_mobile_tablet_controller.dart +++ b/lib/features/composer/presentation/controller/rich_text_mobile_tablet_controller.dart @@ -1,8 +1,8 @@ import 'dart:io'; -import 'package:core/presentation/utils/keyboard_utils.dart'; import 'package:core/utils/app_logger.dart'; import 'package:core/utils/html/html_utils.dart'; +import 'package:core/utils/platform_info.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/cupertino.dart'; import 'package:rich_text_composer/rich_text_composer.dart'; @@ -16,10 +16,12 @@ class RichTextMobileTabletController extends BaseRichTextController { final RichTextController richTextController = RichTextController(); + Future get isEditorFocused async => await htmlEditorApi?.hasFocus() ?? false; + void insertImage(InlineImage inlineImage) async { - bool isEditorFocused = await htmlEditorApi?.hasFocus() ?? false; - log('RichTextMobileTabletController::insertImage: isEditorFocused = $isEditorFocused'); - if (!isEditorFocused) { + final isFocused = await isEditorFocused; + log('RichTextMobileTabletController::insertImage: isEditorFocused = $isFocused'); + if (!isFocused) { await htmlEditorApi?.requestFocusLastChild(); } if (inlineImage.base64Uri?.isNotEmpty == true) { @@ -53,10 +55,9 @@ class RichTextMobileTabletController extends BaseRichTextController { required BuildContext context, required RichTextController? richTextController }) async { - if (Platform.isAndroid) { - await htmlEditorApi?.storeSelectionRange(); - KeyboardUtils.hideSystemKeyboardMobile(); - } else { + if (PlatformInfo.isAndroid) { + await htmlEditorApi?.hideKeyboard(); + } else if (PlatformInfo.isIOS) { await htmlEditorApi?.unfocus(); } diff --git a/lib/features/composer/presentation/widgets/subject_composer_widget.dart b/lib/features/composer/presentation/widgets/subject_composer_widget.dart index 6e6a1bae4..cfc4d8a7a 100644 --- a/lib/features/composer/presentation/widgets/subject_composer_widget.dart +++ b/lib/features/composer/presentation/widgets/subject_composer_widget.dart @@ -11,7 +11,6 @@ class SubjectComposerWidget extends StatelessWidget { final ValueChanged? onTextChange; final EdgeInsetsGeometry? margin; final EdgeInsetsGeometry? padding; - final TapRegionCallback? onTapOutside; const SubjectComposerWidget({ super.key, @@ -20,7 +19,6 @@ class SubjectComposerWidget extends StatelessWidget { required this.onTextChange, this.margin, this.padding, - this.onTapOutside, }); @override @@ -52,7 +50,6 @@ class SubjectComposerWidget extends StatelessWidget { textDirection: DirectionUtils.getDirectionByLanguage(context), textStyle: SubjectComposerWidgetStyle.inputTextStyle, controller: textController, - onTapOutside: onTapOutside, ) ) ] diff --git a/lib/features/manage_account/presentation/menu/settings/settings_view.dart b/lib/features/manage_account/presentation/menu/settings/settings_view.dart index ab292617a..3a85a77e9 100644 --- a/lib/features/manage_account/presentation/menu/settings/settings_view.dart +++ b/lib/features/manage_account/presentation/menu/settings/settings_view.dart @@ -236,7 +236,9 @@ class SettingsView extends GetWidget { } case AccountMenuItem.alwaysReadReceipt: if (controller.manageAccountDashboardController.isServerSettingsCapabilitySupported) { - return const AlwaysReadReceiptView(); + return const SafeArea( + top: false, + child: AlwaysReadReceiptView()); } else { return const SizedBox.shrink(); } @@ -259,7 +261,9 @@ class SettingsView extends GetWidget { top: false, child: MailboxVisibilityView()); case AccountMenuItem.notification: - return const NotificationView(); + return const SafeArea( + top: false, + child: NotificationView()); default: return const SizedBox.shrink(); } diff --git a/lib/features/manage_account/presentation/vacation/vacation_controller.dart b/lib/features/manage_account/presentation/vacation/vacation_controller.dart index 43323bb3f..80b9ce490 100644 --- a/lib/features/manage_account/presentation/vacation/vacation_controller.dart +++ b/lib/features/manage_account/presentation/vacation/vacation_controller.dart @@ -95,13 +95,13 @@ class VacationController extends BaseController { } void _initFocusListener() { - subjectTextFocusNode.addListener(() { - if (subjectTextFocusNode.hasFocus == true) { - if (PlatformInfo.isMobile) { - richTextControllerForMobile.hideRichTextView(); - } - } - }); + subjectTextFocusNode.addListener(_onSubjectTextListener); + } + + void _onSubjectTextListener() { + if (subjectTextFocusNode.hasFocus && PlatformInfo.isMobile) { + richTextControllerForMobile.hideRichTextView(); + } } void _getAllVacation() { @@ -410,6 +410,7 @@ class VacationController extends BaseController { @override void onClose() { + subjectTextFocusNode.removeListener(_onSubjectTextListener); subjectTextFocusNode.dispose(); subjectTextController.dispose(); richTextControllerForMobile.dispose(); diff --git a/pubspec.lock b/pubspec.lock index b20cce3c9..f10241d37 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -436,8 +436,8 @@ packages: dependency: transitive description: path: "." - ref: cherry-pick-fix-rich-text-format-style - resolved-ref: "7041e5822707ab57fcf36964c38556e2d27b06e2" + ref: cnb_supported + resolved-ref: "8301d67b4c30bb2234bbe96de4ae135b88a6af40" url: "https://github.com/linagora/enough_html_editor.git" source: git version: "0.0.5" @@ -1106,8 +1106,8 @@ packages: dependency: "direct main" description: path: "." - ref: cherry-pick-fix-rich-text-format-style - resolved-ref: "2ce34bf07bc0239a6b2502d9ddf0acd8cd2f28e3" + ref: cnb_supported + resolved-ref: ddcfb76517161f63d63470526fe54bf74deac955 url: "https://github.com/linagora/html-editor-enhanced.git" source: git version: "2.5.1" @@ -1621,8 +1621,8 @@ packages: dependency: "direct main" description: path: "." - ref: cherry-pick-fix-rich-text-format-style - resolved-ref: "88dc2d55dabe254c0932410582ae049f4b0c7e54" + ref: cnb_supported + resolved-ref: "955d70b3e57ddeed2b709ee8822c7a8a620e1aaa" url: "https://github.com/linagora/rich-text-composer.git" source: git version: "0.0.2" diff --git a/pubspec.yaml b/pubspec.yaml index ccaad69a7..063059f69 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -55,12 +55,12 @@ dependencies: rich_text_composer: git: url: https://github.com/linagora/rich-text-composer.git - ref: cherry-pick-fix-rich-text-format-style + ref: cnb_supported html_editor_enhanced: git: url: https://github.com/linagora/html-editor-enhanced.git - ref: cherry-pick-fix-rich-text-format-style + ref: cnb_supported # TODO: We will change it when the PR in upstream repository will be merged # https://github.com/linagora/jmap-dart-client/pull/87