diff --git a/lib/features/identity_creator/presentation/identity_creator_controller.dart b/lib/features/identity_creator/presentation/identity_creator_controller.dart index 3e849a94a..d962f54d5 100644 --- a/lib/features/identity_creator/presentation/identity_creator_controller.dart +++ b/lib/features/identity_creator/presentation/identity_creator_controller.dart @@ -1,9 +1,7 @@ import 'package:core/utils/app_logger.dart'; import 'package:core/utils/build_utils.dart'; -import 'package:enough_html_editor/enough_html_editor.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'; @@ -19,7 +17,6 @@ import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:model/model.dart'; import 'package:rich_text_composer/richtext_controller.dart'; import 'package:tmail_ui_user/features/base/base_controller.dart'; -import 'package:tmail_ui_user/features/composer/presentation/controller/rich_text_mobile_tablet_controller.dart'; import 'package:tmail_ui_user/features/composer/presentation/controller/rich_text_web_controller.dart'; import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_bindings.dart'; import 'package:tmail_ui_user/features/identity_creator/presentation/model/identity_creator_arguments.dart'; @@ -32,6 +29,7 @@ import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_id import 'package:tmail_ui_user/features/manage_account/domain/model/edit_identity_request.dart'; import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_identities_state.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/extensions/identity_extension.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/identity_action_type.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/utils/identity_utils.dart'; import 'package:tmail_ui_user/main/error/capability_validator.dart'; @@ -63,7 +61,6 @@ class IdentityCreatorController extends BaseController { late RichTextController keyboardRichTextController; late RichTextWebController richTextWebController; - late RichTextMobileTabletController richTextMobileTabletController; late HtmlEditorController signatureHtmlEditorController; TextEditingController? inputNameIdentityController; TextEditingController? inputBccIdentityController; @@ -78,9 +75,10 @@ class IdentityCreatorController extends BaseController { IdentityCreatorArguments? arguments; OnCreatedIdentityCallback? onCreatedIdentityCallback; VoidCallback? onDismissIdentityCreator; - ScrollController? scrollController; + final ScrollController scrollController = ScrollController(); final GlobalKey htmlKey = GlobalKey(); + final htmlEditorMinHeight = 160; void updateNameIdentity(BuildContext context, String? value) { _nameIdentity = value; @@ -89,9 +87,13 @@ class IdentityCreatorController extends BaseController { void updateContentHtmlEditor(String? text) => _contentHtmlEditor = text; - HtmlEditorApi? get signatureHtmlEditorMobileController => richTextMobileTabletController.htmlEditorApi; - - String? get contentHtmlEditor => _contentHtmlEditor ?? arguments?.identity?.htmlSignature?.value; + String? get contentHtmlEditor { + if (_contentHtmlEditor != null) { + return _contentHtmlEditor; + } else { + return arguments?.identity?.signatureAsString; + } + } IdentityCreatorController( this._verifyNameInteractor, @@ -104,13 +106,10 @@ class IdentityCreatorController extends BaseController { super.onInit(); keyboardRichTextController = RichTextController(); richTextWebController = RichTextWebController(); - richTextMobileTabletController = RichTextMobileTabletController(); - signatureHtmlEditorController = - HtmlEditorController(processNewLineAsBr: true); + signatureHtmlEditorController = HtmlEditorController(processNewLineAsBr: true); inputNameIdentityController = TextEditingController(); inputBccIdentityController = TextEditingController(); inputNameIdentityFocusNode = FocusNode(); - scrollController = ScrollController(); } @override @@ -291,7 +290,7 @@ class IdentityCreatorController extends BaseController { if (BuildUtils.isWeb) { return signatureHtmlEditorController.getText(); } else { - return signatureHtmlEditorMobileController?.getText(); + return keyboardRichTextController.htmlEditorApi?.getText(); } } @@ -423,11 +422,9 @@ class IdentityCreatorController extends BaseController { void clearFocusEditor(BuildContext context) { if (!BuildUtils.isWeb) { - signatureHtmlEditorMobileController?.unfocus(); - richTextMobileTabletController.htmlEditorApi?.unfocus(); - keyboardRichTextController.hideRichTextView(); + keyboardRichTextController.htmlEditorApi?.unfocus(); } - SystemChannels.textInput.invokeMethod('TextInput.hide'); + FocusScope.of(context).unfocus(); } void closeView(BuildContext context) { @@ -447,28 +444,29 @@ class IdentityCreatorController extends BaseController { inputNameIdentityController = null; inputBccIdentityController?.dispose(); inputBccIdentityController = null; - scrollController?.dispose(); - scrollController = null; + scrollController.dispose(); } - void onFocusHTMLEditor() async { - await Scrollable.ensureVisible(htmlKey.currentContext!); + void onFocusHTMLEditorOnMobile() async { + if (htmlKey.currentContext != null) { + await Scrollable.ensureVisible(htmlKey.currentContext!); + } await Future.delayed(const Duration(milliseconds: 500), () { - if (scrollController != null) { - scrollController!.animateTo( - scrollController!.position.pixels + defaultKeyboardToolbarHeight, - duration: const Duration(milliseconds: 1), - curve: Curves.linear, - ); - } + final offset = scrollController.position.pixels + + defaultKeyboardToolbarHeight + + htmlEditorMinHeight; + scrollController.animateTo( + offset, + duration: const Duration(milliseconds: 1), + curve: Curves.linear, + ); }); } - void onEnterKeyDown() { - if(scrollController != null && - scrollController!.position.pixels < scrollController!.position.maxScrollExtent) { - scrollController!.animateTo( - scrollController!.position.pixels + 20, + void onEnterKeyDownOnMobile() { + if(scrollController.position.pixels < scrollController.position.maxScrollExtent) { + scrollController.animateTo( + scrollController.position.pixels + 20, duration: const Duration(milliseconds: 1), curve: Curves.linear, ); diff --git a/lib/features/identity_creator/presentation/identity_creator_view.dart b/lib/features/identity_creator/presentation/identity_creator_view.dart index 7d48d9ea4..01016dca5 100644 --- a/lib/features/identity_creator/presentation/identity_creator_view.dart +++ b/lib/features/identity_creator/presentation/identity_creator_view.dart @@ -54,10 +54,10 @@ class IdentityCreatorView extends GetWidget { onTap: () => controller.clearFocusEditor(context), child: SizedBox( height: MediaQuery.of(context).size.height * 0.95, - child: SafeArea( - child: BuildUtils.isWeb ? Scaffold(body: _buildBodyMobile(context)) : _buildBodyMobile(context), - ), - ) + child: BuildUtils.isWeb + ? Scaffold(body: _buildBodyMobile(context)) + : _buildBodyMobile(context) + ) ), landscapeMobile: Scaffold( backgroundColor: Colors.white, @@ -164,7 +164,7 @@ class IdentityCreatorView extends GetWidget { physics: const ClampingScrollPhysics(), child: Padding( padding: const EdgeInsets.all(24.0), - child: Column(children: [ + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Obx(() => (IdentityInputFieldBuilder( AppLocalizations.of(context).name, controller.errorNameIdentity.value, @@ -237,9 +237,8 @@ class IdentityCreatorView extends GetWidget { const SizedBox(height: 8), PointerInterceptor( child: Container( - height: 300, decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), + borderRadius: BorderRadius.circular(12), border: Border.all(color: AppColor.colorInputBorderCreateMailbox), color: Colors.white, ), @@ -361,84 +360,78 @@ class IdentityCreatorView extends GetWidget { ? _buildHtmlEditorWeb(context, controller.contentHtmlEditor ?? '') : _buildHtmlEditor(context, initialContent: controller.contentHtmlEditor ?? ''); - return SizedBox( - height: 300, - child: Column( - children: [ - if(BuildUtils.isWeb) - ToolbarRichTextWebBuilder( - richTextWebController: controller.richTextWebController, - padding: const EdgeInsets.only(top: 22, bottom: 8.0, left: 24, right: 12)), - htmlEditor, - ], - ), + return Column( + children: [ + if(BuildUtils.isWeb) + ToolbarRichTextWebBuilder( + richTextWebController: controller.richTextWebController, + padding: const EdgeInsets.only(top: 22, bottom: 8.0, left: 24, right: 12)), + htmlEditor, + ], ); } Widget _buildHtmlEditorWeb(BuildContext context, String initContent) { log('IdentityCreatorView::_buildHtmlEditorWeb(): initContent: $initContent'); - return Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 14.0, right: 2.0), - child: html_editor_browser.HtmlEditor( - key: const Key('identity_create_editor_web'), - controller: controller.richTextWebController.editorController, - htmlEditorOptions: const HtmlEditorOptions( - hint: '', - darkMode: false, - customBodyCssStyle: bodyCssStyleForEditor), - blockQuotedContent: initContent, - htmlToolbarOptions: const HtmlToolbarOptions( - toolbarType: ToolbarType.hide, - defaultToolbarButtons: []), - otherOptions: const OtherOptions(height: 550), - callbacks: Callbacks(onBeforeCommand: (currentHtml) { - log('IdentityCreatorView::_buildHtmlEditorWeb(): onBeforeCommand : $currentHtml'); - controller.updateContentHtmlEditor(currentHtml); - }, onChangeContent: (changed) { - log('IdentityCreatorView::_buildHtmlEditorWeb(): onChangeContent : $changed'); - controller.updateContentHtmlEditor(changed); - }, onInit: () { - log('IdentityCreatorView::_buildHtmlEditorWeb(): onInit'); - controller.updateContentHtmlEditor(initContent); - controller.richTextWebController.setFullScreenEditor(); - controller.richTextWebController.setEnableCodeView(); - }, onFocus: () { - log('IdentityCreatorView::_buildHtmlEditorWeb(): onFocus'); - FocusManager.instance.primaryFocus?.unfocus(); - Future.delayed(const Duration(milliseconds: 500), () { - controller.richTextWebController.editorController.setFocus(); - }); - controller.richTextWebController.closeAllMenuPopup(); - }, onChangeSelection: (settings) { - controller.richTextWebController.onEditorSettingsChange(settings); - }, onChangeCodeview: (contentChanged) { - log('IdentityCreatorView::_buildHtmlEditorWeb(): onChangeCodeView : $contentChanged'); - controller.updateContentHtmlEditor(contentChanged); - }), - ), + return Padding( + padding: const EdgeInsets.only(left: 14.0, right: 2.0), + child: html_editor_browser.HtmlEditor( + key: const Key('identity_create_editor_web'), + controller: controller.richTextWebController.editorController, + htmlEditorOptions: const HtmlEditorOptions( + hint: '', + darkMode: false, + customBodyCssStyle: bodyCssStyleForEditor), + blockQuotedContent: initContent, + htmlToolbarOptions: const HtmlToolbarOptions( + toolbarType: ToolbarType.hide, + defaultToolbarButtons: []), + otherOptions: const OtherOptions(height: 150), + callbacks: Callbacks(onBeforeCommand: (currentHtml) { + log('IdentityCreatorView::_buildHtmlEditorWeb(): onBeforeCommand : $currentHtml'); + controller.updateContentHtmlEditor(currentHtml); + }, onChangeContent: (changed) { + log('IdentityCreatorView::_buildHtmlEditorWeb(): onChangeContent : $changed'); + controller.updateContentHtmlEditor(changed); + }, onInit: () { + log('IdentityCreatorView::_buildHtmlEditorWeb(): onInit'); + controller.updateContentHtmlEditor(initContent); + controller.richTextWebController.setFullScreenEditor(); + controller.richTextWebController.setEnableCodeView(); + }, onFocus: () { + log('IdentityCreatorView::_buildHtmlEditorWeb(): onFocus'); + FocusManager.instance.primaryFocus?.unfocus(); + Future.delayed(const Duration(milliseconds: 500), () { + controller.richTextWebController.editorController.setFocus(); + }); + controller.richTextWebController.closeAllMenuPopup(); + }, onChangeSelection: (settings) { + controller.richTextWebController.onEditorSettingsChange(settings); + }, onChangeCodeview: (contentChanged) { + log('IdentityCreatorView::_buildHtmlEditorWeb(): onChangeCodeView : $contentChanged'); + controller.updateContentHtmlEditor(contentChanged); + }), ), ); } Widget _buildHtmlEditor(BuildContext context, {String? initialContent}) { - final richTextMobileTabletController = controller.richTextMobileTabletController; - return Focus( - focusNode: controller.htmlEditorNode, + return Padding( + padding: const EdgeInsets.all(16), child: html_editor_mobile.HtmlEditor( - key: const Key('identity_create_editor'), - minHeight: 111, + key: controller.htmlKey, + minHeight: controller.htmlEditorMinHeight, addDefaultSelectionMenuItems: false, initialContent: initialContent ?? '', onCreated: (editorApi) { - richTextMobileTabletController.htmlEditorApi = editorApi; - controller.keyboardRichTextController.onCreateHTMLEditor( - editorApi, - onEnterKeyDown: controller.onEnterKeyDown, - context: context, - ); + controller.keyboardRichTextController.onCreateHTMLEditor( + editorApi, + onEnterKeyDown: controller.onEnterKeyDownOnMobile, + onFocus: controller.onFocusHTMLEditorOnMobile, + context: context + ); }, - ) + ), ); }