From e1f9eec72b741cbbed4d5fd4bfb4235108da1668 Mon Sep 17 00:00:00 2001 From: dab246 Date: Thu, 2 Oct 2025 15:44:22 +0700 Subject: [PATCH 1/2] TF-4082 Setup text formatting menu state from user's preferences in composer --- .../presentation/composer_controller.dart | 6 +++ .../controller/rich_text_web_controller.dart | 6 +++ .../state/get_text_formatting_menu_state.dart | 17 +++++++ ...text_formatting_menu_state_interactor.dart | 24 ++++++++++ ..._all_composer_cache_on_web_interactor.dart | 2 +- ...omposer_cache_by_id_on_web_interactor.dart | 2 +- .../bindings/mailbox_dashboard_bindings.dart | 10 ++++ .../mailbox_dashboard_controller.dart | 10 ++++ ..._text_formatting_menu_state_extension.dart | 17 +++++++ .../manage_account_datasource_impl.dart | 5 ++ .../local/preferences_setting_manager.dart | 28 +++++++++++ .../preferences/preferences_setting.dart | 12 +++++ .../model/preferences/spam_report_config.dart | 7 +-- .../text_formatting_menu_config.dart | 30 ++++++++++++ .../preferences/thread_detail_config.dart | 6 +-- .../bindings/setting_interactor_bindings.dart | 46 +++++++++++++++++++ .../manage_account_dashboard_bindings.dart | 45 ++---------------- 17 files changed, 219 insertions(+), 54 deletions(-) create mode 100644 lib/features/mailbox_dashboard/domain/state/get_text_formatting_menu_state.dart create mode 100644 lib/features/mailbox_dashboard/domain/usecases/get_text_formatting_menu_state_interactor.dart create mode 100644 lib/features/mailbox_dashboard/presentation/extensions/update_text_formatting_menu_state_extension.dart create mode 100644 lib/features/manage_account/domain/model/preferences/text_formatting_menu_config.dart create mode 100644 lib/features/manage_account/presentation/bindings/setting_interactor_bindings.dart diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart index 0a639e00ea..8337476682 100644 --- a/lib/features/composer/presentation/composer_controller.dart +++ b/lib/features/composer/presentation/composer_controller.dart @@ -669,6 +669,12 @@ class ComposerController extends BaseController responsiveUtils.isWebDesktop(currentContext!)) { await setupSelectedIdentityWithoutApplySignature(); } + + if (PlatformInfo.isWeb) { + richTextWebController?.updateFormattingOptions( + mailboxDashBoardController.isTextFormattingMenuOpened.value, + ); + } } void initAttachmentsAndInlineImages({ diff --git a/lib/features/composer/presentation/controller/rich_text_web_controller.dart b/lib/features/composer/presentation/controller/rich_text_web_controller.dart index 01a327717c..e56762c92d 100644 --- a/lib/features/composer/presentation/controller/rich_text_web_controller.dart +++ b/lib/features/composer/presentation/controller/rich_text_web_controller.dart @@ -313,6 +313,12 @@ class RichTextWebController extends GetxController { } } + void updateFormattingOptions(bool isDisplayed) { + formattingOptionsState.value = isDisplayed + ? FormattingOptionsState.enabled + : FormattingOptionsState.disabled; + } + bool get isFormattingOptionsEnabled => formattingOptionsState.value == FormattingOptionsState.enabled; @override diff --git a/lib/features/mailbox_dashboard/domain/state/get_text_formatting_menu_state.dart b/lib/features/mailbox_dashboard/domain/state/get_text_formatting_menu_state.dart new file mode 100644 index 0000000000..2a5a3d42e5 --- /dev/null +++ b/lib/features/mailbox_dashboard/domain/state/get_text_formatting_menu_state.dart @@ -0,0 +1,17 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; + +class GettingTextFormattingMenuState extends LoadingState {} + +class GetTextFormattingMenuStateSuccess extends UIState { + final bool isDisplayed; + + GetTextFormattingMenuStateSuccess(this.isDisplayed); + + @override + List get props => [isDisplayed]; +} + +class GetTextFormattingMenuStateFailure extends FeatureFailure { + GetTextFormattingMenuStateFailure(dynamic exception) : super(exception: exception); +} diff --git a/lib/features/mailbox_dashboard/domain/usecases/get_text_formatting_menu_state_interactor.dart b/lib/features/mailbox_dashboard/domain/usecases/get_text_formatting_menu_state_interactor.dart new file mode 100644 index 0000000000..ab24df30d0 --- /dev/null +++ b/lib/features/mailbox_dashboard/domain/usecases/get_text_formatting_menu_state_interactor.dart @@ -0,0 +1,24 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_text_formatting_menu_state.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart'; + +class GetTextFormattingMenuStateInteractor { + final ManageAccountRepository _manageAccountRepository; + + GetTextFormattingMenuStateInteractor(this._manageAccountRepository); + + Stream> execute() async* { + try { + yield Right(GettingTextFormattingMenuState()); + final preferencesSetting = + await _manageAccountRepository.getLocalSettings(); + yield Right(GetTextFormattingMenuStateSuccess( + preferencesSetting.textFormattingMenuConfig.isDisplayed, + )); + } catch (exception) { + yield Left(GetTextFormattingMenuStateFailure(exception)); + } + } +} diff --git a/lib/features/mailbox_dashboard/domain/usecases/remove_all_composer_cache_on_web_interactor.dart b/lib/features/mailbox_dashboard/domain/usecases/remove_all_composer_cache_on_web_interactor.dart index 31bc522897..2cb7953c84 100644 --- a/lib/features/mailbox_dashboard/domain/usecases/remove_all_composer_cache_on_web_interactor.dart +++ b/lib/features/mailbox_dashboard/domain/usecases/remove_all_composer_cache_on_web_interactor.dart @@ -13,7 +13,7 @@ class RemoveAllComposerCacheOnWebInteractor { Future> execute(AccountId accountId, UserName userName) async { try { - composerCacheRepository.removeAllComposerCacheOnWeb(accountId, userName); + await composerCacheRepository.removeAllComposerCacheOnWeb(accountId, userName,); return Right(RemoveComposerCacheSuccess()); } catch (exception) { return Left(RemoveComposerCacheFailure(exception)); diff --git a/lib/features/mailbox_dashboard/domain/usecases/remove_composer_cache_by_id_on_web_interactor.dart b/lib/features/mailbox_dashboard/domain/usecases/remove_composer_cache_by_id_on_web_interactor.dart index 08bdc06e5a..36a9339228 100644 --- a/lib/features/mailbox_dashboard/domain/usecases/remove_composer_cache_by_id_on_web_interactor.dart +++ b/lib/features/mailbox_dashboard/domain/usecases/remove_composer_cache_by_id_on_web_interactor.dart @@ -17,7 +17,7 @@ class RemoveComposerCacheByIdOnWebInteractor { String composerId, ) async { try { - composerCacheRepository.removeComposerCacheByIdOnWeb( + await composerCacheRepository.removeComposerCacheByIdOnWeb( accountId, userName, composerId, 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 9a104d90d2..dd60f6cda1 100644 --- a/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart +++ b/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart @@ -85,6 +85,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_com import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_spam_mailbox_cached_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_spam_report_state_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_stored_email_sort_order_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_text_formatting_menu_state_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/quick_search_email_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_all_composer_cache_on_web_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_composer_cache_by_id_on_web_interactor.dart'; @@ -101,7 +102,9 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/spam_report_controller.dart'; import 'package:tmail_ui_user/features/manage_account/data/local/preferences_setting_manager.dart'; import 'package:tmail_ui_user/features/manage_account/domain/repository/identity_repository.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_identities_interactor.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/bindings/setting_interactor_bindings.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/identities/identity_interactors_bindings.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/identities/utils/identity_utils.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/new_email_cache_manager.dart'; @@ -378,6 +381,13 @@ class MailboxDashBoardBindings extends BaseBindings { Get.find() )); PaywallBindings().dependencies(); + + SettingInteractorBindings().dependencies(); + Get.lazyPut( + () => GetTextFormattingMenuStateInteractor( + Get.find(), + ), + ); } @override 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 fb112c6dd9..b3ef99b157 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart @@ -101,9 +101,11 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/exceptions/spam_ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/spam_report_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_composer_cache_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_stored_email_sort_order_state.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_text_formatting_menu_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/remove_email_drafts_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_composer_cache_on_web_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_stored_email_sort_order_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_text_formatting_menu_state_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_all_composer_cache_on_web_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_composer_cache_by_id_on_web_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_email_drafts_interactor.dart'; @@ -128,6 +130,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions 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/extensions/handle_paywall_extension.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/update_text_formatting_menu_state_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/web_auth_redirect_processor_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_routes.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/download/download_task_state.dart'; @@ -262,6 +265,7 @@ class MailboxDashBoardController extends ReloadableController GetServerSettingInteractor? getServerSettingInteractor; CreateNewEmailRuleFilterInteractor? createNewEmailRuleFilterInteractor; SaveLanguageInteractor? saveLanguageInteractor; + GetTextFormattingMenuStateInteractor? getTextFormattingMenuStateInteractor; final scaffoldKey = GlobalKey(); final selectedMailbox = Rxn(); @@ -291,6 +295,7 @@ class MailboxDashBoardController extends ReloadableController final isDrawerOpened = RxBool(false); final isContextMenuOpened = RxBool(false); final isPopupMenuOpened = RxBool(false); + final isTextFormattingMenuOpened = RxBool(false); Map mapDefaultMailboxIdByRole = {}; Map mapMailboxById = {}; @@ -377,6 +382,7 @@ class MailboxDashBoardController extends ReloadableController listSearchFilterScrollController = ScrollController(); twakeAppManager.setExecutingBeforeReconnect(false); isRetryGetPaywallUrl = false; + initialTextFormattingMenuState(); } if (PlatformInfo.isIOS) { _registerPendingCurrentEmailIdInNotification(); @@ -508,6 +514,8 @@ class MailboxDashBoardController extends ReloadableController setUpDefaultEmailSortOrder(success.emailSortOrderType); } else if (success is GetPaywallUrlSuccess) { loadPaywallUrlSuccess(success.paywallUrlPattern); + } else if (success is GetTextFormattingMenuStateSuccess) { + updateTextFormattingMenuState(success.isDisplayed); } else { super.handleSuccessViewState(success); } @@ -555,6 +563,8 @@ class MailboxDashBoardController extends ReloadableController backToHomeScreen(); } else if (failure is GetPaywallUrlFailure) { loadPaywallUrlFailure(); + } else if (failure is GetTextFormattingMenuStateFailure) { + updateTextFormattingMenuState(false); } else { super.handleFailureViewState(failure); } diff --git a/lib/features/mailbox_dashboard/presentation/extensions/update_text_formatting_menu_state_extension.dart b/lib/features/mailbox_dashboard/presentation/extensions/update_text_formatting_menu_state_extension.dart new file mode 100644 index 0000000000..9b6f481799 --- /dev/null +++ b/lib/features/mailbox_dashboard/presentation/extensions/update_text_formatting_menu_state_extension.dart @@ -0,0 +1,17 @@ +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_text_formatting_menu_state_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; +import 'package:tmail_ui_user/main/routes/route_navigation.dart'; + +extension UpdateTextFormattingMenuStateExtension on MailboxDashBoardController { + void initialTextFormattingMenuState() { + getTextFormattingMenuStateInteractor = + getBinding(); + if (getTextFormattingMenuStateInteractor == null) return; + + consumeState(getTextFormattingMenuStateInteractor!.execute()); + } + + void updateTextFormattingMenuState(bool isDisplayed) { + isTextFormattingMenuOpened.value = isDisplayed; + } +} diff --git a/lib/features/manage_account/data/datasource_impl/manage_account_datasource_impl.dart b/lib/features/manage_account/data/datasource_impl/manage_account_datasource_impl.dart index b540baf563..27151f7c96 100644 --- a/lib/features/manage_account/data/datasource_impl/manage_account_datasource_impl.dart +++ b/lib/features/manage_account/data/datasource_impl/manage_account_datasource_impl.dart @@ -6,6 +6,7 @@ import 'package:tmail_ui_user/features/manage_account/data/local/preferences_set import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/preferences_config.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/preferences_setting.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/spam_report_config.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/text_formatting_menu_config.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/thread_detail_config.dart'; import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart'; @@ -39,6 +40,10 @@ class ManageAccountDataSourceImpl extends ManageAccountDataSource { await _preferencesSettingManager.updateSpamReport( isEnabled: preferencesConfig.isEnabled, ); + } else if (preferencesConfig is TextFormattingMenuConfig) { + await _preferencesSettingManager.updateTextFormattingMenu( + isDisplayed: preferencesConfig.isDisplayed, + ); } else { await _preferencesSettingManager.savePreferences( preferencesConfig, diff --git a/lib/features/manage_account/data/local/preferences_setting_manager.dart b/lib/features/manage_account/data/local/preferences_setting_manager.dart index ecb702968e..fb6dc12302 100644 --- a/lib/features/manage_account/data/local/preferences_setting_manager.dart +++ b/lib/features/manage_account/data/local/preferences_setting_manager.dart @@ -6,6 +6,7 @@ import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/e import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/preferences_config.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/preferences_setting.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/spam_report_config.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/text_formatting_menu_config.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/thread_detail_config.dart'; class PreferencesSettingManager { @@ -14,6 +15,8 @@ class PreferencesSettingManager { '${_preferencesSettingKey}_THREAD'; static const String _preferencesSettingSpamReportKey = '${_preferencesSettingKey}_SPAM_REPORT'; + static const String _preferencesSettingTextFormattingMenuKey = + '${_preferencesSettingKey}_TEXT_FORMATTING_MENU'; const PreferencesSettingManager(this._sharedPreferences); @@ -36,6 +39,8 @@ class PreferencesSettingManager { return ThreadDetailConfig.fromJson(jsonDecoded); case _preferencesSettingSpamReportKey: return SpamReportConfig.fromJson(jsonDecoded); + case _preferencesSettingTextFormattingMenuKey: + return TextFormattingMenuConfig.fromJson(jsonDecoded); default: return DefaultPreferencesConfig.fromJson(jsonDecoded); } @@ -61,6 +66,11 @@ class PreferencesSettingManager { _preferencesSettingSpamReportKey, jsonEncode(config.toJson()), ); + } else if (config is TextFormattingMenuConfig) { + await _sharedPreferences.setString( + _preferencesSettingTextFormattingMenuKey, + jsonEncode(config.toJson()), + ); } else { await _sharedPreferences.setString( _preferencesSettingKey, @@ -110,4 +120,22 @@ class PreferencesSettingManager { ? ThreadDetailConfig.initial() : ThreadDetailConfig.fromJson(jsonDecode(jsonString)); } + + Future getTextFormattingMenuConfig() async { + await _sharedPreferences.reload(); + + final jsonString = _sharedPreferences.getString( + _preferencesSettingTextFormattingMenuKey, + ); + + return jsonString == null + ? TextFormattingMenuConfig.initial() + : TextFormattingMenuConfig.fromJson(jsonDecode(jsonString)); + } + + Future updateTextFormattingMenu({required bool isDisplayed}) async { + final currentConfig = await getTextFormattingMenuConfig(); + final updatedConfig = currentConfig.copyWith(isDisplayed: isDisplayed); + await savePreferences(updatedConfig); + } } diff --git a/lib/features/manage_account/domain/model/preferences/preferences_setting.dart b/lib/features/manage_account/domain/model/preferences/preferences_setting.dart index a97b59d261..f80c63397c 100644 --- a/lib/features/manage_account/domain/model/preferences/preferences_setting.dart +++ b/lib/features/manage_account/domain/model/preferences/preferences_setting.dart @@ -2,6 +2,7 @@ import 'package:collection/collection.dart'; import 'package:equatable/equatable.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/preferences_config.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/spam_report_config.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/text_formatting_menu_config.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/thread_detail_config.dart'; class PreferencesSetting with EquatableMixin { @@ -13,6 +14,7 @@ class PreferencesSetting with EquatableMixin { return PreferencesSetting([ ThreadDetailConfig.initial(), SpamReportConfig.initial(), + TextFormattingMenuConfig.initial(), ]); } @@ -36,6 +38,16 @@ class PreferencesSetting with EquatableMixin { } } + TextFormattingMenuConfig get textFormattingMenuConfig { + final formatConfig = configs + .firstWhereOrNull((config) => config is TextFormattingMenuConfig); + if (formatConfig != null) { + return formatConfig as TextFormattingMenuConfig; + } else { + return TextFormattingMenuConfig.initial(); + } + } + @override List get props => [configs]; } diff --git a/lib/features/manage_account/domain/model/preferences/spam_report_config.dart b/lib/features/manage_account/domain/model/preferences/spam_report_config.dart index bb18293972..f4fe12c5f1 100644 --- a/lib/features/manage_account/domain/model/preferences/spam_report_config.dart +++ b/lib/features/manage_account/domain/model/preferences/spam_report_config.dart @@ -14,12 +14,7 @@ class SpamReportConfig extends PreferencesConfig { this.lastTimeDismissedMilliseconds = 0, }); - factory SpamReportConfig.initial() { - return SpamReportConfig( - isEnabled: true, - lastTimeDismissedMilliseconds: 0, - ); - } + factory SpamReportConfig.initial() => SpamReportConfig(); factory SpamReportConfig.fromJson(Map json) => _$SpamReportConfigFromJson(json); diff --git a/lib/features/manage_account/domain/model/preferences/text_formatting_menu_config.dart b/lib/features/manage_account/domain/model/preferences/text_formatting_menu_config.dart new file mode 100644 index 0000000000..88f557715a --- /dev/null +++ b/lib/features/manage_account/domain/model/preferences/text_formatting_menu_config.dart @@ -0,0 +1,30 @@ +import 'package:json_annotation/json_annotation.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/preferences_config.dart'; + +part 'text_formatting_menu_config.g.dart'; + +@JsonSerializable() +class TextFormattingMenuConfig extends PreferencesConfig { + final bool isDisplayed; + + TextFormattingMenuConfig({this.isDisplayed = false}); + + factory TextFormattingMenuConfig.initial() => TextFormattingMenuConfig(); + + factory TextFormattingMenuConfig.fromJson(Map json) => + _$TextFormattingMenuConfigFromJson(json); + + @override + Map toJson() => _$TextFormattingMenuConfigToJson(this); + + @override + List get props => [isDisplayed]; +} + +extension TextFormattingMenuConfigExtension on TextFormattingMenuConfig { + TextFormattingMenuConfig copyWith({bool? isDisplayed}) { + return TextFormattingMenuConfig( + isDisplayed: isDisplayed ?? this.isDisplayed, + ); + } +} diff --git a/lib/features/manage_account/domain/model/preferences/thread_detail_config.dart b/lib/features/manage_account/domain/model/preferences/thread_detail_config.dart index ec12f091f6..6c3dddb470 100644 --- a/lib/features/manage_account/domain/model/preferences/thread_detail_config.dart +++ b/lib/features/manage_account/domain/model/preferences/thread_detail_config.dart @@ -9,11 +9,7 @@ class ThreadDetailConfig extends PreferencesConfig { ThreadDetailConfig({this.isEnabled = false}); - factory ThreadDetailConfig.initial() { - return ThreadDetailConfig( - isEnabled: false, - ); - } + factory ThreadDetailConfig.initial() => ThreadDetailConfig(); factory ThreadDetailConfig.fromJson(Map json) => _$ThreadDetailConfigFromJson(json); diff --git a/lib/features/manage_account/presentation/bindings/setting_interactor_bindings.dart b/lib/features/manage_account/presentation/bindings/setting_interactor_bindings.dart new file mode 100644 index 0000000000..5dd3963b9f --- /dev/null +++ b/lib/features/manage_account/presentation/bindings/setting_interactor_bindings.dart @@ -0,0 +1,46 @@ +import 'package:get/get.dart'; +import 'package:tmail_ui_user/features/base/interactors_bindings.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/local/preferences_setting_manager.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/main/exceptions/cache_exception_thrower.dart'; + +class SettingInteractorBindings extends InteractorsBindings { + @override + void bindingsDataSource() { + Get.lazyPut( + () => Get.find(), + ); + } + + @override + void bindingsDataSourceImpl() { + Get.lazyPut( + () => ManageAccountDataSourceImpl( + Get.find(), + Get.find(), + Get.find(), + ), + ); + } + + @override + void bindingsInteractor() {} + + @override + void bindingsRepository() { + Get.lazyPut( + () => Get.find(), + ); + } + + @override + void bindingsRepositoryImpl() { + Get.lazyPut( + () => ManageAccountRepositoryImpl(Get.find()), + ); + } +} 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 d5a8ff439f..b986990384 100644 --- a/lib/features/manage_account/presentation/manage_account_dashboard_bindings.dart +++ b/lib/features/manage_account/presentation/manage_account_dashboard_bindings.dart @@ -1,55 +1,18 @@ import 'package:get/get.dart'; -import 'package:tmail_ui_user/features/base/base_bindings.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/local/preferences_setting_manager.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/presentation/bindings/setting_interactor_bindings.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/identities/identity_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/menu/settings/settings_bindings.dart'; -import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart'; -class ManageAccountDashBoardBindings extends BaseBindings { +class ManageAccountDashBoardBindings extends Bindings { @override void dependencies() { - super.dependencies(); + SettingInteractorBindings().dependencies(); + Get.put(ManageAccountDashBoardController()); SettingsBindings().dependencies(); ManageAccountMenuBindings().dependencies(); IdentityBindings().dependencies(); } - - @override - void bindingsController() { - Get.put(ManageAccountDashBoardController()); - } - - @override - void bindingsDataSource() { - Get.lazyPut(() => Get.find()); - } - - @override - void bindingsDataSourceImpl() { - Get.lazyPut(() => ManageAccountDataSourceImpl( - Get.find(), - Get.find(), - Get.find())); - } - - @override - void bindingsInteractor() {} - - @override - void bindingsRepository() { - Get.lazyPut(() => Get.find()); - } - - @override - void bindingsRepositoryImpl() { - Get.lazyPut(() => ManageAccountRepositoryImpl(Get.find())); - } } \ No newline at end of file From 049dd832929c1ebe0ea3bc0c024db69b6640c0ad Mon Sep 17 00:00:00 2001 From: dab246 Date: Thu, 2 Oct 2025 16:02:49 +0700 Subject: [PATCH 2/2] TF-4082 Save text formatting menu state to user's preferences when send email or close composer --- .../presentation/composer_controller.dart | 6 +++++ .../save_text_formatting_menu_state.dart | 17 ++++++++++++ ...text_formatting_menu_state_interactor.dart | 26 +++++++++++++++++++ .../bindings/mailbox_dashboard_bindings.dart | 6 +++++ .../mailbox_dashboard_controller.dart | 2 ++ .../open_and_close_composer_extension.dart | 3 +++ ..._text_formatting_menu_state_extension.dart | 14 ++++++++++ 7 files changed, 74 insertions(+) create mode 100644 lib/features/mailbox_dashboard/domain/state/save_text_formatting_menu_state.dart create mode 100644 lib/features/mailbox_dashboard/domain/usecases/save_text_formatting_menu_state_interactor.dart diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart index 8337476682..bd537981c4 100644 --- a/lib/features/composer/presentation/composer_controller.dart +++ b/lib/features/composer/presentation/composer_controller.dart @@ -102,6 +102,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_paywall_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/open_and_close_composer_extension.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/update_text_formatting_menu_state_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/draggable_app_state.dart'; import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_identities_state.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart'; @@ -1479,6 +1480,11 @@ class ComposerController extends BaseController } void _closeComposerAction({dynamic result, bool closeOverlays = false}) { + if (PlatformInfo.isWeb && richTextWebController != null) { + mailboxDashBoardController.updateTextFormattingMenuState( + richTextWebController!.isFormattingOptionsEnabled, + ); + } mailboxDashBoardController.closeComposer( result: result, closeOverlays: closeOverlays, diff --git a/lib/features/mailbox_dashboard/domain/state/save_text_formatting_menu_state.dart b/lib/features/mailbox_dashboard/domain/state/save_text_formatting_menu_state.dart new file mode 100644 index 0000000000..17d8d9eba3 --- /dev/null +++ b/lib/features/mailbox_dashboard/domain/state/save_text_formatting_menu_state.dart @@ -0,0 +1,17 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; + +class SavingTextFormattingMenuState extends LoadingState {} + +class SaveTextFormattingMenuStateSuccess extends UIState { + final bool isDisplayed; + + SaveTextFormattingMenuStateSuccess(this.isDisplayed); + + @override + List get props => [isDisplayed]; +} + +class SaveTextFormattingMenuStateFailure extends FeatureFailure { + SaveTextFormattingMenuStateFailure(dynamic exception) : super(exception: exception); +} diff --git a/lib/features/mailbox_dashboard/domain/usecases/save_text_formatting_menu_state_interactor.dart b/lib/features/mailbox_dashboard/domain/usecases/save_text_formatting_menu_state_interactor.dart new file mode 100644 index 0000000000..6cafbd0a97 --- /dev/null +++ b/lib/features/mailbox_dashboard/domain/usecases/save_text_formatting_menu_state_interactor.dart @@ -0,0 +1,26 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/save_text_formatting_menu_state.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/text_formatting_menu_config.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart'; + +class SaveTextFormattingMenuStateInteractor { + final ManageAccountRepository _manageAccountRepository; + + SaveTextFormattingMenuStateInteractor(this._manageAccountRepository); + + Stream> execute(bool isDisplayed) async* { + try { + yield Right(SavingTextFormattingMenuState()); + final preferencesSetting = await _manageAccountRepository.toggleLocalSettingsState( + TextFormattingMenuConfig(isDisplayed: isDisplayed), + ); + yield Right(SaveTextFormattingMenuStateSuccess( + preferencesSetting.textFormattingMenuConfig.isDisplayed, + )); + } catch (exception) { + yield Left(SaveTextFormattingMenuStateFailure(exception)); + } + } +} 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 dd60f6cda1..67e43054eb 100644 --- a/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart +++ b/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart @@ -91,6 +91,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_composer_cache_by_id_on_web_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_email_drafts_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/save_recent_search_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/save_text_formatting_menu_state_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_email_sort_order_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_last_time_dismissed_spam_reported_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_spam_report_state_interactor.dart'; @@ -388,6 +389,11 @@ class MailboxDashBoardBindings extends BaseBindings { Get.find(), ), ); + Get.lazyPut( + () => SaveTextFormattingMenuStateInteractor( + Get.find(), + ), + ); } @override 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 b3ef99b157..f34eb7855d 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart @@ -109,6 +109,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_tex import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_all_composer_cache_on_web_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_composer_cache_by_id_on_web_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_email_drafts_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/save_text_formatting_menu_state_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_email_sort_order_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/dashboard_action.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/app_grid_dashboard_controller.dart'; @@ -266,6 +267,7 @@ class MailboxDashBoardController extends ReloadableController CreateNewEmailRuleFilterInteractor? createNewEmailRuleFilterInteractor; SaveLanguageInteractor? saveLanguageInteractor; GetTextFormattingMenuStateInteractor? getTextFormattingMenuStateInteractor; + SaveTextFormattingMenuStateInteractor? saveTextFormattingMenuStateInteractor; final scaffoldKey = GlobalKey(); final selectedMailbox = Rxn(); diff --git a/lib/features/mailbox_dashboard/presentation/extensions/open_and_close_composer_extension.dart b/lib/features/mailbox_dashboard/presentation/extensions/open_and_close_composer_extension.dart index 0bf967b5a0..71b657cdfd 100644 --- a/lib/features/mailbox_dashboard/presentation/extensions/open_and_close_composer_extension.dart +++ b/lib/features/mailbox_dashboard/presentation/extensions/open_and_close_composer_extension.dart @@ -12,6 +12,7 @@ import 'package:tmail_ui_user/features/email/presentation/action/email_ui_action import 'package:tmail_ui_user/features/email/presentation/extensions/composer_arguments_extension.dart'; import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/update_text_formatting_menu_state_extension.dart'; import 'package:tmail_ui_user/features/sending_queue/presentation/model/sending_email_arguments.dart'; import 'package:tmail_ui_user/main/routes/app_routes.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart'; @@ -116,6 +117,8 @@ extension OpenAndCloseComposerExtension on MailboxDashBoardController { if (composerId != null) { await removeComposerCacheByIdOnWeb(composerId); } + + saveTextFormattingMenuState(); } void _handleResultAfterCloseComposer(dynamic result) { diff --git a/lib/features/mailbox_dashboard/presentation/extensions/update_text_formatting_menu_state_extension.dart b/lib/features/mailbox_dashboard/presentation/extensions/update_text_formatting_menu_state_extension.dart index 9b6f481799..d164324733 100644 --- a/lib/features/mailbox_dashboard/presentation/extensions/update_text_formatting_menu_state_extension.dart +++ b/lib/features/mailbox_dashboard/presentation/extensions/update_text_formatting_menu_state_extension.dart @@ -1,4 +1,6 @@ +import 'package:core/utils/app_logger.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_text_formatting_menu_state_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/save_text_formatting_menu_state_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart'; @@ -13,5 +15,17 @@ extension UpdateTextFormattingMenuStateExtension on MailboxDashBoardController { void updateTextFormattingMenuState(bool isDisplayed) { isTextFormattingMenuOpened.value = isDisplayed; + log('$runtimeType::updateTextFormattingMenuState(): isDisplayed: $isDisplayed'); + } + + void saveTextFormattingMenuState() { + saveTextFormattingMenuStateInteractor = + getBinding(); + if (saveTextFormattingMenuStateInteractor == null) return; + + final isDisplayed = isTextFormattingMenuOpened.value; + consumeState( + saveTextFormattingMenuStateInteractor!.execute(isDisplayed), + ); } }