TF-3977 Add disable spam banner in preferences setting

This commit is contained in:
dab246
2025-08-29 18:21:10 +07:00
committed by Dat H. Pham
parent 7f4dcf8b38
commit 612fc75f02
41 changed files with 534 additions and 404 deletions
@@ -21,7 +21,6 @@ import 'package:tmail_ui_user/features/login/data/local/token_oidc_cache_manager
import 'package:tmail_ui_user/features/mailbox/data/local/mailbox_cache_manager.dart'; import 'package:tmail_ui_user/features/mailbox/data/local/mailbox_cache_manager.dart';
import 'package:tmail_ui_user/features/mailbox/data/local/state_cache_manager.dart'; import 'package:tmail_ui_user/features/mailbox/data/local/state_cache_manager.dart';
import 'package:tmail_ui_user/features/mailbox/data/model/state_type.dart'; import 'package:tmail_ui_user/features/mailbox/data/model/state_type.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/local/local_spam_report_manager.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_manager.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_manager.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/sending_email_cache_manager.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/sending_email_cache_manager.dart';
@@ -45,7 +44,6 @@ class CachingManager {
final FileUtils _fileUtils; final FileUtils _fileUtils;
final SendingEmailCacheManager _sendingEmailCacheManager; final SendingEmailCacheManager _sendingEmailCacheManager;
final SessionCacheManager _sessionCacheManager; final SessionCacheManager _sessionCacheManager;
final LocalSpamReportManager _localSpamReportManager;
final KeychainSharingManager _keychainSharingManager; final KeychainSharingManager _keychainSharingManager;
final TokenOidcCacheManager _tokenOidcCacheManager; final TokenOidcCacheManager _tokenOidcCacheManager;
final OidcConfigurationCacheManager _oidcConfigurationCacheManager; final OidcConfigurationCacheManager _oidcConfigurationCacheManager;
@@ -67,7 +65,6 @@ class CachingManager {
this._fileUtils, this._fileUtils,
this._sendingEmailCacheManager, this._sendingEmailCacheManager,
this._sessionCacheManager, this._sessionCacheManager,
this._localSpamReportManager,
this._keychainSharingManager, this._keychainSharingManager,
this._tokenOidcCacheManager, this._tokenOidcCacheManager,
this._oidcConfigurationCacheManager, this._oidcConfigurationCacheManager,
@@ -82,7 +79,6 @@ class CachingManager {
_emailCacheManager.clear(), _emailCacheManager.clear(),
_fcmCacheManager.clear(), _fcmCacheManager.clear(),
_accountCacheManager.clear(), _accountCacheManager.clear(),
_localSpamReportManager.clear(),
if (PlatformInfo.isMobile) if (PlatformInfo.isMobile)
...[ ...[
_sessionCacheManager.clear(), _sessionCacheManager.clear(),
@@ -8,11 +8,11 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/spam_repor
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/unread_spam_emails_response.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/unread_spam_emails_response.dart';
abstract class SpamReportDataSource { abstract class SpamReportDataSource {
Future<bool> storeLastTimeDismissedSpamReported(DateTime lastTimeDismissedSpamReported); Future<void> storeLastTimeDismissedSpamReported(DateTime lastTimeDismissedSpamReported);
Future<DateTime> getLastTimeDismissedSpamReported(); Future<DateTime> getLastTimeDismissedSpamReported();
Future<bool> deleteLastTimeDismissedSpamReported(); Future<void> deleteLastTimeDismissedSpamReported();
Future<UnreadSpamEmailsResponse> findNumberOfUnreadSpamEmails( Future<UnreadSpamEmailsResponse> findNumberOfUnreadSpamEmails(
Session session, Session session,
@@ -27,7 +27,5 @@ abstract class SpamReportDataSource {
Future<void> storeSpamReportState(SpamReportState spamReportState); Future<void> storeSpamReportState(SpamReportState spamReportState);
Future<void> deleteSpamReportState();
Future<Mailbox> getSpamMailboxCached(AccountId accountId, UserName userName); Future<Mailbox> getSpamMailboxCached(AccountId accountId, UserName userName);
} }
@@ -22,11 +22,6 @@ class HiveSpamReportDataSourceImpl extends SpamReportDataSource {
throw UnimplementedError(); throw UnimplementedError();
} }
@override
Future<void> deleteSpamReportState() {
throw UnimplementedError();
}
@override @override
Future<UnreadSpamEmailsResponse> findNumberOfUnreadSpamEmails(Session session, AccountId accountId, {MailboxFilterCondition? mailboxFilterCondition, UnsignedInt? limit}) { Future<UnreadSpamEmailsResponse> findNumberOfUnreadSpamEmails(Session session, AccountId accountId, {MailboxFilterCondition? mailboxFilterCondition, UnsignedInt? limit}) {
throw UnimplementedError(); throw UnimplementedError();
@@ -5,35 +5,50 @@ import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox_filter_condition.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox_filter_condition.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource/spam_report_datasource.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource/spam_report_datasource.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/local/local_spam_report_manager.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/spam_report_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/spam_report_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/unread_spam_emails_response.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/unread_spam_emails_response.dart';
import 'package:tmail_ui_user/features/manage_account/data/local/preferences_setting_manager.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/spam_report_config.dart';
import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart'; import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart';
class LocalSpamReportDataSourceImpl extends SpamReportDataSource { class LocalSpamReportDataSourceImpl extends SpamReportDataSource {
final LocalSpamReportManager _localSpamReportManager; final PreferencesSettingManager _preferencesSettingManager;
final ExceptionThrower _exceptionThrower; final ExceptionThrower _exceptionThrower;
LocalSpamReportDataSourceImpl(this._localSpamReportManager, this._exceptionThrower); LocalSpamReportDataSourceImpl(
this._preferencesSettingManager,
this._exceptionThrower,
);
@override @override
Future<DateTime> getLastTimeDismissedSpamReported() async { Future<DateTime> getLastTimeDismissedSpamReported() async {
return Future.sync(() async { return Future.sync(() async {
return await _localSpamReportManager.getLastTimeDismissedSpamReported(); final spamReportConfig =
await _preferencesSettingManager.getSpamReportConfig();
return DateTime.fromMillisecondsSinceEpoch(
spamReportConfig.lastTimeDismissedMilliseconds,
);
}).catchError(_exceptionThrower.throwException); }).catchError(_exceptionThrower.throwException);
} }
@override @override
Future<bool> storeLastTimeDismissedSpamReported(DateTime lastTimeDismissedSpamReported) async { Future<void> storeLastTimeDismissedSpamReported(
DateTime lastTimeDismissedSpamReported,
) async {
return Future.sync(() async { return Future.sync(() async {
return await _localSpamReportManager.storeLastTimeDismissedSpamReported(lastTimeDismissedSpamReported); return await _preferencesSettingManager.updateSpamReport(
lastTimeDismissedMilliseconds:
lastTimeDismissedSpamReported.millisecondsSinceEpoch,
);
}).catchError(_exceptionThrower.throwException); }).catchError(_exceptionThrower.throwException);
} }
@override @override
Future<bool> deleteLastTimeDismissedSpamReported() { Future<void> deleteLastTimeDismissedSpamReported() {
return Future.sync(() async { return Future.sync(() async {
return await _localSpamReportManager.deleteLastTimeDismissedSpamReported(); return await _preferencesSettingManager.updateSpamReport(
lastTimeDismissedMilliseconds: 0,
);
}).catchError(_exceptionThrower.throwException); }).catchError(_exceptionThrower.throwException);
} }
@@ -49,24 +64,21 @@ class LocalSpamReportDataSourceImpl extends SpamReportDataSource {
throw UnimplementedError(); throw UnimplementedError();
} }
@override
Future<void> deleteSpamReportState() {
return Future.sync(() async {
return await _localSpamReportManager.deleteLastTimeDismissedSpamReported();
}).catchError(_exceptionThrower.throwException);
}
@override @override
Future<SpamReportState> getSpamReportState() { Future<SpamReportState> getSpamReportState() {
return Future.sync(() async { return Future.sync(() async {
return await _localSpamReportManager.getSpamReportState(); final spamReportConfig =
await _preferencesSettingManager.getSpamReportConfig();
return spamReportConfig.spamReportState;
}).catchError(_exceptionThrower.throwException); }).catchError(_exceptionThrower.throwException);
} }
@override @override
Future<void> storeSpamReportState(SpamReportState spamReportState) { Future<void> storeSpamReportState(SpamReportState spamReportState) {
return Future.sync(() async { return Future.sync(() async {
return await _localSpamReportManager.storeSpamReportState(spamReportState); return await _preferencesSettingManager.updateSpamReport(
isEnabled: spamReportState == SpamReportState.enabled,
);
}).catchError(_exceptionThrower.throwException); }).catchError(_exceptionThrower.throwException);
} }
@@ -1,48 +0,0 @@
import 'package:core/utils/app_logger.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/spam_report_state.dart';
class LocalSpamReportManager {
static const String _keyLastTimeDismissedSpamReported = 'KEY_LAST_TIME_DISMISSED_SPAM_REPORTED';
static const String _keySpamReportState = 'KEY_SPAM_REPORT_STATE';
final SharedPreferences _sharedPreferences;
LocalSpamReportManager(this._sharedPreferences);
Future<DateTime> getLastTimeDismissedSpamReported() async {
final timeStamp = _sharedPreferences.getInt(_keyLastTimeDismissedSpamReported) ?? 0;
log('LocalSpamReportManager::getLastTimeDismissedSpamReported:timeStamp: $timeStamp');
final lastTimeDismissedSpamReported = DateTime.fromMillisecondsSinceEpoch(timeStamp);
return lastTimeDismissedSpamReported;
}
Future<bool> storeLastTimeDismissedSpamReported(DateTime lastTimeDismissedSpamReported) async {
final timeStamp = lastTimeDismissedSpamReported.millisecondsSinceEpoch;
log('LocalSpamReportManager::storeLastTimeDismissedSpamReported:timeStamp: $timeStamp');
return await _sharedPreferences.setInt(_keyLastTimeDismissedSpamReported, timeStamp);
}
Future<bool> deleteLastTimeDismissedSpamReported() async {
return await _sharedPreferences.remove(_keyLastTimeDismissedSpamReported);
}
Future<bool> deleteSpamReportState() async {
return await _sharedPreferences.remove(_keySpamReportState);
}
Future<SpamReportState> getSpamReportState() async {
final spamReportState = _sharedPreferences.getString(_keySpamReportState) ?? '';
return spamReportState == SpamReportState.disabled.keyValue ? SpamReportState.disabled : SpamReportState.enabled;
}
Future<bool> storeSpamReportState(SpamReportState spamReportState) async {
final spamReportState0 = spamReportState.keyValue;
return await _sharedPreferences.setString(_keySpamReportState, spamReportState0);
}
Future<void> clear() async {
await deleteLastTimeDismissedSpamReported();
await deleteSpamReportState();
}
}
@@ -36,11 +36,6 @@ class SpamReportRepositoryImpl extends SpamReportRepository {
return mapDataSource[DataSourceType.local]!.storeSpamReportState(spamReportState); return mapDataSource[DataSourceType.local]!.storeSpamReportState(spamReportState);
} }
@override
Future<void> deleteSpamReportState() {
return mapDataSource[DataSourceType.local]!.deleteSpamReportState();
}
@override @override
Future<Mailbox> getSpamMailboxCached(AccountId accountId, UserName userName) { Future<Mailbox> getSpamMailboxCached(AccountId accountId, UserName userName) {
return mapDataSource[DataSourceType.hiveCache]!.getSpamMailboxCached(accountId, userName); return mapDataSource[DataSourceType.hiveCache]!.getSpamMailboxCached(accountId, userName);
@@ -14,7 +14,5 @@ abstract class SpamReportRepository {
Future<void> storeSpamReportState(SpamReportState spamReportState); Future<void> storeSpamReportState(SpamReportState spamReportState);
Future<void> deleteSpamReportState();
Future<Mailbox> getSpamMailboxCached(AccountId accountId, UserName userName); Future<Mailbox> getSpamMailboxCached(AccountId accountId, UserName userName);
} }
@@ -1,21 +0,0 @@
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/repository/spam_report_repository.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/delete_spam_report_state.dart';
class DeleteSpamReportStateInteractor {
final SpamReportRepository _spamReportRepository;
DeleteSpamReportStateInteractor(this._spamReportRepository);
Stream<Either<Failure, Success>> execute() async* {
try {
yield Right<Failure, Success>(DeleteSpamReportStateLoading());
await _spamReportRepository.deleteSpamReportState();
yield Right<Failure, Success>(DeleteSpamReportStateSuccess());
} catch (e) {
yield Left<Failure, Success>(DeleteSpamReportStateFailure(e));
}
}
}
@@ -69,7 +69,6 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource_impl/lo
import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource_impl/search_datasource_impl.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource_impl/search_datasource_impl.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource_impl/session_storage_composer_datasoure_impl.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource_impl/session_storage_composer_datasoure_impl.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/local/local_sort_order_manager.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/data/local/local_sort_order_manager.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/local/local_spam_report_manager.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/network/linagora_ecosystem_api.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/data/network/linagora_ecosystem_api.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/repository/app_grid_repository_impl.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/data/repository/app_grid_repository_impl.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/repository/composer_cache_repository_impl.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/data/repository/composer_cache_repository_impl.dart';
@@ -100,6 +99,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/search_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/search_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/spam_report_controller.dart'; 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/identity_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/domain/usecases/get_all_identities_interactor.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/identity_interactors_bindings.dart';
@@ -278,7 +278,7 @@ class MailboxDashBoardBindings extends BaseBindings {
Get.find<HtmlTransform>(), Get.find<HtmlTransform>(),
Get.find<CacheExceptionThrower>())); Get.find<CacheExceptionThrower>()));
Get.lazyPut(() => LocalSpamReportDataSourceImpl( Get.lazyPut(() => LocalSpamReportDataSourceImpl(
Get.find<LocalSpamReportManager>(), Get.find<PreferencesSettingManager>(),
Get.find<CacheExceptionThrower>(), Get.find<CacheExceptionThrower>(),
)); ));
Get.lazyPut(() => HiveSpamReportDataSourceImpl( Get.lazyPut(() => HiveSpamReportDataSourceImpl(
@@ -2004,6 +2004,7 @@ class MailboxDashBoardController extends ReloadableController
_getAllIdentities(); _getAllIdentities();
notifyThreadDetailSettingUpdated(); notifyThreadDetailSettingUpdated();
getServerSetting(); getServerSetting();
spamReportController.getSpamReportStateAction();
} }
Future<List<PresentationEmail>> quickSearchEmails(String query) async { Future<List<PresentationEmail>> quickSearchEmails(String query) async {
@@ -2074,6 +2075,7 @@ class MailboxDashBoardController extends ReloadableController
_getAllIdentities(); _getAllIdentities();
notifyThreadDetailSettingUpdated(); notifyThreadDetailSettingUpdated();
getServerSetting(); getServerSetting();
spamReportController.getSpamReportStateAction();
} }
void _handleUpdateVacationSuccess(UpdateVacationSuccess success) { void _handleUpdateVacationSuccess(UpdateVacationSuccess success) {
@@ -19,6 +19,8 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_spa
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_last_time_dismissed_spam_reported_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_spam_report_state_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_spam_report_state_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/spam_report_loader_status.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
class SpamReportController extends BaseController { class SpamReportController extends BaseController {
final StoreSpamReportInteractor _storeSpamReportInteractor; final StoreSpamReportInteractor _storeSpamReportInteractor;
@@ -29,6 +31,9 @@ class SpamReportController extends BaseController {
final presentationSpamMailbox = Rxn<PresentationMailbox>(); final presentationSpamMailbox = Rxn<PresentationMailbox>();
final spamReportState = Rx<SpamReportState>(SpamReportState.enabled); final spamReportState = Rx<SpamReportState>(SpamReportState.enabled);
AppLifecycleListener? _appLifecycleListener;
SpamReportLoaderStatus _spamReportLoaderStatus = SpamReportLoaderStatus.idle;
SpamReportController( SpamReportController(
this._storeSpamReportInteractor, this._storeSpamReportInteractor,
this._storeSpamReportStateInteractor, this._storeSpamReportStateInteractor,
@@ -36,28 +41,60 @@ class SpamReportController extends BaseController {
this._getSpamMailboxCachedInteractor this._getSpamMailboxCachedInteractor
); );
@override
void onInit() {
super.onInit();
_appLifecycleListener ??= AppLifecycleListener(
onResume: () {
if (_spamReportLoaderStatus == SpamReportLoaderStatus.loading) {
return;
}
getSpamReportStateAction();
},
);
}
@override @override
void handleSuccessViewState(Success success) { void handleSuccessViewState(Success success) {
super.handleSuccessViewState(success);
if (success is StoreLastTimeDismissedSpamReportSuccess) { if (success is StoreLastTimeDismissedSpamReportSuccess) {
presentationSpamMailbox.value = null; presentationSpamMailbox.value = null;
} else if (success is GetSpamReportStateLoading) {
_spamReportLoaderStatus = SpamReportLoaderStatus.loading;
} else if (success is GetSpamReportStateSuccess) { } else if (success is GetSpamReportStateSuccess) {
spamReportState.value = success.spamReportState; _loadSpamReportConfigSuccess(success.spamReportState);
} else if (success is StoreSpamReportStateSuccess) { } else if (success is StoreSpamReportStateSuccess) {
spamReportState.value = success.spamReportState; spamReportState.value = success.spamReportState;
getBinding<MailboxDashBoardController>()?.refreshSpamReportBanner();
} else if (success is GetSpamMailboxCachedSuccess) { } else if (success is GetSpamMailboxCachedSuccess) {
presentationSpamMailbox.value = success.spamMailbox.toPresentationMailbox(); presentationSpamMailbox.value = success.spamMailbox.toPresentationMailbox();
} else {
super.handleSuccessViewState(success);
} }
} }
@override @override
void handleFailureViewState(Failure failure) { void handleFailureViewState(Failure failure) {
super.handleFailureViewState(failure);
if (failure is GetSpamMailboxCachedFailure) { if (failure is GetSpamMailboxCachedFailure) {
presentationSpamMailbox.value = null; presentationSpamMailbox.value = null;
} else if (failure is GetSpamReportStateFailure) {
_spamReportLoaderStatus = SpamReportLoaderStatus.completed;
} else {
super.handleFailureViewState(failure);
} }
} }
@override
void handleErrorViewState(Object error, StackTrace stackTrace) {
super.handleErrorViewState(error, stackTrace);
_spamReportLoaderStatus = SpamReportLoaderStatus.completed;
}
void _loadSpamReportConfigSuccess(SpamReportState newState) {
spamReportState.value = newState;
_spamReportLoaderStatus = SpamReportLoaderStatus.completed;
getBinding<MailboxDashBoardController>()?.refreshSpamReportBanner();
}
void dismissSpamReportAction(BuildContext context) { void dismissSpamReportAction(BuildContext context) {
if (Get.isRegistered<MailboxDashBoardController>()) { if (Get.isRegistered<MailboxDashBoardController>()) {
final mailboxDashBoardController = Get.find<MailboxDashBoardController>(); final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
@@ -109,4 +146,10 @@ class SpamReportController extends BaseController {
void setSpamPresentationMailbox(PresentationMailbox? spamMailbox) { void setSpamPresentationMailbox(PresentationMailbox? spamMailbox) {
presentationSpamMailbox.value = spamMailbox; presentationSpamMailbox.value = spamMailbox;
} }
@override
void onClose() {
_appLifecycleListener?.dispose();
super.onClose();
}
} }
@@ -0,0 +1 @@
enum SpamReportLoaderStatus { idle, loading, completed }
@@ -1,15 +1,11 @@
import 'dart:ui'; import 'dart:ui';
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_options.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/preferences_root.dart';
abstract class ManageAccountDataSource { abstract class ManageAccountDataSource {
Future<void> persistLanguage(Locale localeCurrent); Future<void> persistLanguage(Locale localeCurrent);
Future<void> updateLocalSettings( Future<void> updateLocalSettings(PreferencesRoot preferencesRoot);
Map<SupportedLocalSetting, LocalSettingOptions?> localSettings,
);
Future<Map<SupportedLocalSetting, LocalSettingOptions?>> getLocalSettings( Future<PreferencesRoot> getLocalSettings();
List<SupportedLocalSetting> supportedLocalSettings,
);
} }
@@ -2,19 +2,19 @@ import 'dart:ui';
import 'package:tmail_ui_user/features/manage_account/data/datasource/manage_account_datasource.dart'; import 'package:tmail_ui_user/features/manage_account/data/datasource/manage_account_datasource.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/language_cache_manager.dart';
import 'package:tmail_ui_user/features/manage_account/data/local/local_setting_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/presentation/model/local_setting_options.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/preferences_root.dart';
import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart'; import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart';
class ManageAccountDataSourceImpl extends ManageAccountDataSource { class ManageAccountDataSourceImpl extends ManageAccountDataSource {
final LanguageCacheManager _languageCacheManager; final LanguageCacheManager _languageCacheManager;
final LocalSettingCacheManager _localSettingCacheManager; final PreferencesSettingManager _preferencesSettingManager;
final ExceptionThrower _exceptionThrower; final ExceptionThrower _exceptionThrower;
ManageAccountDataSourceImpl( ManageAccountDataSourceImpl(
this._languageCacheManager, this._languageCacheManager,
this._localSettingCacheManager, this._preferencesSettingManager,
this._exceptionThrower this._exceptionThrower
); );
@@ -26,20 +26,16 @@ class ManageAccountDataSourceImpl extends ManageAccountDataSource {
} }
@override @override
Future<void> updateLocalSettings( Future<void> updateLocalSettings(PreferencesRoot preferencesRoot) {
Map<SupportedLocalSetting, LocalSettingOptions?> localSettings,
) {
return Future.sync(() async { return Future.sync(() async {
return await _localSettingCacheManager.update(localSettings); return await _preferencesSettingManager.savePreferences(preferencesRoot);
}).catchError(_exceptionThrower.throwException); }).catchError(_exceptionThrower.throwException);
} }
@override @override
Future<Map<SupportedLocalSetting, LocalSettingOptions?>> getLocalSettings( Future<PreferencesRoot> getLocalSettings() {
List<SupportedLocalSetting> supportedLocalSettings,
) {
return Future.sync(() async { return Future.sync(() async {
return await _localSettingCacheManager.get(supportedLocalSettings); return await _preferencesSettingManager.loadPreferences();
}).catchError(_exceptionThrower.throwException); }).catchError(_exceptionThrower.throwException);
} }
} }
@@ -1,41 +0,0 @@
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_options.dart';
class LocalSettingCacheManager {
const LocalSettingCacheManager(this._sharedPreferences);
final SharedPreferences _sharedPreferences;
Future<void> update(
Map<SupportedLocalSetting, LocalSettingOptions?> localSettings,
) async {
await Future.wait(localSettings.entries.map((entry) async {
if (entry.value == null) {
await _sharedPreferences.remove(entry.key.name);
return;
}
await _sharedPreferences.setString(
entry.key.name,
jsonEncode(entry.value!.toJson()),
);
}));
}
Future<Map<SupportedLocalSetting, LocalSettingOptions?>> get(
List<SupportedLocalSetting> supportedLocalSettings,
) async {
await _sharedPreferences.reload();
return Map.fromEntries(supportedLocalSettings.map((supportedLocalSetting) {
final data = _sharedPreferences.getString(supportedLocalSetting.name);
return MapEntry(
supportedLocalSetting,
data == null ? null : LocalSettingOptions.fromJson(jsonDecode(data)),
);
}));
}
}
@@ -0,0 +1,55 @@
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/preferences_root.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/spam_report_config.dart';
class PreferencesSettingManager {
static const String _preferencesSettingKey = 'PREFERENCES_SETTING';
const PreferencesSettingManager(this._sharedPreferences);
final SharedPreferences _sharedPreferences;
Future<PreferencesRoot> loadPreferences() async {
await _sharedPreferences.reload();
final jsonString = _sharedPreferences.getString(_preferencesSettingKey);
if (jsonString != null) {
return PreferencesRoot.fromJson(jsonDecode(jsonString));
}
return PreferencesRoot.initial();
}
Future<void> savePreferences(PreferencesRoot root) async {
await _sharedPreferences.setString(
_preferencesSettingKey,
jsonEncode(root.toJson()),
);
}
Future<void> updateThread(bool enabled) async {
final current = await loadPreferences();
final updated = current.updateThreadDetail(enabled);
await savePreferences(updated);
}
Future<void> updateSpamReport({
bool? isEnabled,
int? lastTimeDismissedMilliseconds,
}) async {
final current = await loadPreferences();
final updated = current.updateSpamReport(
isEnabled: isEnabled,
lastTimeDismissedMilliseconds: lastTimeDismissedMilliseconds,
);
await savePreferences(updated);
}
Future<SpamReportConfig> getSpamReportConfig() async {
final preferences = await loadPreferences();
return preferences.setting.spamReport;
}
}
@@ -2,7 +2,7 @@ import 'dart:ui';
import 'package:tmail_ui_user/features/manage_account/data/datasource/manage_account_datasource.dart'; import 'package:tmail_ui_user/features/manage_account/data/datasource/manage_account_datasource.dart';
import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart'; import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_options.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/preferences_root.dart';
class ManageAccountRepositoryImpl extends ManageAccountRepository { class ManageAccountRepositoryImpl extends ManageAccountRepository {
@@ -16,16 +16,12 @@ class ManageAccountRepositoryImpl extends ManageAccountRepository {
} }
@override @override
Future<void> updateLocalSettings( Future<void> updateLocalSettings(PreferencesRoot preferencesRoot) {
Map<SupportedLocalSetting, LocalSettingOptions?> localSettings, return dataSource.updateLocalSettings(preferencesRoot);
) {
return dataSource.updateLocalSettings(localSettings);
} }
@override @override
Future<Map<SupportedLocalSetting, LocalSettingOptions?>> getLocalSettings( Future<PreferencesRoot> getLocalSettings() {
List<SupportedLocalSetting> supportedLocalSettings, return dataSource.getLocalSettings();
) {
return dataSource.getLocalSettings(supportedLocalSettings);
} }
} }
@@ -1,15 +1,11 @@
import 'dart:ui'; import 'dart:ui';
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_options.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/preferences_root.dart';
abstract class ManageAccountRepository { abstract class ManageAccountRepository {
Future<void> persistLanguage(Locale localeCurrent); Future<void> persistLanguage(Locale localeCurrent);
Future<void> updateLocalSettings( Future<void> updateLocalSettings(PreferencesRoot preferencesRoot);
Map<SupportedLocalSetting, LocalSettingOptions?> localSettings,
);
Future<Map<SupportedLocalSetting, LocalSettingOptions?>> getLocalSettings( Future<PreferencesRoot> getLocalSettings();
List<SupportedLocalSetting> supportedLocalSettings, }
);
}
@@ -1,16 +1,16 @@
import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart'; import 'package:core/presentation/state/success.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_options.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/preferences_root.dart';
class GettingLocalSettingsState extends LoadingState {} class GettingLocalSettingsState extends LoadingState {}
class GetLocalSettingsSuccess extends UIState { class GetLocalSettingsSuccess extends UIState {
GetLocalSettingsSuccess(this.localSettings); GetLocalSettingsSuccess(this.preferencesRoot);
final Map<SupportedLocalSetting, LocalSettingOptions?> localSettings; final PreferencesRoot preferencesRoot;
@override @override
List<Object?> get props => [localSettings]; List<Object?> get props => [preferencesRoot];
} }
class GetLocalSettingsFailure extends FeatureFailure { class GetLocalSettingsFailure extends FeatureFailure {
@@ -1,16 +1,16 @@
import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart'; import 'package:core/presentation/state/success.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_options.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/preferences_root.dart';
class UpdatingLocalSettingsState extends LoadingState {} class UpdatingLocalSettingsState extends LoadingState {}
class UpdateLocalSettingsSuccess extends UIState { class UpdateLocalSettingsSuccess extends UIState {
final Map<SupportedLocalSetting, LocalSettingOptions?> localSettings; final PreferencesRoot preferencesRoot;
UpdateLocalSettingsSuccess(this.localSettings); UpdateLocalSettingsSuccess(this.preferencesRoot);
@override @override
List<Object?> get props => [localSettings]; List<Object?> get props => [preferencesRoot];
} }
class UpdateLocalSettingsFailure extends FeatureFailure { class UpdateLocalSettingsFailure extends FeatureFailure {
@@ -4,19 +4,16 @@ import 'package:core/utils/app_logger.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_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/state/get_local_settings_state.dart'; import 'package:tmail_ui_user/features/manage_account/domain/state/get_local_settings_state.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_options.dart';
class GetLocalSettingsInteractor { class GetLocalSettingsInteractor {
const GetLocalSettingsInteractor(this._manageAccountRepository); const GetLocalSettingsInteractor(this._manageAccountRepository);
final ManageAccountRepository _manageAccountRepository; final ManageAccountRepository _manageAccountRepository;
Stream<Either<Failure, Success>> execute( Stream<Either<Failure, Success>> execute() async* {
List<SupportedLocalSetting> supportedLocalSettings,
) async* {
try { try {
yield Right(GettingLocalSettingsState()); yield Right(GettingLocalSettingsState());
final result = await _manageAccountRepository.getLocalSettings(supportedLocalSettings); final result = await _manageAccountRepository.getLocalSettings();
yield Right(GetLocalSettingsSuccess(result)); yield Right(GetLocalSettingsSuccess(result));
} catch (e) { } catch (e) {
logError('$runtimeType::execute(): exception: $e'); logError('$runtimeType::execute(): exception: $e');
@@ -4,7 +4,7 @@ import 'package:core/utils/app_logger.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_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/state/update_local_settings_state.dart'; import 'package:tmail_ui_user/features/manage_account/domain/state/update_local_settings_state.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_options.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/preferences_root.dart';
class UpdateLocalSettingsInteractor { class UpdateLocalSettingsInteractor {
const UpdateLocalSettingsInteractor(this._manageAccountRepository); const UpdateLocalSettingsInteractor(this._manageAccountRepository);
@@ -12,12 +12,12 @@ class UpdateLocalSettingsInteractor {
final ManageAccountRepository _manageAccountRepository; final ManageAccountRepository _manageAccountRepository;
Stream<Either<Failure, Success>> execute( Stream<Either<Failure, Success>> execute(
Map<SupportedLocalSetting, LocalSettingOptions?> localSettings, PreferencesRoot preferencesRoot,
) async* { ) async* {
try { try {
yield Right(UpdatingLocalSettingsState()); yield Right(UpdatingLocalSettingsState());
await _manageAccountRepository.updateLocalSettings(localSettings); await _manageAccountRepository.updateLocalSettings(preferencesRoot);
yield Right(UpdateLocalSettingsSuccess(localSettings)); yield Right(UpdateLocalSettingsSuccess(preferencesRoot));
} catch (e) { } catch (e) {
logError('$runtimeType::execute(): exception: $e'); logError('$runtimeType::execute(): exception: $e');
yield Left(UpdateLocalSettingsFailure(exception: e)); yield Left(UpdateLocalSettingsFailure(exception: e));
@@ -1,6 +0,0 @@
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_detail/thread_detail_local_setting_detail.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_options.dart';
extension LocalSettingsMapExtension on Map<SupportedLocalSetting, LocalSettingOptions?> {
bool? get threadDetailEnabled => (this[SupportedLocalSetting.threadDetail]?.setting as ThreadDetailLocalSettingDetail?)?.value;
}
@@ -3,7 +3,7 @@ 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/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/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/language_cache_manager.dart';
import 'package:tmail_ui_user/features/manage_account/data/local/local_setting_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/data/repository/manage_account_repository_impl.dart';
import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart'; import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/identities/identity_bindings.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/identities/identity_bindings.dart';
@@ -36,7 +36,7 @@ class ManageAccountDashBoardBindings extends BaseBindings {
void bindingsDataSourceImpl() { void bindingsDataSourceImpl() {
Get.lazyPut(() => ManageAccountDataSourceImpl( Get.lazyPut(() => ManageAccountDataSourceImpl(
Get.find<LanguageCacheManager>(), Get.find<LanguageCacheManager>(),
Get.find<LocalSettingCacheManager>(), Get.find<PreferencesSettingManager>(),
Get.find<CacheExceptionThrower>())); Get.find<CacheExceptionThrower>()));
} }
@@ -1,32 +0,0 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_detail/thread_detail_local_setting_detail.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_options.dart';
abstract class LocalSettingDetail<T> extends Equatable {
const LocalSettingDetail(this.value);
final T value;
Map<String, dynamic> toJson();
}
class LocalSettingDetailConverter extends JsonConverter<LocalSettingDetail, Map<String, dynamic>> {
const LocalSettingDetailConverter();
@override
LocalSettingDetail fromJson(Map<String, dynamic> json) {
final type = json['type'] as String?;
if (type == SupportedLocalSetting.threadDetail.name) {
return ThreadDetailLocalSettingDetail.fromJson(json);
}
throw UnimplementedError();
}
@override
Map<String, dynamic> toJson(LocalSettingDetail object) {
return object.toJson();
}
}
@@ -1,24 +0,0 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_detail/local_setting_detail.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_options.dart';
part 'thread_detail_local_setting_detail.g.dart';
@JsonSerializable()
class ThreadDetailLocalSettingDetail extends LocalSettingDetail<bool> {
const ThreadDetailLocalSettingDetail(
super.value, [
this.type = SupportedLocalSetting.threadDetail,
]);
@JsonKey(defaultValue: SupportedLocalSetting.threadDetail)
final SupportedLocalSetting type;
factory ThreadDetailLocalSettingDetail.fromJson(Map<String, dynamic> json) =>
_$ThreadDetailLocalSettingDetailFromJson(json);
@override
Map<String, dynamic> toJson() => _$ThreadDetailLocalSettingDetailToJson(this);
@override
List<Object?> get props => [value, type];
}
@@ -1,26 +0,0 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_detail/local_setting_detail.dart';
part 'local_setting_options.g.dart';
enum SupportedLocalSetting {
threadDetail,
}
@JsonSerializable(converters: [LocalSettingDetailConverter()])
class LocalSettingOptions with EquatableMixin {
const LocalSettingOptions({
required this.setting,
});
final LocalSettingDetail? setting;
factory LocalSettingOptions.fromJson(Map<String, dynamic> json) =>
_$LocalSettingOptionsFromJson(json);
Map<String, dynamic> toJson() => _$LocalSettingOptionsToJson(this);
@override
List<Object?> get props => [setting];
}
@@ -0,0 +1,50 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/preferences_setting.dart';
part 'preferences_root.g.dart';
@JsonSerializable(explicitToJson: true)
class PreferencesRoot with EquatableMixin {
final PreferencesSetting setting;
PreferencesRoot({required this.setting});
factory PreferencesRoot.initial() {
return PreferencesRoot(
setting: PreferencesSetting.initial(),
);
}
factory PreferencesRoot.fromJson(Map<String, dynamic> json) =>
_$PreferencesRootFromJson(json);
Map<String, dynamic> toJson() => _$PreferencesRootToJson(this);
@override
List<Object?> get props => [setting];
}
extension PreferencesRootExtension on PreferencesRoot {
PreferencesRoot copyWith({PreferencesSetting? setting}) {
return PreferencesRoot(
setting: setting ?? this.setting,
);
}
PreferencesRoot updateThreadDetail(bool enabled) {
return copyWith(setting: setting.updateThreadDetail(enabled));
}
PreferencesRoot updateSpamReport({
bool? isEnabled,
int? lastTimeDismissedMilliseconds,
}) {
return copyWith(
setting: setting.updateSpamReport(
isEnabled: isEnabled,
lastTimeDismissedMilliseconds: lastTimeDismissedMilliseconds,
),
);
}
}
@@ -0,0 +1,61 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/spam_report_config.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/thread_detail_config.dart';
part 'preferences_setting.g.dart';
@JsonSerializable(explicitToJson: true)
class PreferencesSetting with EquatableMixin {
final ThreadDetailConfig threadDetail;
final SpamReportConfig spamReport;
PreferencesSetting({
required this.threadDetail,
required this.spamReport,
});
factory PreferencesSetting.initial() {
return PreferencesSetting(
threadDetail: ThreadDetailConfig.initial(),
spamReport: SpamReportConfig.initial(),
);
}
factory PreferencesSetting.fromJson(Map<String, dynamic> json) =>
_$PreferencesSettingFromJson(json);
Map<String, dynamic> toJson() => _$PreferencesSettingToJson(this);
@override
List<Object?> get props => [threadDetail, spamReport];
}
extension PreferencesSettingExtension on PreferencesSetting {
PreferencesSetting copyWith({
ThreadDetailConfig? threadDetail,
SpamReportConfig? spamReport,
}) {
return PreferencesSetting(
threadDetail: threadDetail ?? this.threadDetail,
spamReport: spamReport ?? this.spamReport,
);
}
PreferencesSetting updateThreadDetail(bool enabled) {
return copyWith(threadDetail: threadDetail.copyWith(isEnabled: enabled));
}
PreferencesSetting updateSpamReport({
bool? isEnabled,
int? lastTimeDismissedMilliseconds,
}) {
return copyWith(
spamReport: spamReport.copyWith(
isEnabled: isEnabled ?? spamReport.isEnabled,
lastTimeDismissedMilliseconds: lastTimeDismissedMilliseconds ??
spamReport.lastTimeDismissedMilliseconds,
),
);
}
}
@@ -0,0 +1,47 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/spam_report_state.dart';
part 'spam_report_config.g.dart';
@JsonSerializable()
class SpamReportConfig with EquatableMixin {
final bool isEnabled;
final int lastTimeDismissedMilliseconds;
SpamReportConfig({
this.isEnabled = true,
this.lastTimeDismissedMilliseconds = 0,
});
factory SpamReportConfig.initial() {
return SpamReportConfig(
isEnabled: true,
lastTimeDismissedMilliseconds: 0,
);
}
factory SpamReportConfig.fromJson(Map<String, dynamic> json) =>
_$SpamReportConfigFromJson(json);
Map<String, dynamic> toJson() => _$SpamReportConfigToJson(this);
@override
List<Object> get props => [isEnabled, lastTimeDismissedMilliseconds];
}
extension SpamReportConfigExtension on SpamReportConfig {
SpamReportConfig copyWith({
bool? isEnabled,
int? lastTimeDismissedMilliseconds,
}) {
return SpamReportConfig(
isEnabled: isEnabled ?? this.isEnabled,
lastTimeDismissedMilliseconds:
lastTimeDismissedMilliseconds ?? this.lastTimeDismissedMilliseconds,
);
}
SpamReportState get spamReportState =>
isEnabled ? SpamReportState.enabled : SpamReportState.disabled;
}
@@ -0,0 +1,33 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
part 'thread_detail_config.g.dart';
@JsonSerializable()
class ThreadDetailConfig with EquatableMixin {
final bool isEnabled;
ThreadDetailConfig({this.isEnabled = false});
factory ThreadDetailConfig.initial() {
return ThreadDetailConfig(
isEnabled: false,
);
}
factory ThreadDetailConfig.fromJson(Map<String, dynamic> json) =>
_$ThreadDetailConfigFromJson(json);
Map<String, dynamic> toJson() => _$ThreadDetailConfigToJson(this);
@override
List<Object> get props => [isEnabled];
}
extension ThreadDetailConfigExtension on ThreadDetailConfig {
ThreadDetailConfig copyWith({bool? isEnabled}) {
return ThreadDetailConfig(
isEnabled: isEnabled ?? this.isEnabled,
);
}
}
@@ -1,66 +1,71 @@
import 'package:server_settings/server_settings/tmail_server_settings.dart'; import 'package:server_settings/server_settings/tmail_server_settings.dart';
import 'package:server_settings/server_settings/tmail_server_settings_extension.dart'; import 'package:server_settings/server_settings/tmail_server_settings_extension.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/local_settings_map_extension.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/preferences_setting.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_options.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
enum SettingOptionType { enum PreferencesOptionType {
readReceipt, readReceipt(isLocal: false),
senderPriority, senderPriority(isLocal: false),
thread; thread(isLocal: true),
spamReport(isLocal: true);
final bool isLocal;
const PreferencesOptionType({required this.isLocal});
String getTitle(AppLocalizations appLocalizations) { String getTitle(AppLocalizations appLocalizations) {
switch(this) { switch(this) {
case SettingOptionType.readReceipt: case PreferencesOptionType.readReceipt:
return appLocalizations.emailReadReceipts; return appLocalizations.emailReadReceipts;
case SettingOptionType.senderPriority: case PreferencesOptionType.senderPriority:
return appLocalizations.senderSetImportantFlag; return appLocalizations.senderSetImportantFlag;
case SettingOptionType.thread: case PreferencesOptionType.thread:
return appLocalizations.thread; return appLocalizations.thread;
case PreferencesOptionType.spamReport:
return appLocalizations.spamReports;
} }
} }
String getExplanation(AppLocalizations appLocalizations) { String getExplanation(AppLocalizations appLocalizations) {
switch(this) { switch(this) {
case SettingOptionType.readReceipt: case PreferencesOptionType.readReceipt:
return appLocalizations.emailReadReceiptsSettingExplanation; return appLocalizations.emailReadReceiptsSettingExplanation;
case SettingOptionType.senderPriority: case PreferencesOptionType.senderPriority:
return appLocalizations.senderImportantSettingExplanation; return appLocalizations.senderImportantSettingExplanation;
case SettingOptionType.thread: case PreferencesOptionType.thread:
return appLocalizations.threadSettingExplanation; return appLocalizations.threadSettingExplanation;
case PreferencesOptionType.spamReport:
return appLocalizations.spamReportsSettingExplanation;
} }
} }
String getToggleDescription(AppLocalizations appLocalizations) { String getToggleDescription(AppLocalizations appLocalizations) {
switch(this) { switch(this) {
case SettingOptionType.readReceipt: case PreferencesOptionType.readReceipt:
return appLocalizations.emailReadReceiptsToggleDescription; return appLocalizations.emailReadReceiptsToggleDescription;
case SettingOptionType.senderPriority: case PreferencesOptionType.senderPriority:
return appLocalizations.senderImportantSettingToggleDescription; return appLocalizations.senderImportantSettingToggleDescription;
case SettingOptionType.thread: case PreferencesOptionType.thread:
return appLocalizations.threadToggleDescription; return appLocalizations.threadToggleDescription;
case PreferencesOptionType.spamReport:
return appLocalizations.spamReportToggleDescription;
} }
} }
bool isEnabled( bool isEnabled(
TMailServerSettingOptions? settingOption, TMailServerSettingOptions? settingOption,
Map<SupportedLocalSetting, LocalSettingOptions?> localSettings, PreferencesSetting preferencesSetting,
) { ) {
switch(this) { switch(this) {
case SettingOptionType.readReceipt: case PreferencesOptionType.readReceipt:
return settingOption?.isAlwaysReadReceipts ?? false; return settingOption?.isAlwaysReadReceipts ?? false;
case SettingOptionType.senderPriority: case PreferencesOptionType.senderPriority:
return settingOption?.isDisplaySenderPriority ?? false; return settingOption?.isDisplaySenderPriority ?? false;
case SettingOptionType.thread: case PreferencesOptionType.thread:
return localSettings.threadDetailEnabled ?? false; return preferencesSetting.threadDetail.isEnabled;
case PreferencesOptionType.spamReport:
return preferencesSetting.spamReport.isEnabled;
} }
} }
bool get isLocal {
return switch (this) {
thread => true,
_ => false,
};
}
} }
@@ -3,7 +3,7 @@ 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/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/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/language_cache_manager.dart';
import 'package:tmail_ui_user/features/manage_account/data/local/local_setting_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/data/repository/manage_account_repository_impl.dart';
import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart'; import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/save_language_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/save_language_interactor.dart';
@@ -43,7 +43,7 @@ class PreferencesInteractorsBindings extends InteractorsBindings {
), tag: composerId); ), tag: composerId);
Get.lazyPut(() => ManageAccountDataSourceImpl( Get.lazyPut(() => ManageAccountDataSourceImpl(
Get.find<LanguageCacheManager>(), Get.find<LanguageCacheManager>(),
Get.find<LocalSettingCacheManager>(), Get.find<PreferencesSettingManager>(),
Get.find<CacheExceptionThrower>(), Get.find<CacheExceptionThrower>(),
), tag: composerId); ), tag: composerId);
} }
@@ -10,9 +10,8 @@ import 'package:tmail_ui_user/features/manage_account/domain/state/update_local_
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_local_settings_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_local_settings_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/update_local_settings_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/update_local_settings_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.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/local_setting_detail/thread_detail_local_setting_detail.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/preferences_root.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_options.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences_option_type.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/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/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/get_server_setting_interactor.dart';
@@ -34,7 +33,7 @@ class PreferencesController extends BaseController {
final UpdateLocalSettingsInteractor _updateLocalSettingsInteractor; final UpdateLocalSettingsInteractor _updateLocalSettingsInteractor;
final settingOption = Rxn<TMailServerSettingOptions>(); final settingOption = Rxn<TMailServerSettingOptions>();
final localSettings = Rxn(<SupportedLocalSetting, LocalSettingOptions?>{}); final localSettings = Rxn<PreferencesRoot>();
bool get isLoading => viewState.value.fold( bool get isLoading => viewState.value.fold(
(failure) => false, (failure) => false,
@@ -55,13 +54,9 @@ class PreferencesController extends BaseController {
} else if (success is UpdateServerSettingSuccess) { } else if (success is UpdateServerSettingSuccess) {
_updateSettingOptionValue(newSettingOption: success.settingOption); _updateSettingOptionValue(newSettingOption: success.settingOption);
} else if (success is GetLocalSettingsSuccess) { } else if (success is GetLocalSettingsSuccess) {
_updateLocalSettingOptionValue( _updateLocalSettingOptionValue(success.preferencesRoot);
newLocalSettings: success.localSettings,
);
} else if (success is UpdateLocalSettingsSuccess) { } else if (success is UpdateLocalSettingsSuccess) {
_updateLocalSettingOptionValue( _updateLocalSettingOptionValue(success.preferencesRoot);
newLocalSettings: success.localSettings,
);
} else { } else {
super.handleSuccessViewState(success); super.handleSuccessViewState(success);
} }
@@ -90,49 +85,68 @@ class PreferencesController extends BaseController {
settingOption.value = newSettingOption; settingOption.value = newSettingOption;
} }
void _updateLocalSettingOptionValue({ void _updateLocalSettingOptionValue(PreferencesRoot preferencesRoot) {
required Map<SupportedLocalSetting, LocalSettingOptions?> newLocalSettings localSettings.value = preferencesRoot;
}) {
localSettings.value = newLocalSettings;
} }
void _getSettingOption() { void _getSettingOption() {
consumeState(_getLocalSettingInteractor.execute(SupportedLocalSetting.values)); consumeState(_getLocalSettingInteractor.execute());
final accountId = _manageAccountDashBoardController.accountId.value; final accountId = _manageAccountDashBoardController.accountId.value;
if (accountId != null) { if (accountId != null) {
consumeState(_getServerSettingInteractor.execute(accountId)); consumeState(_getServerSettingInteractor.execute(accountId));
} else { } else {
consumeState(Stream.value(Left(GetServerSettingFailure(NotFoundAccountIdException())))); consumeState(Stream.value(Left(GetServerSettingFailure(NotFoundAccountIdException()))));
consumeState(Stream.value(Left(GetLocalSettingsFailure(
exception: NotFoundAccountIdException(),
))));
} }
} }
void updateStateSettingOption(SettingOptionType optionType, bool isEnabled) { void updateStateSettingOption(
PreferencesOptionType optionType,
bool isEnabled,
) {
if (optionType.isLocal) { if (optionType.isLocal) {
Map<SupportedLocalSetting, LocalSettingOptions?> newLocalSettings = {}; _updateLocalPreferencesSetting(optionType, isEnabled);
switch(optionType) { } else {
case SettingOptionType.thread: _updateServerPreferencesSetting(optionType, isEnabled);
var currentLocalSettings = Map<SupportedLocalSetting, LocalSettingOptions?>.from(localSettings.value ?? {}); }
currentLocalSettings[SupportedLocalSetting.threadDetail] = LocalSettingOptions(setting: ThreadDetailLocalSettingDetail(!isEnabled)); }
newLocalSettings = currentLocalSettings;
break; void _updateLocalPreferencesSetting(
default: PreferencesOptionType optionType,
break; bool isEnabled,
} ) {
consumeState(_updateLocalSettingsInteractor.execute(newLocalSettings)); PreferencesRoot? preferencesRoot;
return; switch(optionType) {
case PreferencesOptionType.thread:
preferencesRoot = localSettings.value?.updateThreadDetail(
!isEnabled,
);
break;
case PreferencesOptionType.spamReport:
preferencesRoot = localSettings.value?.updateSpamReport(
isEnabled: !isEnabled,
);
break;
default:
break;
} }
if (preferencesRoot != null) {
consumeState(_updateLocalSettingsInteractor.execute(preferencesRoot));
}
}
void _updateServerPreferencesSetting(
PreferencesOptionType optionType,
bool isEnabled,
) {
TMailServerSettingOptions? newSettingOption; TMailServerSettingOptions? newSettingOption;
switch(optionType) { switch(optionType) {
case SettingOptionType.readReceipt: case PreferencesOptionType.readReceipt:
newSettingOption = settingOption.value?.copyWith( newSettingOption = settingOption.value?.copyWith(
alwaysReadReceipts: !isEnabled, alwaysReadReceipts: !isEnabled,
); );
break; break;
case SettingOptionType.senderPriority: case PreferencesOptionType.senderPriority:
newSettingOption = settingOption.value?.copyWith( newSettingOption = settingOption.value?.copyWith(
displaySenderPriority: !isEnabled, displaySenderPriority: !isEnabled,
); );
@@ -143,12 +157,18 @@ class PreferencesController extends BaseController {
final accountId = _manageAccountDashBoardController.accountId.value; final accountId = _manageAccountDashBoardController.accountId.value;
if (accountId != null && newSettingOption != null) { if (accountId != null && newSettingOption != null) {
consumeState(_updateServerSettingInteractor.execute( consumeState(
accountId, _updateServerSettingInteractor.execute(
newSettingOption, accountId,
)); newSettingOption,
),
);
} else { } else {
consumeState(Stream.value(Left(UpdateServerSettingFailure(NotFoundAccountIdException())))); consumeState(
Stream.value(
Left(UpdateServerSettingFailure(NotFoundAccountIdException())),
),
);
} }
} }
} }
@@ -4,9 +4,9 @@ import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/base/setting_detail_view_builder.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/base/setting_detail_view_builder.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/setting_option_type.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences_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/preferences_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/preferences/widgets/setting_option_item.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/preferences/widgets/preferences_option_item.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/widgets/setting_header_widget.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/widgets/setting_header_widget.dart';
class PreferencesView extends GetWidget<PreferencesController> with AppLoaderMixin { class PreferencesView extends GetWidget<PreferencesController> with AppLoaderMixin {
@@ -57,31 +57,33 @@ class PreferencesView extends GetWidget<PreferencesController> with AppLoaderMix
), ),
Obx(() { Obx(() {
final settingOption = controller.settingOption.value; final settingOption = controller.settingOption.value;
final localSettingOption = controller.localSettings; final localSettingOption = controller.localSettings.value;
if (settingOption == null && (localSettingOption.value?.isEmpty ?? true)) { if (settingOption == null && localSettingOption == null) {
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
final availableSettingOptions = [ final availableSettingOptions = [
if (settingOption != null) ...SettingOptionType.values.where( if (settingOption != null)
(optionType) => !optionType.isLocal, ...PreferencesOptionType.values.where(
), (optionType) => !optionType.isLocal,
...SettingOptionType.values.where( ),
(optionType) => optionType.isLocal, if (localSettingOption != null)
), ...PreferencesOptionType.values.where(
(optionType) => optionType.isLocal,
),
]; ];
return Expanded( return Expanded(
child: ListView.separated( child: ListView.separated(
itemCount: availableSettingOptions.length, itemCount: availableSettingOptions.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return SettingOptionItem( return PreferencesOptionItem(
imagePaths: controller.imagePaths, imagePaths: controller.imagePaths,
settingOption: settingOption, settingOption: settingOption,
localSettings: localSettingOption.value ?? {}, preferencesSetting: localSettingOption!.setting,
optionType: availableSettingOptions[index], optionType: availableSettingOptions[index],
onTapSettingOptionAction: controller.updateStateSettingOption, onTapPreferencesOptionAction: controller.updateStateSettingOption,
); );
}, },
separatorBuilder: (_, __) => const SizedBox(height: 49), separatorBuilder: (_, __) => const SizedBox(height: 49),
@@ -6,25 +6,27 @@ import 'package:server_settings/server_settings/tmail_server_settings.dart';
import 'package:tmail_ui_user/features/base/widget/default_switch_icon_widget.dart'; import 'package:tmail_ui_user/features/base/widget/default_switch_icon_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_options.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_options.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/setting_option_type.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/setting_option_type.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/preferences_setting.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences_option_type.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
typedef OnTapSettingOptionAction = Function(SettingOptionType optionType, bool isEnabled); typedef OnTapPreferencesOptionAction = Function(PreferencesOptionType optionType, bool isEnabled);
class SettingOptionItem extends StatelessWidget { class PreferencesOptionItem extends StatelessWidget {
final ImagePaths imagePaths; final ImagePaths imagePaths;
final TMailServerSettingOptions? settingOption; final TMailServerSettingOptions? settingOption;
final Map<SupportedLocalSetting, LocalSettingOptions?> localSettings; final PreferencesSetting preferencesSetting;
final SettingOptionType optionType; final PreferencesOptionType optionType;
final OnTapSettingOptionAction onTapSettingOptionAction; final OnTapPreferencesOptionAction onTapPreferencesOptionAction;
const SettingOptionItem({ const PreferencesOptionItem({
super.key, super.key,
required this.imagePaths, required this.imagePaths,
required this.settingOption, required this.settingOption,
required this.localSettings, required this.preferencesSetting,
required this.optionType, required this.optionType,
required this.onTapSettingOptionAction, required this.onTapPreferencesOptionAction,
}); });
@override @override
@@ -60,18 +62,18 @@ class SettingOptionItem extends StatelessWidget {
children: [ children: [
InkWell( InkWell(
key: ValueKey(optionType.getTitle(appLocalizations)), key: ValueKey(optionType.getTitle(appLocalizations)),
onTap: () => onTapSettingOptionAction( onTap: () => onTapPreferencesOptionAction(
optionType, optionType,
optionType.isEnabled(settingOption, localSettings), optionType.isEnabled(settingOption, preferencesSetting),
), ),
child: DefaultSwitchIconWidget( child: DefaultSwitchIconWidget(
key: ValueKey( key: ValueKey(
optionType.isEnabled(settingOption, localSettings) optionType.isEnabled(settingOption, preferencesSetting)
? 'setting_option_switch_on' ? 'setting_option_switch_on'
: 'setting_option_switch_off', : 'setting_option_switch_off',
), ),
imagePaths: imagePaths, imagePaths: imagePaths,
isEnabled: optionType.isEnabled(settingOption, localSettings), isEnabled: optionType.isEnabled(settingOption, preferencesSetting),
), ),
), ),
const SizedBox(width: 12), const SizedBox(width: 12),
@@ -2,19 +2,17 @@ import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/properties/properties.dart'; import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart'; import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:tmail_ui_user/features/manage_account/data/local/local_setting_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/presentation/model/local_setting_detail/thread_detail_local_setting_detail.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_options.dart';
import 'package:tmail_ui_user/features/thread_detail/data/data_source/thread_detail_data_source.dart'; import 'package:tmail_ui_user/features/thread_detail/data/data_source/thread_detail_data_source.dart';
import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart'; import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart';
class ThreadDetailLocalDataSourceImpl implements ThreadDetailDataSource { class ThreadDetailLocalDataSourceImpl implements ThreadDetailDataSource {
const ThreadDetailLocalDataSourceImpl( const ThreadDetailLocalDataSourceImpl(
this._localSettingCacheManager, this._preferencesSettingManager,
this._exceptionThrower, this._exceptionThrower,
); );
final LocalSettingCacheManager _localSettingCacheManager; final PreferencesSettingManager _preferencesSettingManager;
final ExceptionThrower _exceptionThrower; final ExceptionThrower _exceptionThrower;
@override @override
@@ -30,10 +28,8 @@ class ThreadDetailLocalDataSourceImpl implements ThreadDetailDataSource {
@override @override
Future<bool> getThreadDetailStatus() { Future<bool> getThreadDetailStatus() {
return Future.sync(() async { return Future.sync(() async {
final localSetting = await _localSettingCacheManager.get([ final preferencesRoot = await _preferencesSettingManager.loadPreferences();
SupportedLocalSetting.threadDetail, return preferencesRoot.setting.spamReport.isEnabled;
]);
return (localSetting[SupportedLocalSetting.threadDetail]?.setting as ThreadDetailLocalSettingDetail?)?.value ?? false;
}).catchError(_exceptionThrower.throwException); }).catchError(_exceptionThrower.throwException);
} }
} }
@@ -7,7 +7,7 @@ import 'package:tmail_ui_user/features/email/domain/usecases/get_email_content_i
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_email_read_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_email_read_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/print_email_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/print_email_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/data/local/local_setting_cache_manager.dart'; import 'package:tmail_ui_user/features/manage_account/data/local/preferences_setting_manager.dart';
import 'package:tmail_ui_user/features/thread/domain/usecases/mark_as_multiple_email_read_interactor.dart'; import 'package:tmail_ui_user/features/thread/domain/usecases/mark_as_multiple_email_read_interactor.dart';
import 'package:tmail_ui_user/features/thread/domain/usecases/mark_as_star_multiple_email_interactor.dart'; import 'package:tmail_ui_user/features/thread/domain/usecases/mark_as_star_multiple_email_interactor.dart';
import 'package:tmail_ui_user/features/thread_detail/data/data_source/thread_detail_data_source.dart'; import 'package:tmail_ui_user/features/thread_detail/data/data_source/thread_detail_data_source.dart';
@@ -57,7 +57,7 @@ class ThreadDetailBindings extends BaseBindings {
Get.find<RemoteExceptionThrower>(), Get.find<RemoteExceptionThrower>(),
)); ));
Get.lazyPut(() => ThreadDetailLocalDataSourceImpl( Get.lazyPut(() => ThreadDetailLocalDataSourceImpl(
Get.find<LocalSettingCacheManager>(), Get.find<PreferencesSettingManager>(),
Get.find<CacheExceptionThrower>(), Get.find<CacheExceptionThrower>(),
)); ));
} }
+18
View File
@@ -4851,5 +4851,23 @@
"placeholders": { "placeholders": {
"keyword": {} "keyword": {}
} }
},
"spamReports": "Spam reports",
"@spamReports": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"spamReportsSettingExplanation": "Reminds you that you need to moderate your spam emails recurringly",
"@spamReportsSettingExplanation": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"spamReportToggleDescription": "Enable spam report",
"@spamReportToggleDescription": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
} }
} }
+2 -5
View File
@@ -34,9 +34,8 @@ import 'package:tmail_ui_user/features/login/data/local/token_oidc_cache_manager
import 'package:tmail_ui_user/features/mailbox/data/local/mailbox_cache_manager.dart'; import 'package:tmail_ui_user/features/mailbox/data/local/mailbox_cache_manager.dart';
import 'package:tmail_ui_user/features/mailbox/data/local/state_cache_manager.dart'; import 'package:tmail_ui_user/features/mailbox/data/local/state_cache_manager.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/local/local_sort_order_manager.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/data/local/local_sort_order_manager.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/local/local_spam_report_manager.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/language_cache_manager.dart';
import 'package:tmail_ui_user/features/manage_account/data/local/local_setting_cache_manager.dart'; import 'package:tmail_ui_user/features/manage_account/data/local/preferences_setting_manager.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_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/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_manager.dart';
@@ -77,7 +76,7 @@ class LocalBindings extends Bindings {
Get.put(OidcConfigurationCacheClient()); Get.put(OidcConfigurationCacheClient());
Get.put(OidcConfigurationCacheManager(Get.find<SharedPreferences>(), Get.find<OidcConfigurationCacheClient>())); Get.put(OidcConfigurationCacheManager(Get.find<SharedPreferences>(), Get.find<OidcConfigurationCacheClient>()));
Get.put(LanguageCacheManager(Get.find<SharedPreferences>())); Get.put(LanguageCacheManager(Get.find<SharedPreferences>()));
Get.put(LocalSettingCacheManager(Get.find<SharedPreferences>())); Get.put(PreferencesSettingManager(Get.find<SharedPreferences>()));
Get.put(RecentLoginUrlCacheClient()); Get.put(RecentLoginUrlCacheClient());
Get.put(RecentLoginUrlCacheManager((Get.find<RecentLoginUrlCacheClient>()))); Get.put(RecentLoginUrlCacheManager((Get.find<RecentLoginUrlCacheClient>())));
Get.put(RecentLoginUsernameCacheClient()); Get.put(RecentLoginUsernameCacheClient());
@@ -94,7 +93,6 @@ class LocalBindings extends Bindings {
Get.put(SendingEmailCacheManager(Get.find<SendingEmailHiveCacheClient>())); Get.put(SendingEmailCacheManager(Get.find<SendingEmailHiveCacheClient>()));
Get.put(SessionHiveCacheClient()); Get.put(SessionHiveCacheClient());
Get.put(SessionCacheManager(Get.find<SessionHiveCacheClient>())); Get.put(SessionCacheManager(Get.find<SessionHiveCacheClient>()));
Get.put(LocalSpamReportManager(Get.find<SharedPreferences>()));
Get.put(LocalSortOrderManager(Get.find<SharedPreferences>())); Get.put(LocalSortOrderManager(Get.find<SharedPreferences>()));
Get.put(CachingManager( Get.put(CachingManager(
Get.find<MailboxCacheManager>(), Get.find<MailboxCacheManager>(),
@@ -111,7 +109,6 @@ class LocalBindings extends Bindings {
Get.find<FileUtils>(), Get.find<FileUtils>(),
Get.find<SendingEmailCacheManager>(), Get.find<SendingEmailCacheManager>(),
Get.find<SessionCacheManager>(), Get.find<SessionCacheManager>(),
Get.find<LocalSpamReportManager>(),
Get.find<KeychainSharingManager>(), Get.find<KeychainSharingManager>(),
Get.find<TokenOidcCacheManager>(), Get.find<TokenOidcCacheManager>(),
Get.find<OidcConfigurationCacheManager>(), Get.find<OidcConfigurationCacheManager>(),
@@ -5124,4 +5124,25 @@ class AppLocalizations {
args: [keyword], args: [keyword],
); );
} }
String get spamReports {
return Intl.message(
'Spam reports',
name: 'spamReports',
);
}
String get spamReportsSettingExplanation {
return Intl.message(
'Reminds you that you need to moderate your spam emails recurringly',
name: 'spamReportsSettingExplanation',
);
}
String get spamReportToggleDescription {
return Intl.message(
'Enable spam report',
name: 'spamReportToggleDescription',
);
}
} }