TF-1808: Hanlde store email when opening email

(cherry picked from commit 2c895379f83b34e9bafb7545b21d790d01d444af)
This commit is contained in:
HuyNguyen
2023-05-11 17:27:42 +07:00
committed by Dat Vu
parent 28d75ce384
commit 63f375a29c
22 changed files with 215 additions and 95 deletions
+15 -1
View File
@@ -55,7 +55,7 @@ class FileUtils {
return await file.writeAsString(content, mode: FileMode.append); return await file.writeAsString(content, mode: FileMode.append);
} }
Future<String> getFromFile({ Future<String> getContentFromFile({
required String nameFile, required String nameFile,
String? folderPath, String? folderPath,
String? extensionFile String? extensionFile
@@ -73,6 +73,20 @@ class FileUtils {
return emailContent; return emailContent;
} }
Future<bool> isFileExisted({
required String nameFile,
String? folderPath,
String? extensionFile
}) async {
final internalStorageDirPath = await _getInternalStorageDirPath(
nameFile: nameFile,
folderPath: folderPath,
extensionFile: extensionFile
);
return File(internalStorageDirPath).exists();
}
} }
enum ExtensionType { enum ExtensionType {
+1 -1
View File
@@ -30,7 +30,7 @@ void main() {
/// Create a temporary file that will be deleted after `getFromFile` is done /// Create a temporary file that will be deleted after `getFromFile` is done
final file = await FileUtils().saveToFile(nameFile: fileName, content: fileContent); final file = await FileUtils().saveToFile(nameFile: fileName, content: fileContent);
final htmlString = await FileUtils().getFromFile(nameFile: fileName); final htmlString = await FileUtils().getContentFromFile(nameFile: fileName);
expect(htmlString.isNotEmpty, equals(true)); expect(htmlString.isNotEmpty, equals(true));
@@ -0,0 +1,9 @@
import 'package:tmail_ui_user/features/caching/config/hive_cache_client.dart';
import 'package:tmail_ui_user/features/caching/utils/caching_constants.dart';
import 'package:tmail_ui_user/features/offline_mode/model/detailed_email_hive_cache.dart';
class OpenedEmailHiveCacheClient extends HiveCacheClient<DetailedEmailHiveCache> {
@override
String get tableName => CachingConstants.openedEmailCacheBoxName;
}
@@ -21,6 +21,7 @@ class CachingConstants {
static const String fcmCacheBoxName = 'fcm_cache_box'; static const String fcmCacheBoxName = 'fcm_cache_box';
static const String detailedEmailCacheBoxName = 'detailed_email_cache_box'; static const String detailedEmailCacheBoxName = 'detailed_email_cache_box';
static const String emailContentFolderName = 'email_content'; static const String emailContentFolderName = 'email_content';
static const String openedEmailCacheBoxName = 'opened_email_cache_box';
static const int maxNumberNewEmailsForOffline = 10; static const int maxNumberNewEmailsForOffline = 10;
static const int maxNumberOpenedEmailsForOffline = 30; static const int maxNumberOpenedEmailsForOffline = 30;
@@ -46,6 +46,7 @@ import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_id
import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/identity_interactors_bindings.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/identity_interactors_bindings.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_manager.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_manager.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_worker_queue.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_worker_queue.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_manager.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_worker_queue.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_worker_queue.dart';
import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dart'; import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dart';
import 'package:tmail_ui_user/features/upload/data/datasource/attachment_upload_datasource.dart'; import 'package:tmail_ui_user/features/upload/data/datasource/attachment_upload_datasource.dart';
@@ -97,6 +98,7 @@ class ComposerBindings extends BaseBindings {
Get.lazyPut(() => StateDataSourceImpl(Get.find<StateCacheClient>(), Get.find<CacheExceptionThrower>())); Get.lazyPut(() => StateDataSourceImpl(Get.find<StateCacheClient>(), Get.find<CacheExceptionThrower>()));
Get.lazyPut(() => EmailHiveCacheDataSourceImpl( Get.lazyPut(() => EmailHiveCacheDataSourceImpl(
Get.find<DetailedEmailCacheManager>(), Get.find<DetailedEmailCacheManager>(),
Get.find<OpenedEmailCacheManager>(),
Get.find<DetailedEmailCacheWorkerQueue>(), Get.find<DetailedEmailCacheWorkerQueue>(),
Get.find<OpenedEmailCacheWorkerQueue>(), Get.find<OpenedEmailCacheWorkerQueue>(),
Get.find<EmailCacheManager>(), Get.find<EmailCacheManager>(),
@@ -80,5 +80,5 @@ abstract class EmailDataSource {
Future<void> storeEmail(Session session, AccountId accountId, Email email); Future<void> storeEmail(Session session, AccountId accountId, Email email);
Future<void> storeOpenedEmailToCache(Session session, AccountId accountId, DetailedEmail detailedEmail); Future<void> storeOpenedEmail(Session session, AccountId accountId, DetailedEmail detailedEmail);
} }
@@ -168,7 +168,7 @@ class EmailDataSourceImpl extends EmailDataSource {
} }
@override @override
Future<void> storeOpenedEmailToCache(Session session, AccountId accountId, DetailedEmail detailedEmail) { Future<void> storeOpenedEmail(Session session, AccountId accountId, DetailedEmail detailedEmail) {
throw UnimplementedError(); throw UnimplementedError();
} }
} }
@@ -27,6 +27,7 @@ import 'package:tmail_ui_user/features/email/domain/model/move_to_mailbox_reques
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_manager.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_manager.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_worker_queue.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_worker_queue.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_manager.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_worker_queue.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_worker_queue.dart';
import 'package:tmail_ui_user/features/offline_mode/worker/hive_task.dart'; import 'package:tmail_ui_user/features/offline_mode/worker/hive_task.dart';
import 'package:tmail_ui_user/features/thread/data/extensions/email_extension.dart'; import 'package:tmail_ui_user/features/thread/data/extensions/email_extension.dart';
@@ -36,6 +37,7 @@ import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart';
class EmailHiveCacheDataSourceImpl extends EmailDataSource { class EmailHiveCacheDataSourceImpl extends EmailDataSource {
final DetailedEmailCacheManager _detailedEmailCacheManager; final DetailedEmailCacheManager _detailedEmailCacheManager;
final OpenedEmailCacheManager _openedEmailCacheManager;
final DetailedEmailCacheWorkerQueue _cacheWorkerQueue; final DetailedEmailCacheWorkerQueue _cacheWorkerQueue;
final OpenedEmailCacheWorkerQueue _openedEmailCacheWorkerQueue; final OpenedEmailCacheWorkerQueue _openedEmailCacheWorkerQueue;
final EmailCacheManager _emailCacheManager; final EmailCacheManager _emailCacheManager;
@@ -44,6 +46,7 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
EmailHiveCacheDataSourceImpl( EmailHiveCacheDataSourceImpl(
this._detailedEmailCacheManager, this._detailedEmailCacheManager,
this._openedEmailCacheManager,
this._cacheWorkerQueue, this._cacheWorkerQueue,
this._openedEmailCacheWorkerQueue, this._openedEmailCacheWorkerQueue,
this._emailCacheManager, this._emailCacheManager,
@@ -119,8 +122,7 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
final fileSaved = await _fileUtils.saveToFile( final fileSaved = await _fileUtils.saveToFile(
nameFile: detailedEmail.emailId.asString, nameFile: detailedEmail.emailId.asString,
content: detailedEmail.htmlEmailContent ?? '', content: detailedEmail.htmlEmailContent ?? '',
folderPath: detailedEmail.folderPath, folderPath: detailedEmail.folderPath
extensionFile: ExtensionType.text.value
); );
log('EmailHiveCacheDataSourceImpl::storeDetailedEmailToCache():fileSavedPath: ${fileSaved.path}'); log('EmailHiveCacheDataSourceImpl::storeDetailedEmailToCache():fileSavedPath: ${fileSaved.path}');
final detailedEmailSaved = detailedEmail.fromEmailContentPath(fileSaved.path); final detailedEmailSaved = detailedEmail.fromEmailContentPath(fileSaved.path);
@@ -154,25 +156,34 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
} }
@override @override
Future<void> storeOpenedEmailToCache(Session session, AccountId accountId, DetailedEmail detailedEmail) { Future<void> storeOpenedEmail(Session session, AccountId accountId, DetailedEmail detailedEmail) {
return Future.sync(() async { return Future.sync(() async {
final task = HiveTask( final task = HiveTask(
runnable: () async { runnable: () async {
final detailedEmailExisted = await _openedEmailCacheManager.isOpenedDetailEmailCached(accountId, session.username,detailedEmail);
log('EmailHiveCacheDataSourceImpl::storeOpenedEmail():detailedEmailExisted: $detailedEmailExisted');
if (detailedEmailExisted) {
return Future.value();
}
final fileSaved = await _fileUtils.saveToFile( final fileSaved = await _fileUtils.saveToFile(
nameFile: detailedEmail.emailId.asString, nameFile: detailedEmail.emailId.asString,
content: detailedEmail.htmlEmailContent ?? '', content: detailedEmail.htmlEmailContent ?? '',
folderPath: detailedEmail.folderPath, folderPath: detailedEmail.folderPath
extensionFile: ExtensionType.text.value
); );
log('EmailHiveCacheDataSourceImpl::storeOpenedEmailToCache():fileSavedPath: ${fileSaved.path}');
log('EmailHiveCacheDataSourceImpl::storeOpenedEmail():fileSavedPath: ${fileSaved.path}');
final detailedEmailSaved = detailedEmail.fromEmailContentPath(fileSaved.path); final detailedEmailSaved = detailedEmail.fromEmailContentPath(fileSaved.path);
await _detailedEmailCacheManager.storeOpenedEmail( await _openedEmailCacheManager.storeOpenedEmail(
accountId, accountId,
session.username, session.username,
detailedEmailSaved); detailedEmailSaved);
}); });
return await _openedEmailCacheWorkerQueue.addTask(task); return _openedEmailCacheWorkerQueue.addTask(task);
}).catchError(_exceptionThrower.throwException); }).catchError(_exceptionThrower.throwException);
} }
} }
@@ -200,7 +200,7 @@ class EmailRepositoryImpl extends EmailRepository {
} }
@override @override
Future<void> storeOpenedEmailToCache(Session session, AccountId accountId, DetailedEmail detailedEmail) { Future<void> storeOpenedEmail(Session session, AccountId accountId, DetailedEmail detailedEmail) {
return emailDataSource[DataSourceType.hiveCache]!.storeOpenedEmailToCache(session, accountId, detailedEmail); return emailDataSource[DataSourceType.hiveCache]!.storeOpenedEmail(session, accountId, detailedEmail);
} }
} }
@@ -94,5 +94,5 @@ abstract class EmailRepository {
Future<void> storeEmailToCache(Session session, AccountId accountId, Email email); Future<void> storeEmailToCache(Session session, AccountId accountId, Email email);
Future<void> storeOpenedEmailToCache(Session session, AccountId accountId, DetailedEmail detailedEmail); Future<void> storeOpenedEmail(Session session, AccountId accountId, DetailedEmail detailedEmail);
} }
@@ -1,12 +1,13 @@
import 'package:core/core.dart'; import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
class StoreOpenedEmailToCacheLoading extends UIState {} class StoreOpenedEmailLoading extends UIState {}
class StoreOpenedEmailToCacheSuccess extends UIState {} class StoreOpenedEmailSuccess extends UIState {}
class StoreOpenedEmailToCacheFailure extends FeatureFailure { class StoreOpenedEmailFailure extends FeatureFailure {
StoreOpenedEmailToCacheFailure(dynamic exception) : super(exception: exception); StoreOpenedEmailFailure(dynamic exception) : super(exception: exception);
@override @override
List<Object?> get props => [exception]; List<Object?> get props => [exception];
@@ -18,11 +18,11 @@ class StoreOpenedEmailToCacheInteractor {
DetailedEmail detailedEmail DetailedEmail detailedEmail
) async* { ) async* {
try { try {
yield Right<Failure, Success>(StoreOpenedEmailToCacheLoading()); yield Right<Failure, Success>(StoreOpenedEmailLoading());
await _emailRepository.storeOpenedEmailToCache(session, accountId, detailedEmail); await _emailRepository.storeOpenedEmail(session, accountId, detailedEmail);
yield Right<Failure, Success>(StoreOpenedEmailToCacheSuccess()); yield Right<Failure, Success>(StoreOpenedEmailSuccess());
} catch (e) { } catch (e) {
yield Left<Failure, Success>(StoreOpenedEmailToCacheFailure(e)); yield Left<Failure, Success>(StoreOpenedEmailFailure(e));
} }
} }
} }
@@ -26,6 +26,8 @@ import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart'; import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
import 'package:tmail_ui_user/features/composer/presentation/extensions/email_action_type_extension.dart'; import 'package:tmail_ui_user/features/composer/presentation/extensions/email_action_type_extension.dart';
import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart'; import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart';
import 'package:tmail_ui_user/features/email/domain/model/detailed_email.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/store_opened_email_to_cache_interactor.dart';
import 'package:tmail_ui_user/features/email/presentation/controller/email_supervisor_controller.dart'; import 'package:tmail_ui_user/features/email/presentation/controller/email_supervisor_controller.dart';
import 'package:tmail_ui_user/features/email/presentation/model/email_loaded.dart'; import 'package:tmail_ui_user/features/email/presentation/model/email_loaded.dart';
import 'package:tmail_ui_user/features/email/domain/model/move_action.dart'; import 'package:tmail_ui_user/features/email/domain/model/move_action.dart';
@@ -91,6 +93,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
final MarkAsStarEmailInteractor _markAsStarEmailInteractor; final MarkAsStarEmailInteractor _markAsStarEmailInteractor;
final DownloadAttachmentForWebInteractor _downloadAttachmentForWebInteractor; final DownloadAttachmentForWebInteractor _downloadAttachmentForWebInteractor;
final GetAllIdentitiesInteractor _getAllIdentitiesInteractor; final GetAllIdentitiesInteractor _getAllIdentitiesInteractor;
final StoreOpenedEmailToCacheInteractor _storeOpenedEmailToCacheInteractor;
CreateNewEmailRuleFilterInteractor? _createNewEmailRuleFilterInteractor; CreateNewEmailRuleFilterInteractor? _createNewEmailRuleFilterInteractor;
SendReceiptToSenderInteractor? _sendReceiptToSenderInteractor; SendReceiptToSenderInteractor? _sendReceiptToSenderInteractor;
@@ -125,6 +128,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
this._markAsStarEmailInteractor, this._markAsStarEmailInteractor,
this._downloadAttachmentForWebInteractor, this._downloadAttachmentForWebInteractor,
this._getAllIdentitiesInteractor, this._getAllIdentitiesInteractor,
this._storeOpenedEmailToCacheInteractor
); );
@override @override
@@ -370,6 +374,21 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
initialEmailContents = success.emailContents; initialEmailContents = success.emailContents;
attachments.value = success.attachments; attachments.value = success.attachments;
if (!BuildUtils.isWeb) {
final detailedEmail = DetailedEmail(
emailId: currentEmail!.id!,
attachments: attachments,
headers: currentEmail?.emailHeader,
htmlEmailContent: emailContents.asHtmlString
);
_storeOpenedEmailToCache(
mailboxDashBoardController.sessionCurrent,
mailboxDashBoardController.accountId.value,
detailedEmail
);
}
final isShowMessageReadReceipt = success.emailCurrent final isShowMessageReadReceipt = success.emailCurrent
?.hasReadReceipt(mailboxDashBoardController.mapMailboxById) == true; ?.hasReadReceipt(mailboxDashBoardController.mapMailboxById) == true;
if (isShowMessageReadReceipt) { if (isShowMessageReadReceipt) {
@@ -1193,4 +1212,10 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
return false; return false;
} }
void _storeOpenedEmailToCache(Session? session, AccountId? accountId, DetailedEmail detailedEmail) async {
if (session != null && accountId != null) {
consumeState(_storeOpenedEmailToCacheInteractor.execute(session, accountId, detailedEmail));
}
}
} }
@@ -20,6 +20,7 @@ import 'package:tmail_ui_user/features/email/domain/usecases/get_stored_email_st
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/move_to_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/move_to_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/store_opened_email_to_cache_interactor.dart';
import 'package:tmail_ui_user/features/email/presentation/controller/email_supervisor_controller.dart'; import 'package:tmail_ui_user/features/email/presentation/controller/email_supervisor_controller.dart';
import 'package:tmail_ui_user/features/email/presentation/controller/single_email_controller.dart'; import 'package:tmail_ui_user/features/email/presentation/controller/single_email_controller.dart';
import 'package:tmail_ui_user/features/login/data/datasource/account_datasource.dart'; import 'package:tmail_ui_user/features/login/data/datasource/account_datasource.dart';
@@ -44,6 +45,7 @@ import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_id
import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/identity_interactors_bindings.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/identity_interactors_bindings.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_manager.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_manager.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_worker_queue.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_worker_queue.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_manager.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_worker_queue.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_worker_queue.dart';
import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dart'; import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dart';
import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart'; import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart';
@@ -55,15 +57,16 @@ class EmailBindings extends BaseBindings {
void bindingsController() { void bindingsController() {
Get.put(EmailSupervisorController()); Get.put(EmailSupervisorController());
Get.put(SingleEmailController( Get.put(SingleEmailController(
Get.find<GetEmailContentInteractor>(), Get.find<GetEmailContentInteractor>(),
Get.find<MarkAsEmailReadInteractor>(), Get.find<MarkAsEmailReadInteractor>(),
Get.find<DownloadAttachmentsInteractor>(), Get.find<DownloadAttachmentsInteractor>(),
Get.find<DeviceManager>(), Get.find<DeviceManager>(),
Get.find<ExportAttachmentInteractor>(), Get.find<ExportAttachmentInteractor>(),
Get.find<MoveToMailboxInteractor>(), Get.find<MoveToMailboxInteractor>(),
Get.find<MarkAsStarEmailInteractor>(), Get.find<MarkAsStarEmailInteractor>(),
Get.find<DownloadAttachmentForWebInteractor>(), Get.find<DownloadAttachmentForWebInteractor>(),
Get.find<GetAllIdentitiesInteractor>(), Get.find<GetAllIdentitiesInteractor>(),
Get.find<StoreOpenedEmailToCacheInteractor>()
)); ));
} }
@@ -98,6 +101,7 @@ class EmailBindings extends BaseBindings {
Get.lazyPut(() => StateDataSourceImpl(Get.find<StateCacheClient>(), Get.find<CacheExceptionThrower>())); Get.lazyPut(() => StateDataSourceImpl(Get.find<StateCacheClient>(), Get.find<CacheExceptionThrower>()));
Get.lazyPut(() => EmailHiveCacheDataSourceImpl( Get.lazyPut(() => EmailHiveCacheDataSourceImpl(
Get.find<DetailedEmailCacheManager>(), Get.find<DetailedEmailCacheManager>(),
Get.find<OpenedEmailCacheManager>(),
Get.find<DetailedEmailCacheWorkerQueue>(), Get.find<DetailedEmailCacheWorkerQueue>(),
Get.find<OpenedEmailCacheWorkerQueue>(), Get.find<OpenedEmailCacheWorkerQueue>(),
Get.find<EmailCacheManager>(), Get.find<EmailCacheManager>(),
@@ -134,6 +138,7 @@ class EmailBindings extends BaseBindings {
Get.find<AccountRepository>(), Get.find<AccountRepository>(),
Get.find<AuthenticationOIDCRepository>())); Get.find<AuthenticationOIDCRepository>()));
Get.lazyPut(() => GetStoredEmailStateInteractor(Get.find<EmailRepository>())); Get.lazyPut(() => GetStoredEmailStateInteractor(Get.find<EmailRepository>()));
Get.lazyPut(() => StoreOpenedEmailToCacheInteractor(Get.find<EmailRepository>()));
IdentityInteractorsBindings().dependencies(); IdentityInteractorsBindings().dependencies();
} }
@@ -96,6 +96,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller
import 'package:tmail_ui_user/features/manage_account/domain/usecases/log_out_oidc_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/log_out_oidc_interactor.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_manager.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_manager.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_worker_queue.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_worker_queue.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_manager.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_worker_queue.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_worker_queue.dart';
import 'package:tmail_ui_user/features/quotas/presentation/quotas_controller_bindings.dart'; import 'package:tmail_ui_user/features/quotas/presentation/quotas_controller_bindings.dart';
import 'package:tmail_ui_user/features/search/email/domain/usecases/refresh_changes_search_email_interactor.dart'; import 'package:tmail_ui_user/features/search/email/domain/usecases/refresh_changes_search_email_interactor.dart';
@@ -234,6 +235,7 @@ class MailboxDashBoardBindings extends BaseBindings {
Get.find<CacheExceptionThrower>())); Get.find<CacheExceptionThrower>()));
Get.lazyPut(() => EmailHiveCacheDataSourceImpl( Get.lazyPut(() => EmailHiveCacheDataSourceImpl(
Get.find<DetailedEmailCacheManager>(), Get.find<DetailedEmailCacheManager>(),
Get.find<OpenedEmailCacheManager>(),
Get.find<DetailedEmailCacheWorkerQueue>(), Get.find<DetailedEmailCacheWorkerQueue>(),
Get.find<OpenedEmailCacheWorkerQueue>(), Get.find<OpenedEmailCacheWorkerQueue>(),
Get.find<EmailCacheManager>(), Get.find<EmailCacheManager>(),
@@ -1,24 +1,19 @@
import 'package:core/utils/app_logger.dart'; import 'package:core/utils/app_logger.dart';
import 'package:core/utils/file_utils.dart';
import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart'; import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:model/extensions/account_id_extensions.dart'; import 'package:model/extensions/account_id_extensions.dart';
import 'package:model/extensions/email_id_extensions.dart';
import 'package:tmail_ui_user/features/caching/clients/detailed_email_hive_cache_client.dart'; import 'package:tmail_ui_user/features/caching/clients/detailed_email_hive_cache_client.dart';
import 'package:tmail_ui_user/features/caching/utils/cache_utils.dart'; import 'package:tmail_ui_user/features/caching/utils/cache_utils.dart';
import 'package:tmail_ui_user/features/caching/utils/caching_constants.dart'; import 'package:tmail_ui_user/features/caching/utils/caching_constants.dart';
import 'package:tmail_ui_user/features/email/domain/extensions/detailed_email_extension.dart';
import 'package:tmail_ui_user/features/email/domain/model/detailed_email.dart';
import 'package:tmail_ui_user/features/offline_mode/extensions/list_detailed_email_hive_cache_extension.dart'; import 'package:tmail_ui_user/features/offline_mode/extensions/list_detailed_email_hive_cache_extension.dart';
import 'package:tmail_ui_user/features/offline_mode/model/detailed_email_hive_cache.dart'; import 'package:tmail_ui_user/features/offline_mode/model/detailed_email_hive_cache.dart';
class DetailedEmailCacheManager { class DetailedEmailCacheManager {
final DetailedEmailHiveCacheClient _cacheClient; final DetailedEmailHiveCacheClient _cacheClient;
final FileUtils _fileUtils;
DetailedEmailCacheManager(this._cacheClient, this._fileUtils); DetailedEmailCacheManager(this._cacheClient);
Future<DetailedEmailHiveCache> handleStoreDetailedEmail( Future<DetailedEmailHiveCache> handleStoreDetailedEmail(
AccountId accountId, AccountId accountId,
@@ -63,56 +58,4 @@ class DetailedEmailCacheManager {
log('DetailedEmailCacheManager::getAllDetailedEmails():SIZE: ${detailedEmailCacheList.length}'); log('DetailedEmailCacheManager::getAllDetailedEmails():SIZE: ${detailedEmailCacheList.length}');
return detailedEmailCacheList; return detailedEmailCacheList;
} }
Future<void> storeOpenedEmail(
AccountId accountId,
UserName userName,
DetailedEmail detailedEmail
) async {
final listDetailedEmails = await getAllDetailedEmails(accountId, userName);
final checkDuplicateDetailedEmail = await _handleDuplicateOpenedEmail(accountId, detailedEmail);
if (checkDuplicateDetailedEmail) {
return Future.value();
}
if (listDetailedEmails.length >= CachingConstants.maxNumberOpenedEmailsForOffline) {
final latestEmail = listDetailedEmails.last;
log('DetailedEmailCacheManager::handleStoreDetailedEmail():latestEmail: $latestEmail');
await removeDetailedEmail(accountId, userName, latestEmail.emailId);
}
await insertDetailedEmail(accountId, userName, detailedEmail.toHiveCache());
}
Future<bool> _handleDuplicateOpenedEmail(AccountId accountId, DetailedEmail detailedEmail) async {
final emailContentPath = await _getEmailContentPath(detailedEmail);
final detailedEmailCacheExists = await _getDetailedEmailCache(accountId);
if (emailContentPath != null && detailedEmailCacheExists) {
return true;
} else {
return false;
}
}
Future<String?> _getEmailContentPath(DetailedEmail detailedEmail) async {
final fileSaved = await _fileUtils.getFromFile(
nameFile: detailedEmail.emailId.asString,
folderPath: detailedEmail.folderPath,
extensionFile: ExtensionType.text.value
);
log('DetailedEmailCacheManager::_getDetailedEmailCache():_getEmailContentPath: $fileSaved');
return fileSaved;
}
Future<bool> _getDetailedEmailCache(AccountId accountId) async {
final detailedEmailCache = await _cacheClient.getItem(accountId.asString);
log('DetailedEmailCacheManager::_getDetailedEmailCache():_getDetailedEmailCache: $detailedEmailCache');
if (detailedEmailCache != null) {
return true;
} else {
return false;
}
}
} }
@@ -0,0 +1,94 @@
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/file_utils.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:model/extensions/account_id_extensions.dart';
import 'package:model/extensions/email_id_extensions.dart';
import 'package:tmail_ui_user/features/caching/clients/opened_email_hive_cache_client.dart';
import 'package:tmail_ui_user/features/caching/utils/cache_utils.dart';
import 'package:tmail_ui_user/features/caching/utils/caching_constants.dart';
import 'package:tmail_ui_user/features/email/domain/extensions/detailed_email_extension.dart';
import 'package:tmail_ui_user/features/email/domain/model/detailed_email.dart';
import 'package:tmail_ui_user/features/offline_mode/extensions/list_detailed_email_hive_cache_extension.dart';
import 'package:tmail_ui_user/features/offline_mode/model/detailed_email_hive_cache.dart';
class OpenedEmailCacheManager {
final OpenedEmailHiveCacheClient _cacheClient;
final FileUtils _fileUtils;
OpenedEmailCacheManager(this._cacheClient, this._fileUtils);
Future<void> insertDetailedEmail(
AccountId accountId,
UserName userName,
DetailedEmailHiveCache detailedEmailCache
) {
final keyCache = TupleKey(detailedEmailCache.emailId, accountId.asString, userName.value).encodeKey;
log('OpenedEmailCacheManager::insertDetailedEmail(): $keyCache');
return _cacheClient.insertItem(keyCache, detailedEmailCache);
}
Future<void> removeDetailedEmail(
AccountId accountId,
UserName userName,
String emailId
) {
final keyCache = TupleKey(emailId, accountId.asString, userName.value).encodeKey;
log('OpenedEmailCacheManager::removeDetailedEmail(): $keyCache');
return _cacheClient.deleteItem(keyCache);
}
Future<List<DetailedEmailHiveCache>> getAllDetailedEmails(AccountId accountId, UserName userName) async {
final detailedEmailCacheList = await _cacheClient.getListByTupleKey(accountId.asString, userName.value);
detailedEmailCacheList.sortByLatestTime();
log('OpenedEmailCacheManager::getAllDetailedEmails():SIZE: ${detailedEmailCacheList.length}');
return detailedEmailCacheList;
}
Future<void> storeOpenedEmail(
AccountId accountId,
UserName userName,
DetailedEmail detailedEmail
) async {
final listDetailedEmails = await getAllDetailedEmails(accountId, userName);
if (listDetailedEmails.length >= CachingConstants.maxNumberOpenedEmailsForOffline) {
final latestEmail = listDetailedEmails.last;
log('OpenedEmailCacheManager::handleStoreDetailedEmail():latestEmail: $latestEmail');
await removeDetailedEmail(accountId, userName, latestEmail.emailId);
}
await insertDetailedEmail(accountId, userName, detailedEmail.toHiveCache());
}
Future<bool> isOpenedDetailEmailCached(
AccountId accountId,
UserName userName,
DetailedEmail detailedEmail
) async {
final emailContentPathExists = await _isFileExisted(detailedEmail);
final detailedEmailCacheExists = await _isDetailEmailExistedInCache(accountId, userName, detailedEmail);
return emailContentPathExists == true && detailedEmailCacheExists;
}
Future<bool?> _isFileExisted(DetailedEmail detailedEmail) async {
final fileSaved = await _fileUtils.isFileExisted(
nameFile: detailedEmail.emailId.asString,
folderPath: detailedEmail.folderPath,
);
log('OpenedEmailCacheManager::_getDetailedEmailCache():_getEmailContentPath: $fileSaved');
return fileSaved;
}
Future<bool> _isDetailEmailExistedInCache(
AccountId accountId,
UserName userName,
DetailedEmail detailedEmail
) async {
final keyCache = TupleKey(detailedEmail.emailId.asString, accountId.asString, userName.value).encodeKey;
final detailedEmailCache = await _cacheClient.getItem(keyCache);
log('OpenedEmailCacheManager::_getDetailedEmailCache():_getDetailedEmailCache: $detailedEmailCache');
return detailedEmailCache != null;
}
}
@@ -3,5 +3,5 @@ import 'package:tmail_ui_user/features/offline_mode/worker/hive_worker_queue.dar
class OpenedEmailCacheWorkerQueue extends WorkerQueue { class OpenedEmailCacheWorkerQueue extends WorkerQueue {
@override @override
String get workerName => 'OpenedEmailCache'; String get workerName => 'OpenedEmailCacheQueue';
} }
@@ -25,6 +25,7 @@ import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_api.dart';
import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_isolate_worker.dart'; import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_isolate_worker.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_manager.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_manager.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_worker_queue.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_worker_queue.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_manager.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_worker_queue.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_worker_queue.dart';
import 'package:tmail_ui_user/features/push_notification/data/datasource/fcm_datasource.dart'; import 'package:tmail_ui_user/features/push_notification/data/datasource/fcm_datasource.dart';
import 'package:tmail_ui_user/features/push_notification/data/datasource_impl/fcm_datasource_impl.dart'; import 'package:tmail_ui_user/features/push_notification/data/datasource_impl/fcm_datasource_impl.dart';
@@ -103,6 +104,7 @@ class FcmInteractorBindings extends InteractorsBindings {
Get.find<CacheExceptionThrower>())); Get.find<CacheExceptionThrower>()));
Get.lazyPut(() => EmailHiveCacheDataSourceImpl( Get.lazyPut(() => EmailHiveCacheDataSourceImpl(
Get.find<DetailedEmailCacheManager>(), Get.find<DetailedEmailCacheManager>(),
Get.find<OpenedEmailCacheManager>(),
Get.find<DetailedEmailCacheWorkerQueue>(), Get.find<DetailedEmailCacheWorkerQueue>(),
Get.find<OpenedEmailCacheWorkerQueue>(), Get.find<OpenedEmailCacheWorkerQueue>(),
Get.find<EmailCacheManager>(), Get.find<EmailCacheManager>(),
+7 -1
View File
@@ -11,6 +11,7 @@ import 'package:tmail_ui_user/features/caching/clients/encryption_key_cache_clie
import 'package:tmail_ui_user/features/caching/clients/fcm_cache_client.dart'; import 'package:tmail_ui_user/features/caching/clients/fcm_cache_client.dart';
import 'package:tmail_ui_user/features/caching/clients/hive_cache_version_client.dart'; import 'package:tmail_ui_user/features/caching/clients/hive_cache_version_client.dart';
import 'package:tmail_ui_user/features/caching/clients/mailbox_cache_client.dart'; import 'package:tmail_ui_user/features/caching/clients/mailbox_cache_client.dart';
import 'package:tmail_ui_user/features/caching/clients/opened_email_hive_cache_client.dart';
import 'package:tmail_ui_user/features/caching/clients/recent_login_url_cache_client.dart'; import 'package:tmail_ui_user/features/caching/clients/recent_login_url_cache_client.dart';
import 'package:tmail_ui_user/features/caching/clients/recent_login_username_cache_client.dart'; import 'package:tmail_ui_user/features/caching/clients/recent_login_username_cache_client.dart';
import 'package:tmail_ui_user/features/caching/clients/recent_search_cache_client.dart'; import 'package:tmail_ui_user/features/caching/clients/recent_search_cache_client.dart';
@@ -30,6 +31,8 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/data/local/share_prefer
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/offline_mode/manager/detailed_email_cache_manager.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_manager.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_worker_queue.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_worker_queue.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_manager.dart';
import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_worker_queue.dart';
import 'package:tmail_ui_user/features/push_notification/data/local/fcm_cache_manager.dart'; import 'package:tmail_ui_user/features/push_notification/data/local/fcm_cache_manager.dart';
import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dart'; import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dart';
import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart'; import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart';
@@ -70,7 +73,9 @@ class LocalBindings extends Bindings {
Get.put(FCMCacheManager(Get.find<FcmCacheClient>(),Get.find<FCMSubscriptionCacheClient>())); Get.put(FCMCacheManager(Get.find<FcmCacheClient>(),Get.find<FCMSubscriptionCacheClient>()));
Get.put(HiveCacheVersionClient(Get.find<SharedPreferences>(), Get.find<CacheExceptionThrower>())); Get.put(HiveCacheVersionClient(Get.find<SharedPreferences>(), Get.find<CacheExceptionThrower>()));
Get.put(DetailedEmailHiveCacheClient()); Get.put(DetailedEmailHiveCacheClient());
Get.put(DetailedEmailCacheManager(Get.find<DetailedEmailHiveCacheClient>(), Get.find<FileUtils>())); Get.put(DetailedEmailCacheManager(Get.find<DetailedEmailHiveCacheClient>()));
Get.put(OpenedEmailHiveCacheClient());
Get.put(OpenedEmailCacheManager(Get.find<OpenedEmailHiveCacheClient>(), Get.find<FileUtils>()));
Get.put(CachingManager( Get.put(CachingManager(
Get.find<MailboxCacheClient>(), Get.find<MailboxCacheClient>(),
Get.find<StateCacheClient>(), Get.find<StateCacheClient>(),
@@ -90,5 +95,6 @@ class LocalBindings extends Bindings {
void _bindingWorkerQueue() { void _bindingWorkerQueue() {
Get.put(DetailedEmailCacheWorkerQueue()); Get.put(DetailedEmailCacheWorkerQueue());
Get.put(OpenedEmailCacheWorkerQueue());
} }
} }
+6 -2
View File
@@ -5,6 +5,7 @@ import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
import 'package:jmap_dart_client/jmap/core/utc_date.dart'; import 'package:jmap_dart_client/jmap/core/utc_date.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_header.dart';
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart'; import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/extensions/email_address_extension.dart'; import 'package:model/extensions/email_address_extension.dart';
@@ -31,6 +32,7 @@ class PresentationEmail with EquatableMixin {
final SelectMode selectMode; final SelectMode selectMode;
final Uri? routeWeb; final Uri? routeWeb;
final PresentationMailbox? mailboxContain; final PresentationMailbox? mailboxContain;
final List<EmailHeader>? emailHeader;
PresentationEmail({ PresentationEmail({
this.id, this.id,
@@ -50,7 +52,8 @@ class PresentationEmail with EquatableMixin {
this.mailboxNames, this.mailboxNames,
this.selectMode = SelectMode.INACTIVE, this.selectMode = SelectMode.INACTIVE,
this.routeWeb, this.routeWeb,
this.mailboxContain this.mailboxContain,
this.emailHeader
}); });
String getSenderName() { String getSenderName() {
@@ -117,6 +120,7 @@ class PresentationEmail with EquatableMixin {
mailboxNames, mailboxNames,
selectMode, selectMode,
routeWeb, routeWeb,
mailboxContain mailboxContain,
emailHeader
]; ];
} }
@@ -72,6 +72,7 @@ extension EmailExtension on Email {
replyTo: replyTo, replyTo: replyTo,
mailboxIds: mailboxIds, mailboxIds: mailboxIds,
selectMode: selectMode, selectMode: selectMode,
emailHeader: headers?.toList()
); );
} }