From ff4f96e3d22dd9539066d3d8378e30dffe2c5ec9 Mon Sep 17 00:00:00 2001 From: dab246 Date: Tue, 30 Jan 2024 04:41:15 +0700 Subject: [PATCH] TF-2475 Handle format style rich text in vacation --- .../menu/settings/settings_view.dart | 97 +-- .../vacation/vacation_controller.dart | 41 +- .../presentation/vacation/vacation_view.dart | 573 ++++++++++-------- 3 files changed, 417 insertions(+), 294 deletions(-) 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 81b433ac0..ab292617a 100644 --- a/lib/features/manage_account/presentation/menu/settings/settings_view.dart +++ b/lib/features/manage_account/presentation/menu/settings/settings_view.dart @@ -37,43 +37,60 @@ class SettingsView extends GetWidget { return Container( color: Colors.white, child: SafeArea( + top: controller.manageAccountDashboardController.isVacationCapabilitySupported, + bottom: controller.manageAccountDashboardController.isVacationCapabilitySupported, + left: controller.manageAccountDashboardController.isVacationCapabilitySupported && + controller.responsiveUtils.isPortraitMobile(context), + right: controller.manageAccountDashboardController.isVacationCapabilitySupported && + controller.responsiveUtils.isPortraitMobile(context), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox.fromSize( - size: const Size.fromHeight(52), - child: Padding( - padding: SettingsUtils.getPaddingAppBar(context, controller.responsiveUtils), - child: _buildAppbar(context))), + SafeArea( + bottom: false, + child: SizedBox.fromSize( + size: const Size.fromHeight(52), + child: Padding( + padding: SettingsUtils.getPaddingAppBar(context, controller.responsiveUtils), + child: _buildAppbar(context))), + ), const Divider(color: AppColor.colorDividerComposer, height: 1), Obx(() { if (controller.manageAccountDashboardController.vacationResponse.value?.vacationResponderIsValid == true) { - return VacationNotificationMessageWidget( - margin: const EdgeInsetsDirectional.only( - start: PlatformInfo.isWeb ? 24 : 16, - end: PlatformInfo.isWeb ? 24 : 16, - top: 16), - fromAccountDashBoard: true, - vacationResponse: controller.manageAccountDashboardController.vacationResponse.value!, - actionGotoVacationSetting: !controller.manageAccountDashboardController.inVacationSettings() - ? () => controller.manageAccountDashboardController.selectAccountMenuItem(AccountMenuItem.vacation) - : null, - actionEndNow: () => controller.manageAccountDashboardController.disableVacationResponder()); + return SafeArea( + top: false, + bottom: false, + child: VacationNotificationMessageWidget( + margin: const EdgeInsetsDirectional.only( + start: PlatformInfo.isWeb ? 24 : 16, + end: PlatformInfo.isWeb ? 24 : 16, + top: 16), + fromAccountDashBoard: true, + vacationResponse: controller.manageAccountDashboardController.vacationResponse.value!, + actionGotoVacationSetting: !controller.manageAccountDashboardController.inVacationSettings() + ? () => controller.manageAccountDashboardController.selectAccountMenuItem(AccountMenuItem.vacation) + : null, + actionEndNow: () => controller.manageAccountDashboardController.disableVacationResponder()), + ); } else if ((controller.manageAccountDashboardController.vacationResponse.value?.vacationResponderIsWaiting == true || controller.manageAccountDashboardController.vacationResponse.value?.vacationResponderIsStopped == true) && controller.manageAccountDashboardController.inVacationSettings()) { - return VacationNotificationMessageWidget( - margin: const EdgeInsetsDirectional.only( - start: PlatformInfo.isWeb ? 24 : 16, - end: PlatformInfo.isWeb ? 24 : 16, - top: 16), - fromAccountDashBoard: true, - vacationResponse: controller.manageAccountDashboardController.vacationResponse.value!, - padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16), - leadingIcon: const Padding( - padding: EdgeInsetsDirectional.only(end: 16), - child: Icon(Icons.timer, size: 20), - ) + return SafeArea( + top: false, + bottom: false, + child: VacationNotificationMessageWidget( + margin: const EdgeInsetsDirectional.only( + start: PlatformInfo.isWeb ? 24 : 16, + end: PlatformInfo.isWeb ? 24 : 16, + top: 16), + fromAccountDashBoard: true, + vacationResponse: controller.manageAccountDashboardController.vacationResponse.value!, + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16), + leadingIcon: const Padding( + padding: EdgeInsetsDirectional.only(end: 16), + child: Icon(Icons.timer, size: 20), + ) + ), ); } else { return const SizedBox.shrink(); @@ -189,7 +206,9 @@ class SettingsView extends GetWidget { return Obx(() { switch (controller.manageAccountDashboardController.settingsPageLevel.value) { case SettingsPageLevel.universal: - return const SettingsFirstLevelView(); + return const SafeArea( + top: false, + child: SettingsFirstLevelView()); case SettingsPageLevel.level1: return _viewDisplayedOfAccountMenuItem(); } @@ -200,12 +219,18 @@ class SettingsView extends GetWidget { return Obx(() { switch(controller.manageAccountDashboardController.accountMenuItemSelected.value) { case AccountMenuItem.profiles: - return ProfilesView(); + return SafeArea( + top: false, + child: ProfilesView()); case AccountMenuItem.languageAndRegion: - return const LanguageAndRegionView(); + return const SafeArea( + top: false, + child: LanguageAndRegionView()); case AccountMenuItem.emailRules: if (controller.manageAccountDashboardController.isRuleFilterCapabilitySupported) { - return EmailRulesView(); + return SafeArea( + top: false, + child: EmailRulesView()); } else { return const SizedBox.shrink(); } @@ -217,7 +242,9 @@ class SettingsView extends GetWidget { } case AccountMenuItem.forward: if (controller.manageAccountDashboardController.isForwardCapabilitySupported) { - return ForwardView(); + return SafeArea( + top: false, + child: ForwardView()); } else { return const SizedBox.shrink(); } @@ -228,7 +255,9 @@ class SettingsView extends GetWidget { return const SizedBox.shrink(); } case AccountMenuItem.mailboxVisibility: - return MailboxVisibilityView(); + return SafeArea( + top: false, + child: MailboxVisibilityView()); case AccountMenuItem.notification: return const NotificationView(); default: diff --git a/lib/features/manage_account/presentation/vacation/vacation_controller.dart b/lib/features/manage_account/presentation/vacation/vacation_controller.dart index a81962bfa..43323bb3f 100644 --- a/lib/features/manage_account/presentation/vacation/vacation_controller.dart +++ b/lib/features/manage_account/presentation/vacation/vacation_controller.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart'; import 'package:pointer_interceptor/pointer_interceptor.dart'; -import 'package:rich_text_composer/rich_text_controller.dart'; +import 'package:rich_text_composer/rich_text_composer.dart'; import 'package:rich_text_composer/views/commons/constants.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'; @@ -64,6 +64,7 @@ class VacationController extends BaseController { @override void onInit() { _initWorker(); + _initFocusListener(); super.onInit(); } @@ -93,6 +94,16 @@ class VacationController extends BaseController { }); } + void _initFocusListener() { + subjectTextFocusNode.addListener(() { + if (subjectTextFocusNode.hasFocus == true) { + if (PlatformInfo.isMobile) { + richTextControllerForMobile.hideRichTextView(); + } + } + }); + } + void _getAllVacation() { final accountId = _accountDashBoardController.accountId.value; if (accountId != null) { @@ -156,6 +167,11 @@ class VacationController extends BaseController { } void selectDate(BuildContext context, DateType dateType, DateTime? currentDate) async { + if (PlatformInfo.isMobile) { + richTextControllerForMobile.htmlEditorApi?.unfocus(); + } + FocusScope.of(context).unfocus(); + _accountDashBoardController.isVacationDateDialogDisplayed = true; final datePicked = await showDatePicker( context: context, @@ -197,6 +213,11 @@ class VacationController extends BaseController { } void selectTime(BuildContext context, DateType dateType, TimeOfDay? currentTime) async { + if (PlatformInfo.isMobile) { + richTextControllerForMobile.htmlEditorApi?.unfocus(); + } + FocusScope.of(context).unfocus(); + _accountDashBoardController.isVacationDateDialogDisplayed = true; final timePicked = await showTimePicker( context: context, @@ -340,7 +361,6 @@ class VacationController extends BaseController { void clearFocusEditor(BuildContext context) { if (PlatformInfo.isMobile) { richTextControllerForMobile.htmlEditorApi?.unfocus(); - KeyboardUtils.hideSystemKeyboardMobile(); } KeyboardUtils.hideKeyboard(context); } @@ -350,7 +370,22 @@ class VacationController extends BaseController { _settingController.backToUniversalSettings(); } - void onFocusHTMLEditor() async { + void initRichTextForMobile(BuildContext context, HtmlEditorApi editorApi) { + richTextControllerForMobile.onCreateHTMLEditor( + editorApi, + onFocus: () => onFocusHTMLEditor(context), + onEnterKeyDown: onEnterKeyDown, + ); + } + + void onFocusHTMLEditor(BuildContext context) async { + if (PlatformInfo.isAndroid) { + FocusScope.of(context).unfocus(); + await Future.delayed( + const Duration(milliseconds: 300), + richTextControllerForMobile.showDeviceKeyboard); + } + subjectTextFocusNode.unfocus(); await Scrollable.ensureVisible(htmlKey.currentContext!); diff --git a/lib/features/manage_account/presentation/vacation/vacation_view.dart b/lib/features/manage_account/presentation/vacation/vacation_view.dart index 513e84e81..085a4b38f 100644 --- a/lib/features/manage_account/presentation/vacation/vacation_view.dart +++ b/lib/features/manage_account/presentation/vacation/vacation_view.dart @@ -2,11 +2,14 @@ import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/utils/keyboard_utils.dart'; import 'package:core/presentation/views/button/icon_button_web.dart'; +import 'package:core/presentation/views/responsive/responsive_widget.dart'; import 'package:core/utils/html/html_utils.dart'; import 'package:core/utils/platform_info.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_portal/flutter_portal.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; +import 'package:html_editor_enhanced/html_editor.dart' as html_editor_browser; import 'package:pointer_interceptor/pointer_interceptor.dart'; import 'package:rich_text_composer/rich_text_composer.dart'; import 'package:rich_text_composer/views/widgets/rich_text_keyboard_toolbar.dart'; @@ -15,12 +18,12 @@ import 'package:tmail_ui_user/features/base/widget/text_input_field_builder.dart import 'package:tmail_ui_user/features/composer/presentation/mixin/rich_text_button_mixin.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/button_layout_type.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/base/setting_detail_view_builder.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/vacation/date_type.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/vacation/vacation_responder_status.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/vacation/utils/vacation_utils.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/vacation/vacation_controller.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; -import 'package:html_editor_enhanced/html_editor.dart' as html_editor_browser; import 'package:tmail_ui_user/main/utils/app_utils.dart'; class VacationView extends GetWidget with RichTextButtonMixin { @@ -29,227 +32,218 @@ class VacationView extends GetWidget with RichTextButtonMixi @override Widget build(BuildContext context) { - if (PlatformInfo.isWeb) { - return _buildVacationFormView(context); - } else { - return KeyboardRichText( - richTextController: controller.richTextControllerForMobile, - keyBroadToolbar: RichTextKeyboardToolBar( - titleBack: AppLocalizations.of(context).format, - backgroundKeyboardToolBarColor: PlatformInfo.isIOS - ? AppColor.colorBackgroundKeyboard - : AppColor.colorBackgroundKeyboardAndroid, - richTextController: controller.richTextControllerForMobile, - quickStyleLabel: AppLocalizations.of(context).titleQuickStyles, - backgroundLabel: AppLocalizations.of(context).titleBackground, - foregroundLabel: AppLocalizations.of(context).titleForeground, - formatLabel: AppLocalizations.of(context).titleFormat, - rootContext: context, - ), - child: _buildVacationFormView(context) - ); - } - } - - Widget _buildVacationFormView(BuildContext context) { - return SettingDetailViewBuilder( - responsiveUtils: controller.responsiveUtils, - padding: const EdgeInsets.symmetric(horizontal: 4), - onTapGestureDetector: () => controller.clearFocusEditor(context), - child: SingleChildScrollView( - physics: const ClampingScrollPhysics(), - controller: controller.scrollController, - child: Padding( - padding: VacationUtils.getPaddingView(context, controller.responsiveUtils), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (controller.responsiveUtils.isWebDesktop(context)) - ...[ - Text( - AppLocalizations.of(context).vacation, - style: const TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - color: Colors.black - ) - ), - const SizedBox(height: 8) - ], - Text( - AppLocalizations.of(context).vacationSettingExplanation, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.normal, - color: AppColor.colorVacationSettingExplanation - ) - ), - const SizedBox(height: 24), - Row(children: [ - Obx(() { - return InkWell( - onTap: () { - final newStatus = controller.isVacationDeactivated - ? VacationResponderStatus.activated - : VacationResponderStatus.deactivated; - controller.updateVacationPresentation(newStatus: newStatus); - }, - child: SvgPicture.asset( - controller.isVacationDeactivated - ? controller.imagePaths.icSwitchOff - : controller.imagePaths.icSwitchOn, - fit: BoxFit.fill, - width: 24, - height: 24 - ) - ); - }), - const SizedBox(width: 16), - Expanded( - child: Text( - AppLocalizations.of(context).vacationSettingToggleButtonAutoReply, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black - ) - ), - ) - ]), - const SizedBox(height: 28), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14), - child: Column(children: [ - Obx(() => AbsorbPointer( - absorbing: controller.isVacationDeactivated, - child: Opacity( - opacity: controller.isVacationDeactivated ? 0.3 : 1.0, - child: controller.responsiveUtils.isPortraitMobile(context) - ? Column(children: [ - BorderButtonField( - label: AppLocalizations.of(context).startDate, - value: controller.vacationPresentation.value.startDate, - mouseCursor: SystemMouseCursors.text, - backgroundColor: AppColor.colorBackgroundVacationSettingField, - isEmpty: !controller.isVacationDeactivated && controller.vacationPresentation.value.startDateIsNull, - hintText: AppLocalizations.of(context).startDate, - tapActionCallback: (value) => controller.selectDate(context, DateType.start, value)), - const SizedBox(height: 18), - BorderButtonField( - label: AppLocalizations.of(context).startTime, - value: controller.vacationPresentation.value.startTime, - mouseCursor: SystemMouseCursors.text, - backgroundColor: AppColor.colorBackgroundVacationSettingField, - isEmpty: !controller.isVacationDeactivated && controller.vacationPresentation.value.starTimeIsNull, - hintText: AppLocalizations.of(context).noStartTime, - tapActionCallback: (value) => controller.selectTime(context, DateType.start, value)), - ]) - : Row(children: [ - Expanded(child: BorderButtonField( - label: AppLocalizations.of(context).startDate, - value: controller.vacationPresentation.value.startDate, - mouseCursor: SystemMouseCursors.text, - backgroundColor: AppColor.colorBackgroundVacationSettingField, - isEmpty: !controller.isVacationDeactivated && controller.vacationPresentation.value.startDateIsNull, - hintText: AppLocalizations.of(context).startDate, - tapActionCallback: (value) => controller.selectDate(context, DateType.start, value))), - const SizedBox(width: 24), - Expanded(child: BorderButtonField( - label: AppLocalizations.of(context).startTime, - value: controller.vacationPresentation.value.startTime, - mouseCursor: SystemMouseCursors.text, - backgroundColor: AppColor.colorBackgroundVacationSettingField, - isEmpty: !controller.isVacationDeactivated && controller.vacationPresentation.value.starTimeIsNull, - hintText: AppLocalizations.of(context).noStartTime, - tapActionCallback: (value) => controller.selectTime(context, DateType.start, value))), - ]), - ), - )), - const SizedBox(height: 24), - Obx(() => AbsorbPointer( - absorbing: controller.isVacationDeactivated, - child: Opacity( - opacity: controller.isVacationDeactivated ? 0.3 : 1.0, - child: Row(children: [ - Obx(() => InkWell( - onTap: () { - final value = !controller.vacationPresentation.value.vacationStopEnabled; - controller.updateVacationPresentation(vacationStopEnabled: value); - }, - child: SvgPicture.asset( - controller.vacationPresentation.value.vacationStopEnabled - ? controller.imagePaths.icSwitchOn - : controller.imagePaths.icSwitchOff, - fit: BoxFit.fill, - width: 24, - height: 24 - ) - )), - const SizedBox(width: 16), - Expanded( - child: Text( - AppLocalizations.of(context).vacationStopsAt, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black - ) - ), - ) - ]), - ) - )), - const SizedBox(height: 24), - Obx(() => AbsorbPointer( - absorbing: !controller.canChangeEndDate, - child: Opacity( - opacity: !controller.canChangeEndDate ? 0.3 : 1.0, - child: controller.responsiveUtils.isPortraitMobile(context) - ? Column(children: [ - BorderButtonField( - label: AppLocalizations.of(context).endDate, - value: controller.vacationPresentation.value.endDate, - mouseCursor: SystemMouseCursors.text, - backgroundColor: AppColor.colorBackgroundVacationSettingField, - isEmpty: controller.canChangeEndDate && controller.vacationPresentation.value.endDateIsNull, - hintText: AppLocalizations.of(context).noEndDate, - tapActionCallback: (value) => controller.selectDate(context, DateType.end, value)), - const SizedBox(height: 18), - BorderButtonField( - label: AppLocalizations.of(context).endTime, - value: controller.vacationPresentation.value.endTime, - mouseCursor: SystemMouseCursors.text, - backgroundColor: AppColor.colorBackgroundVacationSettingField, - isEmpty: controller.canChangeEndDate && controller.vacationPresentation.value.endTimeIsNull, - hintText: AppLocalizations.of(context).noEndTime, - tapActionCallback: (value) => controller.selectTime(context, DateType.end, value)), - ]) - : Row(children: [ - Expanded(child: BorderButtonField( - label: AppLocalizations.of(context).endDate, - value: controller.vacationPresentation.value.endDate, - mouseCursor: SystemMouseCursors.text, - backgroundColor: AppColor.colorBackgroundVacationSettingField, - isEmpty: controller.canChangeEndDate && controller.vacationPresentation.value.endDateIsNull, - hintText: AppLocalizations.of(context).noEndDate, - tapActionCallback: (value) => controller.selectDate(context, DateType.end, value))), - const SizedBox(width: 24), - Expanded(child: BorderButtonField( - label: AppLocalizations.of(context).endTime, - value: controller.vacationPresentation.value.endTime, - mouseCursor: SystemMouseCursors.text, - backgroundColor: AppColor.colorBackgroundVacationSettingField, - isEmpty: controller.canChangeEndDate && controller.vacationPresentation.value.endTimeIsNull, - hintText: AppLocalizations.of(context).noEndTime, - tapActionCallback: (value) => controller.selectTime(context, DateType.end, value))), - ]), - ) - )), - const SizedBox(height: 24), - Obx(() => AbsorbPointer( - absorbing: controller.isVacationDeactivated, + Widget vacationInputForm = SingleChildScrollView( + physics: const ClampingScrollPhysics(), + controller: controller.scrollController, + child: Padding( + padding: VacationUtils.getPaddingView(context, controller.responsiveUtils), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (controller.responsiveUtils.isWebDesktop(context)) + ...[ + Text( + AppLocalizations.of(context).vacation, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, + color: Colors.black + ) + ), + const SizedBox(height: 8) + ], + Text( + AppLocalizations.of(context).vacationSettingExplanation, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.normal, + color: AppColor.colorVacationSettingExplanation + ) + ), + const SizedBox(height: 24), + Row(children: [ + Obx(() { + return InkWell( + onTap: () { + final newStatus = controller.isVacationDeactivated + ? VacationResponderStatus.activated + : VacationResponderStatus.deactivated; + controller.updateVacationPresentation(newStatus: newStatus); + }, + child: SvgPicture.asset( + controller.isVacationDeactivated + ? controller.imagePaths.icSwitchOff + : controller.imagePaths.icSwitchOn, + fit: BoxFit.fill, + width: 24, + height: 24 + ) + ); + }), + const SizedBox(width: 16), + Expanded( + child: Text( + AppLocalizations.of(context).vacationSettingToggleButtonAutoReply, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.normal, + color: Colors.black + ) + ), + ) + ]), + const SizedBox(height: 28), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14), + child: Column(children: [ + Obx(() => AbsorbPointer( + absorbing: controller.isVacationDeactivated, + child: Opacity( + opacity: controller.isVacationDeactivated ? 0.3 : 1.0, child: controller.responsiveUtils.isPortraitMobile(context) - ? Opacity( + ? Column(children: [ + BorderButtonField( + label: AppLocalizations.of(context).startDate, + value: controller.vacationPresentation.value.startDate, + mouseCursor: SystemMouseCursors.text, + backgroundColor: AppColor.colorBackgroundVacationSettingField, + isEmpty: !controller.isVacationDeactivated && controller.vacationPresentation.value.startDateIsNull, + hintText: AppLocalizations.of(context).startDate, + tapActionCallback: (value) => controller.selectDate(context, DateType.start, value) + ), + const SizedBox(height: 18), + BorderButtonField( + label: AppLocalizations.of(context).startTime, + value: controller.vacationPresentation.value.startTime, + mouseCursor: SystemMouseCursors.text, + backgroundColor: AppColor.colorBackgroundVacationSettingField, + isEmpty: !controller.isVacationDeactivated && controller.vacationPresentation.value.starTimeIsNull, + hintText: AppLocalizations.of(context).noStartTime, + tapActionCallback: (value) => controller.selectTime(context, DateType.start, value) + ), + ]) + : Row(children: [ + Expanded(child: BorderButtonField( + label: AppLocalizations.of(context).startDate, + value: controller.vacationPresentation.value.startDate, + mouseCursor: SystemMouseCursors.text, + backgroundColor: AppColor.colorBackgroundVacationSettingField, + isEmpty: !controller.isVacationDeactivated && controller.vacationPresentation.value.startDateIsNull, + hintText: AppLocalizations.of(context).startDate, + tapActionCallback: (value) => controller.selectDate(context, DateType.start, value)) + ), + const SizedBox(width: 24), + Expanded(child: BorderButtonField( + label: AppLocalizations.of(context).startTime, + value: controller.vacationPresentation.value.startTime, + mouseCursor: SystemMouseCursors.text, + backgroundColor: AppColor.colorBackgroundVacationSettingField, + isEmpty: !controller.isVacationDeactivated && controller.vacationPresentation.value.starTimeIsNull, + hintText: AppLocalizations.of(context).noStartTime, + tapActionCallback: (value) => controller.selectTime(context, DateType.start, value)) + ), + ]), + ), + )), + const SizedBox(height: 24), + Obx(() => AbsorbPointer( + absorbing: controller.isVacationDeactivated, + child: Opacity( + opacity: controller.isVacationDeactivated ? 0.3 : 1.0, + child: Row(children: [ + Obx(() => InkWell( + onTap: () { + final value = !controller.vacationPresentation.value.vacationStopEnabled; + controller.updateVacationPresentation(vacationStopEnabled: value); + }, + child: SvgPicture.asset( + controller.vacationPresentation.value.vacationStopEnabled + ? controller.imagePaths.icSwitchOn + : controller.imagePaths.icSwitchOff, + fit: BoxFit.fill, + width: 24, + height: 24 + ) + )), + const SizedBox(width: 16), + Expanded( + child: Text( + AppLocalizations.of(context).vacationStopsAt, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.normal, + color: Colors.black + ) + ), + ) + ]), + ) + )), + const SizedBox(height: 24), + Obx(() => AbsorbPointer( + absorbing: !controller.canChangeEndDate, + child: Opacity( + opacity: !controller.canChangeEndDate ? 0.3 : 1.0, + child: controller.responsiveUtils.isPortraitMobile(context) + ? Column(children: [ + BorderButtonField( + label: AppLocalizations.of(context).endDate, + value: controller.vacationPresentation.value.endDate, + mouseCursor: SystemMouseCursors.text, + backgroundColor: AppColor.colorBackgroundVacationSettingField, + isEmpty: controller.canChangeEndDate && controller.vacationPresentation.value.endDateIsNull, + hintText: AppLocalizations.of(context).noEndDate, + tapActionCallback: (value) => controller.selectDate(context, DateType.end, value) + ), + const SizedBox(height: 18), + BorderButtonField( + label: AppLocalizations.of(context).endTime, + value: controller.vacationPresentation.value.endTime, + mouseCursor: SystemMouseCursors.text, + backgroundColor: AppColor.colorBackgroundVacationSettingField, + isEmpty: controller.canChangeEndDate && controller.vacationPresentation.value.endTimeIsNull, + hintText: AppLocalizations.of(context).noEndTime, + tapActionCallback: (value) => controller.selectTime(context, DateType.end, value) + ), + ]) + : Row(children: [ + Expanded(child: BorderButtonField( + label: AppLocalizations.of(context).endDate, + value: controller.vacationPresentation.value.endDate, + mouseCursor: SystemMouseCursors.text, + backgroundColor: AppColor.colorBackgroundVacationSettingField, + isEmpty: controller.canChangeEndDate && controller.vacationPresentation.value.endDateIsNull, + hintText: AppLocalizations.of(context).noEndDate, + tapActionCallback: (value) => controller.selectDate(context, DateType.end, value)) + ), + const SizedBox(width: 24), + Expanded(child: BorderButtonField( + label: AppLocalizations.of(context).endTime, + value: controller.vacationPresentation.value.endTime, + mouseCursor: SystemMouseCursors.text, + backgroundColor: AppColor.colorBackgroundVacationSettingField, + isEmpty: controller.canChangeEndDate && controller.vacationPresentation.value.endTimeIsNull, + hintText: AppLocalizations.of(context).noEndTime, + tapActionCallback: (value) => controller.selectTime(context, DateType.end, value)) + ), + ]), + ) + )), + const SizedBox(height: 24), + Obx(() => AbsorbPointer( + absorbing: controller.isVacationDeactivated, + child: controller.responsiveUtils.isPortraitMobile(context) + ? Opacity( + opacity: controller.isVacationDeactivated ? 0.3 : 1.0, + child: TextInputFieldBuilder( + label: AppLocalizations.of(context).subject, + hint: AppLocalizations.of(context).hintSubjectInputVacationSetting, + editingController: controller.subjectTextController, + focusNode: controller.subjectTextFocusNode, + ), + ) + : Row(children: [ + Expanded(child: Opacity( opacity: controller.isVacationDeactivated ? 0.3 : 1.0, child: TextInputFieldBuilder( label: AppLocalizations.of(context).subject, @@ -257,38 +251,109 @@ class VacationView extends GetWidget with RichTextButtonMixi editingController: controller.subjectTextController, focusNode: controller.subjectTextFocusNode, ), - ) - : Row(children: [ - Expanded(child: Opacity( - opacity: controller.isVacationDeactivated ? 0.3 : 1.0, - child: TextInputFieldBuilder( - label: AppLocalizations.of(context).subject, - hint: AppLocalizations.of(context).hintSubjectInputVacationSetting, - editingController: controller.subjectTextController, - focusNode: controller.subjectTextFocusNode, - ), - )), - const SizedBox(width: 24), - const Expanded(child: SizedBox.shrink()) - ]) - )), - const SizedBox(height: 24), - Obx(() => AbsorbPointer( - absorbing: controller.isVacationDeactivated, - child: Opacity( - opacity: controller.isVacationDeactivated ? 0.3 : 1.0, - child: _buildVacationMessage(context), - ), - )), - const SizedBox(height: 24), - _buildListButtonAction(context) - ]), - ) - ] - ), + )), + const SizedBox(width: 24), + const Expanded(child: SizedBox.shrink()) + ]) + )), + const SizedBox(height: 24), + Obx(() => AbsorbPointer( + absorbing: controller.isVacationDeactivated, + child: Opacity( + opacity: controller.isVacationDeactivated ? 0.3 : 1.0, + child: _buildVacationMessage(context), + ), + )), + const SizedBox(height: 24), + _buildListButtonAction(context), + const SizedBox(height: 24), + ]), + ) + ] ), ), ); + + if (PlatformInfo.isWeb) { + return SettingDetailViewBuilder( + responsiveUtils: controller.responsiveUtils, + padding: const EdgeInsets.symmetric(horizontal: 4), + onTapGestureDetector: () => controller.clearFocusEditor(context), + child: vacationInputForm, + ); + } else { + return ResponsiveWidget( + responsiveUtils: controller.responsiveUtils, + mobile: GestureDetector( + onTap: () => controller.clearFocusEditor(context), + child: Scaffold( + backgroundColor: SettingsUtils.getBackgroundColor(context, controller.responsiveUtils), + body: SafeArea( + left: controller.responsiveUtils.isPortraitMobile(context), + top: false, + right: controller.responsiveUtils.isPortraitMobile(context), + child: KeyboardRichText( + richTextController: controller.richTextControllerForMobile, + keyBroadToolbar: RichTextKeyboardToolBar( + rootContext: context, + titleBack: AppLocalizations.of(context).format, + backgroundKeyboardToolBarColor: PlatformInfo.isIOS + ? AppColor.colorBackgroundKeyboard + : AppColor.colorBackgroundKeyboardAndroid, + formatLabel: AppLocalizations.of(context).format, + richTextController: controller.richTextControllerForMobile, + quickStyleLabel: AppLocalizations.of(context).quickStyles, + backgroundLabel: AppLocalizations.of(context).background, + foregroundLabel: AppLocalizations.of(context).foreground, + ), + child: Container( + width: double.infinity, + height: double.infinity, + color: Colors.white, + padding: const EdgeInsets.symmetric(horizontal: 4), + child: SafeArea( + top: false, + bottom: false, + child: vacationInputForm), + ) + ), + ), + ), + ), + tablet: Portal( + child: GestureDetector( + onTap: () => controller.clearFocusEditor(context), + child: Scaffold( + backgroundColor: SettingsUtils.getBackgroundColor(context, controller.responsiveUtils), + body: SafeArea( + child: KeyboardRichText( + richTextController: controller.richTextControllerForMobile, + keyBroadToolbar: RichTextKeyboardToolBar( + rootContext: context, + titleBack: AppLocalizations.of(context).format, + backgroundKeyboardToolBarColor: PlatformInfo.isIOS + ? AppColor.colorBackgroundKeyboard + : AppColor.colorBackgroundKeyboardAndroid, + formatLabel: AppLocalizations.of(context).format, + richTextController: controller.richTextControllerForMobile, + quickStyleLabel: AppLocalizations.of(context).quickStyles, + backgroundLabel: AppLocalizations.of(context).background, + foregroundLabel: AppLocalizations.of(context).foreground, + ), + child: Container( + width: double.infinity, + height: double.infinity, + color: Colors.white, + padding: const EdgeInsets.symmetric(horizontal: 4), + child: vacationInputForm, + ), + ), + ), + ), + ), + ), + ); + } } Widget _buildListButtonAction(BuildContext context) { @@ -444,13 +509,7 @@ class VacationView extends GetWidget with RichTextButtonMixi addDefaultSelectionMenuItems: false, initialContent: controller.vacationMessageHtmlText ?? '', customStyleCss: HtmlUtils.customCssStyleHtmlEditor(direction: AppUtils.getCurrentDirection(context)), - onCreated: (htmlApi) { - controller.richTextControllerForMobile.onCreateHTMLEditor( - htmlApi, - onFocus: controller.onFocusHTMLEditor, - onEnterKeyDown: controller.onEnterKeyDown, - ); - } + onCreated: (editorApi) => controller.initRichTextForMobile(context, editorApi) ); } }