From f2a72ac883cd23608e13533b74a05ac32cc765cc Mon Sep 17 00:00:00 2001 From: dab246 Date: Wed, 17 Aug 2022 22:10:11 +0700 Subject: [PATCH] TF-801 Show notification message when vacation enabled --- assets/images/ic_calendar.svg | 3 + assets/images/ic_clock.svg | 3 + assets/images/ic_switch_off.svg | 6 + assets/images/ic_switch_on.svg | 9 + .../{ic_configuration.svg => ic_vacation.svg} | 0 .../extensions/color_extension.dart | 1 + .../presentation/resources/image_paths.dart | 4 + .../email/presentation/email_view.dart | 18 ++ .../bindings/mailbox_dashboard_bindings.dart | 15 + .../mailbox_dashboard_controller.dart | 29 +- .../mailbox_dashboard_view_web.dart | 11 + .../mixin/user_setting_popup_menu_mixin.dart | 2 +- .../configuration/configuration_bindings.dart | 38 --- .../configuration_controller.dart | 11 - .../configuration/configuration_view.dart | 81 ----- .../vacation_response_extension.dart | 17 ++ .../manage_account_dashboard_bindings.dart | 9 +- .../manage_account_dashboard_controller.dart | 25 +- .../manage_account_dashboard_view.dart | 138 +++++---- .../menu/manage_account_menu_controller.dart | 22 +- .../menu/manage_account_menu_view.dart | 6 +- .../account_menu_item_tile_builder.dart | 4 +- .../presentation/model/account_menu_item.dart | 8 +- .../vacation/vacation_bindings.dart | 2 +- .../vacation/vacation_controller.dart | 30 +- .../vacation/vacation_view.dart | 289 ++++++++++-------- .../vacation_input_decoration_builder.dart | 0 .../vacation_notification_message_widget.dart | 59 ++++ .../thread/presentation/thread_view.dart | 13 + lib/l10n/intl_messages.arb | 20 +- lib/main/localizations/app_localizations.dart | 21 +- pubspec.yaml | 2 - 32 files changed, 531 insertions(+), 365 deletions(-) create mode 100644 assets/images/ic_calendar.svg create mode 100644 assets/images/ic_clock.svg create mode 100644 assets/images/ic_switch_off.svg create mode 100644 assets/images/ic_switch_on.svg rename assets/images/{ic_configuration.svg => ic_vacation.svg} (100%) delete mode 100644 lib/features/manage_account/presentation/configuration/configuration_bindings.dart delete mode 100644 lib/features/manage_account/presentation/configuration/configuration_controller.dart delete mode 100644 lib/features/manage_account/presentation/configuration/configuration_view.dart rename lib/features/manage_account/presentation/{configuration => }/vacation/vacation_bindings.dart (96%) rename lib/features/manage_account/presentation/{configuration => }/vacation/vacation_controller.dart (88%) rename lib/features/manage_account/presentation/{configuration => }/vacation/vacation_view.dart (68%) rename lib/features/manage_account/presentation/{configuration => }/vacation/widgets/vacation_input_decoration_builder.dart (100%) create mode 100644 lib/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart diff --git a/assets/images/ic_calendar.svg b/assets/images/ic_calendar.svg new file mode 100644 index 000000000..b03f8f12a --- /dev/null +++ b/assets/images/ic_calendar.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/ic_clock.svg b/assets/images/ic_clock.svg new file mode 100644 index 000000000..0bd512090 --- /dev/null +++ b/assets/images/ic_clock.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/ic_switch_off.svg b/assets/images/ic_switch_off.svg new file mode 100644 index 000000000..2dfdbec23 --- /dev/null +++ b/assets/images/ic_switch_off.svg @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/assets/images/ic_switch_on.svg b/assets/images/ic_switch_on.svg new file mode 100644 index 000000000..76174df7c --- /dev/null +++ b/assets/images/ic_switch_on.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/assets/images/ic_configuration.svg b/assets/images/ic_vacation.svg similarity index 100% rename from assets/images/ic_configuration.svg rename to assets/images/ic_vacation.svg diff --git a/core/lib/presentation/extensions/color_extension.dart b/core/lib/presentation/extensions/color_extension.dart index 4503f362d..8d6c2b97d 100644 --- a/core/lib/presentation/extensions/color_extension.dart +++ b/core/lib/presentation/extensions/color_extension.dart @@ -138,6 +138,7 @@ extension AppColor on Color { static const colorBackgroundFieldConditionRulesFilter = Color(0xFFF2F3F5); static const colorDividerRuleFilter = Color(0xFFE7E8EC); static const colorIconTextField = Color(0xFFB8C1CC); + static const colorVacationNotificationMessageBackground = Color(0x2999A2AD); static const mapGradientColor = [ [Color(0xFF21D4FD), Color(0xFFB721FF)], diff --git a/core/lib/presentation/resources/image_paths.dart b/core/lib/presentation/resources/image_paths.dart index 772712f70..54d16e23d 100644 --- a/core/lib/presentation/resources/image_paths.dart +++ b/core/lib/presentation/resources/image_paths.dart @@ -155,6 +155,10 @@ class ImagePaths { String get icDeleteEmailForward => _getImagePath('ic_delete_email_forward.svg'); String get icVacation => _getImagePath('ic_vacation.svg'); String get icSignOut => _getImagePath('ic_sign_out.svg'); + String get icSwitchOn => _getImagePath('ic_switch_on.svg'); + String get icSwitchOff => _getImagePath('ic_switch_off.svg'); + String get icClock => _getImagePath('ic_clock.svg'); + String get icCalendar => _getImagePath('ic_calendar.svg'); String _getImagePath(String imageName) { return AssetsPaths.images + imageName; diff --git a/lib/features/email/presentation/email_view.dart b/lib/features/email/presentation/email_view.dart index dc01cc7a9..e4823ce1c 100644 --- a/lib/features/email/presentation/email_view.dart +++ b/lib/features/email/presentation/email_view.dart @@ -15,6 +15,8 @@ import 'package:tmail_ui_user/features/email/presentation/widgets/app_bar_mail_w import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_file_tile_builder.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/bottom_bar_mail_widget_builder.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/email_action_cupertino_action_sheet_action_builder.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; class EmailView extends GetWidget with NetworkConnectionMixin { @@ -58,6 +60,22 @@ class EmailView extends GetWidget with NetworkConnectionMixin { : EdgeInsets.zero, child: Column(children: [ _buildAppBar(context), + Obx(() { + if (controller.mailboxDashBoardController.vacationResponse.value?.vacationResponderIsReady == true && + (responsiveUtils.isMobile(context) || + responsiveUtils.isTablet(context) || + responsiveUtils.isLandscapeMobile(context))) { + return Padding( + padding: const EdgeInsets.only(bottom: 5), + child: VacationNotificationMessageWidget( + radius: 0, + margin: EdgeInsets.zero, + vacationResponse: controller.mailboxDashBoardController.vacationResponse.value!), + ); + } else { + return const SizedBox.shrink(); + } + }), if (responsiveUtils.isWebDesktop(context)) const SizedBox(height: 5), Obx(() { diff --git a/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart b/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart index 7bbb33bb9..8891f3426 100644 --- a/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart +++ b/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart @@ -66,6 +66,13 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/download/download_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/search_controller.dart'; +import 'package:tmail_ui_user/features/manage_account/data/datasource/manage_account_datasource.dart'; +import 'package:tmail_ui_user/features/manage_account/data/datasource_impl/manage_account_datasource_impl.dart'; +import 'package:tmail_ui_user/features/manage_account/data/local/language_cache_manager.dart'; +import 'package:tmail_ui_user/features/manage_account/data/network/manage_account_api.dart'; +import 'package:tmail_ui_user/features/manage_account/data/repository/manage_account_repository_impl.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_vacation_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/log_out_oidc_interactor.dart'; import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart'; import 'package:tmail_ui_user/features/thread/data/datasource_impl/local_thread_datasource_impl.dart'; @@ -102,6 +109,7 @@ class MailboxDashBoardBindings extends BaseBindings { Get.find(), Get.find(), Get.find(), + Get.find(), )); Get.put(AdvancedFilterController()); } @@ -117,6 +125,7 @@ class MailboxDashBoardBindings extends BaseBindings { Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); + Get.lazyPut(() => Get.find()); } @override @@ -140,6 +149,9 @@ class MailboxDashBoardBindings extends BaseBindings { Get.find() )); Get.lazyPut(() => SessionStorageComposerDatasourceImpl()); + Get.lazyPut(() => ManageAccountDataSourceImpl( + Get.find(), + Get.find())); } @override @@ -179,6 +191,7 @@ class MailboxDashBoardBindings extends BaseBindings { Get.lazyPut(() => GetComposerCacheOnWebInteractor(Get.find())); Get.lazyPut(() => SaveComposerCacheOnWebInteractor(Get.find())); Get.lazyPut(() => RemoveComposerCacheOnWebInteractor(Get.find())); + Get.lazyPut(() => GetAllVacationInteractor(Get.find())); } @override @@ -191,6 +204,7 @@ class MailboxDashBoardBindings extends BaseBindings { Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); + Get.lazyPut(() => Get.find()); } @override @@ -219,5 +233,6 @@ class MailboxDashBoardBindings extends BaseBindings { Get.lazyPut(() => AccountRepositoryImpl(Get.find())); Get.lazyPut(() => AuthenticationOIDCRepositoryImpl(Get.find())); Get.lazyPut(() => ComposerCacheRepositoryImpl(Get.find())); + Get.lazyPut(() => ManageAccountRepositoryImpl(Get.find())); } } \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart index bf3df7e17..fdb58a985 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart @@ -13,6 +13,7 @@ import 'package:jmap_dart_client/jmap/core/session/session.dart'; import 'package:jmap_dart_client/jmap/core/unsigned_int.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; +import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart'; import 'package:model/model.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:tmail_ui_user/features/base/action/ui_action.dart'; @@ -43,6 +44,8 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/composer_overlay_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/download/download_task_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/quick_search_filter.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_vacation_state.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_vacation_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/log_out_oidc_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/manage_account_arguments.dart'; import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart'; @@ -71,6 +74,7 @@ class MailboxDashBoardController extends ReloadableController { final DeleteEmailPermanentlyInteractor _deleteEmailPermanentlyInteractor; final MarkAsMailboxReadInteractor _markAsMailboxReadInteractor; final GetComposerCacheOnWebInteractor _getEmailCacheOnWebInteractor; + final GetAllVacationInteractor _getAllVacationInteractor; final scaffoldKey = GlobalKey(); final selectedMailbox = Rxn(); @@ -85,6 +89,7 @@ class MailboxDashBoardController extends ReloadableController { final listEmailSelected = [].obs; final composerOverlayState = ComposerOverlayState.inActive.obs; final viewStateMarkAsReadMailbox = Rx>(Right(UIState.idle)); + final vacationResponse = Rxn(); Session? sessionCurrent; Map mapDefaultMailboxId = {}; @@ -106,6 +111,7 @@ class MailboxDashBoardController extends ReloadableController { this._deleteEmailPermanentlyInteractor, this._markAsMailboxReadInteractor, this._getEmailCacheOnWebInteractor, + this._getAllVacationInteractor, ) : super(logoutOidcInteractor, deleteAuthorityOidcInteractor, getAuthenticatedAccountInteractor); @@ -125,6 +131,7 @@ class MailboxDashBoardController extends ReloadableController { dispatchRoute(AppRoutes.THREAD); _setSessionCurrent(); _getUserProfile(); + _getVacationResponse(); _getAppVersion(); super.onReady(); } @@ -210,6 +217,10 @@ class MailboxDashBoardController extends ReloadableController { } else if (success is MarkAsMailboxReadAllSuccess || success is MarkAsMailboxReadHasSomeEmailFailure) { _markAsReadMailboxSuccess(success); + } else if (success is GetAllVacationSuccess) { + if (success.listVacationResponse.isNotEmpty) { + vacationResponse.value = success.listVacationResponse.first; + } } } ); @@ -292,6 +303,12 @@ class MailboxDashBoardController extends ReloadableController { appInformation.value = info; } + void _getVacationResponse() { + if (accountId.value != null) { + consumeState(_getAllVacationInteractor.execute(accountId.value!)); + } + } + MailboxId? getMailboxIdByRole(Role role) { return mapDefaultMailboxId[role]; } @@ -448,6 +465,7 @@ class MailboxDashBoardController extends ReloadableController { sessionCurrent = session; accountId.value = sessionCurrent?.accounts.keys.first; _getUserProfile(); + _getVacationResponse(); _handleComposerCache(); injectAutoCompleteBindings(); } @@ -544,13 +562,16 @@ class MailboxDashBoardController extends ReloadableController { dashBoardAction.value = DashBoardAction.idle; } - void goToSettings() { - if (currentContext != null && (_responsiveUtils.isMobile(currentContext!) - || _responsiveUtils.isTablet(currentContext!))) { + void goToSettings() async { + if (isDrawerOpen) { closeMailboxMenuDrawer(); } - push(AppRoutes.MANAGE_ACCOUNT, + final result = await push(AppRoutes.MANAGE_ACCOUNT, arguments: ManageAccountArguments(sessionCurrent)); + + if (result is VacationResponse) { + vacationResponse.value = result; + } } void selectQuickSearchFilter({ diff --git a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart index 903616086..feeba1245 100644 --- a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart +++ b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart @@ -19,6 +19,8 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/ad import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/download/download_task_item_widget.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/email_quick_search_item_tile_widget.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/recent_search_item_tile_widget.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart'; import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart'; import 'package:tmail_ui_user/features/thread/presentation/thread_view.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; @@ -93,6 +95,15 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { children: [ SizedBox(child: MailboxView(), width: responsiveUtils.defaultSizeMenu), Expanded(child: Column(children: [ + Obx(() { + if (controller.vacationResponse.value?.vacationResponderIsReady == true) { + return VacationNotificationMessageWidget( + margin: const EdgeInsets.only(top: 16, right: 16), + vacationResponse: controller.vacationResponse.value!); + } else { + return const SizedBox.shrink(); + } + }), _buildMarkAsMailboxReadLoading(context), Expanded(child: Obx(() { switch(controller.routePath.value) { diff --git a/lib/features/mailbox_dashboard/presentation/mixin/user_setting_popup_menu_mixin.dart b/lib/features/mailbox_dashboard/presentation/mixin/user_setting_popup_menu_mixin.dart index a5ea0a517..0cf702606 100644 --- a/lib/features/mailbox_dashboard/presentation/mixin/user_setting_popup_menu_mixin.dart +++ b/lib/features/mailbox_dashboard/presentation/mixin/user_setting_popup_menu_mixin.dart @@ -44,7 +44,7 @@ mixin UserSettingPopupMenuMixin { Widget _settingAction(BuildContext context, Function? onCallBack) { return PopupMenuItemWidget( _imagePaths.icSetting, - AppLocalizations.of(context).settings, + AppLocalizations.of(context).manage_account, () => onCallBack?.call()); } diff --git a/lib/features/manage_account/presentation/configuration/configuration_bindings.dart b/lib/features/manage_account/presentation/configuration/configuration_bindings.dart deleted file mode 100644 index 232018bc9..000000000 --- a/lib/features/manage_account/presentation/configuration/configuration_bindings.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:get/get.dart'; -import 'package:tmail_ui_user/features/base/base_bindings.dart'; -import 'package:tmail_ui_user/features/manage_account/presentation/configuration/configuration_controller.dart'; -import 'package:tmail_ui_user/features/manage_account/presentation/configuration/vacation/vacation_bindings.dart'; - -class ConfigurationBindings extends BaseBindings { - - @override - void dependencies() { - super.dependencies(); - VacationBindings().dependencies(); - } - - @override - void bindingsController() { - Get.lazyPut(() => ConfigurationController()); - } - - @override - void bindingsDataSource() { - } - - @override - void bindingsDataSourceImpl() { - } - - @override - void bindingsInteractor() { - } - - @override - void bindingsRepository() { - } - - @override - void bindingsRepositoryImpl() { - } -} \ No newline at end of file diff --git a/lib/features/manage_account/presentation/configuration/configuration_controller.dart b/lib/features/manage_account/presentation/configuration/configuration_controller.dart deleted file mode 100644 index c5d766365..000000000 --- a/lib/features/manage_account/presentation/configuration/configuration_controller.dart +++ /dev/null @@ -1,11 +0,0 @@ - -import 'package:tmail_ui_user/features/base/base_controller.dart'; - -class ConfigurationController extends BaseController { - - @override - void onDone() {} - - @override - void onError(error) {} -} \ No newline at end of file diff --git a/lib/features/manage_account/presentation/configuration/configuration_view.dart b/lib/features/manage_account/presentation/configuration/configuration_view.dart deleted file mode 100644 index a085080df..000000000 --- a/lib/features/manage_account/presentation/configuration/configuration_view.dart +++ /dev/null @@ -1,81 +0,0 @@ - -import 'package:core/core.dart'; -import 'package:flutter/material.dart'; -import 'package:get/get.dart'; -import 'package:tmail_ui_user/features/manage_account/presentation/configuration/configuration_controller.dart'; -import 'package:tmail_ui_user/features/manage_account/presentation/configuration/vacation/vacation_view.dart'; -import 'package:tmail_ui_user/features/manage_account/presentation/model/configuration_tab_type.dart'; - -class ConfigurationView extends GetWidget { - - final _responsiveUtils = Get.find(); - - ConfigurationView({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: _responsiveUtils.isWebDesktop(context) - ? AppColor.colorBgDesktop - : Colors.white, - body: Container( - margin: _responsiveUtils.isWebDesktop(context) - ? const EdgeInsets.all(24) - : EdgeInsets.zero, - color: _responsiveUtils.isWebDesktop(context) ? null : Colors.white, - decoration: _responsiveUtils.isWebDesktop(context) - ? BoxDecoration( - borderRadius: BorderRadius.circular(20), - border: Border.all(color: AppColor.colorBorderBodyThread, width: 1), - color: Colors.white) - : null, - child: ClipRRect( - borderRadius: BorderRadius.circular( - _responsiveUtils.isWebDesktop(context) ? 20 : 0), - child: Padding( - padding: const EdgeInsets.only( - left: BuildUtils.isWeb ? 10 : 0, - right: 10, - bottom: 10), - child: DefaultTabController( - initialIndex: 0, - length: 1, - child: Scaffold( - appBar: TabBar( - unselectedLabelColor: AppColor.colorTextButtonHeaderThread, - unselectedLabelStyle: const TextStyle( - fontSize: 15, - fontWeight: FontWeight.normal, - color: AppColor.colorTextButtonHeaderThread), - labelStyle: const TextStyle( - fontSize: 15, - fontWeight: FontWeight.w500, - color: AppColor.primaryColor), - labelColor: AppColor.primaryColor, - indicatorSize: TabBarIndicatorSize.label, - isScrollable: true, - indicator: const CustomIndicator( - indicatorHeight: 4, - indicatorColor: AppColor.primaryColor, - indicatorSize: CustomIndicatorSize.full), - onTap: (index) {}, - tabs: ConfigurationTabType.values - .map((tab) => Tab(text: tab.getTitle(context))) - .toList() - ), - body: Column(children: [ - const Divider(color: AppColor.colorDividerMailbox, height: 0.5, thickness: 0.2), - Expanded(child: TabBarView( - children: [ - VacationView(), - ], - )) - ]), - ) - ), - ), - ), - ), - ); - } -} \ No newline at end of file diff --git a/lib/features/manage_account/presentation/extensions/vacation_response_extension.dart b/lib/features/manage_account/presentation/extensions/vacation_response_extension.dart index 4ee375faa..ce0453126 100644 --- a/lib/features/manage_account/presentation/extensions/vacation_response_extension.dart +++ b/lib/features/manage_account/presentation/extensions/vacation_response_extension.dart @@ -1,4 +1,5 @@ +import 'package:core/utils/app_logger.dart'; import 'package:flutter/material.dart'; import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/vacation/vacation_presentation.dart'; @@ -23,4 +24,20 @@ extension VacationResponseExtension on VacationResponse { vacationStopEnabled: toDate != null ); } + + bool get vacationResponderIsReady { + if (isEnabled == true) { + final currentDate = DateTime.now().toUtc(); + log('VacationResponseExtension::vacationResponderEnabled(): currentDate: $currentDate'); + final startDate = fromDate?.value.toUtc(); + log('VacationResponseExtension::vacationResponderEnabled(): startDate: $startDate'); + if (startDate?.isBefore(currentDate) == true || + startDate?.isAtSameMomentAs(currentDate) == true) { + return true; + } else { + return false; + } + } + return false; + } } \ No newline at end of file diff --git a/lib/features/manage_account/presentation/manage_account_dashboard_bindings.dart b/lib/features/manage_account/presentation/manage_account_dashboard_bindings.dart index ecf5f3244..0e29be507 100644 --- a/lib/features/manage_account/presentation/manage_account_dashboard_bindings.dart +++ b/lib/features/manage_account/presentation/manage_account_dashboard_bindings.dart @@ -25,12 +25,13 @@ import 'package:tmail_ui_user/features/manage_account/data/local/language_cache_ import 'package:tmail_ui_user/features/manage_account/data/network/manage_account_api.dart'; import 'package:tmail_ui_user/features/manage_account/data/repository/manage_account_repository_impl.dart'; import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_vacation_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/log_out_oidc_interactor.dart'; -import 'package:tmail_ui_user/features/manage_account/presentation/configuration/configuration_bindings.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/language_and_region/language_and_region_bindings.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/menu/manage_account_menu_bindings.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/profiles/profiles_bindings.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/vacation/vacation_bindings.dart'; class ManageAccountDashBoardBindings extends BaseBindings { @@ -40,7 +41,7 @@ class ManageAccountDashBoardBindings extends BaseBindings { ManageAccountMenuBindings().dependencies(); ProfileBindings().dependencies(); LanguageAndRegionBindings().dependencies(); - ConfigurationBindings().dependencies(); + VacationBindings().dependencies(); } @override @@ -48,7 +49,8 @@ class ManageAccountDashBoardBindings extends BaseBindings { Get.lazyPut(() => ManageAccountDashBoardController( Get.find(), Get.find(), - Get.find() + Get.find(), + Get.find() )); } @@ -91,6 +93,7 @@ class ManageAccountDashBoardBindings extends BaseBindings { Get.find(), Get.find(), )); + Get.lazyPut(() => GetAllVacationInteractor(Get.find())); } @override diff --git a/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart b/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart index c6ae709bd..3bbaedf1f 100644 --- a/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart +++ b/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart @@ -6,6 +6,7 @@ import 'package:forward/forward/capability_forward.dart'; import 'package:get/get.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/core/session/session.dart'; +import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart'; import 'package:model/model.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:rule_filter/rule_filter/capability_rule_filter.dart'; @@ -13,6 +14,8 @@ import 'package:tmail_ui_user/features/base/reloadable/reloadable_controller.dar import 'package:tmail_ui_user/features/login/domain/usecases/delete_authority_oidc_interactor.dart'; import 'package:tmail_ui_user/features/login/domain/usecases/get_authenticated_account_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_user_profile_state.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_vacation_state.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_vacation_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/log_out_oidc_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/email_rules_bindings.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/forward/forward_bindings.dart'; @@ -23,6 +26,8 @@ import 'package:tmail_ui_user/main/routes/route_navigation.dart'; class ManageAccountDashBoardController extends ReloadableController { + final GetAllVacationInteractor _getAllVacationInteractor; + final menuDrawerKey = GlobalKey(debugLabel: 'manage_account'); final appInformation = Rxn(); @@ -30,11 +35,13 @@ class ManageAccountDashBoardController extends ReloadableController { final accountId = Rxn(); final accountMenuItemSelected = AccountMenuItem.profiles.obs; final sessionCurrent = Rxn(); + final vacationResponse = Rxn(); ManageAccountDashBoardController( LogoutOidcInteractor logoutOidcInteractor, DeleteAuthorityOidcInteractor deleteAuthorityOidcInteractor, GetAuthenticatedAccountInteractor getAuthenticatedAccountInteractor, + this._getAllVacationInteractor, ) : super(logoutOidcInteractor, deleteAuthorityOidcInteractor, getAuthenticatedAccountInteractor); @@ -53,6 +60,10 @@ class ManageAccountDashBoardController extends ReloadableController { (success) { if (success is GetUserProfileSuccess) { userProfile.value = success.userProfile; + } else if (success is GetAllVacationSuccess) { + if (success.listVacationResponse.isNotEmpty) { + vacationResponse.value = success.listVacationResponse.first; + } } } ); @@ -67,6 +78,7 @@ class ManageAccountDashBoardController extends ReloadableController { sessionCurrent.value = session; accountId.value = session.accounts.keys.first; _getUserProfile(); + _getVacationResponse(); injectAutoCompleteBindings(); } @@ -77,6 +89,7 @@ class ManageAccountDashBoardController extends ReloadableController { sessionCurrent.value = arguments.session; accountId.value = sessionCurrent.value?.accounts.keys.first; _getUserProfile(); + _getVacationResponse(); injectAutoCompleteBindings(); } else { if (kIsWeb) { @@ -95,6 +108,16 @@ class ManageAccountDashBoardController extends ReloadableController { userProfile.value = sessionCurrent.value != null ? UserProfile(sessionCurrent.value!.username.value) : null; } + void _getVacationResponse() { + if (accountId.value != null) { + consumeState(_getAllVacationInteractor.execute(accountId.value!)); + } + } + + void updateVacationResponse(VacationResponse? newVacation) { + vacationResponse.value = newVacation; + } + void openMenuDrawer() { menuDrawerKey.currentState?.openDrawer(); } @@ -128,7 +151,7 @@ class ManageAccountDashBoardController extends ReloadableController { closeMenuDrawer(); } if (canBack(context)) { - popBack(); + popBack(result: vacationResponse.value); } else { log('ManageAccountDashBoardController::backToMailboxDashBoard(): canBack: FALSE'); pushAndPopAll(AppRoutes.MAILBOX_DASHBOARD, arguments: sessionCurrent); diff --git a/lib/features/manage_account/presentation/manage_account_dashboard_view.dart b/lib/features/manage_account/presentation/manage_account_dashboard_view.dart index e56d06ec8..11c252648 100644 --- a/lib/features/manage_account/presentation/manage_account_dashboard_view.dart +++ b/lib/features/manage_account/presentation/manage_account_dashboard_view.dart @@ -4,7 +4,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mixin/user_setting_popup_menu_mixin.dart'; -import 'package:tmail_ui_user/features/manage_account/presentation/configuration/configuration_view.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/email_rules_view.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/forward/forward_view.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/language_and_region/language_and_region_view.dart'; @@ -12,6 +13,7 @@ import 'package:tmail_ui_user/features/manage_account/presentation/manage_accoun import 'package:tmail_ui_user/features/manage_account/presentation/menu/manage_account_menu_view.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/profiles/profiles_view.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/vacation/vacation_view.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart'; @@ -25,7 +27,7 @@ class ManageAccountDashBoardView extends GetWidget controller.backToMailboxDashBoard(context)) - ..setLogo(_imagePaths.icLogoTMail)) - .build(), + body: GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: ResponsiveWidget( + responsiveUtils: _responsiveUtils, + desktop: Column(children: [ + Row(children: [ + Container(width: 256, color: Colors.white, + padding: const EdgeInsets.only(top: 25, bottom: 25, left: 32), + child: Row(children: [ + (SloganBuilder(arrangedByHorizontal: true) + ..setSloganText(AppLocalizations.of(context).app_name) + ..setSloganTextAlign(TextAlign.center) + ..setSloganTextStyle(const TextStyle(color: Colors.black, fontSize: 20, fontWeight: FontWeight.bold)) + ..setSizeLogo(24) + ..addOnTapCallback(() => controller.backToMailboxDashBoard(context)) + ..setLogo(_imagePaths.icLogoTMail)) + .build(), + Obx(() { + if (controller.appInformation.value != null) { + return Padding(padding: const EdgeInsets.only(top: 6), + child: Text( + 'v.${controller.appInformation.value!.version}', + textAlign: TextAlign.center, + style: const TextStyle(fontSize: 13, color: AppColor.colorContentEmail, fontWeight: FontWeight.w500), + )); + } else { + return const SizedBox.shrink(); + } + }), + ]) + ), + Expanded(child: Padding( + padding: const EdgeInsets.only(right: 10, top: 16, bottom: 10, left: 48), + child: _buildRightHeader(context))) + ]), + Expanded(child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(child: ManageAccountMenuView(), width: _responsiveUtils.defaultSizeMenu), + Expanded(child: Container( + color: AppColor.colorBgDesktop, + child: Column(children: [ + Obx(() { + if (controller.vacationResponse.value?.vacationResponderIsReady == true) { + return VacationNotificationMessageWidget( + margin: const EdgeInsets.only( + top: 16, + left: BuildUtils.isWeb ? 24 : 16, + right: BuildUtils.isWeb ? 24 : 16), + vacationResponse: controller.vacationResponse.value!); + } else { + return const SizedBox.shrink(); + } + }), + Expanded(child: _viewDisplayedOfAccountMenuItem()) + ]), + )) + ], + )) + ]), + mobile: SafeArea( + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Padding( + padding: !BuildUtils.isWeb && _responsiveUtils.isPortraitMobile(context) + ? const EdgeInsets.only(left: 4, right: 8) + : const EdgeInsets.only(top: 16, left: 24, right: 32), + child: _buildAppbar(context)), Obx(() { - if (controller.appInformation.value != null) { - return Padding(padding: const EdgeInsets.only(top: 6), - child: Text( - 'v.${controller.appInformation.value!.version}', - textAlign: TextAlign.center, - style: const TextStyle(fontSize: 13, color: AppColor.colorContentEmail, fontWeight: FontWeight.w500), - )); + if (controller.vacationResponse.value?.vacationResponderIsReady == true) { + return VacationNotificationMessageWidget( + margin: const EdgeInsets.only( + left: BuildUtils.isWeb ? 24 : 16, + right: BuildUtils.isWeb ? 24 : 16, + top: BuildUtils.isWeb ? 16 : 0), + vacationResponse: controller.vacationResponse.value!); } else { return const SizedBox.shrink(); } }), - ]) - ), - Expanded(child: Padding( - padding: const EdgeInsets.only(right: 10, top: 16, bottom: 10, left: 48), - child: _buildRightHeader(context))) - ]), - Expanded(child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox(child: ManageAccountMenuView(), width: _responsiveUtils.defaultSizeMenu), - Expanded(child: _viewDisplayedOfAccountMenuItem()) - ], - )) - ]), - mobile: SafeArea( - child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - Padding( - padding: !BuildUtils.isWeb && _responsiveUtils.isPortraitMobile(context) - ? const EdgeInsets.only(left: 4, right: 8) - : const EdgeInsets.only(top: 16, left: 24, right: 32), - child: _buildAppbar(context)), - Expanded(child: Padding( - padding: !BuildUtils.isWeb && _responsiveUtils.isPortraitMobile(context) - ? const EdgeInsets.only(left: 8) - : const EdgeInsets.only(left: 24), - child: _viewDisplayedOfAccountMenuItem())) - ]) - ) + Expanded(child: Padding( + padding: !BuildUtils.isWeb && _responsiveUtils.isPortraitMobile(context) + ? const EdgeInsets.only(left: 8) + : const EdgeInsets.only(left: 24), + child: _viewDisplayedOfAccountMenuItem())) + ]) + ) + ), ), ); } diff --git a/lib/features/manage_account/presentation/menu/manage_account_menu_controller.dart b/lib/features/manage_account/presentation/menu/manage_account_menu_controller.dart index e519669e0..892136e05 100644 --- a/lib/features/manage_account/presentation/menu/manage_account_menu_controller.dart +++ b/lib/features/manage_account/presentation/menu/manage_account_menu_controller.dart @@ -34,27 +34,17 @@ class ManageAccountMenuController extends BaseController { super.onInit(); } - _createListAccountMenu(){ + void _createListAccountMenu(){ listAccountMenuItem.clear(); - listAccountMenuItem.add( - AccountMenuItem.profiles, - ); + listAccountMenuItem.add(AccountMenuItem.profiles); if (dashBoardController.checkAvailableRuleFilterInSession()) { - listAccountMenuItem.add( - AccountMenuItem.emailRules, - ); + listAccountMenuItem.add(AccountMenuItem.emailRules); } if (dashBoardController.checkAvailableForwardInSession()) { - listAccountMenuItem.add( - AccountMenuItem.forward, - ); + listAccountMenuItem.add(AccountMenuItem.forward); } - listAccountMenuItem.add( - AccountMenuItem.languageAndRegion, - ); - listAccountMenuItem.add( - AccountMenuItem.vacation, - ); + listAccountMenuItem.add(AccountMenuItem.languageAndRegion); + listAccountMenuItem.add(AccountMenuItem.vacation); } @override diff --git a/lib/features/manage_account/presentation/menu/manage_account_menu_view.dart b/lib/features/manage_account/presentation/menu/manage_account_menu_view.dart index 5797db41c..0ed1efb09 100644 --- a/lib/features/manage_account/presentation/menu/manage_account_menu_view.dart +++ b/lib/features/manage_account/presentation/menu/manage_account_menu_view.dart @@ -23,7 +23,7 @@ class ManageAccountMenuView extends GetWidget { body: SafeArea(right: false, bottom: false, child: Column( children: [ - if (!_responsiveUtils.isDesktop(context)) + if (!_responsiveUtils.isWebDesktop(context)) Container( color: Colors.white, padding: const EdgeInsets.only(top: 16, bottom: 16, left: 16), @@ -51,10 +51,10 @@ class ManageAccountMenuView extends GetWidget { }), ]) ), - if (!_responsiveUtils.isDesktop(context)) + if (!_responsiveUtils.isWebDesktop(context)) const Divider(color: AppColor.colorDividerMailbox, height: 0.5, thickness: 0.2), Expanded(child: Container( - color: _responsiveUtils.isDesktop(context) ? AppColor.colorBgDesktop : Colors.white, + color: _responsiveUtils.isWebDesktop(context) ? AppColor.colorBgDesktop : Colors.white, child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.only(left: 20, top: 24), diff --git a/lib/features/manage_account/presentation/menu/widgets/account_menu_item_tile_builder.dart b/lib/features/manage_account/presentation/menu/widgets/account_menu_item_tile_builder.dart index 96a184f9f..46e82458d 100644 --- a/lib/features/manage_account/presentation/menu/widgets/account_menu_item_tile_builder.dart +++ b/lib/features/manage_account/presentation/menu/widgets/account_menu_item_tile_builder.dart @@ -51,6 +51,8 @@ class AccountMenuItemTileBuilder extends StatelessWidget { if (_menuItemSelected == _menuItem) { return AppColor.colorBgMailboxSelected; } - return _responsiveUtils.isDesktop(_context) ? AppColor.colorBgDesktop : Colors.white; + return _responsiveUtils.isWebDesktop(_context) + ? AppColor.colorBgDesktop + : Colors.white; } } \ No newline at end of file diff --git a/lib/features/manage_account/presentation/model/account_menu_item.dart b/lib/features/manage_account/presentation/model/account_menu_item.dart index acd62177b..e0a64ee39 100644 --- a/lib/features/manage_account/presentation/model/account_menu_item.dart +++ b/lib/features/manage_account/presentation/model/account_menu_item.dart @@ -20,8 +20,8 @@ enum AccountMenuItem { return imagePaths.icEmailRules; case AccountMenuItem.forward: return imagePaths.icForward; - case AccountMenuItem.configuration: - return imagePaths.icConfiguration; + case AccountMenuItem.vacation: + return imagePaths.icVacation; } } @@ -35,8 +35,8 @@ enum AccountMenuItem { return AppLocalizations.of(context).emailRules; case AccountMenuItem.forward: return AppLocalizations.of(context).forwarding; - case AccountMenuItem.configuration: - return AppLocalizations.of(context).configuration; + case AccountMenuItem.vacation: + return AppLocalizations.of(context).vacation; } } } \ No newline at end of file diff --git a/lib/features/manage_account/presentation/configuration/vacation/vacation_bindings.dart b/lib/features/manage_account/presentation/vacation/vacation_bindings.dart similarity index 96% rename from lib/features/manage_account/presentation/configuration/vacation/vacation_bindings.dart rename to lib/features/manage_account/presentation/vacation/vacation_bindings.dart index 205a61aca..04894ee57 100644 --- a/lib/features/manage_account/presentation/configuration/vacation/vacation_bindings.dart +++ b/lib/features/manage_account/presentation/vacation/vacation_bindings.dart @@ -4,7 +4,7 @@ import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_na import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_vacation_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/update_vacation_interactor.dart'; -import 'package:tmail_ui_user/features/manage_account/presentation/configuration/vacation/vacation_controller.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/vacation/vacation_controller.dart'; class VacationBindings extends BaseBindings { diff --git a/lib/features/manage_account/presentation/configuration/vacation/vacation_controller.dart b/lib/features/manage_account/presentation/vacation/vacation_controller.dart similarity index 88% rename from lib/features/manage_account/presentation/configuration/vacation/vacation_controller.dart rename to lib/features/manage_account/presentation/vacation/vacation_controller.dart index 14c6e2343..a3bab4d33 100644 --- a/lib/features/manage_account/presentation/configuration/vacation/vacation_controller.dart +++ b/lib/features/manage_account/presentation/vacation/vacation_controller.dart @@ -116,7 +116,18 @@ class VacationController extends BaseController { initialDatePickerMode: DatePickerMode.day, firstDate: DateTime(1900), lastDate: DateTime(2100), - locale: Localizations.localeOf(context) + locale: Localizations.localeOf(context), + builder: (context, child) { + return Theme( + data: Theme.of(context).copyWith( + colorScheme: const ColorScheme.light( + primary: AppColor.primaryColor, + onPrimary: Colors.white, + onSurface: Colors.black), + textButtonTheme: TextButtonThemeData( + style: TextButton.styleFrom(primary: AppColor.primaryColor))), + child: child!); + } ); if (datePicked == null) { @@ -135,9 +146,18 @@ class VacationController extends BaseController { context: context, initialTime: currentTime ?? TimeOfDay.now(), builder: (context, child) { - return MediaQuery( - data: const MediaQueryData(alwaysUse24HourFormat: true), - child: child!); + return Theme( + data: Theme.of(context).copyWith( + colorScheme: const ColorScheme.light( + primary: AppColor.primaryColor, + onPrimary: Colors.white, + onSurface: Colors.black), + textButtonTheme: TextButtonThemeData( + style: TextButton.styleFrom(primary: AppColor.primaryColor))), + child: MediaQuery( + data: const MediaQueryData(alwaysUse24HourFormat: true), + child: child!), + ); } ); @@ -233,6 +253,8 @@ class VacationController extends BaseController { final newVacationPresentation = currentVacation.toVacationPresentation(); vacationPresentation.value = newVacationPresentation; messageBodyEditorController.text = newVacationPresentation.messageBody ?? ''; + + _accountDashBoardController.updateVacationResponse(currentVacation); } } diff --git a/lib/features/manage_account/presentation/configuration/vacation/vacation_view.dart b/lib/features/manage_account/presentation/vacation/vacation_view.dart similarity index 68% rename from lib/features/manage_account/presentation/configuration/vacation/vacation_view.dart rename to lib/features/manage_account/presentation/vacation/vacation_view.dart index 17faefe4c..3e852a6b1 100644 --- a/lib/features/manage_account/presentation/configuration/vacation/vacation_view.dart +++ b/lib/features/manage_account/presentation/vacation/vacation_view.dart @@ -1,31 +1,43 @@ import 'package:core/core.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; import 'package:tmail_ui_user/features/base/widget/border_button_field.dart'; -import 'package:tmail_ui_user/features/manage_account/presentation/configuration/vacation/vacation_controller.dart'; -import 'package:tmail_ui_user/features/manage_account/presentation/configuration/vacation/widgets/vacation_input_decoration_builder.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/vacation/vacation_controller.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_input_decoration_builder.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/main/localizations/app_localizations.dart'; -import 'package:toggle_switch/toggle_switch.dart'; class VacationView extends GetWidget { final _responsiveUtils = Get.find(); + final _imagePaths = Get.find(); VacationView({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Colors.white, + backgroundColor: _responsiveUtils.isWebDesktop(context) + ? AppColor.colorBgDesktop + : Colors.white, body: GestureDetector( onTap: () => FocusScope.of(context).unfocus(), child: Container( width: double.infinity, - color: Colors.white, - padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 16), + height: double.infinity, + margin: _responsiveUtils.isWebDesktop(context) + ? const EdgeInsets.all(24) + : EdgeInsets.zero, + decoration: _responsiveUtils.isWebDesktop(context) + ? BoxDecoration( + borderRadius: BorderRadius.circular(20), + border: Border.all(color: AppColor.colorBorderBodyThread, width: 1), + color: Colors.white) + : null, + padding: _getPaddingView(context), child: ResponsiveWidget( responsiveUtils: _responsiveUtils, desktop: SingleChildScrollView( @@ -43,28 +55,58 @@ class VacationView extends GetWidget { fontWeight: FontWeight.normal, color: Colors.black))), const SizedBox(width: 16), - Obx(() => ToggleSwitch( - minWidth: 150.0, - cornerRadius: 20.0, - activeBgColors: const [[Colors.green], [Colors.redAccent]], - activeFgColor: Colors.white, - inactiveBgColor: Colors.grey, - inactiveFgColor: Colors.white, - initialLabelIndex: controller.isVacationDeactivated ? 1 : 0, - totalSwitches: VacationResponderStatus.values.length, - labels: VacationResponderStatus.values - .map((status) => status.getTitle(context)) - .toList(), - radiusStyle: true, - onToggle: (index) { - final newStatus = index == 0 - ? VacationResponderStatus.activated - : VacationResponderStatus.deactivated; - controller.updateVacationPresentation(newStatus: newStatus); - }, - )), + Obx(() { + return Row( + children: [ + Material( + color: Colors.transparent, + child: InkWell( + onTap: () { + controller.updateVacationPresentation(newStatus: VacationResponderStatus.deactivated); + }, + child: Text(AppLocalizations.of(context).deactivated, + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.normal, + color: Colors.black.withOpacity( + controller.isVacationDeactivated ? 1.0 : 0.3))), + ), + ), + Padding( + padding: const EdgeInsets.only(top: 3, right: 16, left: 16), + child: InkWell( + onTap: () { + final newStatus = controller.isVacationDeactivated + ? VacationResponderStatus.activated + : VacationResponderStatus.deactivated; + controller.updateVacationPresentation(newStatus: newStatus); + }, + child: SvgPicture.asset( + controller.isVacationDeactivated + ? _imagePaths.icSwitchOff + : _imagePaths.icSwitchOn, + fit: BoxFit.fill, + width: 24, + height: 24)), + ), + Material( + color: Colors.transparent, + child: InkWell( + onTap: () { + controller.updateVacationPresentation(newStatus: VacationResponderStatus.activated); + }, + child: Text(AppLocalizations.of(context).activated, + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.normal, + color: Colors.black.withOpacity( + controller.isVacationDeactivated ? 0.3 : 1.0))), + ), + ) + ]); + }) ]), - const SizedBox(height: 20), + const SizedBox(height: 16), Obx(() => AbsorbPointer( absorbing: controller.isVacationDeactivated, child: Row(children: [ @@ -90,10 +132,7 @@ class VacationView extends GetWidget { color: Colors.black.withOpacity( controller.isVacationDeactivated ? 0.5 : 1.0)), hintText: AppLocalizations.of(context).startDate, - icon: const Icon( - Icons.date_range, - color: AppColor.colorIconTextField, - size: 20), + icon: SvgPicture.asset(_imagePaths.icCalendar), tapActionCallback: (value) => controller.selectDate(context, DateType.start, value)))), const SizedBox(width: 16), @@ -108,15 +147,12 @@ class VacationView extends GetWidget { color: Colors.black.withOpacity( controller.isVacationDeactivated ? 0.5 : 1.0)), hintText: AppLocalizations.of(context).noStartTime, - icon: const Icon( - Icons.timer, - color: AppColor.colorIconTextField, - size: 20), + icon: SvgPicture.asset(_imagePaths.icClock), tapActionCallback: (value) => controller.selectTime(context, DateType.start, value)))), ]), )), - const SizedBox(height: 20), + const SizedBox(height: 16), Obx(() => AbsorbPointer( absorbing: controller.isVacationDeactivated, child: Container( @@ -164,10 +200,7 @@ class VacationView extends GetWidget { color: Colors.black.withOpacity( !controller.canChangeEndDate ? 0.5 : 1.0)), hintText: AppLocalizations.of(context).noEndDate, - icon: const Icon( - Icons.date_range, - color: AppColor.colorIconTextField, - size: 20), + icon: SvgPicture.asset(_imagePaths.icCalendar), tapActionCallback: (value) => controller.selectDate(context, DateType.end, value)))), const SizedBox(width: 16), @@ -182,15 +215,12 @@ class VacationView extends GetWidget { color: Colors.black.withOpacity( !controller.canChangeEndDate ? 0.5 : 1.0)), hintText: AppLocalizations.of(context).noEndTime, - icon: const Icon( - Icons.timer, - color: AppColor.colorIconTextField, - size: 20), + icon: SvgPicture.asset(_imagePaths.icClock), tapActionCallback: (value) => controller.selectTime(context, DateType.end, value)))), ]) )), - const SizedBox(height: 20), + const SizedBox(height: 16), Obx(() => AbsorbPointer( absorbing: controller.isVacationDeactivated, child: Row(crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -210,7 +240,7 @@ class VacationView extends GetWidget { controller.isVacationDeactivated ? 0.5 : 1.0)) ]), )), - const SizedBox(height: 20), + const SizedBox(height: 16), Align( alignment: Alignment.centerRight, child: buildTextButton( @@ -227,69 +257,66 @@ class VacationView extends GetWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (_responsiveUtils.isPortraitMobile(context)) - Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - AppLocalizations.of(context).vacationResponder, - style: const TextStyle( - fontSize: 15, - fontWeight: FontWeight.normal, - color: Colors.black)), - const SizedBox(height: 16), - Obx(() => ToggleSwitch( - minWidth: 150.0, - cornerRadius: 20.0, - activeBgColors: const [[Colors.green], [Colors.redAccent]], - activeFgColor: Colors.white, - inactiveBgColor: Colors.grey, - inactiveFgColor: Colors.white, - initialLabelIndex: controller.isVacationDeactivated ? 1 : 0, - totalSwitches: VacationResponderStatus.values.length, - labels: VacationResponderStatus.values - .map((status) => status.getTitle(context)) - .toList(), - radiusStyle: true, - onToggle: (index) { - final newStatus = index == 0 - ? VacationResponderStatus.activated - : VacationResponderStatus.deactivated; - controller.updateVacationPresentation(newStatus: newStatus); - }, - )) - ]) - else - Row(children: [ - Expanded( - child: Text( - AppLocalizations.of(context).vacationResponder, - style: const TextStyle( - fontSize: 15, - fontWeight: FontWeight.normal, - color: Colors.black)), - ), - const SizedBox(width: 16), - Obx(() => ToggleSwitch( - minWidth: 150.0, - cornerRadius: 20.0, - activeBgColors: const [[Colors.green], [Colors.redAccent]], - activeFgColor: Colors.white, - inactiveBgColor: Colors.grey, - inactiveFgColor: Colors.white, - initialLabelIndex: controller.isVacationDeactivated ? 1 : 0, - totalSwitches: VacationResponderStatus.values.length, - labels: VacationResponderStatus.values - .map((status) => status.getTitle(context)) - .toList(), - radiusStyle: true, - onToggle: (index) { - final newStatus = index == 0 - ? VacationResponderStatus.activated - : VacationResponderStatus.deactivated; - controller.updateVacationPresentation(newStatus: newStatus); - }, - )) - ]), - const SizedBox(height: 20), + Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Text( + AppLocalizations.of(context).vacationResponder, + style: const TextStyle( + fontSize: 15, + fontWeight: FontWeight.normal, + color: Colors.black)), + const SizedBox(height: 10), + Obx(() { + return Row( + children: [ + Material( + color: Colors.transparent, + child: InkWell( + onTap: () { + controller.updateVacationPresentation(newStatus: VacationResponderStatus.deactivated); + }, + child: Text(AppLocalizations.of(context).deactivated, + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.normal, + color: Colors.black.withOpacity( + controller.isVacationDeactivated ? 1.0 : 0.3))), + ), + ), + Padding( + padding: const EdgeInsets.only(top: 3, right: 16, left: 16), + child: InkWell( + onTap: () { + final newStatus = controller.isVacationDeactivated + ? VacationResponderStatus.activated + : VacationResponderStatus.deactivated; + controller.updateVacationPresentation(newStatus: newStatus); + }, + child: SvgPicture.asset( + controller.isVacationDeactivated + ? _imagePaths.icSwitchOff + : _imagePaths.icSwitchOn, + fit: BoxFit.fill, + width: 24, + height: 24)), + ), + Material( + color: Colors.transparent, + child: InkWell( + onTap: () { + controller.updateVacationPresentation(newStatus: VacationResponderStatus.activated); + }, + child: Text(AppLocalizations.of(context).activated, + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.normal, + color: Colors.black.withOpacity( + controller.isVacationDeactivated ? 0.3 : 1.0))), + ), + ) + ]); + }) + ]), + const SizedBox(height: 16), Obx(() => AbsorbPointer( absorbing: controller.isVacationDeactivated, child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -311,10 +338,7 @@ class VacationView extends GetWidget { color: Colors.black.withOpacity( controller.isVacationDeactivated ? 0.5 : 1.0)), hintText: AppLocalizations.of(context).startDate, - icon: const Icon( - Icons.date_range, - color: AppColor.colorIconTextField, - size: 20), + icon: SvgPicture.asset(_imagePaths.icCalendar), tapActionCallback: (value) => controller.selectDate(context, DateType.start, value)))), const SizedBox(width: 16), @@ -327,16 +351,13 @@ class VacationView extends GetWidget { color: Colors.black.withOpacity( controller.isVacationDeactivated ? 0.5 : 1.0)), hintText: AppLocalizations.of(context).noStartTime, - icon: const Icon( - Icons.timer, - color: AppColor.colorIconTextField, - size: 20), + icon: SvgPicture.asset(_imagePaths.icClock), tapActionCallback: (value) => controller.selectTime(context, DateType.start, value)))) ]), ]), )), - const SizedBox(height: 20), + const SizedBox(height: 16), Obx(() => AbsorbPointer( absorbing: controller.isVacationDeactivated, child: CheckboxListTile( @@ -376,10 +397,7 @@ class VacationView extends GetWidget { color: Colors.black.withOpacity( !controller.canChangeEndDate ? 0.5 : 1.0)), hintText: AppLocalizations.of(context).noEndDate, - icon: const Icon( - Icons.date_range, - color: AppColor.colorIconTextField, - size: 20), + icon: SvgPicture.asset(_imagePaths.icCalendar), tapActionCallback: (value) => controller.selectDate(context, DateType.end, value)))), const SizedBox(width: 16), @@ -392,16 +410,13 @@ class VacationView extends GetWidget { color: Colors.black.withOpacity( !controller.canChangeEndDate ? 0.5 : 1.0)), hintText: AppLocalizations.of(context).noEndTime, - icon: const Icon( - Icons.timer, - color: AppColor.colorIconTextField, - size: 20), + icon: SvgPicture.asset(_imagePaths.icClock), tapActionCallback: (value) => controller.selectTime(context, DateType.end, value)))) ]), ]) )), - const SizedBox(height: 20), + const SizedBox(height: 16), Obx(() => AbsorbPointer( absorbing: controller.isVacationDeactivated, child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -418,7 +433,7 @@ class VacationView extends GetWidget { controller.isVacationDeactivated ? 0.5 : 1.0) ]), )), - const SizedBox(height: 20), + const SizedBox(height: 16), Align( alignment: Alignment.centerRight, child: buildTextButton( @@ -462,9 +477,25 @@ class VacationView extends GetWidget { .hintMessageBodyVacation)) .build()) ..onChange((value) => controller.updateMessageBody(context, value)) - ..minLines(8) + ..minLines(10) ..maxLines(null)) .build(); }); } + + EdgeInsets _getPaddingView(BuildContext context) { + if (BuildUtils.isWeb) { + if (_responsiveUtils.isDesktop(context)) { + return const EdgeInsets.all(16); + } else { + return const EdgeInsets.only(top: 16, bottom: 16, left: 0, right: 24); + } + } else { + if (_responsiveUtils.isPortraitMobile(context)) { + return const EdgeInsets.only(top: 16, bottom: 16, left: 16, right: 24); + } else { + return const EdgeInsets.only(top: 16, bottom: 16, left: 0, right: 24); + } + } + } } \ No newline at end of file diff --git a/lib/features/manage_account/presentation/configuration/vacation/widgets/vacation_input_decoration_builder.dart b/lib/features/manage_account/presentation/vacation/widgets/vacation_input_decoration_builder.dart similarity index 100% rename from lib/features/manage_account/presentation/configuration/vacation/widgets/vacation_input_decoration_builder.dart rename to lib/features/manage_account/presentation/vacation/widgets/vacation_input_decoration_builder.dart diff --git a/lib/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart b/lib/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart new file mode 100644 index 000000000..71d83a52c --- /dev/null +++ b/lib/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart @@ -0,0 +1,59 @@ + +import 'package:core/core.dart'; +import 'package:flutter/material.dart'; +import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +typedef DisableVacationResponderAction = Function(); + +class VacationNotificationMessageWidget extends StatelessWidget { + + final VacationResponse vacationResponse; + final DisableVacationResponderAction? action; + final EdgeInsets? margin; + final EdgeInsets? padding; + final double? radius; + + const VacationNotificationMessageWidget({ + super.key, + required this.vacationResponse, + this.action, + this.radius, + this.margin, + this.padding, + }); + + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + margin: margin ?? const EdgeInsets.symmetric(horizontal: 16), + padding: padding ?? const EdgeInsets.only(top: 5, bottom: 5, left: 16), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(radius ?? 5), + color: AppColor.colorVacationNotificationMessageBackground, + ), + child: Row(children: [ + Expanded( + child: Text( + AppLocalizations.of(context).yourVacationResponderIsEnabled, + style: const TextStyle( + color: Colors.black, + fontSize: 16, + fontWeight: FontWeight.bold, + ))), + buildTextButton( + AppLocalizations.of(context).disable.allInCaps, + textStyle: const TextStyle( + fontWeight: FontWeight.w500, + fontSize: 16, + color: AppColor.colorTextButton), + backgroundColor: Colors.transparent, + width: 128, + height: 44, + radius: 10, + onTap: () => action?.call()) + ]), + ); + } +} \ No newline at end of file diff --git a/lib/features/thread/presentation/thread_view.dart b/lib/features/thread/presentation/thread_view.dart index f35df7b03..a4307f251 100644 --- a/lib/features/thread/presentation/thread_view.dart +++ b/lib/features/thread/presentation/thread_view.dart @@ -16,6 +16,8 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/ad import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/advanced_search/icon_open_advanced_search_widget.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/email_quick_search_item_tile_widget.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/recent_search_item_tile_widget.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart'; import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart'; import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart'; import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.dart'; @@ -60,6 +62,17 @@ class ThreadView extends GetWidget with AppLoaderMixin, if ((!_responsiveUtils.isDesktop(context) && BuildUtils.isWeb) || !BuildUtils.isWeb) ... [ _buildAppBarNormal(context), + Obx(() { + if (controller.mailboxDashBoardController.vacationResponse.value?.vacationResponderIsReady == true) { + return Padding( + padding: const EdgeInsets.only(bottom: 16), + child: VacationNotificationMessageWidget( + vacationResponse: controller.mailboxDashBoardController.vacationResponse.value!), + ); + } else { + return const SizedBox.shrink(); + } + }), Obx(() { return Stack(children: [ if (!controller.isSearchActive()) diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index 73fa82262..c33805f9e 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -1,5 +1,5 @@ { - "@@last_modified": "2022-08-17T20:19:48.796318", + "@@last_modified": "2022-08-18T14:30:25.186365", "initializing_data": "Initializing data...", "@initializing_data": { "type": "text", @@ -1910,12 +1910,6 @@ "placeholders_order": [], "placeholders": {} }, - "configuration": "Configuration", - "@configuration": { - "type": "text", - "placeholders_order": [], - "placeholders": {} - }, "vacationResponder": "Vacation responder", "@vacationResponder": { "type": "text", @@ -2005,5 +1999,17 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "yourVacationResponderIsEnabled": "Your vacation responder is enabled.", + "@yourVacationResponderIsEnabled": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "disable": "Disable", + "@disable": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } \ No newline at end of file diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart index 7f98fcbaf..c97e80368 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -1967,13 +1967,6 @@ class AppLocalizations { ); } - String get configuration { - return Intl.message( - 'Configuration', - name: 'configuration', - ); - } - String get vacationResponder { return Intl.message( 'Vacation responder', @@ -2078,4 +2071,18 @@ class AppLocalizations { name: 'vacationSettingSaved', ); } + + String get yourVacationResponderIsEnabled { + return Intl.message( + 'Your vacation responder is enabled.', + name: 'yourVacationResponderIsEnabled', + ); + } + + String get disable { + return Intl.message( + 'Disable', + name: 'disable', + ); + } } \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 703689ece..375d57299 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -187,8 +187,6 @@ dependencies: byte_converter: 1.3.0 - toggle_switch: 2.0.1 - dev_dependencies: flutter_test: sdk: flutter