diff --git a/assets/images/ic_always_read_receipt.svg b/assets/images/ic_preferences.svg similarity index 100% rename from assets/images/ic_always_read_receipt.svg rename to assets/images/ic_preferences.svg diff --git a/core/lib/presentation/resources/image_paths.dart b/core/lib/presentation/resources/image_paths.dart index bfcba1b50..83e10f612 100644 --- a/core/lib/presentation/resources/image_paths.dart +++ b/core/lib/presentation/resources/image_paths.dart @@ -212,7 +212,7 @@ class ImagePaths { String get icUnsubscribe => _getImagePath('ic_unsubscribe.svg'); String get icRecoverDeletedMessages => _getImagePath('ic_recover_deleted_messages.svg'); String get icPrinter => _getImagePath('ic_printer.svg'); - String get icAlwaysReadReceipt => _getImagePath('ic_always_read_receipt.svg'); + String get icPreferences => _getImagePath('ic_preferences.svg'); String get icNotification => _getImagePath('ic_notification.svg'); String get icRemoveRule => _getImagePath('ic_remove_rule.svg'); String get icCheckboxUnselected => _getImagePath('ic_checkbox_unselected.svg'); diff --git a/lib/features/composer/presentation/composer_bindings.dart b/lib/features/composer/presentation/composer_bindings.dart index 30a23f980..24f8cd7f5 100644 --- a/lib/features/composer/presentation/composer_bindings.dart +++ b/lib/features/composer/presentation/composer_bindings.dart @@ -50,18 +50,14 @@ import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_reposit import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/composer_cache_repository.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_composer_cache_on_web_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/preferences/bindings/preferences_interactors_bindings.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/identity_interactors_bindings.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/new_email_cache_manager.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/new_email_cache_worker_queue.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_manager.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_worker_queue.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/sending_email_cache_manager.dart'; -import 'package:tmail_ui_user/features/server_settings/data/datasource/server_settings_data_source.dart'; -import 'package:tmail_ui_user/features/server_settings/data/datasource_impl/remote_server_settings_data_source_impl.dart'; -import 'package:tmail_ui_user/features/server_settings/data/network/server_settings_api.dart'; -import 'package:tmail_ui_user/features/server_settings/data/repository/server_settings_repository_impl.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/repository/server_settings_repository.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/usecases/get_always_read_receipt_setting_interactor.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/usecases/get_server_setting_interactor.dart'; import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dart'; import 'package:tmail_ui_user/features/upload/data/datasource/attachment_upload_datasource.dart'; import 'package:tmail_ui_user/features/upload/data/datasource_impl/attachment_upload_datasource_impl.dart'; @@ -141,9 +137,6 @@ class ComposerBindings extends BaseBindings { Get.lazyPut(() => EmailSessionStorageDatasourceImpl( Get.find(), Get.find())); - Get.lazyPut(() => RemoteServerSettingsDataSourceImpl( - Get.find(), - Get.find())); } @override @@ -156,8 +149,6 @@ class ComposerBindings extends BaseBindings { Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); - Get.lazyPut( - () => Get.find()); } @override @@ -188,9 +179,6 @@ class ComposerBindings extends BaseBindings { Get.find(), Get.find(), )); - Get.lazyPut(() => ServerSettingsRepositoryImpl( - Get.find(), - )); } @override @@ -199,7 +187,6 @@ class ComposerBindings extends BaseBindings { Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); - Get.lazyPut(() => Get.find()); } @override @@ -215,7 +202,6 @@ class ComposerBindings extends BaseBindings { )); Get.lazyPut(() => DownloadImageAsBase64Interactor(Get.find())); Get.lazyPut(() => TransformHtmlEmailContentInteractor(Get.find())); - Get.lazyPut(() => GetAlwaysReadReceiptSettingInteractor(Get.find())); Get.lazyPut(() => CreateNewAndSendEmailInteractor( Get.find(), Get.find(), @@ -230,6 +216,7 @@ class ComposerBindings extends BaseBindings { Get.find())); IdentityInteractorsBindings().dependencies(); + PreferencesInteractorsBindings().dependencies(); } @override @@ -250,7 +237,7 @@ class ComposerBindings extends BaseBindings { Get.find(), Get.find(), Get.find(), - Get.find(), + Get.find(), Get.find(), Get.find(), Get.find(), diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart index 76c8e937d..64e3a38e1 100644 --- a/lib/features/composer/presentation/composer_controller.dart +++ b/lib/features/composer/presentation/composer_controller.dart @@ -29,6 +29,7 @@ import 'package:permission_handler/permission_handler.dart'; import 'package:pointer_interceptor/pointer_interceptor.dart'; import 'package:receive_sharing_intent/receive_sharing_intent.dart'; import 'package:rich_text_composer/rich_text_composer.dart'; +import 'package:server_settings/server_settings/tmail_server_settings_extension.dart'; import 'package:super_tag_editor/tag_editor.dart'; import 'package:tmail_ui_user/features/base/base_controller.dart'; import 'package:tmail_ui_user/features/base/before_reconnect_handler.dart'; @@ -93,8 +94,8 @@ import 'package:tmail_ui_user/features/manage_account/presentation/extensions/id import 'package:tmail_ui_user/features/network_connection/presentation/network_connection_controller.dart' if (dart.library.html) 'package:tmail_ui_user/features/network_connection/presentation/web_network_connection_controller.dart'; import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/state/get_always_read_receipt_setting_state.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/usecases/get_always_read_receipt_setting_interactor.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/state/get_server_setting_state.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/usecases/get_server_setting_interactor.dart'; import 'package:tmail_ui_user/features/upload/domain/exceptions/pick_file_exception.dart'; import 'package:tmail_ui_user/features/upload/domain/extensions/list_file_info_extension.dart'; import 'package:tmail_ui_user/features/upload/domain/extensions/file_info_extension.dart'; @@ -148,7 +149,7 @@ class ComposerController extends BaseController final SaveComposerCacheOnWebInteractor _saveComposerCacheOnWebInteractor; final DownloadImageAsBase64Interactor _downloadImageAsBase64Interactor; final TransformHtmlEmailContentInteractor _transformHtmlEmailContentInteractor; - final GetAlwaysReadReceiptSettingInteractor _getAlwaysReadReceiptSettingInteractor; + final GetServerSettingInteractor _getServerSettingInteractor; final CreateNewAndSendEmailInteractor _createNewAndSendEmailInteractor; final CreateNewAndSaveEmailToDraftsInteractor _createNewAndSaveEmailToDraftsInteractor; final PrintEmailInteractor printEmailInteractor; @@ -240,7 +241,7 @@ class ComposerController extends BaseController this._saveComposerCacheOnWebInteractor, this._downloadImageAsBase64Interactor, this._transformHtmlEmailContentInteractor, - this._getAlwaysReadReceiptSettingInteractor, + this._getServerSettingInteractor, this._createNewAndSendEmailInteractor, this._createNewAndSaveEmailToDraftsInteractor, this.printEmailInteractor, @@ -367,8 +368,8 @@ class ComposerController extends BaseController richTextMobileTabletController?.insertImage(inlineImage); } maxWithEditor = null; - } else if (success is GetAlwaysReadReceiptSettingSuccess) { - hasRequestReadReceipt.value = success.alwaysReadReceiptEnabled; + } else if (success is GetServerSettingSuccess) { + hasRequestReadReceipt.value = success.settingOption.isAlwaysReadReceipts; _initEmailDraftHash(); } else if (success is RestoreEmailInlineImagesSuccess) { _updateEditorContent(success); @@ -396,7 +397,7 @@ class ComposerController extends BaseController if (identitySelected.value == null) { _autoFocusFieldWhenLauncher(); } - } else if (failure is GetAlwaysReadReceiptSettingFailure) { + } else if (failure is GetServerSettingFailure) { hasRequestReadReceipt.value = false; _initEmailDraftHash(); } @@ -772,7 +773,7 @@ class ComposerController extends BaseController log('ComposerController::_initEmail: hasRequestReadReceipt = ${arguments.hasRequestReadReceipt}'); hasRequestReadReceipt.value = arguments.hasRequestReadReceipt ?? false; } else if (composerArguments.value?.emailActionType != EmailActionType.editDraft) { - _getAlwaysReadReceiptSetting(); + _getServerSetting(); } } } @@ -2242,11 +2243,10 @@ class ComposerController extends BaseController ); } - void _getAlwaysReadReceiptSetting() { - log('ComposerController::_getAlwaysReadReceiptSetting:'); + void _getServerSetting() { final accountId = mailboxDashBoardController.accountId.value; if (accountId != null) { - consumeState(_getAlwaysReadReceiptSettingInteractor.execute(accountId)); + consumeState(_getServerSettingInteractor.execute(accountId)); } } @@ -2447,7 +2447,7 @@ class ComposerController extends BaseController void _handleGetEmailContentFailure(GetEmailContentFailure failure) { emailContentsViewState.value = Left(failure); if (composerArguments.value?.emailActionType == EmailActionType.editDraft) { - _getAlwaysReadReceiptSetting(); + _getServerSetting(); } } @@ -2456,7 +2456,7 @@ class ComposerController extends BaseController hasRequestReadReceipt.value = true; _initEmailDraftHash(); } else { - _getAlwaysReadReceiptSetting(); + _getServerSetting(); } } 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 cb3b444f3..936608005 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart @@ -102,6 +102,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/search_controller.dart' as search; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/spam_report_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/delete_emails_in_mailbox_extension.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_preferences_setting_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/set_error_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/update_current_emails_flags_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mixin/user_setting_popup_menu_mixin.dart'; @@ -144,6 +145,8 @@ import 'package:tmail_ui_user/features/sending_queue/domain/usecases/get_all_sen import 'package:tmail_ui_user/features/sending_queue/domain/usecases/store_sending_email_interactor.dart'; import 'package:tmail_ui_user/features/sending_queue/domain/usecases/update_sending_email_interactor.dart'; import 'package:tmail_ui_user/features/sending_queue/presentation/model/sending_email_arguments.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/state/get_server_setting_state.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/usecases/get_server_setting_interactor.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/empty_spam_folder_state.dart'; @@ -174,6 +177,7 @@ import 'package:tmail_ui_user/main/universal_import/html_stub.dart' as html; import 'package:tmail_ui_user/main/utils/app_config.dart'; import 'package:tmail_ui_user/main/utils/email_receive_manager.dart'; import 'package:tmail_ui_user/main/utils/ios_notification_manager.dart'; +import 'package:server_settings/server_settings/tmail_server_settings_extension.dart'; import 'package:uuid/uuid.dart'; class MailboxDashBoardController extends ReloadableController @@ -221,6 +225,7 @@ class MailboxDashBoardController extends ReloadableController DeleteMailboxStateToRefreshInteractor? _deleteMailboxStateToRefreshInteractor; GetAutoCompleteInteractor? _getAutoCompleteInteractor; IOSNotificationManager? _iosNotificationManager; + GetServerSettingInteractor? getServerSettingInteractor; final scaffoldKey = GlobalKey(); final selectedMailbox = Rxn(); @@ -245,6 +250,7 @@ class MailboxDashBoardController extends ReloadableController final attachmentDraggableAppState = Rxn(); final isRecoveringDeletedMessage = RxBool(false); final localFileDraggableAppState = Rxn(); + final isSenderImportantFlagEnabled = RxBool(true); Session? sessionCurrent; Map mapDefaultMailboxIdByRole = {}; @@ -439,6 +445,8 @@ class MailboxDashBoardController extends ReloadableController [success.emailId], markStarAction: success.markStarAction, ); + } else if (success is GetServerSettingSuccess) { + isSenderImportantFlagEnabled.value = success.settingOption.isDisplaySenderPriority; } } @@ -471,6 +479,8 @@ class MailboxDashBoardController extends ReloadableController toastManager.showMessageFailure(failure); } else if (failure is GetComposerCacheFailure) { _handleIdentityCache(); + } else if (failure is GetServerSettingFailure) { + isSenderImportantFlagEnabled.value = true; } } @@ -734,6 +744,7 @@ class MailboxDashBoardController extends ReloadableController injectRuleFilterBindings(session, currentAccountId); injectVacationBindings(session, currentAccountId); injectWebSocket(session, currentAccountId); + injectPreferencesBindings(); if (PlatformInfo.isMobile) { injectFCMBindings(session, currentAccountId); } @@ -741,6 +752,7 @@ class MailboxDashBoardController extends ReloadableController _getVacationResponse(); spamReportController.getSpamReportStateAction(); _getAllIdentities(); + getServerSetting(); if (PlatformInfo.isMobile) { getAllSendingEmails(); @@ -1900,6 +1912,7 @@ class MailboxDashBoardController extends ReloadableController } _getAllIdentities(); + getServerSetting(); } Future> quickSearchEmails(String query) async { @@ -1965,6 +1978,7 @@ class MailboxDashBoardController extends ReloadableController } _getAllIdentities(); + getServerSetting(); } void _handleUpdateVacationSuccess(UpdateVacationSuccess success) { diff --git a/lib/features/mailbox_dashboard/presentation/extensions/handle_preferences_setting_extension.dart b/lib/features/mailbox_dashboard/presentation/extensions/handle_preferences_setting_extension.dart new file mode 100644 index 000000000..5719e7145 --- /dev/null +++ b/lib/features/mailbox_dashboard/presentation/extensions/handle_preferences_setting_extension.dart @@ -0,0 +1,32 @@ + +import 'package:server_settings/server_settings/capability_server_settings.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/preferences/bindings/preferences_interactors_bindings.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/usecases/get_server_setting_interactor.dart'; +import 'package:tmail_ui_user/main/error/capability_validator.dart'; +import 'package:tmail_ui_user/main/routes/route_navigation.dart'; + +extension HandlePreferencesSettingExtension on MailboxDashBoardController { + + bool get isServerSettingsCapabilitySupported { + if (accountId.value == null || sessionCurrent == null) return false; + + return capabilityServerSettings.isSupported( + sessionCurrent!, + accountId.value!, + ); + } + + void injectPreferencesBindings() { + if (isServerSettingsCapabilitySupported) { + PreferencesInteractorsBindings().dependencies(); + getServerSettingInteractor = getBinding(); + } + } + + void getServerSetting() { + if (accountId.value == null || getServerSettingInteractor == null) return; + + consumeState(getServerSettingInteractor!.execute(accountId.value!)); + } +} \ No newline at end of file diff --git a/lib/features/manage_account/presentation/always_read_receipt/always_read_receipt_controller.dart b/lib/features/manage_account/presentation/always_read_receipt/always_read_receipt_controller.dart deleted file mode 100644 index 71fc11933..000000000 --- a/lib/features/manage_account/presentation/always_read_receipt/always_read_receipt_controller.dart +++ /dev/null @@ -1,99 +0,0 @@ -import 'package:core/presentation/state/failure.dart'; -import 'package:core/presentation/state/success.dart'; -import 'package:get/get.dart'; -import 'package:tmail_ui_user/features/base/base_controller.dart'; -import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/state/get_always_read_receipt_setting_state.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/state/update_always_read_receipt_setting_state.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/usecases/get_always_read_receipt_setting_interactor.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/usecases/update_always_read_receipt_setting_interactor.dart'; -import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; -import 'package:tmail_ui_user/main/routes/route_navigation.dart'; - -class AlwaysReadReceiptController extends BaseController { - AlwaysReadReceiptController( - this._getAlwaysReadReceiptSettingInteractor, - this._updateAlwaysReadReceiptSettingInteractor, - ); - - final GetAlwaysReadReceiptSettingInteractor _getAlwaysReadReceiptSettingInteractor; - final UpdateAlwaysReadReceiptSettingInteractor _updateAlwaysReadReceiptSettingInteractor; - - final alwaysReadReceipt = Rxn(); - bool get isLoading => viewState.value.fold( - (failure) => false, - (success) => success is GettingAlwaysReadReceiptSetting || success is UpdatingAlwaysReadReceiptSetting); - final _manageAccountDashBoardController = Get.find(); - - @override - void onInit() { - super.onInit(); - - _getCurrentAlwaysReadReceiptSetting(); - } - - @override - void handleSuccessViewState(Success success) { - super.handleSuccessViewState(success); - if (success is GetAlwaysReadReceiptSettingSuccess) { - _getAlwaysReadReceiptSettingSuccess(success); - } else if (success is UpdateAlwaysReadReceiptSettingSuccess) { - _updateAlwaysReadReceiptSettingSuccess(success); - } - } - - @override - void handleFailureViewState(Failure failure) { - super.handleFailureViewState(failure); - if (failure is GetAlwaysReadReceiptSettingFailure) { - _getAlwaysReadReceiptSettingFailure(); - } else if (failure is UpdateAlwaysReadReceiptSettingFailure) { - _updateAlwaysReadReceiptSettingFailure(); - } - } - - void _updateAlwaysReadReceiptValue(bool value) { - alwaysReadReceipt.value = value; - } - - void _updateAlwaysReadReceiptSettingFailure() { - if (currentOverlayContext != null && currentContext != null) { - appToast.showToastErrorMessage( - currentOverlayContext!, - AppLocalizations.of(currentContext!).an_error_occurred); - } - } - - void _updateAlwaysReadReceiptSettingSuccess( - UpdateAlwaysReadReceiptSettingSuccess success - ) { - _updateAlwaysReadReceiptValue(success.alwaysReadReceiptIsEnabled); - } - - void toggleAlwaysReadReceipt() { - if (isLoading || alwaysReadReceipt.value == null) return; - final accountId = _manageAccountDashBoardController.accountId.value; - if (accountId != null) { - consumeState(_updateAlwaysReadReceiptSettingInteractor.execute( - accountId, - !alwaysReadReceipt.value!)); - } - } - - void _getAlwaysReadReceiptSettingFailure() { - alwaysReadReceipt.value = false; - } - - void _getAlwaysReadReceiptSettingSuccess( - GetAlwaysReadReceiptSettingSuccess success - ) { - _updateAlwaysReadReceiptValue(success.alwaysReadReceiptEnabled); - } - - void _getCurrentAlwaysReadReceiptSetting() { - final accountId = _manageAccountDashBoardController.accountId.value; - if (accountId != null) { - consumeState(_getAlwaysReadReceiptSettingInteractor.execute(accountId)); - } - } -} \ No newline at end of file diff --git a/lib/features/manage_account/presentation/always_read_receipt/always_read_receipt_view.dart b/lib/features/manage_account/presentation/always_read_receipt/always_read_receipt_view.dart deleted file mode 100644 index 760999122..000000000 --- a/lib/features/manage_account/presentation/always_read_receipt/always_read_receipt_view.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'package:core/presentation/extensions/color_extension.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/mixin/app_loader_mixin.dart'; -import 'package:tmail_ui_user/features/manage_account/presentation/always_read_receipt/always_read_receipt_controller.dart'; -import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.dart'; -import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; - -class AlwaysReadReceiptView extends GetWidget with AppLoaderMixin { - const AlwaysReadReceiptView({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: SettingsUtils.getBackgroundColor(context, controller.responsiveUtils), - body: Padding( - padding: SettingsUtils.getMarginViewForSettingDetails(context, controller.responsiveUtils), - child: Column( - children: [ - Obx(() { - if (!controller.isLoading) { - return const SizedBox.shrink(); - } - return Padding( - padding: const EdgeInsets.only(bottom: 8), - child: horizontalLoadingWidget, - ); - }), - Expanded( - child: Container( - color: SettingsUtils.getContentBackgroundColor(context, controller.responsiveUtils), - decoration: SettingsUtils.getBoxDecorationForContent(context, controller.responsiveUtils), - padding: SettingsUtils.getPaddingAlwaysReadReceiptSetting(context, controller.responsiveUtils), - child: ListView( - physics: const ClampingScrollPhysics(), - children: [ - Text( - AppLocalizations.of(context).emailReadReceipts, - style: const TextStyle( - fontSize: 17, - height: 24 / 17, - fontWeight: FontWeight.w500, - color: Colors.black)), - const SizedBox(height: 8), - Text( - AppLocalizations.of(context).emailReadReceiptsSettingExplanation, - style: const TextStyle( - fontSize: 16, - height: 20 / 16, - color: AppColor.colorTextSettingDescriptions)), - const SizedBox(height: 24), - Obx(() { - if (controller.alwaysReadReceipt.value == null) { - return const SizedBox.shrink(); - } - - return Row( - children: [ - InkWell( - onTap: controller.toggleAlwaysReadReceipt, - child: Padding( - padding: const EdgeInsets.all(4), - child: SvgPicture.asset( - controller.alwaysReadReceipt.value! - ? controller.imagePaths.icSwitchOn - : controller.imagePaths.icSwitchOff, - fit: BoxFit.fill, - width: 32, - height: 20), - ), - ), - const SizedBox(width: 12), - Expanded( - child: Text( - AppLocalizations.of(context).emailReadReceiptsToggleDescription, - style: const TextStyle( - fontSize: 16, - height: 20 / 16, - color: Colors.black), - )), - ], - ); - }), - ], - ), - ), - ), - ], - ), - ), - ); - } - -} \ No newline at end of file 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 33a10bd2e..5dee14063 100644 --- a/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart +++ b/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart @@ -22,7 +22,6 @@ import 'package:tmail_ui_user/features/manage_account/domain/state/update_vacati 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/action/dashboard_setting_action.dart'; -import 'package:tmail_ui_user/features/manage_account/presentation/always_read_receipt/bindings/always_read_receipt_bindings.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/bindings/email_rules_bindings.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/forward/bindings/forward_bindings.dart'; @@ -32,6 +31,7 @@ import 'package:tmail_ui_user/features/manage_account/presentation/model/account import 'package:tmail_ui_user/features/manage_account/presentation/model/manage_account_arguments.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/settings_page_level.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/notification/bindings/notification_binding.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/preferences/bindings/preferences_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_controller_bindings.dart'; import 'package:tmail_ui_user/main/error/capability_validator.dart'; @@ -184,8 +184,8 @@ class ManageAccountDashBoardController extends ReloadableController with UserSet case AccountMenuItem.emailRules: EmailRulesBindings().dependencies(); break; - case AccountMenuItem.alwaysReadReceipt: - AlwaysReadReceiptBindings().dependencies(); + case AccountMenuItem.preferences: + PreferencesBindings().dependencies(); break; case AccountMenuItem.forward: ForwardBindings().dependencies(); @@ -224,7 +224,7 @@ class ManageAccountDashBoardController extends ReloadableController with UserSet bool get isVacationCapabilitySupported { if (accountId.value != null && sessionCurrent != null) { - return [CapabilityIdentifier.jmapVacationResponse].isSupported(sessionCurrent!, accountId.value!); + return CapabilityIdentifier.jmapVacationResponse.isSupported(sessionCurrent!, accountId.value!); } else { return false; } @@ -240,7 +240,7 @@ class ManageAccountDashBoardController extends ReloadableController with UserSet bool get isServerSettingsCapabilitySupported { if (accountId.value != null && sessionCurrent != null) { - return [capabilityServerSettings].isSupported(sessionCurrent!, accountId.value!); + return capabilityServerSettings.isSupported(sessionCurrent!, accountId.value!); } else { return false; } @@ -248,7 +248,7 @@ class ManageAccountDashBoardController extends ReloadableController with UserSet bool get isRuleFilterCapabilitySupported { if (accountId.value != null && sessionCurrent != null) { - return [capabilityRuleFilter].isSupported(sessionCurrent!, accountId.value!); + return capabilityRuleFilter.isSupported(sessionCurrent!, accountId.value!); } else { return false; } @@ -256,7 +256,7 @@ class ManageAccountDashBoardController extends ReloadableController with UserSet bool get isForwardCapabilitySupported { if (accountId.value != null && sessionCurrent != null) { - return [capabilityForward].isSupported(sessionCurrent!, accountId.value!); + return capabilityForward.isSupported(sessionCurrent!, accountId.value!); } else { return false; } 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 935b71b11..403de0cd1 100644 --- a/lib/features/manage_account/presentation/manage_account_dashboard_view.dart +++ b/lib/features/manage_account/presentation/manage_account_dashboard_view.dart @@ -6,7 +6,6 @@ import 'package:get/get.dart'; import 'package:model/model.dart'; import 'package:tmail_ui_user/features/base/state/banner_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/navigation_bar/navigation_bar_widget.dart'; -import 'package:tmail_ui_user/features/manage_account/presentation/always_read_receipt/always_read_receipt_view.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/extensions/vacation_response_extension.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/forward/forward_view.dart'; @@ -17,6 +16,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/menu/settings/settings_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/preferences/preferences_view.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/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart'; @@ -117,19 +117,19 @@ class ManageAccountDashBoardView extends GetWidget { if (controller.manageAccountDashboardController.isServerSettingsCapabilitySupported) { return Column(children: [ SettingFirstLevelTileBuilder( - AccountMenuItem.alwaysReadReceipt.getName(context), - AccountMenuItem.alwaysReadReceipt.getIcon(controller.imagePaths), + AccountMenuItem.preferences.getName(context), + AccountMenuItem.preferences.getIcon(controller.imagePaths), subtitle: AppLocalizations.of(context).emailReadReceiptsSettingExplanation, - () => controller.selectSettings(AccountMenuItem.alwaysReadReceipt) + () => controller.selectSettings(AccountMenuItem.preferences) ), Divider( color: AppColor.colorDividerHorizontal, 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 a68487cb3..7fda57f4a 100644 --- a/lib/features/manage_account/presentation/menu/settings/settings_view.dart +++ b/lib/features/manage_account/presentation/menu/settings/settings_view.dart @@ -6,7 +6,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; import 'package:tmail_ui_user/features/base/state/banner_state.dart'; -import 'package:tmail_ui_user/features/manage_account/presentation/always_read_receipt/always_read_receipt_view.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/extensions/vacation_response_extension.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/forward/forward_view.dart'; @@ -19,6 +18,7 @@ import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/settings_page_level.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/notification/notification_view.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/preferences/preferences_view.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/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart'; @@ -198,9 +198,9 @@ class SettingsView extends GetWidget { } else { return const SizedBox.shrink(); } - case AccountMenuItem.alwaysReadReceipt: + case AccountMenuItem.preferences: if (controller.manageAccountDashboardController.isServerSettingsCapabilitySupported) { - return const AlwaysReadReceiptView(); + return const PreferencesView(); } else { return const SizedBox.shrink(); } 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 1c4a0ede6..f8bd0c3ec 100644 --- a/lib/features/manage_account/presentation/model/account_menu_item.dart +++ b/lib/features/manage_account/presentation/model/account_menu_item.dart @@ -1,12 +1,12 @@ -import 'package:core/core.dart'; +import 'package:core/presentation/resources/image_paths.dart'; import 'package:flutter/cupertino.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; enum AccountMenuItem { profiles, languageAndRegion, - alwaysReadReceipt, + preferences, emailRules, forward, vacation, @@ -22,8 +22,8 @@ enum AccountMenuItem { return imagePaths.icProfiles; case AccountMenuItem.languageAndRegion: return imagePaths.icLanguage; - case AccountMenuItem.alwaysReadReceipt: - return imagePaths.icAlwaysReadReceipt; + case AccountMenuItem.preferences: + return imagePaths.icPreferences; case AccountMenuItem.emailRules: return imagePaths.icEmailRules; case AccountMenuItem.forward: @@ -51,8 +51,8 @@ enum AccountMenuItem { return AppLocalizations.of(context).language; case AccountMenuItem.emailRules: return AppLocalizations.of(context).emailRules; - case AccountMenuItem.alwaysReadReceipt: - return AppLocalizations.of(context).emailReadReceipts; + case AccountMenuItem.preferences: + return AppLocalizations.of(context).preferences; case AccountMenuItem.forward: return AppLocalizations.of(context).forwarding; case AccountMenuItem.vacation: @@ -78,8 +78,8 @@ enum AccountMenuItem { return 'language-region'; case AccountMenuItem.emailRules: return 'email-rules'; - case AccountMenuItem.alwaysReadReceipt: - return 'email-read-receipts'; + case AccountMenuItem.preferences: + return 'preferences'; case AccountMenuItem.forward: return 'forwarding'; case AccountMenuItem.vacation: diff --git a/lib/features/manage_account/presentation/model/setting_option_type.dart b/lib/features/manage_account/presentation/model/setting_option_type.dart new file mode 100644 index 000000000..e7ef2bce2 --- /dev/null +++ b/lib/features/manage_account/presentation/model/setting_option_type.dart @@ -0,0 +1,45 @@ + +import 'package:server_settings/server_settings/tmail_server_settings.dart'; +import 'package:server_settings/server_settings/tmail_server_settings_extension.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +enum SettingOptionType { + readReceipt, + senderPriority; + + String getTitle(AppLocalizations appLocalizations) { + switch(this) { + case SettingOptionType.readReceipt: + return appLocalizations.emailReadReceipts; + case SettingOptionType.senderPriority: + return appLocalizations.senderSetImportantFlag; + } + } + + String getExplanation(AppLocalizations appLocalizations) { + switch(this) { + case SettingOptionType.readReceipt: + return appLocalizations.emailReadReceiptsSettingExplanation; + case SettingOptionType.senderPriority: + return appLocalizations.senderImportantSettingExplanation; + } + } + + String getToggleDescription(AppLocalizations appLocalizations) { + switch(this) { + case SettingOptionType.readReceipt: + return appLocalizations.emailReadReceiptsToggleDescription; + case SettingOptionType.senderPriority: + return appLocalizations.senderImportantSettingToggleDescription; + } + } + + bool isEnabled(TMailServerSettingOptions settingOption) { + switch(this) { + case SettingOptionType.readReceipt: + return settingOption.isAlwaysReadReceipts; + case SettingOptionType.senderPriority: + return settingOption.isDisplaySenderPriority; + } + } +} \ No newline at end of file diff --git a/lib/features/manage_account/presentation/preferences/bindings/preferences_bindings.dart b/lib/features/manage_account/presentation/preferences/bindings/preferences_bindings.dart new file mode 100644 index 000000000..deef60812 --- /dev/null +++ b/lib/features/manage_account/presentation/preferences/bindings/preferences_bindings.dart @@ -0,0 +1,18 @@ +import 'package:get/get.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/preferences/bindings/preferences_interactors_bindings.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/preferences/preferences_controller.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/usecases/get_server_setting_interactor.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/usecases/update_server_setting_interactor.dart'; + +class PreferencesBindings extends Bindings { + + @override + void dependencies() { + PreferencesInteractorsBindings().dependencies(); + + Get.lazyPut(() => PreferencesController( + Get.find(), + Get.find(), + )); + } +} \ No newline at end of file diff --git a/lib/features/manage_account/presentation/always_read_receipt/bindings/always_read_receipt_bindings.dart b/lib/features/manage_account/presentation/preferences/bindings/preferences_interactors_bindings.dart similarity index 63% rename from lib/features/manage_account/presentation/always_read_receipt/bindings/always_read_receipt_bindings.dart rename to lib/features/manage_account/presentation/preferences/bindings/preferences_interactors_bindings.dart index c1bfad429..d9cf6212f 100644 --- a/lib/features/manage_account/presentation/always_read_receipt/bindings/always_read_receipt_bindings.dart +++ b/lib/features/manage_account/presentation/preferences/bindings/preferences_interactors_bindings.dart @@ -1,22 +1,15 @@ import 'package:get/get.dart'; -import 'package:tmail_ui_user/features/base/base_bindings.dart'; -import 'package:tmail_ui_user/features/manage_account/presentation/always_read_receipt/always_read_receipt_controller.dart'; +import 'package:tmail_ui_user/features/base/interactors_bindings.dart'; import 'package:tmail_ui_user/features/server_settings/data/datasource/server_settings_data_source.dart'; import 'package:tmail_ui_user/features/server_settings/data/datasource_impl/remote_server_settings_data_source_impl.dart'; import 'package:tmail_ui_user/features/server_settings/data/network/server_settings_api.dart'; import 'package:tmail_ui_user/features/server_settings/data/repository/server_settings_repository_impl.dart'; import 'package:tmail_ui_user/features/server_settings/domain/repository/server_settings_repository.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/usecases/get_always_read_receipt_setting_interactor.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/usecases/update_always_read_receipt_setting_interactor.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/usecases/get_server_setting_interactor.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/usecases/update_server_setting_interactor.dart'; import 'package:tmail_ui_user/main/exceptions/remote_exception_thrower.dart'; -class AlwaysReadReceiptBindings extends BaseBindings { - @override - void bindingsController() { - Get.put(AlwaysReadReceiptController( - Get.find(), - Get.find())); - } +class PreferencesInteractorsBindings extends InteractorsBindings { @override void bindingsDataSource() { @@ -27,13 +20,14 @@ class AlwaysReadReceiptBindings extends BaseBindings { void bindingsDataSourceImpl() { Get.lazyPut(() => RemoteServerSettingsDataSourceImpl( Get.find(), - Get.find())); + Get.find(), + )); } @override void bindingsInteractor() { - Get.lazyPut(() => GetAlwaysReadReceiptSettingInteractor(Get.find())); - Get.lazyPut(() => UpdateAlwaysReadReceiptSettingInteractor(Get.find())); + Get.lazyPut(() => GetServerSettingInteractor(Get.find())); + Get.lazyPut(() => UpdateServerSettingInteractor(Get.find())); } @override diff --git a/lib/features/manage_account/presentation/preferences/preferences_controller.dart b/lib/features/manage_account/presentation/preferences/preferences_controller.dart new file mode 100644 index 000000000..6e2e36fca --- /dev/null +++ b/lib/features/manage_account/presentation/preferences/preferences_controller.dart @@ -0,0 +1,110 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:get/get.dart'; +import 'package:server_settings/server_settings/tmail_server_settings.dart'; +import 'package:tmail_ui_user/features/base/base_controller.dart'; +import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/model/setting_option_type.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/state/get_server_setting_state.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/state/update_server_setting_state.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/usecases/get_server_setting_interactor.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/usecases/update_server_setting_interactor.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; +import 'package:tmail_ui_user/main/routes/route_navigation.dart'; + +class PreferencesController extends BaseController { + PreferencesController( + this._getServerSettingInteractor, + this._updateServerSettingInteractor, + ); + + final GetServerSettingInteractor _getServerSettingInteractor; + final UpdateServerSettingInteractor _updateServerSettingInteractor; + + final settingOption = Rxn(); + + bool get isLoading => viewState.value.fold( + (failure) => false, + (success) => success is GettingServerSetting || success is UpdatingServerSetting); + + final _manageAccountDashBoardController = Get.find(); + + @override + void onInit() { + super.onInit(); + _getSettingOption(); + } + + @override + void handleSuccessViewState(Success success) { + if (success is GetServerSettingSuccess) { + _updateSettingOptionValue(newSettingOption: success.settingOption); + } else if (success is UpdateServerSettingSuccess) { + _updateSettingOptionValue(newSettingOption: success.settingOption); + } else { + super.handleSuccessViewState(success); + } + } + + @override + void handleFailureViewState(Failure failure) { + if (failure is GetServerSettingFailure) { + _updateSettingOptionValue(newSettingOption: null); + } else if (failure is UpdateServerSettingFailure) { + _handleUpdateServerSettingFailure(); + } else { + super.handleFailureViewState(failure); + } + } + + void _handleUpdateServerSettingFailure() { + if (currentOverlayContext != null && currentContext != null) { + appToast.showToastErrorMessage( + currentOverlayContext!, + AppLocalizations.of(currentContext!).an_error_occurred); + } + } + + void _updateSettingOptionValue({required TMailServerSettingOptions? newSettingOption}) { + settingOption.value = newSettingOption; + } + + void _getSettingOption() { + final accountId = _manageAccountDashBoardController.accountId.value; + if (accountId != null) { + consumeState(_getServerSettingInteractor.execute(accountId)); + } else { + consumeState(Stream.value(Left(GetServerSettingFailure(NotFoundAccountIdException())))); + } + } + + void updateStateSettingOption(SettingOptionType optionType, bool isEnabled) { + TMailServerSettingOptions? newSettingOption; + switch(optionType) { + case SettingOptionType.readReceipt: + newSettingOption = settingOption.value?.copyWith( + alwaysReadReceipts: !isEnabled, + ); + break; + case SettingOptionType.senderPriority: + newSettingOption = settingOption.value?.copyWith( + displaySenderPriority: !isEnabled, + ); + break; + default: + break; + } + + final accountId = _manageAccountDashBoardController.accountId.value; + if (accountId != null && newSettingOption != null) { + consumeState(_updateServerSettingInteractor.execute( + accountId, + newSettingOption, + )); + } else { + consumeState(Stream.value(Left(UpdateServerSettingFailure(NotFoundAccountIdException())))); + } + } +} \ No newline at end of file diff --git a/lib/features/manage_account/presentation/preferences/preferences_view.dart b/lib/features/manage_account/presentation/preferences/preferences_view.dart new file mode 100644 index 000000000..2e760d667 --- /dev/null +++ b/lib/features/manage_account/presentation/preferences/preferences_view.dart @@ -0,0 +1,70 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/model/setting_option_type.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/preferences/preferences_controller.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/preferences/widgets/setting_option_item.dart'; + +class PreferencesView extends GetWidget with AppLoaderMixin { + const PreferencesView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: SettingsUtils.getBackgroundColor(context, controller.responsiveUtils), + body: Padding( + padding: SettingsUtils.getMarginViewForSettingDetails(context, controller.responsiveUtils), + child: Column( + children: [ + Obx(() { + if (!controller.isLoading) { + return const SizedBox.shrink(); + } + return Padding( + padding: const EdgeInsets.only(bottom: 8), + child: horizontalLoadingWidget, + ); + }), + Expanded( + child: Container( + color: SettingsUtils.getContentBackgroundColor( + context, controller.responsiveUtils, + ), + decoration: SettingsUtils.getBoxDecorationForContent( + context, + controller.responsiveUtils, + ), + width: double.infinity, + padding: SettingsUtils.getPaddingAlwaysReadReceiptSetting( + context, + controller.responsiveUtils, + ), + child: Obx(() { + final settingOption = controller.settingOption.value; + + if (settingOption == null) return const SizedBox.shrink(); + + final settingOptionList = SettingOptionType.values.toList(); + + return ListView.separated( + itemCount: settingOptionList.length, + itemBuilder: (context, index) { + return SettingOptionItem( + imagePaths: controller.imagePaths, + settingOption: settingOption, + optionType: settingOptionList[index], + onTapSettingOptionAction: controller.updateStateSettingOption, + ); + }, + separatorBuilder: (_, __) => const SizedBox(height: 60), + ); + }), + ), + ), + ], + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/features/manage_account/presentation/preferences/widgets/setting_option_item.dart b/lib/features/manage_account/presentation/preferences/widgets/setting_option_item.dart new file mode 100644 index 000000000..f97230873 --- /dev/null +++ b/lib/features/manage_account/presentation/preferences/widgets/setting_option_item.dart @@ -0,0 +1,86 @@ + +import 'package:core/presentation/resources/image_paths.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:server_settings/server_settings/tmail_server_settings.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/model/setting_option_type.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +typedef OnTapSettingOptionAction = Function(SettingOptionType optionType, bool isEnabled); + +class SettingOptionItem extends StatelessWidget { + + final ImagePaths imagePaths; + final TMailServerSettingOptions settingOption; + final SettingOptionType optionType; + final OnTapSettingOptionAction onTapSettingOptionAction; + + const SettingOptionItem({ + super.key, + required this.imagePaths, + required this.settingOption, + required this.optionType, + required this.onTapSettingOptionAction, + }); + + @override + Widget build(BuildContext context) { + final appLocalizations = AppLocalizations.of(context); + + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + optionType.getTitle(appLocalizations), + style: const TextStyle( + fontSize: 15, + height: 20 / 15, + fontWeight: FontWeight.bold, + color: Colors.black, + ), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 24), + child: Text( + optionType.getExplanation(appLocalizations), + style: const TextStyle( + fontSize: 13, + height: 16 / 13, + color: Colors.black, + ), + ), + ), + Row( + children: [ + InkWell( + onTap: () => onTapSettingOptionAction( + optionType, + optionType.isEnabled(settingOption), + ), + child: SvgPicture.asset( + optionType.isEnabled(settingOption) + ? imagePaths.icSwitchOn + : imagePaths.icSwitchOff, + fit: BoxFit.fill, + width: 44, + height: 28, + ), + ), + const SizedBox(width: 12), + Expanded( + child: Text( + optionType.getToggleDescription(appLocalizations), + style: const TextStyle( + fontSize: 13, + height: 16 / 13, + color: Colors.black, + ), + ), + ), + ], + ), + ], + ); + } +} diff --git a/lib/features/search/email/presentation/search_email_view.dart b/lib/features/search/email/presentation/search_email_view.dart index d422074e9..08b5c4c41 100644 --- a/lib/features/search/email/presentation/search_email_view.dart +++ b/lib/features/search/email/presentation/search_email_view.dart @@ -648,6 +648,7 @@ class SearchEmailView extends GetWidget selectAllMode: controller.selectionMode.value, searchQuery: controller.searchQuery, isShowingEmailContent: controller.mailboxDashBoardController.selectedEmail.value?.id == currentPresentationEmail.id, + isSenderImportantFlagEnabled: controller.mailboxDashBoardController.isSenderImportantFlagEnabled.value, isSearchEmailRunning: true, padding: SearchEmailViewStyle.getPaddingSearchResultList(context, controller.responsiveUtils), mailboxContain: currentPresentationEmail.mailboxContain, @@ -697,6 +698,7 @@ class SearchEmailView extends GetWidget selectAllMode: controller.selectionMode.value, searchQuery: controller.searchQuery, isShowingEmailContent: controller.mailboxDashBoardController.selectedEmail.value?.id == currentPresentationEmail.id, + isSenderImportantFlagEnabled: controller.mailboxDashBoardController.isSenderImportantFlagEnabled.value, isSearchEmailRunning: true, padding: SearchEmailViewStyle.getPaddingSearchResultList( context, diff --git a/lib/features/server_settings/domain/exceptions/server_settings_exception.dart b/lib/features/server_settings/domain/exceptions/server_settings_exception.dart index 03cf865ee..63e1eefe5 100644 --- a/lib/features/server_settings/domain/exceptions/server_settings_exception.dart +++ b/lib/features/server_settings/domain/exceptions/server_settings_exception.dart @@ -1,3 +1,5 @@ class NotFoundServerSettingsException implements Exception {} +class NotFoundSettingOptionException implements Exception {} + class CanNotUpdateServerSettingsException implements Exception {} \ No newline at end of file diff --git a/lib/features/server_settings/domain/state/get_always_read_receipt_setting_state.dart b/lib/features/server_settings/domain/state/get_always_read_receipt_setting_state.dart deleted file mode 100644 index b34798335..000000000 --- a/lib/features/server_settings/domain/state/get_always_read_receipt_setting_state.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:core/presentation/state/failure.dart'; -import 'package:core/presentation/state/success.dart'; - -class GettingAlwaysReadReceiptSetting extends LoadingState {} - -class GetAlwaysReadReceiptSettingSuccess extends UIState { - final bool alwaysReadReceiptEnabled; - - GetAlwaysReadReceiptSettingSuccess({required this.alwaysReadReceiptEnabled}); - - @override - List get props => [alwaysReadReceiptEnabled]; -} - -class GetAlwaysReadReceiptSettingFailure extends FeatureFailure { - GetAlwaysReadReceiptSettingFailure(dynamic exception) - : super(exception: exception); -} \ No newline at end of file diff --git a/lib/features/server_settings/domain/state/get_server_setting_state.dart b/lib/features/server_settings/domain/state/get_server_setting_state.dart new file mode 100644 index 000000000..f8e2e3289 --- /dev/null +++ b/lib/features/server_settings/domain/state/get_server_setting_state.dart @@ -0,0 +1,19 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:server_settings/server_settings/tmail_server_settings.dart'; + +class GettingServerSetting extends LoadingState {} + +class GetServerSettingSuccess extends UIState { + final TMailServerSettingOptions settingOption; + + GetServerSettingSuccess(this.settingOption); + + @override + List get props => [settingOption]; +} + +class GetServerSettingFailure extends FeatureFailure { + GetServerSettingFailure(dynamic exception) + : super(exception: exception); +} \ No newline at end of file diff --git a/lib/features/server_settings/domain/state/update_always_read_receipt_setting_state.dart b/lib/features/server_settings/domain/state/update_always_read_receipt_setting_state.dart deleted file mode 100644 index 3227dcef2..000000000 --- a/lib/features/server_settings/domain/state/update_always_read_receipt_setting_state.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:core/core.dart'; - -class UpdatingAlwaysReadReceiptSetting extends LoadingState {} - -class UpdateAlwaysReadReceiptSettingSuccess extends UIState { - final bool alwaysReadReceiptIsEnabled; - - UpdateAlwaysReadReceiptSettingSuccess({required this.alwaysReadReceiptIsEnabled}); - - @override - List get props => [alwaysReadReceiptIsEnabled]; -} - -class UpdateAlwaysReadReceiptSettingFailure extends FeatureFailure { - UpdateAlwaysReadReceiptSettingFailure(dynamic exception) - : super(exception: exception); -} \ No newline at end of file diff --git a/lib/features/server_settings/domain/state/update_server_setting_state.dart b/lib/features/server_settings/domain/state/update_server_setting_state.dart new file mode 100644 index 000000000..8dd6780fd --- /dev/null +++ b/lib/features/server_settings/domain/state/update_server_setting_state.dart @@ -0,0 +1,19 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:server_settings/server_settings/tmail_server_settings.dart'; + +class UpdatingServerSetting extends LoadingState {} + +class UpdateServerSettingSuccess extends UIState { + final TMailServerSettingOptions settingOption; + + UpdateServerSettingSuccess(this.settingOption); + + @override + List get props => [settingOption]; +} + +class UpdateServerSettingFailure extends FeatureFailure { + UpdateServerSettingFailure(dynamic exception) + : super(exception: exception); +} \ No newline at end of file diff --git a/lib/features/server_settings/domain/usecases/get_always_read_receipt_setting_interactor.dart b/lib/features/server_settings/domain/usecases/get_always_read_receipt_setting_interactor.dart deleted file mode 100644 index a4e6f14ac..000000000 --- a/lib/features/server_settings/domain/usecases/get_always_read_receipt_setting_interactor.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:core/presentation/state/failure.dart'; -import 'package:core/presentation/state/success.dart'; -import 'package:dartz/dartz.dart'; -import 'package:jmap_dart_client/jmap/account_id.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/repository/server_settings_repository.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/state/get_always_read_receipt_setting_state.dart'; - -class GetAlwaysReadReceiptSettingInteractor { - final ServerSettingsRepository _serverSettingsRepository; - - GetAlwaysReadReceiptSettingInteractor(this._serverSettingsRepository); - - Stream> execute(AccountId accountId) async* { - try { - yield Right(GettingAlwaysReadReceiptSetting()); - final result = await _serverSettingsRepository.getServerSettings(accountId); - yield Right(GetAlwaysReadReceiptSettingSuccess( - alwaysReadReceiptEnabled: result.settings?.alwaysReadReceipts ?? false)); - } catch (e) { - yield Left(GetAlwaysReadReceiptSettingFailure(e)); - } - } -} \ No newline at end of file diff --git a/lib/features/server_settings/domain/usecases/get_server_setting_interactor.dart b/lib/features/server_settings/domain/usecases/get_server_setting_interactor.dart new file mode 100644 index 000000000..85f32a7df --- /dev/null +++ b/lib/features/server_settings/domain/usecases/get_server_setting_interactor.dart @@ -0,0 +1,28 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/exceptions/server_settings_exception.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/repository/server_settings_repository.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/state/get_server_setting_state.dart'; + +class GetServerSettingInteractor { + final ServerSettingsRepository _serverSettingsRepository; + + GetServerSettingInteractor(this._serverSettingsRepository); + + Stream> execute(AccountId accountId) async* { + try { + yield Right(GettingServerSetting()); + final serverSetting = await _serverSettingsRepository.getServerSettings(accountId); + final settingOption = serverSetting.settings; + if (settingOption == null) { + yield Left(GetServerSettingFailure(NotFoundSettingOptionException())); + } else { + yield Right(GetServerSettingSuccess(settingOption)); + } + } catch (e) { + yield Left(GetServerSettingFailure(e)); + } + } +} \ No newline at end of file diff --git a/lib/features/server_settings/domain/usecases/update_always_read_receipt_setting_interactor.dart b/lib/features/server_settings/domain/usecases/update_always_read_receipt_setting_interactor.dart deleted file mode 100644 index 62fed0b19..000000000 --- a/lib/features/server_settings/domain/usecases/update_always_read_receipt_setting_interactor.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:core/core.dart'; -import 'package:dartz/dartz.dart'; -import 'package:jmap_dart_client/jmap/account_id.dart'; -import 'package:server_settings/server_settings/tmail_server_settings.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/repository/server_settings_repository.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/state/update_always_read_receipt_setting_state.dart'; - -class UpdateAlwaysReadReceiptSettingInteractor { - final ServerSettingsRepository _serverSettingsRepository; - - UpdateAlwaysReadReceiptSettingInteractor(this._serverSettingsRepository); - - Stream> execute( - AccountId accountId, - bool isEnabled - ) async* { - yield Right(UpdatingAlwaysReadReceiptSetting()); - try { - final result = await _serverSettingsRepository.updateServerSettings( - accountId, - TMailServerSettings( - settings: TMailServerSettingOptions(alwaysReadReceipts: isEnabled) - ) - ); - yield Right(UpdateAlwaysReadReceiptSettingSuccess( - alwaysReadReceiptIsEnabled: result.settings?.alwaysReadReceipts ?? true)); - } catch (e) { - yield Left(UpdateAlwaysReadReceiptSettingFailure(e)); - } - } -} \ No newline at end of file diff --git a/lib/features/server_settings/domain/usecases/update_server_setting_interactor.dart b/lib/features/server_settings/domain/usecases/update_server_setting_interactor.dart new file mode 100644 index 000000000..b134625e4 --- /dev/null +++ b/lib/features/server_settings/domain/usecases/update_server_setting_interactor.dart @@ -0,0 +1,35 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:server_settings/server_settings/tmail_server_settings.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/exceptions/server_settings_exception.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/repository/server_settings_repository.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/state/update_server_setting_state.dart'; + +class UpdateServerSettingInteractor { + final ServerSettingsRepository _serverSettingsRepository; + + UpdateServerSettingInteractor(this._serverSettingsRepository); + + Stream> execute( + AccountId accountId, + TMailServerSettingOptions newSettingOption, + ) async* { + yield Right(UpdatingServerSetting()); + try { + final serverSetting = await _serverSettingsRepository.updateServerSettings( + accountId, + TMailServerSettings(settings: newSettingOption), + ); + final settingOption = serverSetting.settings; + if (settingOption == null) { + yield Left(UpdateServerSettingFailure(NotFoundServerSettingsException())); + } else { + yield Right(UpdateServerSettingSuccess(settingOption)); + } + } catch (e) { + yield Left(UpdateServerSettingFailure(e)); + } + } +} \ 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 95e8ec5e1..d7371565d 100644 --- a/lib/features/thread/presentation/thread_view.dart +++ b/lib/features/thread/presentation/thread_view.dart @@ -497,6 +497,8 @@ class ThreadView extends GetWidget Widget _buildEmailItemWhenDragging(BuildContext context, PresentationEmail presentationEmail) { final isShowingEmailContent = controller.mailboxDashBoardController.selectedEmail.value?.id == presentationEmail.id; final selectModeAll = controller.mailboxDashBoardController.currentSelectMode.value; + final isSenderImportantFlagEnabled = + controller.mailboxDashBoardController.isSenderImportantFlagEnabled.value; return EmailTileBuilder( key: Key('email_tile_builder_${presentationEmail.id?.asString}'), @@ -506,13 +508,16 @@ class ThreadView extends GetWidget searchQuery: controller.searchQuery, mailboxContain: presentationEmail.mailboxContain, isSearchEmailRunning: controller.searchController.isSearchEmailRunning, - isDrag: true + isDrag: true, + isSenderImportantFlagEnabled: isSenderImportantFlagEnabled, ); } Widget _buildEmailItemNotDraggable(BuildContext context, PresentationEmail presentationEmail) { final isShowingEmailContent = controller.mailboxDashBoardController.selectedEmail.value?.id == presentationEmail.id; final selectModeAll = controller.mailboxDashBoardController.currentSelectMode.value; + final isSenderImportantFlagEnabled = + controller.mailboxDashBoardController.isSenderImportantFlagEnabled.value; return Dismissible( key: ValueKey(presentationEmail.id), @@ -588,6 +593,7 @@ class ThreadView extends GetWidget presentationEmail: presentationEmail, selectAllMode: selectModeAll, isShowingEmailContent: isShowingEmailContent, + isSenderImportantFlagEnabled: isSenderImportantFlagEnabled, searchQuery: controller.searchQuery, mailboxContain: presentationEmail.mailboxContain, isSearchEmailRunning: controller.searchController.isSearchEmailRunning, diff --git a/lib/features/thread/presentation/widgets/email_tile_builder.dart b/lib/features/thread/presentation/widgets/email_tile_builder.dart index 752a65420..67ef43d57 100644 --- a/lib/features/thread/presentation/widgets/email_tile_builder.dart +++ b/lib/features/thread/presentation/widgets/email_tile_builder.dart @@ -19,6 +19,7 @@ class EmailTileBuilder extends StatelessWidget with BaseEmailItemTile { final EdgeInsetsGeometry? padding; final bool isDrag; final bool isShowingEmailContent; + final bool isSenderImportantFlagEnabled; final OnPressEmailActionClick? emailActionClick; final OnMoreActionClick? onMoreActionClick; @@ -29,6 +30,7 @@ class EmailTileBuilder extends StatelessWidget with BaseEmailItemTile { required this.isShowingEmailContent, this.searchQuery, this.isSearchEmailRunning = false, + this.isSenderImportantFlagEnabled = true, this.mailboxContain, this.padding, this.isDrag = false, @@ -104,7 +106,7 @@ class EmailTileBuilder extends StatelessWidget with BaseEmailItemTile { children: [ if (presentationEmail.hasCalendarEvent) buildCalendarEventIcon(context: context, presentationEmail: presentationEmail), - if (presentationEmail.isMarkAsImportant) + if (presentationEmail.isMarkAsImportant && isSenderImportantFlagEnabled) buildMarkAsImportantIcon(context), Expanded(child: buildEmailTitle( context, diff --git a/lib/features/thread/presentation/widgets/email_tile_web_builder.dart b/lib/features/thread/presentation/widgets/email_tile_web_builder.dart index a114f3d28..fb33eea5a 100644 --- a/lib/features/thread/presentation/widgets/email_tile_web_builder.dart +++ b/lib/features/thread/presentation/widgets/email_tile_web_builder.dart @@ -24,6 +24,7 @@ class EmailTileBuilder extends StatefulWidget { final EdgeInsetsGeometry? padding; final bool isDrag; final bool isShowingEmailContent; + final bool isSenderImportantFlagEnabled; final OnPressEmailActionClick? emailActionClick; final OnMoreActionClick? onMoreActionClick; @@ -34,6 +35,7 @@ class EmailTileBuilder extends StatefulWidget { required this.isShowingEmailContent, this.searchQuery, this.isSearchEmailRunning = false, + this.isSenderImportantFlagEnabled = true, this.mailboxContain, this.padding, this.isDrag = false, @@ -140,7 +142,7 @@ class _EmailTileBuilderState extends State with BaseEmailItem context: context, presentationEmail: widget.presentationEmail ), - if (widget.presentationEmail.isMarkAsImportant) + if (widget.presentationEmail.isMarkAsImportant && widget.isSenderImportantFlagEnabled) buildMarkAsImportantIcon(context), Expanded( child: buildEmailTitle( @@ -259,7 +261,7 @@ class _EmailTileBuilderState extends State with BaseEmailItem context: context, presentationEmail: widget.presentationEmail ), - if (widget.presentationEmail.isMarkAsImportant) + if (widget.presentationEmail.isMarkAsImportant && widget.isSenderImportantFlagEnabled) buildMarkAsImportantIcon(context), Expanded( child: buildEmailTitle( @@ -615,7 +617,7 @@ class _EmailTileBuilderState extends State with BaseEmailItem return Row(children: [ if (widget.presentationEmail.hasCalendarEvent) buildCalendarEventIcon(context: context, presentationEmail: widget.presentationEmail), - if (widget.presentationEmail.isMarkAsImportant) + if (widget.presentationEmail.isMarkAsImportant && widget.isSenderImportantFlagEnabled) buildMarkAsImportantIcon(context), if (widget.presentationEmail.getEmailTitle().isNotEmpty) Container( diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index 888345a31..42a40b0b5 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -4339,5 +4339,29 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "preferences": "Preferences", + "@preferences": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "senderSetImportantFlag": "Sender-set important flag", + "@senderSetImportantFlag": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "senderImportantSettingExplanation": "Enables display of important emails flag in your inbox. This feature is controlled by the sender and thus could result in abuses.", + "@senderImportantSettingExplanation": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "senderImportantSettingToggleDescription": "Display sender-set important flag", + "@senderImportantSettingToggleDescription": { + "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 c9e3b461a..37afe08cf 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -4555,4 +4555,32 @@ class AppLocalizations { name: 'turnOffMarkAsImportant', ); } + + String get preferences { + return Intl.message( + 'Preferences', + name: 'preferences', + ); + } + + String get senderSetImportantFlag { + return Intl.message( + 'Sender-set important flag', + name: 'senderSetImportantFlag', + ); + } + + String get senderImportantSettingExplanation { + return Intl.message( + 'Enables display of important emails flag in your inbox. This feature is controlled by the sender and thus could result in abuses.', + name: 'senderImportantSettingExplanation', + ); + } + + String get senderImportantSettingToggleDescription { + return Intl.message( + 'Display sender-set important flag', + name: 'senderImportantSettingToggleDescription', + ); + } } diff --git a/server_settings/lib/server_settings/converter/always_read_receipt_nullable_converter.dart b/server_settings/lib/server_settings/converter/boolean_nullable_converter.dart similarity index 62% rename from server_settings/lib/server_settings/converter/always_read_receipt_nullable_converter.dart rename to server_settings/lib/server_settings/converter/boolean_nullable_converter.dart index 8427174f8..8c0b85966 100644 --- a/server_settings/lib/server_settings/converter/always_read_receipt_nullable_converter.dart +++ b/server_settings/lib/server_settings/converter/boolean_nullable_converter.dart @@ -1,13 +1,13 @@ import 'package:json_annotation/json_annotation.dart'; -class AlwaysReadReceiptNullableConverter implements JsonConverter { - const AlwaysReadReceiptNullableConverter(); +class BooleanNullableConverter implements JsonConverter { + const BooleanNullableConverter(); @override bool? fromJson(String? json) { if (json == null) { return null; - } else if (json == 'true') { + } else if (json.trim().toLowerCase() == 'true') { return true; } else { return false; diff --git a/server_settings/lib/server_settings/tmail_server_settings.dart b/server_settings/lib/server_settings/tmail_server_settings.dart index 648d15fc4..335537dfc 100644 --- a/server_settings/lib/server_settings/tmail_server_settings.dart +++ b/server_settings/lib/server_settings/tmail_server_settings.dart @@ -1,6 +1,6 @@ import 'package:equatable/equatable.dart'; import 'package:json_annotation/json_annotation.dart'; -import 'package:server_settings/server_settings/converter/always_read_receipt_nullable_converter.dart'; +import 'package:server_settings/server_settings/converter/boolean_nullable_converter.dart'; import 'package:server_settings/server_settings/converter/server_settings_id_nullable_converter.dart'; import 'package:server_settings/server_settings/server_settings.dart'; import 'package:server_settings/server_settings/server_settings_id.dart'; @@ -28,23 +28,38 @@ class TMailServerSettings extends ServerSettings { @JsonSerializable( explicitToJson: true, includeIfNull: false, - converters: [AlwaysReadReceiptNullableConverter()]) + converters: [BooleanNullableConverter()] +) class TMailServerSettingOptions with EquatableMixin { @JsonKey(name: 'read.receipts.always') final bool? alwaysReadReceipts; - TMailServerSettingOptions({this.alwaysReadReceipts}); + + @JsonKey(name: 'display.sender.priority') + final bool? displaySenderPriority; + + TMailServerSettingOptions({ + this.alwaysReadReceipts, + this.displaySenderPriority, + }); factory TMailServerSettingOptions.fromJson(Map json) => _$TMailServerSettingOptionsFromJson(json); Map toJson() => _$TMailServerSettingOptionsToJson(this); - TMailServerSettingOptions copyWith({bool? alwaysReadReceipts}) { + TMailServerSettingOptions copyWith({ + bool? alwaysReadReceipts, + bool? displaySenderPriority, + }) { return TMailServerSettingOptions( alwaysReadReceipts: alwaysReadReceipts ?? this.alwaysReadReceipts, + displaySenderPriority: displaySenderPriority ?? this.displaySenderPriority, ); } @override - List get props => [alwaysReadReceipts]; + List get props => [ + alwaysReadReceipts, + displaySenderPriority, + ]; } diff --git a/server_settings/lib/server_settings/tmail_server_settings_extension.dart b/server_settings/lib/server_settings/tmail_server_settings_extension.dart new file mode 100644 index 000000000..8e53d9957 --- /dev/null +++ b/server_settings/lib/server_settings/tmail_server_settings_extension.dart @@ -0,0 +1,8 @@ + +import 'package:server_settings/server_settings/tmail_server_settings.dart'; + +extension TmailServerSettingsExtension on TMailServerSettingOptions { + bool get isDisplaySenderPriority => displaySenderPriority ?? true; + + bool get isAlwaysReadReceipts => alwaysReadReceipts ?? false; +} \ No newline at end of file diff --git a/test/features/composer/presentation/composer_controller_test.dart b/test/features/composer/presentation/composer_controller_test.dart index 21aba3859..46e0dbd9e 100644 --- a/test/features/composer/presentation/composer_controller_test.dart +++ b/test/features/composer/presentation/composer_controller_test.dart @@ -28,6 +28,7 @@ import 'package:model/email/email_property.dart'; import 'package:model/email/presentation_email.dart'; import 'package:model/mailbox/presentation_mailbox.dart'; import 'package:rich_text_composer/rich_text_composer.dart'; +import 'package:server_settings/server_settings/tmail_server_settings.dart'; import 'package:tmail_ui_user/features/base/before_reconnect_manager.dart'; import 'package:tmail_ui_user/features/caching/caching_manager.dart'; import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_drafts_state.dart'; @@ -58,8 +59,8 @@ import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_ident import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/log_out_oidc_interactor.dart'; import 'package:tmail_ui_user/features/network_connection/presentation/network_connection_controller.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/state/get_always_read_receipt_setting_state.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/usecases/get_always_read_receipt_setting_interactor.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/state/get_server_setting_state.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/usecases/get_server_setting_interactor.dart'; import 'package:tmail_ui_user/features/upload/domain/usecases/local_file_picker_interactor.dart'; import 'package:tmail_ui_user/features/upload/domain/usecases/local_image_picker_interactor.dart'; import 'package:tmail_ui_user/features/upload/presentation/controller/upload_controller.dart'; @@ -159,7 +160,7 @@ class MockMailboxDashBoardController extends Mock implements MailboxDashBoardCon MockSpec(), MockSpec(), MockSpec(), - MockSpec(), + MockSpec(), MockSpec(), MockSpec(), MockSpec(), @@ -202,7 +203,7 @@ void main() { late MockSaveComposerCacheOnWebInteractor mockSaveComposerCacheOnWebInteractor; late MockDownloadImageAsBase64Interactor mockDownloadImageAsBase64Interactor; late MockTransformHtmlEmailContentInteractor mockTransformHtmlEmailContentInteractor; - late MockGetAlwaysReadReceiptSettingInteractor mockGetAlwaysReadReceiptSettingInteractor; + late MockGetServerSettingInteractor mockGetServerSettingInteractor; late MockCreateNewAndSendEmailInteractor mockCreateNewAndSendEmailInteractor; late MockCreateNewAndSaveEmailToDraftsInteractor mockCreateNewAndSaveEmailToDraftsInteractor; late MockPrintEmailInteractor mockPrintEmailInteractor; @@ -270,7 +271,7 @@ void main() { mockSaveComposerCacheOnWebInteractor = MockSaveComposerCacheOnWebInteractor(); mockDownloadImageAsBase64Interactor = MockDownloadImageAsBase64Interactor(); mockTransformHtmlEmailContentInteractor = MockTransformHtmlEmailContentInteractor(); - mockGetAlwaysReadReceiptSettingInteractor = MockGetAlwaysReadReceiptSettingInteractor(); + mockGetServerSettingInteractor = MockGetServerSettingInteractor(); mockCreateNewAndSendEmailInteractor = MockCreateNewAndSendEmailInteractor(); mockCreateNewAndSaveEmailToDraftsInteractor = MockCreateNewAndSaveEmailToDraftsInteractor(); mockPrintEmailInteractor = MockPrintEmailInteractor(); @@ -285,7 +286,7 @@ void main() { mockSaveComposerCacheOnWebInteractor, mockDownloadImageAsBase64Interactor, mockTransformHtmlEmailContentInteractor, - mockGetAlwaysReadReceiptSettingInteractor, + mockGetServerSettingInteractor, mockCreateNewAndSendEmailInteractor, mockCreateNewAndSaveEmailToDraftsInteractor, mockPrintEmailInteractor, @@ -335,8 +336,7 @@ void main() { composerController?.listReplyToEmailAddress = [replyToRecipient]; composerController?.identitySelected.value = identity; when(mockUploadController.attachmentsUploaded).thenReturn([attachment]); - final state = GetAlwaysReadReceiptSettingSuccess( - alwaysReadReceiptEnabled: alwaysReadReceiptEnabled); + final state = GetServerSettingSuccess(TMailServerSettingOptions(alwaysReadReceipts: alwaysReadReceiptEnabled)); final savedEmailDraft = SavedEmailDraft( content: emailContent, @@ -376,7 +376,7 @@ void main() { composerController?.listReplyToEmailAddress = [replyToRecipient]; composerController?.identitySelected.value = identity; when(mockUploadController.attachmentsUploaded).thenReturn([attachment]); - final state = GetAlwaysReadReceiptSettingFailure(Exception()); + final state = GetServerSettingFailure(Exception()); final savedEmailDraft = SavedEmailDraft( content: emailContent, @@ -757,8 +757,7 @@ void main() { when(mockUploadController.attachmentsUploaded).thenReturn([attachment]); const alwaysReadReceiptEnabled = true; - final state = GetAlwaysReadReceiptSettingSuccess( - alwaysReadReceiptEnabled: alwaysReadReceiptEnabled); + final state = GetServerSettingSuccess(TMailServerSettingOptions(alwaysReadReceipts: alwaysReadReceiptEnabled)); final savedEmailDraft = SavedEmailDraft( content: emailContent, @@ -799,7 +798,7 @@ void main() { composerController?.identitySelected.value = identity; when(mockUploadController.attachmentsUploaded).thenReturn([attachment]); - final state = GetAlwaysReadReceiptSettingFailure(Exception()); + final state = GetServerSettingFailure(Exception()); final savedEmailDraft = SavedEmailDraft( content: emailContent, @@ -1310,8 +1309,7 @@ void main() { when(mockRichTextMobileTabletController.htmlEditorApi).thenReturn( mockHtmlEditorApi); - final state = GetAlwaysReadReceiptSettingSuccess( - alwaysReadReceiptEnabled: true); + final state = GetServerSettingSuccess(TMailServerSettingOptions(alwaysReadReceipts: true)); // act composerController?.handleSuccessViewState(state); @@ -1330,7 +1328,7 @@ void main() { when(mockRichTextMobileTabletController.htmlEditorApi).thenReturn( mockHtmlEditorApi); - final state = GetAlwaysReadReceiptSettingFailure(Exception()); + final state = GetServerSettingFailure(Exception()); // act composerController?.handleFailureViewState(state); diff --git a/test/features/server_settings/domain/usecases/get_always_read_receipt_setting_interactor_test.dart b/test/features/server_settings/domain/usecases/get_server_setting_interactor_test.dart similarity index 70% rename from test/features/server_settings/domain/usecases/get_always_read_receipt_setting_interactor_test.dart rename to test/features/server_settings/domain/usecases/get_server_setting_interactor_test.dart index 166d1ad7f..c57c44355 100644 --- a/test/features/server_settings/domain/usecases/get_always_read_receipt_setting_interactor_test.dart +++ b/test/features/server_settings/domain/usecases/get_server_setting_interactor_test.dart @@ -7,17 +7,17 @@ import 'package:mockito/mockito.dart'; import 'package:server_settings/server_settings/tmail_server_settings.dart'; import 'package:tmail_ui_user/features/server_settings/domain/exceptions/server_settings_exception.dart'; import 'package:tmail_ui_user/features/server_settings/domain/repository/server_settings_repository.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/state/get_always_read_receipt_setting_state.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/usecases/get_always_read_receipt_setting_interactor.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/state/get_server_setting_state.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/usecases/get_server_setting_interactor.dart'; -import 'get_always_read_receipt_setting_interactor_test.mocks.dart'; +import 'get_server_setting_interactor_test.mocks.dart'; @GenerateNiceMocks([MockSpec()]) void main() { final accountId = AccountId(Id('123')); final serverSettingsRepository = MockServerSettingsRepository(); - final getAlwaysReadReceiptSettingInteractor = - GetAlwaysReadReceiptSettingInteractor(serverSettingsRepository); + final getServerSettingInteractor = + GetServerSettingInteractor(serverSettingsRepository); group('get always read receipt setting interactor', () { test('should return right with value returned from repository', () { @@ -29,10 +29,10 @@ void main() { // assert expect( - getAlwaysReadReceiptSettingInteractor.execute(accountId), + getServerSettingInteractor.execute(accountId), emitsInOrder([ - Right(GettingAlwaysReadReceiptSetting()), - Right(GetAlwaysReadReceiptSettingSuccess(alwaysReadReceiptEnabled: false)), + Right(GettingServerSetting()), + Right(GetServerSettingSuccess(TMailServerSettingOptions(alwaysReadReceipts: false))), ]) ); }); @@ -44,10 +44,10 @@ void main() { // assert expect( - getAlwaysReadReceiptSettingInteractor.execute(accountId), + getServerSettingInteractor.execute(accountId), emitsInOrder([ - Right(GettingAlwaysReadReceiptSetting()), - Left(GetAlwaysReadReceiptSettingFailure(exception)), + Right(GettingServerSetting()), + Left(GetServerSettingFailure(exception)), ]) ); }); diff --git a/test/features/server_settings/domain/usecases/update_always_read_receipt_setting_interactor_test.dart b/test/features/server_settings/domain/usecases/update_server_setting_interactor_test.dart similarity index 60% rename from test/features/server_settings/domain/usecases/update_always_read_receipt_setting_interactor_test.dart rename to test/features/server_settings/domain/usecases/update_server_setting_interactor_test.dart index 571175392..829b6bf95 100644 --- a/test/features/server_settings/domain/usecases/update_always_read_receipt_setting_interactor_test.dart +++ b/test/features/server_settings/domain/usecases/update_server_setting_interactor_test.dart @@ -2,14 +2,17 @@ import 'package:dartz/dartz.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/core/id.dart'; +import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:server_settings/server_settings/tmail_server_settings.dart'; import 'package:tmail_ui_user/features/server_settings/domain/exceptions/server_settings_exception.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/state/update_always_read_receipt_setting_state.dart'; -import 'package:tmail_ui_user/features/server_settings/domain/usecases/update_always_read_receipt_setting_interactor.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/repository/server_settings_repository.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/state/update_server_setting_state.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/usecases/update_server_setting_interactor.dart'; -import 'get_always_read_receipt_setting_interactor_test.mocks.dart'; +import 'update_server_setting_interactor_test.mocks.dart'; +@GenerateNiceMocks([MockSpec()]) void main() { final accountId = AccountId(Id('123')); const alwaysReadReceipts = false; @@ -17,8 +20,7 @@ void main() { settings: TMailServerSettingOptions(alwaysReadReceipts: alwaysReadReceipts) ); final serverSettingsRepository = MockServerSettingsRepository(); - final updateAlwaysReadReceiptSettingInteractor = - UpdateAlwaysReadReceiptSettingInteractor(serverSettingsRepository); + final updateServerSettingInteractor = UpdateServerSettingInteractor(serverSettingsRepository); group('update always read receipt setting interactor', () { test('should return right with value returned from repository', () { // arrange @@ -27,11 +29,13 @@ void main() { // assert expect( - updateAlwaysReadReceiptSettingInteractor - .execute(accountId, alwaysReadReceipts), + updateServerSettingInteractor.execute( + accountId, + TMailServerSettingOptions(alwaysReadReceipts: alwaysReadReceipts), + ), emitsInOrder([ - Right(UpdatingAlwaysReadReceiptSetting()), - Right(UpdateAlwaysReadReceiptSettingSuccess(alwaysReadReceiptIsEnabled: alwaysReadReceipts)), + Right(UpdatingServerSetting()), + Right(UpdateServerSettingSuccess(TMailServerSettingOptions(alwaysReadReceipts: alwaysReadReceipts))), ]) ); }); @@ -44,10 +48,13 @@ void main() { // assert expect( - updateAlwaysReadReceiptSettingInteractor.execute(accountId, alwaysReadReceipts), + updateServerSettingInteractor.execute( + accountId, + TMailServerSettingOptions(alwaysReadReceipts: alwaysReadReceipts), + ), emitsInOrder([ - Right(UpdatingAlwaysReadReceiptSetting()), - Left(UpdateAlwaysReadReceiptSettingFailure(exception)), + Right(UpdatingServerSetting()), + Left(UpdateServerSettingFailure(exception)), ]) ); });