From 9609e7ee9c04fe9ee7dfa8a10176dba635c88d04 Mon Sep 17 00:00:00 2001 From: dab246 Date: Wed, 1 Mar 2023 17:36:40 +0700 Subject: [PATCH] TF-1512 Show keyboard below editor while type text --- .../identity_creator_controller.dart | 55 +++++++------ .../presentation/identity_creator_view.dart | 81 ++++++++++++------- .../identities/identities_controller.dart | 32 ++------ lib/main/pages/app_pages.dart | 10 +++ 4 files changed, 98 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 d962f54d5..144444d55 100644 --- a/lib/features/identity_creator/presentation/identity_creator_controller.dart +++ b/lib/features/identity_creator/presentation/identity_creator_controller.dart @@ -18,7 +18,6 @@ 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_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'; import 'package:tmail_ui_user/features/mailbox_creator/domain/model/verification/email_address_validator.dart'; import 'package:tmail_ui_user/features/mailbox_creator/domain/model/verification/empty_name_validator.dart'; @@ -56,8 +55,6 @@ class IdentityCreatorController extends BaseController { final bccOfIdentity = Rxn(); final actionType = IdentityActionType.create.obs; final isDefaultIdentity = RxBool(false); - final htmlEditorNode = FocusNode(debugLabel: 'html_editor'); - final identityCreatorBinding = IdentityCreatorBindings(); late RichTextController keyboardRichTextController; late RichTextWebController richTextWebController; @@ -75,8 +72,8 @@ class IdentityCreatorController extends BaseController { IdentityCreatorArguments? arguments; OnCreatedIdentityCallback? onCreatedIdentityCallback; VoidCallback? onDismissIdentityCreator; + ScrollController? scrollController; - final ScrollController scrollController = ScrollController(); final GlobalKey htmlKey = GlobalKey(); final htmlEditorMinHeight = 160; @@ -110,6 +107,7 @@ class IdentityCreatorController extends BaseController { inputNameIdentityController = TextEditingController(); inputBccIdentityController = TextEditingController(); inputNameIdentityFocusNode = FocusNode(); + scrollController = ScrollController(); } @override @@ -128,7 +126,6 @@ class IdentityCreatorController extends BaseController { @override void onClose() { - keyboardRichTextController.dispose(); _disposeWidget(); super.onClose(); } @@ -153,9 +150,11 @@ class IdentityCreatorController extends BaseController { _nameIdentity = identity?.name ?? ''; inputNameIdentityController?.text = identity?.name ?? ''; - if (identity?.htmlSignature?.value.isNotEmpty == true) { - updateContentHtmlEditor(arguments?.identity?.htmlSignature?.value ?? ''); - signatureHtmlEditorController.setText(arguments?.identity?.htmlSignature?.value ?? ''); + if (identity?.signatureAsString.isNotEmpty == true) { + updateContentHtmlEditor(arguments?.identity?.signatureAsString ?? ''); + if (BuildUtils.isWeb) { + signatureHtmlEditorController.setText(arguments?.identity?.signatureAsString ?? ''); + } } } @@ -339,14 +338,13 @@ class IdentityCreatorController extends BaseController { newIdentity, isDefaultIdentity: isDefaultIdentity.value ); - _disposeWidget(); if (BuildUtils.isWeb) { + _disposeWidget(); onCreatedIdentityCallback?.call(identityRequest); } else { popBack(result: identityRequest); } - } else { final identityRequest = EditIdentityRequest( identityId: identity!.id!, @@ -360,7 +358,6 @@ class IdentityCreatorController extends BaseController { popBack(result: identityRequest); } } - identityCreatorBinding.dispose(); } void onCheckboxChanged() { @@ -433,40 +430,42 @@ class IdentityCreatorController extends BaseController { onDismissIdentityCreator?.call(); } else { popBack(); - identityCreatorBinding.dispose(); } } void _disposeWidget() { + keyboardRichTextController.dispose(); inputNameIdentityFocusNode?.dispose(); inputNameIdentityFocusNode = null; inputNameIdentityController?.dispose(); inputNameIdentityController = null; inputBccIdentityController?.dispose(); inputBccIdentityController = null; - scrollController.dispose(); + scrollController?.dispose(); } void onFocusHTMLEditorOnMobile() async { - if (htmlKey.currentContext != null) { - await Scrollable.ensureVisible(htmlKey.currentContext!); + if (scrollController != null) { + if (htmlKey.currentContext != null) { + await Scrollable.ensureVisible(htmlKey.currentContext!); + } + await Future.delayed(const Duration(milliseconds: 500), () { + final offset = scrollController!.position.pixels + + defaultKeyboardToolbarHeight + + htmlEditorMinHeight; + scrollController!.animateTo( + offset, + duration: const Duration(milliseconds: 1), + curve: Curves.linear, + ); + }); } - await Future.delayed(const Duration(milliseconds: 500), () { - final offset = scrollController.position.pixels + - defaultKeyboardToolbarHeight + - htmlEditorMinHeight; - scrollController.animateTo( - offset, - duration: const Duration(milliseconds: 1), - curve: Curves.linear, - ); - }); } void onEnterKeyDownOnMobile() { - if(scrollController.position.pixels < scrollController.position.maxScrollExtent) { - scrollController.animateTo( - scrollController.position.pixels + 20, + if (scrollController != null && 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 01016dca5..6dddfd516 100644 --- a/lib/features/identity_creator/presentation/identity_creator_view.dart +++ b/lib/features/identity_creator/presentation/identity_creator_view.dart @@ -50,14 +50,47 @@ class IdentityCreatorView extends GetWidget { Widget build(BuildContext context) { return ResponsiveWidget( responsiveUtils: _responsiveUtils, - mobile: GestureDetector( - onTap: () => controller.clearFocusEditor(context), - child: SizedBox( - height: MediaQuery.of(context).size.height * 0.95, - child: BuildUtils.isWeb - ? Scaffold(body: _buildBodyMobile(context)) - : _buildBodyMobile(context) - ) + mobile: Card( + margin: EdgeInsets.zero, + borderOnForeground: false, + color: Colors.transparent, + child: SafeArea( + top: !BuildUtils.isWeb, + bottom: false, + left: false, + right: false, + child: ClipRRect( + borderRadius: const BorderRadius.only( + topRight: Radius.circular(16), + topLeft: Radius.circular(16)), + child: GestureDetector( + onTap: () => controller.clearFocusEditor(context), + child: Scaffold( + backgroundColor: Colors.white, + body: Container( + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topRight: Radius.circular(16), + topLeft: Radius.circular(16)), + boxShadow: [ + BoxShadow( + color: AppColor.colorShadowLayerBottom, + blurRadius: 96, + spreadRadius: 96, + offset: Offset.zero), + BoxShadow( + color: AppColor.colorShadowLayerTop, + blurRadius: 2, + spreadRadius: 2, + offset: Offset.zero), + ]), + child: _buildBodyMobile(context), + ), + ), + ), + ), + ), ), landscapeMobile: Scaffold( backgroundColor: Colors.white, @@ -163,7 +196,7 @@ class IdentityCreatorView extends GetWidget { controller: controller.scrollController, physics: const ClampingScrollPhysics(), child: Padding( - padding: const EdgeInsets.all(24.0), + padding: const EdgeInsets.all(24.0), child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Obx(() => (IdentityInputFieldBuilder( AppLocalizations.of(context).name, @@ -223,27 +256,21 @@ class IdentityCreatorView extends GetWidget { .build() ), const SizedBox(height: 32), - Row( - children: [ - Text(AppLocalizations.of(context).signature, - style: const TextStyle( - fontWeight: FontWeight.normal, - fontSize: 14, - color: AppColor.colorContentEmail, - ), - ), - ], + Text(AppLocalizations.of(context).signature, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 14, + color: AppColor.colorContentEmail, + ), ), const SizedBox(height: 8), - PointerInterceptor( - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - border: Border.all(color: AppColor.colorInputBorderCreateMailbox), - color: Colors.white, - ), - child: _buildSignatureHtmlTemplate(context), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + border: Border.all(color: AppColor.colorInputBorderCreateMailbox), + color: Colors.white, ), + child: _buildSignatureHtmlTemplate(context), ), if (_responsiveUtils.isTablet(context) || _responsiveUtils.isMobile(context))...[ Obx(() => Padding( 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 6304a31e3..07e149ea6 100644 --- a/lib/features/manage_account/presentation/profiles/identities/identities_controller.dart +++ b/lib/features/manage_account/presentation/profiles/identities/identities_controller.dart @@ -11,8 +11,6 @@ import 'package:get/get.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/identities/identity.dart'; import 'package:tmail_ui_user/features/base/base_controller.dart'; -import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_bindings.dart'; -import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_view.dart'; import 'package:tmail_ui_user/features/identity_creator/presentation/model/identity_creator_arguments.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_identity_request.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/edit_identity_request.dart'; @@ -32,6 +30,7 @@ import 'package:tmail_ui_user/features/manage_account/presentation/model/identit import 'package:tmail_ui_user/features/manage_account/presentation/model/settings_page_level.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/widgets/delete_identity_dialog_builder.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; +import 'package:tmail_ui_user/main/routes/app_routes.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart'; class IdentitiesController extends BaseController { @@ -40,7 +39,6 @@ class IdentitiesController extends BaseController { final _appToast = Get.find(); final _imagePaths = Get.find(); final _responsiveUtils = Get.find(); - final _identityCreatorBindings = IdentityCreatorBindings(); final GetAllIdentitiesInteractor _getAllIdentitiesInteractor; final CreateNewIdentityInteractor _createNewIdentityInteractor; @@ -165,8 +163,9 @@ class IdentitiesController extends BaseController { } }); } else { - final newIdentityArguments = - await _getIdentityRequest(context, arguments); + final newIdentityArguments = await push( + AppRoutes.identityCreator, + arguments: arguments); if (newIdentityArguments is CreateNewIdentityRequest) { _createNewIdentityAction(accountId, newIdentityArguments); @@ -177,25 +176,6 @@ class IdentitiesController extends BaseController { } } - Future _getIdentityRequest( - BuildContext context, - dynamic arguments - ) async { - return await showModalBottomSheet( - enableDrag: false, - context: context, - isScrollControlled: true, - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(16.0), - topRight: Radius.circular(16.0)), - ), - builder: (context) { - _identityCreatorBindings.dependencies(); - return IdentityCreatorView.fromArguments(arguments); - }); - } - void _createNewIdentityAction( AccountId accountId, CreateNewIdentityRequest identityRequest @@ -308,7 +288,9 @@ class IdentitiesController extends BaseController { } }); } else { - final newIdentityArguments = await _getIdentityRequest(context, arguments); + final newIdentityArguments = await push( + AppRoutes.identityCreator, + arguments: arguments); if (newIdentityArguments is CreateNewIdentityRequest) { _createNewIdentityAction(accountId, newIdentityArguments); diff --git a/lib/main/pages/app_pages.dart b/lib/main/pages/app_pages.dart index c5a63f649..4cd3c93d6 100644 --- a/lib/main/pages/app_pages.dart +++ b/lib/main/pages/app_pages.dart @@ -9,6 +9,7 @@ import 'package:tmail_ui_user/features/destination_picker/presentation/destinati import 'package:tmail_ui_user/features/home/presentation/home_bindings.dart'; import 'package:tmail_ui_user/features/home/presentation/home_view.dart'; import 'package:tmail_ui_user/features/contact/presentation/contact_view.dart' deferred as contact_view; +import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_bindings.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/rules_filter_creator_bindings.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/rules_filter_creator_view.dart' deferred as rules_filter_creator; import 'package:tmail_ui_user/features/login/presentation/login_bindings.dart'; @@ -16,6 +17,7 @@ import 'package:tmail_ui_user/features/login/presentation/login_view.dart' if (dart.library.html) 'package:tmail_ui_user/features/login/presentation/login_view_web.dart' deferred as login; import 'package:tmail_ui_user/features/mailbox_creator/presentation/mailbox_creator_bindings.dart'; import 'package:tmail_ui_user/features/mailbox_creator/presentation/mailbox_creator_view.dart' deferred as mailbox_creator; +import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_view.dart' deferred as identity_creator; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_view.dart' if (dart.library.html) 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart' deferred as mailbox_dashboard; @@ -107,6 +109,14 @@ class AppPages { () => search_mailbox_view.SearchMailboxView() ), binding: SearchMailboxBindings()), + GetPage( + name: AppRoutes.identityCreator, + opaque: false, + page: () => DeferredWidget( + identity_creator.loadLibrary, + () => identity_creator.IdentityCreatorView() + ), + binding: IdentityCreatorBindings()), ] ];