diff --git a/lib/features/composer/data/repository/composer_repository_impl.dart b/lib/features/composer/data/repository/composer_repository_impl.dart index 2f502bd40c..295fa32c00 100644 --- a/lib/features/composer/data/repository/composer_repository_impl.dart +++ b/lib/features/composer/data/repository/composer_repository_impl.dart @@ -51,7 +51,8 @@ class ComposerRepositoryImpl extends ComposerRepository { if (createEmailRequest.inlineAttachments?.isNotEmpty == true) { final tupleContentInlineAttachments = await _replaceImageBase64ToImageCID( emailContent: emailContent, - inlineAttachments: createEmailRequest.inlineAttachments! + inlineAttachments: createEmailRequest.inlineAttachments!, + isCaching: createEmailRequest.isCaching ); emailContent = tupleContentInlineAttachments.value1; @@ -77,12 +78,14 @@ class ComposerRepositoryImpl extends ComposerRepository { Future>> _replaceImageBase64ToImageCID({ required String emailContent, - required Map inlineAttachments + required Map inlineAttachments, + bool isCaching = false }) { try { return _htmlDataSource.replaceImageBase64ToImageCID( emailContent: emailContent, - inlineAttachments: inlineAttachments); + inlineAttachments: inlineAttachments, + isCaching: isCaching); } catch (e) { logError('ComposerRepositoryImpl::_replaceImageBase64ToImageCID: Exception: $e'); return Future.value( diff --git a/lib/features/composer/domain/usecases/restore_email_inline_images_interactor.dart b/lib/features/composer/domain/usecases/convert_image_cid_to_base64_interactor.dart similarity index 83% rename from lib/features/composer/domain/usecases/restore_email_inline_images_interactor.dart rename to lib/features/composer/domain/usecases/convert_image_cid_to_base64_interactor.dart index 0d10be8191..75e541625d 100644 --- a/lib/features/composer/domain/usecases/restore_email_inline_images_interactor.dart +++ b/lib/features/composer/domain/usecases/convert_image_cid_to_base64_interactor.dart @@ -5,8 +5,8 @@ import 'package:dartz/dartz.dart'; import 'package:tmail_ui_user/features/composer/domain/state/restore_email_inline_images_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/composer_cache_repository.dart'; -class RestoreEmailInlineImagesInteractor { - RestoreEmailInlineImagesInteractor(this._composerCacheRepository); +class ConvertImageCIDToBase46Interactor { + ConvertImageCIDToBase46Interactor(this._composerCacheRepository); final ComposerCacheRepository _composerCacheRepository; @@ -17,8 +17,7 @@ class RestoreEmailInlineImagesInteractor { }) async* { try { yield Right(RestoringEmailInlineImages()); - - final emailContent = await _composerCacheRepository.restoreEmailInlineImages( + final emailContent = await _composerCacheRepository.convertImageCIDToBase64( htmlContent, transformConfiguration, mapUrlDownloadCID); diff --git a/lib/features/composer/domain/usecases/save_composer_cache_on_web_interactor.dart b/lib/features/composer/domain/usecases/save_composer_cache_on_web_interactor.dart index 086709ab73..7a84ef6c6b 100644 --- a/lib/features/composer/domain/usecases/save_composer_cache_on_web_interactor.dart +++ b/lib/features/composer/domain/usecases/save_composer_cache_on_web_interactor.dart @@ -5,7 +5,7 @@ import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/core/user_name.dart'; import 'package:tmail_ui_user/features/composer/domain/repository/composer_repository.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/create_email_request.dart'; -import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/data/model/composer_cache.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/composer_cache_repository.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/save_composer_cache_state.dart'; @@ -21,19 +21,20 @@ class SaveComposerCacheOnWebInteractor { Future> execute( CreateEmailRequest createEmailRequest, AccountId accountId, - UserName userName, - {required ScreenDisplayMode displayMode} + UserName userName ) async { try { final emailCreated = await _composerRepository.generateEmail(createEmailRequest); - final identity = createEmailRequest.identity; + final composerCache = ComposerCache( + email: emailCreated, + identity: createEmailRequest.identity, + isRequestReadReceipt: createEmailRequest.isRequestReadReceipt, + displayMode: createEmailRequest.displayMode, + ); await _composerCacheRepository.saveComposerCacheOnWeb( - emailCreated, - accountId: accountId, - userName: userName, - displayMode: displayMode, - identity: identity, - readReceipentEnabled: createEmailRequest.isRequestReadReceipt); + composerCache, + accountId, + userName); return Right(SaveComposerCacheSuccess()); } catch (exception) { return Left(SaveComposerCacheFailure(exception)); diff --git a/lib/features/composer/presentation/composer_bindings.dart b/lib/features/composer/presentation/composer_bindings.dart index f7ded3ee1c..2882c7347e 100644 --- a/lib/features/composer/presentation/composer_bindings.dart +++ b/lib/features/composer/presentation/composer_bindings.dart @@ -10,12 +10,11 @@ import 'package:tmail_ui_user/features/composer/data/repository/composer_reposit import 'package:tmail_ui_user/features/composer/data/repository/contact_repository_impl.dart'; import 'package:tmail_ui_user/features/composer/domain/repository/composer_repository.dart'; import 'package:tmail_ui_user/features/composer/domain/repository/contact_repository.dart'; +import 'package:tmail_ui_user/features/composer/domain/usecases/convert_image_cid_to_base64_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/create_new_and_save_email_to_drafts_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/create_new_and_send_email_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/download_image_as_base64_interactor.dart'; -import 'package:tmail_ui_user/features/composer/domain/usecases/restore_email_inline_images_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/save_composer_cache_on_web_interactor.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_composed_email_to_local_storage_browser_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/upload_attachment_interactor.dart'; import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart'; import 'package:tmail_ui_user/features/composer/presentation/controller/rich_text_mobile_tablet_controller.dart'; @@ -46,6 +45,7 @@ import 'package:tmail_ui_user/features/mailbox/data/repository/mailbox_repositor import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/composer_cache_repository.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_composer_cache_on_web_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/save_composer_cache_to_local_storage_browser_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/profiles/identities/identity_interactors_bindings.dart'; import 'package:tmail_ui_user/features/offline_mode/manager/new_email_cache_manager.dart'; @@ -210,9 +210,9 @@ class ComposerBindings extends BaseBindings { Get.find(), Get.find(), )); - Get.lazyPut(() => RestoreEmailInlineImagesInteractor( + Get.lazyPut(() => ConvertImageCIDToBase46Interactor( Get.find())); - Get.lazyPut(() => StoreComposedEmailToLocalStorageBrowserInteractor( + Get.lazyPut(() => SaveComposerCacheToLocalStorageBrowserInteractor( Get.find(), Get.find(), )); @@ -241,7 +241,7 @@ class ComposerBindings extends BaseBindings { Get.find(), Get.find(), Get.find(), - Get.find(), + Get.find(), )); } diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart index c48de3e76d..25d806e36e 100644 --- a/lib/features/composer/presentation/composer_controller.dart +++ b/lib/features/composer/presentation/composer_controller.dart @@ -15,7 +15,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; -import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/identities/identity.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; @@ -41,15 +40,15 @@ import 'package:tmail_ui_user/features/composer/domain/state/restore_email_inlin import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_drafts_state.dart'; import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart'; import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts_state.dart'; +import 'package:tmail_ui_user/features/composer/domain/usecases/convert_image_cid_to_base64_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/create_new_and_save_email_to_drafts_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/create_new_and_send_email_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/download_image_as_base64_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/get_all_autocomplete_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/get_autocomplete_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/get_device_contact_suggestions_interactor.dart'; -import 'package:tmail_ui_user/features/composer/domain/usecases/restore_email_inline_images_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/save_composer_cache_on_web_interactor.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_composed_email_to_local_storage_browser_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/save_composer_cache_to_local_storage_browser_state.dart'; import 'package:tmail_ui_user/features/composer/presentation/controller/rich_text_mobile_tablet_controller.dart'; import 'package:tmail_ui_user/features/composer/presentation/controller/rich_text_web_controller.dart'; import 'package:tmail_ui_user/features/composer/presentation/extensions/email_action_type_extension.dart'; @@ -72,8 +71,8 @@ import 'package:tmail_ui_user/features/email/domain/usecases/get_email_content_i import 'package:tmail_ui_user/features/email/domain/usecases/transform_html_email_content_interactor.dart'; import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart'; import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/store_composed_email_to_local_storage_browser_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_composer_cache_on_web_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/save_composer_cache_to_local_storage_browser_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/model/draggable_app_state.dart'; import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_identities_state.dart'; @@ -135,12 +134,12 @@ class ComposerController extends BaseController with DragDropFileMixin implement final GetAlwaysReadReceiptSettingInteractor _getAlwaysReadReceiptSettingInteractor; final CreateNewAndSendEmailInteractor _createNewAndSendEmailInteractor; final CreateNewAndSaveEmailToDraftsInteractor _createNewAndSaveEmailToDraftsInteractor; - final StoreComposedEmailToLocalStorageBrowserInteractor _storeComposedEmailToLocalStorageBrowserInteractor; + final SaveComposerCacheToLocalStorageBrowserInteractor _saveComposerCacheToLocalStorageBrowserInteractor; GetAllAutoCompleteInteractor? _getAllAutoCompleteInteractor; GetAutoCompleteInteractor? _getAutoCompleteInteractor; GetDeviceContactSuggestionsInteractor? _getDeviceContactSuggestionsInteractor; - RestoreEmailInlineImagesInteractor? _restoreEmailInlineImagesInteractor; + ConvertImageCIDToBase46Interactor? _convertImageCIDToBase46Interactor; List listToEmailAddress = []; List listCcEmailAddress = []; @@ -212,7 +211,7 @@ class ComposerController extends BaseController with DragDropFileMixin implement this._getAlwaysReadReceiptSettingInteractor, this._createNewAndSendEmailInteractor, this._createNewAndSaveEmailToDraftsInteractor, - this._storeComposedEmailToLocalStorageBrowserInteractor, + this._saveComposerCacheToLocalStorageBrowserInteractor, ); @override @@ -229,7 +228,6 @@ class ComposerController extends BaseController with DragDropFileMixin implement createFocusNodeInput(); scrollControllerEmailAddress.addListener(_scrollControllerEmailAddressListener); _listenStreamEvent(); - _getAlwaysReadReceiptSetting(); _beforeUnloadManager.addListener(onBeforeUnload); } @@ -324,16 +322,14 @@ class ComposerController extends BaseController with DragDropFileMixin implement hasRequestReadReceipt.value = success.alwaysReadReceiptEnabled; } else if (success is RestoreEmailInlineImagesSuccess) { _updateEditorContent(success); - } else if (success is StoreComposedEmailToLocalStorageBrowserSuccess) { - _handleStoreComposedEmailToLocalStorageBrowserSuccess(); + } else if (success is SaveComposerCacheToLocalStorageBrowserSuccess) { + _handleSaveComposerCacheToLocalStorageBrowserSuccess(); } } void _updateEditorContent(RestoreEmailInlineImagesSuccess success) { - richTextWebController?.editorController.setText(success.emailContent); consumeState(Stream.value(Right(GetEmailContentSuccess( - htmlEmailContent: success.emailContent, - attachments: [])))); + htmlEmailContent: success.emailContent)))); } @override @@ -353,7 +349,7 @@ class ComposerController extends BaseController with DragDropFileMixin implement } } else if (failure is GetAlwaysReadReceiptSettingFailure) { hasRequestReadReceipt.value = false; - } else if (failure is StoreComposedEmailToLocalStorageBrowserFailure) { + } else if (failure is SaveComposerCacheToLocalStorageBrowserFailure) { openNewTabButtonState = ButtonState.enabled; } } @@ -404,17 +400,16 @@ class ComposerController extends BaseController with DragDropFileMixin implement Future _saveComposerCacheOnWebAction() async { _autoCreateEmailTag(); - final createEmailRequest = await _generateCreateEmailRequest(); + final createEmailRequest = await _generateCreateEmailRequest(isCaching: true); if (createEmailRequest == null) return; await _saveComposerCacheOnWebInteractor.execute( createEmailRequest, mailboxDashBoardController.accountId.value!, - mailboxDashBoardController.sessionCurrent!.username, - displayMode: screenDisplayMode.value); + mailboxDashBoardController.sessionCurrent!.username); } - Future _generateCreateEmailRequest() async { + Future _generateCreateEmailRequest({bool isCaching = false}) async { if (composerArguments.value == null || mailboxDashBoardController.sessionCurrent == null || mailboxDashBoardController.accountId.value == null @@ -447,7 +442,9 @@ class ComposerController extends BaseController with DragDropFileMixin implement unsubscribeEmailId: composerArguments.value!.previousEmailId, messageId: composerArguments.value!.messageId, references: composerArguments.value!.references, - emailSendingQueue: composerArguments.value!.sendingEmail + emailSendingQueue: composerArguments.value!.sendingEmail, + isCaching: isCaching, + displayMode: screenDisplayMode.value ); } @@ -499,7 +496,7 @@ class ComposerController extends BaseController with DragDropFileMixin implement } void onCreatedMobileEditorAction(BuildContext context, HtmlEditorApi editorApi, String? content) { - if (identitySelected.value != null) { + if (listFromIdentities.isNotEmpty) { initTextEditor(content); } richTextMobileTabletController?.htmlEditorApi = editorApi; @@ -513,14 +510,12 @@ class ComposerController extends BaseController with DragDropFileMixin implement ); } - void onLoadCompletedMobileEditorAction(HtmlEditorApi editorApi, WebUri? url) async { + Future onLoadCompletedMobileEditorAction( + HtmlEditorApi editorApi, + WebUri? url + ) async { _isEmailBodyLoaded = true; - if (identitySelected.value == null) { - _getAllIdentities(); - } else { - await _selectIdentity(identitySelected.value); - _autoFocusFieldWhenLauncher(); - } + await _applyIdentityToEditor(); } void _initEmail() { @@ -563,6 +558,13 @@ class ComposerController extends BaseController with DragDropFileMixin implement presentationEmail: arguments.sendingEmail!.presentationEmail, actionType: EmailActionType.editSendingEmail ); + + final allAttachments = arguments.sendingEmail!.email.allAttachments; + _initAttachmentsAndInlineImages( + attachments: allAttachments.getListAttachmentsDisplayedOutside( + arguments.sendingEmail!.email.htmlBodyAttachments), + inlineImages: allAttachments.listAttachmentsDisplayedInContent); + _getEmailContentFromSendingEmail(arguments.sendingEmail!); _emailIdEditing = arguments.sendingEmail!.presentationEmail.id!; break; @@ -602,6 +604,10 @@ class ComposerController extends BaseController with DragDropFileMixin implement presentationEmail: arguments.presentationEmail!, actionType: arguments.emailActionType ); + _initAttachmentsAndInlineImages( + attachments: arguments.attachments, + inlineImages: arguments.inlineImages); + _transformHtmlEmailContent(arguments.emailContents); break; case EmailActionType.forward: @@ -609,38 +615,11 @@ class ComposerController extends BaseController with DragDropFileMixin implement presentationEmail: arguments.presentationEmail!, actionType: arguments.emailActionType ); - _initAttachments(arguments.attachments ?? []); - _transformHtmlEmailContent(arguments.emailContents); - break; - case EmailActionType.reopenComposerBrowser: - if (!PlatformInfo.isWeb) return; - - screenDisplayMode.value = arguments.displayMode; - - _initEmailAddress( - presentationEmail: arguments.presentationEmail!, - actionType: EmailActionType.reopenComposerBrowser - ); - _initSubjectEmail( - presentationEmail: arguments.presentationEmail!, - actionType: EmailActionType.reopenComposerBrowser - ); - _initAttachments( - arguments.attachments ?? [], - inlineAttachments: arguments.inlineImages); - - final accountId = mailboxDashBoardController.accountId.value; - final downloadUrl = mailboxDashBoardController.sessionCurrent - ?.getDownloadUrl(jmapUrl: dynamicUrlInterceptors.jmapUrl); - if (accountId == null || downloadUrl == null) return; - _getEmailContentFromSessionStorageBrowser( - htmlContent: arguments.emailContents ?? '', - inlineImages: arguments.inlineImages ?? [], - accountId: accountId, - downloadUrl: downloadUrl - ); + _initAttachmentsAndInlineImages( + attachments: arguments.attachments, + inlineImages: arguments.inlineImages); - hasRequestReadReceipt.value = arguments.readRecepientEnabled ?? false; + _transformHtmlEmailContent(arguments.emailContents); break; case EmailActionType.composeFromUnsubscribeMailtoLink: if (arguments.subject != null) { @@ -655,22 +634,38 @@ class ComposerController extends BaseController with DragDropFileMixin implement _getEmailContentFromUnsubscribeMailtoLink(arguments.body ?? ''); _updateStatusEmailSendButton(); break; - case EmailActionType.restoreComposedEmailFromLocalStorage: + case EmailActionType.reopenComposerBrowser: + case EmailActionType.composeEmailIntoNewTab: + screenDisplayMode.value = arguments.displayMode; + _initEmailAddress( presentationEmail: arguments.presentationEmail!, - actionType: EmailActionType.restoreComposedEmailFromLocalStorage + actionType: arguments.emailActionType ); _initSubjectEmail( presentationEmail: arguments.presentationEmail!, - actionType: EmailActionType.restoreComposedEmailFromLocalStorage + actionType: arguments.emailActionType ); - _initAttachments(arguments.attachments ?? []); - _getEmailContentFromLocalStorageBrowser(arguments.emailContents!); + _initAttachmentsAndInlineImages( + attachments: arguments.attachments, + inlineImages: arguments.inlineImages); + + _getEmailContentFromStorageBrowser( + htmlContent: arguments.emailContents ?? '', + inlineImages: arguments.inlineImages ?? []); break; default: break; } } + + if ((composerArguments.value?.emailActionType == EmailActionType.composeEmailIntoNewTab + || composerArguments.value?.emailActionType == EmailActionType.reopenComposerBrowser) + && composerArguments.value?.isRequestReadReceipt == true) { + hasRequestReadReceipt.value = arguments.isRequestReadReceipt; + } else { + _getAlwaysReadReceiptSetting(); + } } void _initSubjectEmail({ @@ -683,55 +678,51 @@ class ComposerController extends BaseController with DragDropFileMixin implement subjectEmailInputController.text = newSubject; } - void _initAttachments(List attachments, {List? inlineAttachments}) { - if (attachments.isNotEmpty) { - initialAttachments = attachments; + void _initAttachmentsAndInlineImages({ + List? attachments, + List? inlineImages + }) { + if (attachments?.isNotEmpty == true) { + initialAttachments = attachments!; uploadController.initializeUploadAttachments(attachments); } - if (inlineAttachments != null) { - uploadController.initializeUploadInlineAttachments(inlineAttachments); + if (inlineImages?.isNotEmpty == true) { + uploadController.initializeUploadInlineAttachments(inlineImages!); } } void _initIdentities(ComposerArguments composerArguments) { listFromIdentities.value = composerArguments.identities ?? []; - if (listFromIdentities.isEmpty) { - _getAllIdentities(); - } else if (composerArguments.selectedIdentity != null - && listFromIdentities.contains(composerArguments.selectedIdentity!) - ) { - _selectIdentity(composerArguments.selectedIdentity!); - } else if (composerArguments.identities?.isNotEmpty == true) { - _selectIdentity(composerArguments.identities!.first); - } } void _getAllIdentities() { log('ComposerController::_getAllIdentities: Fetch again identity !'); final accountId = mailboxDashBoardController.accountId.value; final session = mailboxDashBoardController.sessionCurrent; - if (accountId != null && session != null) { - consumeState(_getAllIdentitiesInteractor.execute(session, accountId)); - } + if (accountId == null || session == null) return; + consumeState(_getAllIdentitiesInteractor.execute(session, accountId)); } - void _handleGetAllIdentitiesSuccess(GetAllIdentitiesSuccess success) async { - final listIdentitiesMayDeleted = success.identities?.toListMayDeleted() ?? []; - if (listIdentitiesMayDeleted.isNotEmpty) { - listFromIdentities.value = listIdentitiesMayDeleted; - - if (identitySelected.value == null) { - final selectedIdentityFromArguments = composerArguments.value?.selectedIdentity; - if (selectedIdentityFromArguments != null - && listFromIdentities.contains(selectedIdentityFromArguments) - ) { - await _selectIdentity(selectedIdentityFromArguments); - } else { - await _selectIdentity(listIdentitiesMayDeleted.firstOrNull); - } + Future _applyIdentityToEditor() async { + if (listFromIdentities.isEmpty) { + _getAllIdentities(); + } else { + final selectedIdentityFromArguments = composerArguments.value?.selectedIdentity; + if (selectedIdentityFromArguments != null + && listFromIdentities.contains(selectedIdentityFromArguments)) { + await _selectIdentity(selectedIdentityFromArguments); + } else { + await _selectIdentity(listFromIdentities.first); } + await _autoFocusFieldWhenLauncher(); } - _autoFocusFieldWhenLauncher(); + } + + Future _handleGetAllIdentitiesSuccess(GetAllIdentitiesSuccess success) async { + final listIdentitiesMayDeleted = success.identities?.toListMayDeleted() ?? []; + if (listIdentitiesMayDeleted.isEmpty) return; + listFromIdentities.value = listIdentitiesMayDeleted; + await _applyIdentityToEditor(); } void _initEmailAddress({ @@ -1314,64 +1305,50 @@ class ComposerController extends BaseController with DragDropFileMixin implement consumeState(Stream.value( Right(GetEmailContentSuccess( htmlEmailContent: sendingEmail.presentationEmail.emailContentList.asHtmlString, - attachments: sendingEmail.email.allAttachments, emailCurrent: sendingEmail.email )) )); } - void _getEmailContentFromSessionStorageBrowser({ + void _getEmailContentFromStorageBrowser({ required String htmlContent, required List inlineImages, - required AccountId accountId, - required String downloadUrl }) { - _restoreEmailInlineImagesInteractor = getBinding(); - if (_restoreEmailInlineImagesInteractor == null) return; - consumeState(_restoreEmailInlineImagesInteractor!.execute( + consumeState(Stream.value(Right(GetEmailContentLoading()))); + + final accountId = mailboxDashBoardController.accountId.value; + final baseDownloadUrl = mailboxDashBoardController.baseDownloadUrl; + + if (accountId == null || baseDownloadUrl.isEmpty) { + consumeState(Stream.value(Right(GetEmailContentSuccess(htmlEmailContent: htmlContent)))); + return; + } + + _convertImageCIDToBase46Interactor = getBinding(); + if (_convertImageCIDToBase46Interactor == null) return; + + final mapUrlDownloadCID = inlineImages.toMapCidImageDownloadUrl( + accountId: accountId, + downloadUrl: baseDownloadUrl); + + consumeState(_convertImageCIDToBase46Interactor!.execute( htmlContent: htmlContent, transformConfiguration: TransformConfiguration.forRestoreEmail(), - mapUrlDownloadCID: inlineImages.toMapCidImageDownloadUrl( - accountId: accountId, - downloadUrl: downloadUrl))); - } - - void _getEmailContentFromLocalStorageBrowser(String content) { - consumeState(Stream.value( - Right(GetEmailContentSuccess( - htmlEmailContent: content, - attachments: [], - )) - )); + mapUrlDownloadCID: mapUrlDownloadCID)); } void _getEmailContentFromContentShared(String content) { - consumeState(Stream.value( - Right(GetEmailContentSuccess( - htmlEmailContent: content, - attachments: [], - )) - )); + consumeState(Stream.value(Right(GetEmailContentSuccess(htmlEmailContent: content)))); } void _getEmailContentFromMailtoUri(String content) { log('ComposerController::_getEmailContentFromMailtoUri:content: $content'); - consumeState(Stream.value( - Right(GetEmailContentSuccess( - htmlEmailContent: content, - attachments: [], - )) - )); + consumeState(Stream.value(Right(GetEmailContentSuccess(htmlEmailContent: content)))); } void _getEmailContentFromUnsubscribeMailtoLink(String content) { log('ComposerController::_getEmailContentFromUnsubscribeMailtoLink:content: $content'); - consumeState(Stream.value( - Right(GetEmailContentSuccess( - htmlEmailContent: content, - attachments: [], - )) - )); + consumeState(Stream.value(Right(GetEmailContentSuccess(htmlEmailContent: content)))); } void _getEmailContentFromEmailId({required EmailId emailId, bool isDraftEmail = false}) { @@ -1389,12 +1366,16 @@ class ComposerController extends BaseController with DragDropFileMixin implement } void _getEmailContentOffLineSuccess(GetEmailContentFromCacheSuccess success) { - _initAttachments(success.attachments); + _initAttachmentsAndInlineImages( + attachments: success.attachments, + inlineImages: success.inlineImages); emailContentsViewState.value = Right(success); } void _getEmailContentSuccess(GetEmailContentSuccess success) { - _initAttachments(success.attachments); + _initAttachmentsAndInlineImages( + attachments: success.attachments, + inlineImages: success.inlineImages); emailContentsViewState.value = Right(success); } @@ -1640,36 +1621,36 @@ class ComposerController extends BaseController with DragDropFileMixin implement } } - Future _selectIdentity(Identity? newIdentity) async { - final formerIdentity = identitySelected.value; + Future _selectIdentity(Identity newIdentity) async { + final oldIdentity = identitySelected.value; identitySelected.value = newIdentity; - if (newIdentity == null) return; - - if (composerArguments.value?.emailActionType == EmailActionType.reopenComposerBrowser) { - composerArguments.value = composerArguments.value?.copyWith( - emailActionType: EmailActionType.editDraft); - } else { - await _applyIdentityForAllFieldComposer(formerIdentity, newIdentity); + if (oldIdentity != null + || composerArguments.value?.emailActionType == EmailActionType.reopenComposerBrowser + || composerArguments.value?.emailActionType == EmailActionType.composeEmailIntoNewTab) { + return; } + + await _applyIdentityForAllFieldComposer( + oldIdentity: oldIdentity, + newIdentity: newIdentity); } - Future _applyIdentityForAllFieldComposer( - Identity? formerIdentity, - Identity newIdentity - ) async { - if (formerIdentity != null) { - if (formerIdentity.bcc?.isNotEmpty == true) { - _removeBccEmailAddressFromFormerIdentity(formerIdentity.bcc!); - } - await _removeSignature(); + Future _applyIdentityForAllFieldComposer({ + required Identity? oldIdentity, + required Identity? newIdentity + }) async { + await _removeSignature(); + + if (oldIdentity?.bcc?.isNotEmpty == true) { + _removeBccEmailAddressFromFormerIdentity(oldIdentity!.bcc!); } - if (newIdentity.bcc?.isNotEmpty == true) { - _applyBccEmailAddressFromIdentity(newIdentity.bcc!); + if (newIdentity?.bcc?.isNotEmpty == true) { + _applyBccEmailAddressFromIdentity(newIdentity!.bcc!); } - if (newIdentity.signatureAsString.isNotEmpty == true) { - await _applySignature(newIdentity.signatureAsString.asSignatureHtml()); + if (newIdentity?.signatureAsString.isNotEmpty == true) { + await _applySignature(newIdentity!.signatureAsString.asSignatureHtml()); } if (PlatformInfo.isMobile) { @@ -1858,19 +1839,14 @@ class ComposerController extends BaseController with DragDropFileMixin implement } - void handleInitHtmlEditorWeb(String initContent) async { + Future handleInitHtmlEditorWeb(String initContent) async { log('ComposerController::handleInitHtmlEditorWeb:'); _isEmailBodyLoaded = true; richTextWebController?.editorController.setFullScreen(); richTextWebController?.editorController.setOnDragDropEvent(); onChangeTextEditorWeb(initContent); richTextWebController?.setEnableCodeView(); - if (identitySelected.value == null) { - _getAllIdentities(); - } else { - await _selectIdentity(identitySelected.value); - _autoFocusFieldWhenLauncher(); - } + await _applyIdentityToEditor(); } void handleOnFocusHtmlEditorWeb() { @@ -1915,7 +1891,7 @@ class ComposerController extends BaseController with DragDropFileMixin implement HtmlEditorApi? get htmlEditorApi => richTextMobileTabletController?.htmlEditorApi; void onChangeTextEditorWeb(String? text) { - if (identitySelected.value != null) { + if (listFromIdentities.isNotEmpty) { initTextEditor(text); } _textEditorWeb = text; @@ -1971,7 +1947,11 @@ class ComposerController extends BaseController with DragDropFileMixin implement } Future onChangeIdentity(Identity? newIdentity) async { - await _selectIdentity(newIdentity); + final oldIdentity = identitySelected.value; + identitySelected.value = newIdentity; + await _applyIdentityForAllFieldComposer( + oldIdentity: oldIdentity, + newIdentity: newIdentity); } void _searchIdentities(String searchText) { @@ -2323,46 +2303,17 @@ class ComposerController extends BaseController with DragDropFileMixin implement _autoCreateEmailTag(); } - final arguments = composerArguments.value; - final session = mailboxDashBoardController.sessionCurrent; - final accountId = mailboxDashBoardController.accountId.value; - - if (arguments == null || session == null || accountId == null) { - log('ComposerController::onOpenNewTabAction: SESSION or ACCOUNT_ID or ARGUMENTS is NULL'); - return; - } - - final emailContent = await _getContentInEditor(); - - final createEmailRequest = CreateEmailRequest( - session: session, - accountId: accountId, - emailActionType: arguments.emailActionType, - subject: subjectEmail.value ?? '', - emailContent: emailContent, - fromSender: arguments.presentationEmail?.from ?? {}, - toRecipients: listToEmailAddress.toSet(), - ccRecipients: listCcEmailAddress.toSet(), - bccRecipients: listBccEmailAddress.toSet(), - isRequestReadReceipt: hasRequestReadReceipt.value, - identity: identitySelected.value, - attachments: uploadController.attachmentsUploaded, - inlineAttachments: uploadController.mapInlineAttachments, - outboxMailboxId: mailboxDashBoardController.outboxMailbox?.mailboxId, - sentMailboxId: mailboxDashBoardController.mapDefaultMailboxIdByRole[PresentationMailbox.roleSent], - draftsMailboxId: mailboxDashBoardController.mapDefaultMailboxIdByRole[PresentationMailbox.roleDrafts], - draftsEmailId: _getDraftEmailId(), - answerForwardEmailId: arguments.presentationEmail?.id, - unsubscribeEmailId: arguments.previousEmailId, - messageId: arguments.messageId, - references:arguments.references, - emailSendingQueue: arguments.sendingEmail - ); + final createEmailRequest = await _generateCreateEmailRequest(isCaching: true); + if (createEmailRequest == null) return; - consumeState(_storeComposedEmailToLocalStorageBrowserInteractor.execute(createEmailRequest)); + consumeState(_saveComposerCacheToLocalStorageBrowserInteractor.execute( + createEmailRequest, + mailboxDashBoardController.accountId.value!, + mailboxDashBoardController.sessionCurrent!.username, + )); } - Future _handleStoreComposedEmailToLocalStorageBrowserSuccess() async { + Future _handleSaveComposerCacheToLocalStorageBrowserSuccess() async { openNewTabButtonState = ButtonState.enabled; await AppUtils.launchLink( diff --git a/lib/features/composer/presentation/extensions/email_action_type_extension.dart b/lib/features/composer/presentation/extensions/email_action_type_extension.dart index 24462965a2..d2692cda55 100644 --- a/lib/features/composer/presentation/extensions/email_action_type_extension.dart +++ b/lib/features/composer/presentation/extensions/email_action_type_extension.dart @@ -31,7 +31,7 @@ extension EmailActionTypeExtension on EmailActionType { case EmailActionType.editDraft: case EmailActionType.editSendingEmail: case EmailActionType.reopenComposerBrowser: - case EmailActionType.restoreComposedEmailFromLocalStorage: + case EmailActionType.composeEmailIntoNewTab: return subject; default: return ''; diff --git a/lib/features/composer/presentation/model/create_email_request.dart b/lib/features/composer/presentation/model/create_email_request.dart index 1cc956a167..91b1ce73a6 100644 --- a/lib/features/composer/presentation/model/create_email_request.dart +++ b/lib/features/composer/presentation/model/create_email_request.dart @@ -8,6 +8,7 @@ import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:model/email/attachment.dart'; import 'package:model/email/email_action_type.dart'; +import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.dart'; import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart'; class CreateEmailRequest with EquatableMixin { @@ -34,6 +35,8 @@ class CreateEmailRequest with EquatableMixin { final MessageIdsHeaderValue? messageId; final MessageIdsHeaderValue? references; final SendingEmail? emailSendingQueue; + final bool isCaching; + final ScreenDisplayMode displayMode; CreateEmailRequest({ required this.session, @@ -57,7 +60,9 @@ class CreateEmailRequest with EquatableMixin { this.unsubscribeEmailId, this.messageId, this.references, - this.emailSendingQueue + this.emailSendingQueue, + this.isCaching = false, + this.displayMode = ScreenDisplayMode.normal, }); @override @@ -83,6 +88,8 @@ class CreateEmailRequest with EquatableMixin { unsubscribeEmailId, references, references, - emailSendingQueue + emailSendingQueue, + isCaching, + displayMode, ]; } \ No newline at end of file diff --git a/lib/features/composer/presentation/view/web/web_editor_view.dart b/lib/features/composer/presentation/view/web/web_editor_view.dart index 2f3925abfe..8a6bda52de 100644 --- a/lib/features/composer/presentation/view/web/web_editor_view.dart +++ b/lib/features/composer/presentation/view/web/web_editor_view.dart @@ -7,6 +7,7 @@ import 'package:dartz/dartz.dart'; import 'package:flutter/material.dart'; import 'package:html_editor_enhanced/html_editor.dart'; import 'package:model/email/email_action_type.dart'; +import 'package:tmail_ui_user/features/composer/domain/state/restore_email_inline_images_state.dart'; import 'package:tmail_ui_user/features/composer/presentation/view/editor_view_mixin.dart'; import 'package:tmail_ui_user/features/composer/presentation/widgets/web/web_editor_widget.dart'; import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart'; @@ -80,7 +81,7 @@ class WebEditorView extends StatelessWidget with EditorViewMixin { case EmailActionType.reopenComposerBrowser: case EmailActionType.composeFromUnsubscribeMailtoLink: case EmailActionType.composeFromMailtoUri: - case EmailActionType.restoreComposedEmailFromLocalStorage: + case EmailActionType.composeEmailIntoNewTab: if (contentViewState == null) { return const SizedBox.shrink(); } @@ -101,7 +102,7 @@ class WebEditorView extends StatelessWidget with EditorViewMixin { onDragEnter: onDragEnter, ), (success) { - if (success is GetEmailContentLoading) { + if (success is GetEmailContentLoading || success is RestoringEmailInlineImages) { return const CupertinoLoadingWidget(padding: EdgeInsets.all(16.0)); } else { var newContent = success is GetEmailContentSuccess diff --git a/lib/features/email/data/datasource/html_datasource.dart b/lib/features/email/data/datasource/html_datasource.dart index 3545774623..d2a65c92e3 100644 --- a/lib/features/email/data/datasource/html_datasource.dart +++ b/lib/features/email/data/datasource/html_datasource.dart @@ -18,8 +18,15 @@ abstract class HtmlDataSource { Future>> replaceImageBase64ToImageCID({ required String emailContent, - required Map inlineAttachments + required Map inlineAttachments, + bool isCaching = false }); Future removeCollapsedExpandedSignatureEffect({required String emailContent}); + + Future convertImageCIDToBase64( + String htmlContent, + TransformConfiguration transformConfiguration, + Map mapUrlDownloadCID + ); } \ No newline at end of file diff --git a/lib/features/email/data/datasource_impl/html_datasource_impl.dart b/lib/features/email/data/datasource_impl/html_datasource_impl.dart index 5d695d739d..860020a515 100644 --- a/lib/features/email/data/datasource_impl/html_datasource_impl.dart +++ b/lib/features/email/data/datasource_impl/html_datasource_impl.dart @@ -42,12 +42,14 @@ class HtmlDataSourceImpl extends HtmlDataSource { @override Future>> replaceImageBase64ToImageCID({ required String emailContent, - required Map inlineAttachments + required Map inlineAttachments, + bool isCaching = false }) { return Future.sync(() async { return await _htmlAnalyzer.replaceImageBase64ToImageCID( emailContent: emailContent, - inlineAttachments: inlineAttachments + inlineAttachments: inlineAttachments, + isCaching: isCaching ); }).catchError(_exceptionThrower.throwException); } @@ -60,4 +62,18 @@ class HtmlDataSourceImpl extends HtmlDataSource { ); }).catchError(_exceptionThrower.throwException); } + + @override + Future convertImageCIDToBase64( + String htmlContent, + TransformConfiguration transformConfiguration, + Map mapUrlDownloadCID + ) { + return Future.sync(() async { + return await _htmlAnalyzer.convertImageCIDToBase64( + htmlContent, + mapUrlDownloadCID, + transformConfiguration); + }).catchError(_exceptionThrower.throwException); + } } \ No newline at end of file diff --git a/lib/features/email/data/local/html_analyzer.dart b/lib/features/email/data/local/html_analyzer.dart index 904c320a05..922355e63f 100644 --- a/lib/features/email/data/local/html_analyzer.dart +++ b/lib/features/email/data/local/html_analyzer.dart @@ -107,7 +107,8 @@ class HtmlAnalyzer { Future>> replaceImageBase64ToImageCID({ required String emailContent, - required Map inlineAttachments + required Map inlineAttachments, + bool isCaching = false }) async { final document = parse(emailContent); final listImgTag = document.querySelectorAll('img[src^="data:image/"][id^="cid:"]'); @@ -116,7 +117,9 @@ class HtmlAnalyzer { final idImg = imgTag.attributes['id']; final cid = idImg!.replaceFirst('cid:', '').trim(); imgTag.attributes['src'] = 'cid:$cid'; - imgTag.attributes.remove('id'); + if (!isCaching) { + imgTag.attributes.remove('id'); + } return cid; })).then((listCid) { final listInlineAttachment = listCid @@ -157,4 +160,15 @@ class HtmlAnalyzer { log('HtmlAnalyzer::removeCollapsedExpandedSignatureEffect: AFTER = $newContent'); return newContent; } + + Future convertImageCIDToBase64( + String htmlContent, + Map mapCidImageDownloadUrl, + TransformConfiguration transformConfiguration + ) async { + return await _htmlTransform.transformToHtml( + htmlContent: htmlContent, + mapCidImageDownloadUrl: mapCidImageDownloadUrl, + transformConfiguration: transformConfiguration); + } } \ No newline at end of file diff --git a/lib/features/email/domain/extensions/detailed_email_extension.dart b/lib/features/email/domain/extensions/detailed_email_extension.dart index c7b9396db9..80180121b1 100644 --- a/lib/features/email/domain/extensions/detailed_email_extension.dart +++ b/lib/features/email/domain/extensions/detailed_email_extension.dart @@ -18,6 +18,7 @@ extension DetailedEmailExtension on DetailedEmail { emailContentPath: emailContentPath, messageId: messageId?.ids.toList(), references: references?.ids.toList(), + inlineImages: inlineImages?.toHiveCache(), ); } @@ -36,6 +37,7 @@ extension DetailedEmailExtension on DetailedEmail { emailContentPath: path, messageId: messageId, references: references, + inlineImages: inlineImages, ); } } \ No newline at end of file diff --git a/lib/features/email/domain/extensions/detailed_email_hive_cache_extension.dart b/lib/features/email/domain/extensions/detailed_email_hive_cache_extension.dart index 1a32803059..78b1c7dae7 100644 --- a/lib/features/email/domain/extensions/detailed_email_hive_cache_extension.dart +++ b/lib/features/email/domain/extensions/detailed_email_hive_cache_extension.dart @@ -22,7 +22,8 @@ extension DetailedEmailHiveCacheExtension on DetailedEmailHiveCache { : null, references: references != null ? MessageIdsHeaderValue(references!.toSet()) - : null + : null, + inlineImages: inlineImages?.toAttachment(), ); } } \ No newline at end of file diff --git a/lib/features/email/domain/extensions/email_extension.dart b/lib/features/email/domain/extensions/email_extension.dart index 782e169e68..957f3736eb 100644 --- a/lib/features/email/domain/extensions/email_extension.dart +++ b/lib/features/email/domain/extensions/email_extension.dart @@ -14,7 +14,8 @@ extension EmailExtension on Email { keywords: keywords, htmlEmailContent: htmlEmailContent, messageId: messageId, - references: references + references: references, + inlineImages: allAttachments.listAttachmentsDisplayedInContent, ); } } \ No newline at end of file diff --git a/lib/features/email/domain/model/detailed_email.dart b/lib/features/email/domain/model/detailed_email.dart index 008e19df7c..cbfa6f26c2 100644 --- a/lib/features/email/domain/model/detailed_email.dart +++ b/lib/features/email/domain/model/detailed_email.dart @@ -14,6 +14,7 @@ class DetailedEmail with EquatableMixin { final DateTime createdTime; final MessageIdsHeaderValue? messageId; final MessageIdsHeaderValue? references; + final List? inlineImages; DetailedEmail({ required this.emailId, @@ -25,6 +26,7 @@ class DetailedEmail with EquatableMixin { this.emailContentPath, this.messageId, this.references, + this.inlineImages, }); @override @@ -38,5 +40,6 @@ class DetailedEmail with EquatableMixin { emailContentPath, messageId, references, + inlineImages, ]; } \ No newline at end of file diff --git a/lib/features/email/domain/state/get_email_content_state.dart b/lib/features/email/domain/state/get_email_content_state.dart index 9742216d9c..57250a68f3 100644 --- a/lib/features/email/domain/state/get_email_content_state.dart +++ b/lib/features/email/domain/state/get_email_content_state.dart @@ -7,12 +7,14 @@ class GetEmailContentLoading extends LoadingState {} class GetEmailContentSuccess extends UIState { final String htmlEmailContent; - final List attachments; + final List? attachments; + final List? inlineImages; final Email? emailCurrent; GetEmailContentSuccess({ required this.htmlEmailContent, - required this.attachments, + this.attachments, + this.inlineImages, this.emailCurrent }); @@ -20,18 +22,21 @@ class GetEmailContentSuccess extends UIState { List get props => [ htmlEmailContent, attachments, + inlineImages, emailCurrent ]; } class GetEmailContentFromCacheSuccess extends UIState { final String htmlEmailContent; - final List attachments; + final List? attachments; + final List? inlineImages; final Email? emailCurrent; GetEmailContentFromCacheSuccess({ required this.htmlEmailContent, - required this.attachments, + this.attachments, + this.inlineImages, this.emailCurrent }); @@ -39,6 +44,7 @@ class GetEmailContentFromCacheSuccess extends UIState { List get props => [ htmlEmailContent, attachments, + inlineImages, emailCurrent, ]; } diff --git a/lib/features/email/domain/usecases/get_email_content_interactor.dart b/lib/features/email/domain/usecases/get_email_content_interactor.dart index c2e1c6f355..8b96abbb94 100644 --- a/lib/features/email/domain/usecases/get_email_content_interactor.dart +++ b/lib/features/email/domain/usecases/get_email_content_interactor.dart @@ -48,8 +48,11 @@ class GetEmailContentInteractor { try { final email = await emailRepository.getEmailContent(session, accountId, emailId); + final listInlineImages = email.allAttachments.listAttachmentsDisplayedInContent; + final listAttachments = email.allAttachments.getListAttachmentsDisplayedOutside(email.htmlBodyAttachments); + if (email.emailContentList.isNotEmpty) { - final mapCidImageDownloadUrl = email.attachmentsWithCid.toMapCidImageDownloadUrl( + final mapCidImageDownloadUrl = listInlineImages.toMapCidImageDownloadUrl( accountId: accountId, downloadUrl: baseDownloadUrl ); @@ -61,13 +64,15 @@ class GetEmailContentInteractor { yield Right(GetEmailContentSuccess( htmlEmailContent: newEmailContents.asHtmlString, - attachments: email.allAttachments.getListAttachmentsDisplayedOutside(email.htmlBodyAttachments), + attachments: listAttachments, + inlineImages: listInlineImages, emailCurrent: email )); } else { yield Right(GetEmailContentSuccess( htmlEmailContent: '', - attachments: email.allAttachments.getListAttachmentsDisplayedOutside(email.htmlBodyAttachments), + attachments: listAttachments, + inlineImages: listInlineImages, emailCurrent: email )); } @@ -90,6 +95,7 @@ class GetEmailContentInteractor { yield Right(GetEmailContentFromCacheSuccess( htmlEmailContent: detailedEmail.htmlEmailContent ?? '', attachments: detailedEmail.attachments ?? [], + inlineImages: detailedEmail.inlineImages ?? [], emailCurrent: Email( id: emailId, headers: detailedEmail.headers, @@ -121,6 +127,7 @@ class GetEmailContentInteractor { yield Right(GetEmailContentFromCacheSuccess( htmlEmailContent: detailedEmail.htmlEmailContent ?? '', attachments: detailedEmail.attachments ?? [], + inlineImages: detailedEmail.inlineImages ?? [], emailCurrent: Email( id: emailId, headers: detailedEmail.headers, diff --git a/lib/features/email/domain/usecases/get_list_detailed_email_by_id_interator.dart b/lib/features/email/domain/usecases/get_list_detailed_email_by_id_interator.dart index 8e0e2448a1..21f5eab568 100644 --- a/lib/features/email/domain/usecases/get_list_detailed_email_by_id_interator.dart +++ b/lib/features/email/domain/usecases/get_list_detailed_email_by_id_interator.dart @@ -57,7 +57,7 @@ class GetListDetailedEmailByIdInteractor { final listEmailContent = email.emailContentList; if (listEmailContent.isNotEmpty) { - final mapCidImageDownloadUrl = email.attachmentsWithCid.toMapCidImageDownloadUrl( + final mapCidImageDownloadUrl = email.allAttachments.listAttachmentsDisplayedInContent.toMapCidImageDownloadUrl( accountId: accountId, downloadUrl: baseDownloadUrl ); diff --git a/lib/features/email/presentation/controller/single_email_controller.dart b/lib/features/email/presentation/controller/single_email_controller.dart index 49f05d3310..ed9d012169 100644 --- a/lib/features/email/presentation/controller/single_email_controller.dart +++ b/lib/features/email/presentation/controller/single_email_controller.dart @@ -468,6 +468,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin { GetEmailContentSuccess( htmlEmailContent: emailLoaded.htmlContent, attachments: emailLoaded.attachments, + inlineImages: emailLoaded.inlineImages, emailCurrent: emailLoaded.emailCurrent ) ))); @@ -500,22 +501,23 @@ class SingleEmailController extends BaseController with AppLoaderMixin { currentEmailLoaded.value = EmailLoaded( htmlContent: success.htmlEmailContent, - attachments: List.of(success.attachments), + attachments: List.of(success.attachments ?? []), + inlineImages: List.of(success.inlineImages ?? []), emailCurrent: success.emailCurrent, ); emailSupervisorController.pushEmailQueue(currentEmailLoaded.value!); if (success.emailCurrent?.id == currentEmail?.id) { - attachments.value = success.attachments; + attachments.value = success.attachments ?? []; attachmentsViewState.value = { for (var attachment in attachments.where((item) => item.blobId != null)) attachment.blobId!: Right(IdleDownloadAttachmentForWeb()) }; - if (_canParseCalendarEvent(blobIds: success.attachments.calendarEventBlobIds)) { + if (_canParseCalendarEvent(blobIds: success.attachments?.calendarEventBlobIds ?? {})) { _parseCalendarEventAction( accountId: mailboxDashBoardController.accountId.value!, - blobIds: success.attachments.calendarEventBlobIds, + blobIds: success.attachments?.calendarEventBlobIds ?? {}, emailContents: success.htmlEmailContent ); } else { @@ -544,22 +546,23 @@ class SingleEmailController extends BaseController with AppLoaderMixin { currentEmailLoaded.value = EmailLoaded( htmlContent: success.htmlEmailContent, - attachments: List.of(success.attachments), + attachments: List.of(success.attachments ?? []), + inlineImages: List.of(success.inlineImages ?? []), emailCurrent: success.emailCurrent, ); emailSupervisorController.pushEmailQueue(currentEmailLoaded.value!); if (success.emailCurrent?.id == currentEmail?.id) { - attachments.value = success.attachments; + attachments.value = success.attachments ?? []; attachmentsViewState.value = { for (var attachment in attachments.where((item) => item.blobId != null)) attachment.blobId!: Right(IdleDownloadAttachmentForWeb()) }; - if (_canParseCalendarEvent(blobIds: success.attachments.calendarEventBlobIds)) { + if (_canParseCalendarEvent(blobIds: success.attachments?.calendarEventBlobIds ?? {})) { _parseCalendarEventAction( accountId: mailboxDashBoardController.accountId.value!, - blobIds: success.attachments.calendarEventBlobIds, + blobIds: success.attachments?.calendarEventBlobIds ?? {}, emailContents: success.htmlEmailContent ); } else { @@ -576,6 +579,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin { htmlEmailContent: success.htmlEmailContent, messageId: success.emailCurrent?.messageId, references: success.emailCurrent?.references, + inlineImages: success.inlineImages, ); _storeOpenedEmailAction( @@ -1342,6 +1346,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin { ComposerArguments.replyEmail( presentationEmail: presentationEmail, content: currentEmailLoaded.value?.htmlContent ?? '', + inlineImages: currentEmailLoaded.value?.inlineImages ?? [], mailboxRole: presentationEmail.mailboxContain?.role, messageId: currentEmailLoaded.value?.emailCurrent?.messageId, references: currentEmailLoaded.value?.emailCurrent?.references, @@ -1353,6 +1358,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin { ComposerArguments.replyAllEmail( presentationEmail: presentationEmail, content: currentEmailLoaded.value?.htmlContent ?? '', + inlineImages: currentEmailLoaded.value?.inlineImages ?? [], mailboxRole: presentationEmail.mailboxContain?.role, messageId: currentEmailLoaded.value?.emailCurrent?.messageId, references: currentEmailLoaded.value?.emailCurrent?.references, @@ -1365,6 +1371,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin { presentationEmail: presentationEmail, content: currentEmailLoaded.value?.htmlContent ?? '', attachments: attachments, + inlineImages: currentEmailLoaded.value?.inlineImages ?? [], messageId: currentEmailLoaded.value?.emailCurrent?.messageId, references: currentEmailLoaded.value?.emailCurrent?.references, ) diff --git a/lib/features/email/presentation/model/composer_arguments.dart b/lib/features/email/presentation/model/composer_arguments.dart index f93476023d..bb755d54d1 100644 --- a/lib/features/email/presentation/model/composer_arguments.dart +++ b/lib/features/email/presentation/model/composer_arguments.dart @@ -28,7 +28,7 @@ class ComposerArguments extends RouterArguments { final List? identities; final Identity? selectedIdentity; final List? inlineImages; - final bool? readRecepientEnabled; + final bool isRequestReadReceipt; final ScreenDisplayMode displayMode; ComposerArguments({ @@ -48,7 +48,7 @@ class ComposerArguments extends RouterArguments { this.identities, this.selectedIdentity, this.inlineImages, - this.readRecepientEnabled, + this.isRequestReadReceipt = false, this.displayMode = ScreenDisplayMode.normal }); @@ -95,26 +95,29 @@ class ComposerArguments extends RouterArguments { emailActionType: EmailActionType.reopenComposerBrowser, presentationEmail: composerCache.email?.toPresentationEmail(), emailContents: composerCache.email?.emailContentList.asHtmlString, - attachments: composerCache.email?.allAttachments - .where((attachment) => attachment.disposition != ContentDisposition.inline) - .toList(), + attachments: composerCache.email?.allAttachments.getListAttachmentsDisplayedOutside(composerCache.email?.htmlBodyAttachments ?? []), selectedIdentity: composerCache.identity, - inlineImages: composerCache.email?.attachmentsWithCid, - readRecepientEnabled: composerCache.readReceipentEnabled, + inlineImages: composerCache.email?.allAttachments.listAttachmentsDisplayedInContent, + isRequestReadReceipt: composerCache.isRequestReadReceipt, displayMode: composerCache.displayMode, ); - factory ComposerArguments.fromLocalStorageBrowser(Email email) => + factory ComposerArguments.fromLocalStorageBrowser(ComposerCache composerCache) => ComposerArguments( - emailActionType: EmailActionType.restoreComposedEmailFromLocalStorage, - presentationEmail: email.toPresentationEmail(), - attachments: email.allAttachments, - emailContents: email.emailContentList.asHtmlString, + emailActionType: EmailActionType.composeEmailIntoNewTab, + presentationEmail: composerCache.email?.toPresentationEmail(), + emailContents: composerCache.email?.emailContentList.asHtmlString, + attachments: composerCache.email?.allAttachments.getListAttachmentsDisplayedOutside(composerCache.email?.htmlBodyAttachments ?? []), + selectedIdentity: composerCache.identity, + inlineImages: composerCache.email?.allAttachments.listAttachmentsDisplayedInContent, + isRequestReadReceipt: composerCache.isRequestReadReceipt, + displayMode: composerCache.displayMode, ); factory ComposerArguments.replyEmail({ required PresentationEmail presentationEmail, required String content, + required List inlineImages, Role? mailboxRole, MessageIdsHeaderValue? messageId, MessageIdsHeaderValue? references, @@ -122,6 +125,7 @@ class ComposerArguments extends RouterArguments { emailActionType: EmailActionType.reply, presentationEmail: presentationEmail, emailContents: content, + inlineImages: inlineImages, mailboxRole: mailboxRole, messageId: messageId, references: references, @@ -130,6 +134,7 @@ class ComposerArguments extends RouterArguments { factory ComposerArguments.replyAllEmail({ required PresentationEmail presentationEmail, required String content, + required List inlineImages, Role? mailboxRole, MessageIdsHeaderValue? messageId, MessageIdsHeaderValue? references, @@ -137,6 +142,7 @@ class ComposerArguments extends RouterArguments { emailActionType: EmailActionType.replyAll, presentationEmail: presentationEmail, emailContents: content, + inlineImages: inlineImages, mailboxRole: mailboxRole, messageId: messageId, references: references, @@ -146,6 +152,7 @@ class ComposerArguments extends RouterArguments { required PresentationEmail presentationEmail, required String content, required List attachments, + required List inlineImages, MessageIdsHeaderValue? messageId, MessageIdsHeaderValue? references, }) => ComposerArguments( @@ -153,6 +160,7 @@ class ComposerArguments extends RouterArguments { presentationEmail: presentationEmail, emailContents: content, attachments: attachments, + inlineImages: inlineImages, mailboxRole: presentationEmail.mailboxContain?.role, messageId: messageId, references: references, @@ -211,7 +219,7 @@ class ComposerArguments extends RouterArguments { List? identities, Identity? selectedIdentity, List? inlineImages, - bool? readRecepientEnabled, + bool? isRequestReadReceipt, ScreenDisplayMode? displayMode, }) { return ComposerArguments( @@ -231,7 +239,7 @@ class ComposerArguments extends RouterArguments { identities: identities ?? this.identities, selectedIdentity: selectedIdentity ?? this.selectedIdentity, inlineImages: inlineImages ?? this.inlineImages, - readRecepientEnabled: readRecepientEnabled ?? this.readRecepientEnabled, + isRequestReadReceipt: isRequestReadReceipt ?? this.isRequestReadReceipt, displayMode: displayMode ?? this.displayMode, ); } diff --git a/lib/features/email/presentation/model/email_loaded.dart b/lib/features/email/presentation/model/email_loaded.dart index 948a684216..99886aef70 100644 --- a/lib/features/email/presentation/model/email_loaded.dart +++ b/lib/features/email/presentation/model/email_loaded.dart @@ -5,11 +5,13 @@ import 'package:model/email/attachment.dart'; class EmailLoaded with EquatableMixin { final String htmlContent; final List attachments; + final List inlineImages; final Email? emailCurrent; EmailLoaded({ required this.htmlContent, required this.attachments, + required this.inlineImages, this.emailCurrent, }); @@ -17,6 +19,7 @@ class EmailLoaded with EquatableMixin { List get props => [ htmlContent, attachments, + inlineImages, emailCurrent ]; } diff --git a/lib/features/mailbox_dashboard/data/datasource/local_storage_browser_datasource.dart b/lib/features/mailbox_dashboard/data/datasource/local_storage_browser_datasource.dart index 2a2427c82d..ef5f9bbef9 100644 --- a/lib/features/mailbox_dashboard/data/datasource/local_storage_browser_datasource.dart +++ b/lib/features/mailbox_dashboard/data/datasource/local_storage_browser_datasource.dart @@ -1,9 +1,3 @@ -import 'package:jmap_dart_client/jmap/mail/email/email.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource/storage_browser_datasource.dart'; -abstract class LocalStorageBrowserDatasource { - Future storeComposedEmail(Email email); - - Future getComposedEmail(); - - Future deleteComposedEmail(); -} \ No newline at end of file +abstract class LocalStorageBrowserDatasource extends StorageBrowserDatasource {} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/data/datasource/session_storage_composer_datasource.dart b/lib/features/mailbox_dashboard/data/datasource/session_storage_composer_datasource.dart index 1c36acf85d..b3b5b9553f 100644 --- a/lib/features/mailbox_dashboard/data/datasource/session_storage_composer_datasource.dart +++ b/lib/features/mailbox_dashboard/data/datasource/session_storage_composer_datasource.dart @@ -1,31 +1,3 @@ -import 'package:core/presentation/utils/html_transformer/transform_configuration.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/identities/identity.dart'; -import 'package:jmap_dart_client/jmap/mail/email/email.dart'; -import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/data/model/composer_cache.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource/storage_browser_datasource.dart'; -abstract class SessionStorageComposerDatasource { - Future saveComposerCacheOnWeb( - Email email, - { - required AccountId accountId, - required UserName userName, - required ScreenDisplayMode displayMode, - Identity? identity, - bool? readReceipentEnabled, - } - ); - - Future getComposerCacheOnWeb( - AccountId accountId, - UserName userName); - - Future removeComposerCacheOnWeb(); - - Future restoreEmailInlineImages( - String htmlContent, - TransformConfiguration transformConfiguration, - Map mapUrlDownloadCID); -} \ No newline at end of file +abstract class SessionStorageComposerDatasource extends StorageBrowserDatasource {} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/data/datasource/storage_browser_datasource.dart b/lib/features/mailbox_dashboard/data/datasource/storage_browser_datasource.dart new file mode 100644 index 0000000000..da50d6ff40 --- /dev/null +++ b/lib/features/mailbox_dashboard/data/datasource/storage_browser_datasource.dart @@ -0,0 +1,13 @@ +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/core/user_name.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/data/model/composer_cache.dart'; + +abstract class StorageBrowserDatasource { + String generateComposerCacheKey(AccountId accountId, UserName userName); + + Future saveComposerCache(ComposerCache composerCache, AccountId accountId, UserName userName); + + Future getComposerCache(AccountId accountId, UserName userName); + + Future deleteComposerCache(); +} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/data/datasource_impl/local_storage_browser_datasoure_impl.dart b/lib/features/mailbox_dashboard/data/datasource_impl/local_storage_browser_datasoure_impl.dart index 32c450a6db..35c58f5cca 100644 --- a/lib/features/mailbox_dashboard/data/datasource_impl/local_storage_browser_datasoure_impl.dart +++ b/lib/features/mailbox_dashboard/data/datasource_impl/local_storage_browser_datasoure_impl.dart @@ -1,45 +1,64 @@ import 'dart:convert'; + import 'package:collection/collection.dart'; -import 'package:jmap_dart_client/jmap/mail/email/email.dart'; -import 'package:model/extensions/email_extension.dart'; +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/core/user_name.dart'; +import 'package:model/email/email_action_type.dart'; +import 'package:model/extensions/account_id_extensions.dart'; +import 'package:tmail_ui_user/features/caching/utils/cache_utils.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource/local_storage_browser_datasource.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/domain/exceptions/local_storage_browser_exception.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/data/model/composer_cache.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/exceptions/storage_browser_exception.dart'; import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart'; import 'package:universal_html/html.dart' as html; class LocalStorageBrowserDatasourceImpl extends LocalStorageBrowserDatasource { - - static const String composedEmailLocalStorageKey = 'composed-email'; - final ExceptionThrower _exceptionThrower; LocalStorageBrowserDatasourceImpl(this._exceptionThrower); @override - Future storeComposedEmail(Email email) { + String generateComposerCacheKey(AccountId accountId, UserName userName) { + return TupleKey( + EmailActionType.composeEmailIntoNewTab.name, + accountId.asString, + userName.value).toString(); + } + + @override + Future deleteComposerCache() { return Future.sync(() async { - return html.window.localStorage.addAll({ - composedEmailLocalStorageKey: email.asString() - }); + return html.window.localStorage.removeWhere((key, value) => + key.startsWith(EmailActionType.composeEmailIntoNewTab.name)); }).catchError(_exceptionThrower.throwException); } @override - Future getComposedEmail() { + Future getComposerCache(AccountId accountId, UserName userName) { return Future.sync(() async { - final entry = html.window.localStorage.entries.firstWhereOrNull((e) => e.key == composedEmailLocalStorageKey); - if (entry != null) { - return Email.fromJson(jsonDecode(entry.value)); + final storageKey = generateComposerCacheKey(accountId, userName); + + final result = html.window.localStorage.entries + .firstWhereOrNull((entry) => entry.key == storageKey); + + if (result != null) { + return ComposerCache.fromJson(jsonDecode(result.value)); } else { - throw NotFoundLComposedEmailException(); + throw NotFoundDataInStorageBrowserException(); } }).catchError(_exceptionThrower.throwException); } @override - Future deleteComposedEmail() { + Future saveComposerCache(ComposerCache composerCache, AccountId accountId, UserName userName) { return Future.sync(() async { - return html.window.localStorage.remove(composedEmailLocalStorageKey); + final storageKey = generateComposerCacheKey(accountId, userName); + + Map entries = { + storageKey: jsonEncode(composerCache.toJson()) + }; + + return html.window.localStorage.addAll(entries); }).catchError(_exceptionThrower.throwException); } } diff --git a/lib/features/mailbox_dashboard/data/datasource_impl/session_storage_composer_datasoure_impl.dart b/lib/features/mailbox_dashboard/data/datasource_impl/session_storage_composer_datasoure_impl.dart index 9ff3d3c88b..8d2a214b55 100644 --- a/lib/features/mailbox_dashboard/data/datasource_impl/session_storage_composer_datasoure_impl.dart +++ b/lib/features/mailbox_dashboard/data/datasource_impl/session_storage_composer_datasoure_impl.dart @@ -1,94 +1,62 @@ import 'dart:convert'; import 'package:collection/collection.dart'; -import 'package:core/core.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/identities/identity.dart'; -import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:model/model.dart'; import 'package:tmail_ui_user/features/caching/utils/cache_utils.dart'; -import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource/session_storage_composer_datasource.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/data/model/composer_cache.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/exceptions/storage_browser_exception.dart'; import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart'; import 'package:universal_html/html.dart' as html; -class SessionStorageComposerDatasourceImpl - extends SessionStorageComposerDatasource { - SessionStorageComposerDatasourceImpl(this._htmlTransform, this._exceptionThrower); - - final HtmlTransform _htmlTransform; +class SessionStorageComposerDatasourceImpl extends SessionStorageComposerDatasource { final ExceptionThrower _exceptionThrower; + SessionStorageComposerDatasourceImpl(this._exceptionThrower); + @override - Future getComposerCacheOnWeb( - AccountId accountId, - UserName userName - ) async { - return Future.sync(() async { - final keyWithIdentity = TupleKey( + String generateComposerCacheKey(AccountId accountId, UserName userName) { + return TupleKey( EmailActionType.reopenComposerBrowser.name, accountId.asString, userName.value).toString(); - - final result = html.window.sessionStorage.entries.firstWhereOrNull( - (entry) => entry.key == keyWithIdentity); - if (result != null) { - return ComposerCache.fromJson(jsonDecode(result.value)); - } else { - throw NotFoundInWebSessionException(); - } - }).catchError(_exceptionThrower.throwException); } @override - Future removeComposerCacheOnWeb() async { - return Future.sync(() { - html.window.sessionStorage.removeWhere( - (key, value) => key.startsWith(EmailActionType.reopenComposerBrowser.name)); + Future deleteComposerCache() { + return Future.sync(() async { + return html.window.sessionStorage.removeWhere((key, value) => + key.startsWith(EmailActionType.reopenComposerBrowser.name)); }).catchError(_exceptionThrower.throwException); } @override - Future saveComposerCacheOnWeb( - Email email, - { - required AccountId accountId, - required UserName userName, - required ScreenDisplayMode displayMode, - Identity? identity, - bool? readReceipentEnabled - } - ) async { - return Future.sync(() { - final composerCacheKey = TupleKey( - EmailActionType.reopenComposerBrowser.name, - accountId.asString, - userName.value).toString(); - Map entries = { - composerCacheKey: jsonEncode( - ComposerCache( - displayMode: displayMode, - email: email, - identity: identity, - readReceipentEnabled: readReceipentEnabled, - ).toJson() - ) - }; - html.window.sessionStorage.addAll(entries); + Future getComposerCache(AccountId accountId, UserName userName) { + return Future.sync(() async { + final storageKey = generateComposerCacheKey(accountId, userName); + + final result = html.window.sessionStorage.entries + .firstWhereOrNull((entry) => entry.key == storageKey); + + if (result != null) { + return ComposerCache.fromJson(jsonDecode(result.value)); + } else { + throw NotFoundDataInStorageBrowserException(); + } }).catchError(_exceptionThrower.throwException); } - + @override - Future restoreEmailInlineImages( - String htmlContent, - TransformConfiguration transformConfiguration, - Map mapUrlDownloadCID) { + Future saveComposerCache(ComposerCache composerCache, AccountId accountId, UserName userName) { return Future.sync(() async { - return await _htmlTransform.transformToHtml( - htmlContent: htmlContent, - transformConfiguration: transformConfiguration, - mapCidImageDownloadUrl: mapUrlDownloadCID); + final storageKey = generateComposerCacheKey(accountId, userName); + + Map entries = { + storageKey: jsonEncode(composerCache.toJson()) + }; + + return html.window.sessionStorage.addAll(entries); }).catchError(_exceptionThrower.throwException); } } diff --git a/lib/features/mailbox_dashboard/data/model/composer_cache.dart b/lib/features/mailbox_dashboard/data/model/composer_cache.dart index 5eda2a6ba6..025b7c2e4f 100644 --- a/lib/features/mailbox_dashboard/data/model/composer_cache.dart +++ b/lib/features/mailbox_dashboard/data/model/composer_cache.dart @@ -1,44 +1,35 @@ import 'package:equatable/equatable.dart'; import 'package:jmap_dart_client/jmap/identities/identity.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; +import 'package:json_annotation/json_annotation.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.dart'; +part 'composer_cache.g.dart'; + +@JsonSerializable(explicitToJson: true, includeIfNull: false) class ComposerCache with EquatableMixin { final Email? email; final Identity? identity; - final bool? readReceipentEnabled; + final bool isRequestReadReceipt; final ScreenDisplayMode displayMode; ComposerCache({ - required this.displayMode, this.email, this.identity, - this.readReceipentEnabled, + this.isRequestReadReceipt = false, + this.displayMode = ScreenDisplayMode.normal, }); + factory ComposerCache.fromJson(Map json) => _$ComposerCacheFromJson(json); + + Map toJson() => _$ComposerCacheToJson(this); + @override List get props => [ email, identity, - readReceipentEnabled + isRequestReadReceipt, + displayMode ]; - - Map toJson() { - return { - 'email': email?.toJson(), - 'identity': identity?.toJson(), - 'readReceipentEnabled': readReceipentEnabled, - 'displayMode': displayMode.toJson() - }; - } - - factory ComposerCache.fromJson(Map map) { - return ComposerCache( - displayMode: ScreenDisplayMode.fromJson(map['displayMode'] ?? ''), - email: map['email'] != null ? Email.fromJson(map['email']) : null, - identity: map['identity'] != null ? Identity.fromJson(map['identity']) : null, - readReceipentEnabled: map['readReceipentEnabled'] as bool? - ); - } } diff --git a/lib/features/mailbox_dashboard/data/repository/composer_cache_repository_impl.dart b/lib/features/mailbox_dashboard/data/repository/composer_cache_repository_impl.dart index 9cd3cd6fd8..cf6a2507c6 100644 --- a/lib/features/mailbox_dashboard/data/repository/composer_cache_repository_impl.dart +++ b/lib/features/mailbox_dashboard/data/repository/composer_cache_repository_impl.dart @@ -1,9 +1,7 @@ import 'package:core/presentation/utils/html_transformer/transform_configuration.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/identities/identity.dart'; -import 'package:jmap_dart_client/jmap/mail/email/email.dart'; -import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.dart'; +import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource/local_storage_browser_datasource.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource/session_storage_composer_datasource.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/data/model/composer_cache.dart'; @@ -11,12 +9,14 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/compo class ComposerCacheRepositoryImpl extends ComposerCacheRepository { - final SessionStorageComposerDatasource composerCacheDataSource; + final SessionStorageComposerDatasource _sessionStorageComposerDatasource; final LocalStorageBrowserDatasource _localStorageBrowserDatasource; + final HtmlDataSource _htmlDataSource; ComposerCacheRepositoryImpl( - this.composerCacheDataSource, + this._sessionStorageComposerDatasource, this._localStorageBrowserDatasource, + this._htmlDataSource, ); @override @@ -24,57 +24,60 @@ class ComposerCacheRepositoryImpl extends ComposerCacheRepository { AccountId accountId, UserName userName ) { - return composerCacheDataSource.getComposerCacheOnWeb(accountId, userName); + return _sessionStorageComposerDatasource.getComposerCache(accountId, userName); } @override Future removeComposerCacheOnWeb() { - return composerCacheDataSource.removeComposerCacheOnWeb(); + return _sessionStorageComposerDatasource.deleteComposerCache(); } @override Future saveComposerCacheOnWeb( - Email email, - { - required AccountId accountId, - required UserName userName, - required ScreenDisplayMode displayMode, - Identity? identity, - bool? readReceipentEnabled - } + ComposerCache composerCache, + AccountId accountId, + UserName userName ) { - return composerCacheDataSource.saveComposerCacheOnWeb( - email, - accountId: accountId, - userName: userName, - displayMode: displayMode, - identity: identity, - readReceipentEnabled: readReceipentEnabled); + return _sessionStorageComposerDatasource.saveComposerCache( + composerCache, + accountId, + userName); } @override - Future restoreEmailInlineImages( + Future convertImageCIDToBase64( String htmlContent, TransformConfiguration transformConfiguration, - Map mapUrlDownloadCID) { - return composerCacheDataSource.restoreEmailInlineImages( + Map mapUrlDownloadCID + ) { + return _htmlDataSource.convertImageCIDToBase64( htmlContent, transformConfiguration, mapUrlDownloadCID); } @override - Future getComposedEmailFromLocalStorageBrowser() { - return _localStorageBrowserDatasource.getComposedEmail(); + Future deleteComposerCacheInLocalStorageBrowser() { + return _localStorageBrowserDatasource.deleteComposerCache(); } @override - Future storeComposedEmailToLocalStorageBrowser(Email email) { - return _localStorageBrowserDatasource.storeComposedEmail(email); + Future getComposerCacheInLocalStorageBrowser( + AccountId accountId, + UserName userName + ) { + return _localStorageBrowserDatasource.getComposerCache(accountId, userName); } @override - Future deleteComposedEmailOnLocalStorageBrowser() { - return _localStorageBrowserDatasource.deleteComposedEmail(); + Future saveComposerCacheToLocalStorageBrowser( + ComposerCache composerCache, + AccountId accountId, + UserName userName + ) { + return _localStorageBrowserDatasource.saveComposerCache( + composerCache, + accountId, + userName); } } \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/domain/exceptions/local_storage_browser_exception.dart b/lib/features/mailbox_dashboard/domain/exceptions/local_storage_browser_exception.dart deleted file mode 100644 index 01c4677184..0000000000 --- a/lib/features/mailbox_dashboard/domain/exceptions/local_storage_browser_exception.dart +++ /dev/null @@ -1,2 +0,0 @@ - -class NotFoundLComposedEmailException implements Exception {} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/domain/exceptions/storage_browser_exception.dart b/lib/features/mailbox_dashboard/domain/exceptions/storage_browser_exception.dart new file mode 100644 index 0000000000..567cd085a3 --- /dev/null +++ b/lib/features/mailbox_dashboard/domain/exceptions/storage_browser_exception.dart @@ -0,0 +1,2 @@ + +class NotFoundDataInStorageBrowserException implements Exception {} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/domain/repository/composer_cache_repository.dart b/lib/features/mailbox_dashboard/domain/repository/composer_cache_repository.dart index ab8e52d342..ee1963d4d9 100644 --- a/lib/features/mailbox_dashboard/domain/repository/composer_cache_repository.dart +++ b/lib/features/mailbox_dashboard/domain/repository/composer_cache_repository.dart @@ -1,22 +1,13 @@ import 'package:core/presentation/utils/html_transformer/transform_configuration.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/identities/identity.dart'; -import 'package:jmap_dart_client/jmap/mail/email/email.dart'; -import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/data/model/composer_cache.dart'; abstract class ComposerCacheRepository { Future saveComposerCacheOnWeb( - Email email, - { - required AccountId accountId, - required UserName userName, - required ScreenDisplayMode displayMode, - Identity? identity, - bool? readReceipentEnabled - } - ); + ComposerCache composerCache, + AccountId accountId, + UserName userName); Future getComposerCacheOnWeb( AccountId accountId, @@ -24,14 +15,19 @@ abstract class ComposerCacheRepository { Future removeComposerCacheOnWeb(); - Future restoreEmailInlineImages( + Future convertImageCIDToBase64( String htmlContent, TransformConfiguration transformConfiguration, Map mapUrlDownloadCID); - Future storeComposedEmailToLocalStorageBrowser(Email email); + Future saveComposerCacheToLocalStorageBrowser( + ComposerCache composerCache, + AccountId accountId, + UserName userName); - Future getComposedEmailFromLocalStorageBrowser(); + Future getComposerCacheInLocalStorageBrowser( + AccountId accountId, + UserName userName); - Future deleteComposedEmailOnLocalStorageBrowser(); + Future deleteComposerCacheInLocalStorageBrowser(); } diff --git a/lib/features/mailbox_dashboard/domain/state/delete_composed_email_on_local_storage_browser_state.dart b/lib/features/mailbox_dashboard/domain/state/delete_composed_email_on_local_storage_browser_state.dart deleted file mode 100644 index d04169aa35..0000000000 --- a/lib/features/mailbox_dashboard/domain/state/delete_composed_email_on_local_storage_browser_state.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:core/presentation/state/failure.dart'; -import 'package:core/presentation/state/success.dart'; - -class DeleteComposedEmailOnLocalStorageBrowserLoading extends LoadingState {} - -class DeleteComposedEmailOnLocalStorageBrowserSuccess extends UIState {} - -class DeleteComposedEmailOnLocalStorageBrowserFailure extends FeatureFailure { - - DeleteComposedEmailOnLocalStorageBrowserFailure(dynamic exception) : super(exception: exception); -} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/domain/state/delete_composer_cache_in_local_storage_browser_state.dart b/lib/features/mailbox_dashboard/domain/state/delete_composer_cache_in_local_storage_browser_state.dart new file mode 100644 index 0000000000..3bd0bdabbb --- /dev/null +++ b/lib/features/mailbox_dashboard/domain/state/delete_composer_cache_in_local_storage_browser_state.dart @@ -0,0 +1,11 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; + +class DeleteComposeCacheInLocalStorageBrowserLoading extends LoadingState {} + +class DeleteComposeCacheInLocalStorageBrowserSuccess extends UIState {} + +class DeleteComposeCacheInLocalStorageBrowserFailure extends FeatureFailure { + + DeleteComposeCacheInLocalStorageBrowserFailure(dynamic exception) : super(exception: exception); +} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/domain/state/get_composed_email_from_local_storage_browser_state.dart b/lib/features/mailbox_dashboard/domain/state/get_composed_email_from_local_storage_browser_state.dart deleted file mode 100644 index 08e99d52a8..0000000000 --- a/lib/features/mailbox_dashboard/domain/state/get_composed_email_from_local_storage_browser_state.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:core/presentation/state/failure.dart'; -import 'package:core/presentation/state/success.dart'; -import 'package:jmap_dart_client/jmap/mail/email/email.dart'; - -class GetComposedEmailFromLocalStorageBrowserLoading extends LoadingState {} - -class GetComposedEmailFromLocalStorageBrowserSuccess extends UIState { - - final Email email; - - GetComposedEmailFromLocalStorageBrowserSuccess(this.email); - - @override - List get props => [email]; -} - -class GetComposedEmailFromLocalStorageBrowserFailure extends FeatureFailure { - - GetComposedEmailFromLocalStorageBrowserFailure(dynamic exception) : super(exception: exception); -} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/domain/state/get_composer_cache_in_local_storage_browser_state.dart b/lib/features/mailbox_dashboard/domain/state/get_composer_cache_in_local_storage_browser_state.dart new file mode 100644 index 0000000000..0d97e45544 --- /dev/null +++ b/lib/features/mailbox_dashboard/domain/state/get_composer_cache_in_local_storage_browser_state.dart @@ -0,0 +1,20 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/data/model/composer_cache.dart'; + +class GetComposerCacheInLocalStorageBrowserLoading extends LoadingState {} + +class GetComposerCacheInLocalStorageBrowserSuccess extends UIState { + + final ComposerCache composerCache; + + GetComposerCacheInLocalStorageBrowserSuccess(this.composerCache); + + @override + List get props => [composerCache]; +} + +class GetComposerCacheInLocalStorageBrowserFailure extends FeatureFailure { + + GetComposerCacheInLocalStorageBrowserFailure(dynamic exception) : super(exception: exception); +} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/domain/state/save_composer_cache_to_local_storage_browser_state.dart b/lib/features/mailbox_dashboard/domain/state/save_composer_cache_to_local_storage_browser_state.dart new file mode 100644 index 0000000000..d5773dd15d --- /dev/null +++ b/lib/features/mailbox_dashboard/domain/state/save_composer_cache_to_local_storage_browser_state.dart @@ -0,0 +1,11 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; + +class SaveComposerCacheToLocalStorageBrowserLoading extends LoadingState {} + +class SaveComposerCacheToLocalStorageBrowserSuccess extends UIState {} + +class SaveComposerCacheToLocalStorageBrowserFailure extends FeatureFailure { + + SaveComposerCacheToLocalStorageBrowserFailure(dynamic exception) : super(exception: exception); +} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/domain/state/store_composed_email_to_local_storage_browser_state.dart b/lib/features/mailbox_dashboard/domain/state/store_composed_email_to_local_storage_browser_state.dart deleted file mode 100644 index 2ee1f01695..0000000000 --- a/lib/features/mailbox_dashboard/domain/state/store_composed_email_to_local_storage_browser_state.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:core/presentation/state/failure.dart'; -import 'package:core/presentation/state/success.dart'; - -class StoreComposedEmailToLocalStorageBrowserLoading extends LoadingState {} - -class StoreComposedEmailToLocalStorageBrowserSuccess extends UIState {} - -class StoreComposedEmailToLocalStorageBrowserFailure extends FeatureFailure { - - StoreComposedEmailToLocalStorageBrowserFailure(dynamic exception) : super(exception: exception); -} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/domain/usecases/delete_composed_email_on_local_storage_browser_interactor.dart b/lib/features/mailbox_dashboard/domain/usecases/delete_composed_email_on_local_storage_browser_interactor.dart deleted file mode 100644 index 20455c88fd..0000000000 --- a/lib/features/mailbox_dashboard/domain/usecases/delete_composed_email_on_local_storage_browser_interactor.dart +++ /dev/null @@ -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/composer_cache_repository.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/delete_composed_email_on_local_storage_browser_state.dart'; - -class DeleteComposedEmailOnLocalStorageBrowserInteractor { - final ComposerCacheRepository _composerCacheRepository; - - DeleteComposedEmailOnLocalStorageBrowserInteractor(this._composerCacheRepository); - - Stream> execute() async* { - try { - yield Right(DeleteComposedEmailOnLocalStorageBrowserLoading()); - await _composerCacheRepository.deleteComposedEmailOnLocalStorageBrowser(); - yield Right(DeleteComposedEmailOnLocalStorageBrowserSuccess()); - } catch (exception) { - yield Left(DeleteComposedEmailOnLocalStorageBrowserFailure(exception)); - } - } -} diff --git a/lib/features/mailbox_dashboard/domain/usecases/delete_composer_cache_in_local_storage_browser_interactor.dart b/lib/features/mailbox_dashboard/domain/usecases/delete_composer_cache_in_local_storage_browser_interactor.dart new file mode 100644 index 0000000000..86df892c1e --- /dev/null +++ b/lib/features/mailbox_dashboard/domain/usecases/delete_composer_cache_in_local_storage_browser_interactor.dart @@ -0,0 +1,21 @@ +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/composer_cache_repository.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/delete_composer_cache_in_local_storage_browser_state.dart'; + +class DeleteComposerCacheInLocalStorageBrowserInteractor { + final ComposerCacheRepository _composerCacheRepository; + + DeleteComposerCacheInLocalStorageBrowserInteractor(this._composerCacheRepository); + + Stream> execute() async* { + try { + yield Right(DeleteComposeCacheInLocalStorageBrowserLoading()); + await _composerCacheRepository.deleteComposerCacheInLocalStorageBrowser(); + yield Right(DeleteComposeCacheInLocalStorageBrowserSuccess()); + } catch (exception) { + yield Left(DeleteComposeCacheInLocalStorageBrowserFailure(exception)); + } + } +} diff --git a/lib/features/mailbox_dashboard/domain/usecases/get_composed_email_from_local_storage_browser_interactor.dart b/lib/features/mailbox_dashboard/domain/usecases/get_composed_email_from_local_storage_browser_interactor.dart deleted file mode 100644 index c8f8738fa5..0000000000 --- a/lib/features/mailbox_dashboard/domain/usecases/get_composed_email_from_local_storage_browser_interactor.dart +++ /dev/null @@ -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/composer_cache_repository.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_composed_email_from_local_storage_browser_state.dart'; - -class GetComposedEmailFromLocalStorageBrowserInteractor { - final ComposerCacheRepository _composerCacheRepository; - - GetComposedEmailFromLocalStorageBrowserInteractor(this._composerCacheRepository); - - Stream> execute() async* { - try { - yield Right(GetComposedEmailFromLocalStorageBrowserLoading()); - final email = await _composerCacheRepository.getComposedEmailFromLocalStorageBrowser(); - yield Right(GetComposedEmailFromLocalStorageBrowserSuccess(email)); - } catch (exception) { - yield Left(GetComposedEmailFromLocalStorageBrowserFailure(exception)); - } - } -} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/domain/usecases/get_composer_cache_in_local_storage_browser_interactor.dart b/lib/features/mailbox_dashboard/domain/usecases/get_composer_cache_in_local_storage_browser_interactor.dart new file mode 100644 index 0000000000..59e37afd3d --- /dev/null +++ b/lib/features/mailbox_dashboard/domain/usecases/get_composer_cache_in_local_storage_browser_interactor.dart @@ -0,0 +1,23 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/core/user_name.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/composer_cache_repository.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_composer_cache_in_local_storage_browser_state.dart'; + +class GetComposerCacheInLocalStorageBrowserInteractor { + final ComposerCacheRepository _composerCacheRepository; + + GetComposerCacheInLocalStorageBrowserInteractor(this._composerCacheRepository); + + Stream> execute(AccountId accountId, UserName userName) async* { + try { + yield Right(GetComposerCacheInLocalStorageBrowserLoading()); + final composerCache = await _composerCacheRepository.getComposerCacheInLocalStorageBrowser(accountId, userName); + yield Right(GetComposerCacheInLocalStorageBrowserSuccess(composerCache)); + } catch (exception) { + yield Left(GetComposerCacheInLocalStorageBrowserFailure(exception)); + } + } +} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/domain/usecases/save_composer_cache_to_local_storage_browser_interactor.dart b/lib/features/mailbox_dashboard/domain/usecases/save_composer_cache_to_local_storage_browser_interactor.dart new file mode 100644 index 0000000000..be727f2268 --- /dev/null +++ b/lib/features/mailbox_dashboard/domain/usecases/save_composer_cache_to_local_storage_browser_interactor.dart @@ -0,0 +1,46 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/core/user_name.dart'; +import 'package:tmail_ui_user/features/composer/domain/repository/composer_repository.dart'; +import 'package:tmail_ui_user/features/composer/presentation/model/create_email_request.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/data/model/composer_cache.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/composer_cache_repository.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/save_composer_cache_to_local_storage_browser_state.dart'; + +class SaveComposerCacheToLocalStorageBrowserInteractor { + final ComposerCacheRepository _composerCacheRepository; + final ComposerRepository _composerRepository; + + SaveComposerCacheToLocalStorageBrowserInteractor( + this._composerCacheRepository, + this._composerRepository, + ); + + Stream> execute( + CreateEmailRequest createEmailRequest, + AccountId accountId, + UserName userName, + ) async* { + try { + yield Right(SaveComposerCacheToLocalStorageBrowserLoading()); + + final emailCreated = await _composerRepository.generateEmail(createEmailRequest); + final composerCache = ComposerCache( + email: emailCreated, + identity: createEmailRequest.identity, + isRequestReadReceipt: createEmailRequest.isRequestReadReceipt, + displayMode: createEmailRequest.displayMode); + + await _composerCacheRepository.saveComposerCacheToLocalStorageBrowser( + composerCache, + accountId, + userName); + + yield Right(SaveComposerCacheToLocalStorageBrowserSuccess()); + } catch (exception) { + yield Left(SaveComposerCacheToLocalStorageBrowserFailure(exception)); + } + } +} diff --git a/lib/features/mailbox_dashboard/domain/usecases/store_composed_email_to_local_storage_browser_interactor.dart b/lib/features/mailbox_dashboard/domain/usecases/store_composed_email_to_local_storage_browser_interactor.dart deleted file mode 100644 index 0fa39fa83a..0000000000 --- a/lib/features/mailbox_dashboard/domain/usecases/store_composed_email_to_local_storage_browser_interactor.dart +++ /dev/null @@ -1,28 +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/composer/domain/repository/composer_repository.dart'; -import 'package:tmail_ui_user/features/composer/presentation/model/create_email_request.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/composer_cache_repository.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/store_composed_email_to_local_storage_browser_state.dart'; - -class StoreComposedEmailToLocalStorageBrowserInteractor { - final ComposerCacheRepository _composerCacheRepository; - final ComposerRepository _composerRepository; - - StoreComposedEmailToLocalStorageBrowserInteractor( - this._composerCacheRepository, - this._composerRepository, - ); - - Stream> execute(CreateEmailRequest createEmailRequest) async* { - try { - yield Right(StoreComposedEmailToLocalStorageBrowserLoading()); - final emailCreated = await _composerRepository.generateEmail(createEmailRequest); - await _composerCacheRepository.storeComposedEmailToLocalStorageBrowser(emailCreated); - yield Right(StoreComposedEmailToLocalStorageBrowserSuccess()); - } catch (exception) { - yield Left(StoreComposedEmailToLocalStorageBrowserFailure(exception)); - } - } -} diff --git a/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart b/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart index 006a799718..90d8f75762 100644 --- a/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart +++ b/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart @@ -1,6 +1,5 @@ import 'package:core/data/model/source_type/data_source_type.dart'; import 'package:core/presentation/resources/image_paths.dart'; -import 'package:core/presentation/utils/html_transformer/html_transform.dart'; import 'package:core/utils/config/app_config_loader.dart'; import 'package:core/utils/file_utils.dart'; import 'package:core/utils/print_utils.dart'; @@ -63,9 +62,10 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/data/repository/spam_re import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/composer_cache_repository.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/search_repository.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/spam_report_repository.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/delete_composed_email_on_local_storage_browser_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/delete_composer_cache_in_local_storage_browser_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_all_recent_search_latest_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_app_dashboard_configuration_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_composer_cache_in_local_storage_browser_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_composer_cache_on_web_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_spam_mailbox_cached_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_spam_report_state_interactor.dart'; @@ -73,7 +73,6 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_unr import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/quick_search_email_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_composer_cache_on_web_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_email_drafts_interactor.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_composed_email_from_local_storage_browser_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/save_recent_search_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_last_time_dismissed_spam_reported_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_spam_report_state_interactor.dart'; @@ -182,8 +181,8 @@ class MailboxDashBoardBindings extends BaseBindings { Get.find(), Get.find(), Get.find(), - Get.find(), - Get.find(), + Get.find(), + Get.find(), )); Get.put(AdvancedFilterController()); } @@ -240,10 +239,7 @@ class MailboxDashBoardBindings extends BaseBindings { Get.lazyPut(() => MailboxCacheDataSourceImpl( Get.find(), Get.find())); - Get.lazyPut(() => SessionStorageComposerDatasourceImpl( - Get.find(), - Get.find())); - Get.lazyPut(() => SessionStorageComposerDatasourceImpl()); + Get.lazyPut(() => SessionStorageComposerDatasourceImpl(Get.find())); Get.lazyPut(() => LocalStorageBrowserDatasourceImpl(Get.find())); Get.lazyPut(() => SpamReportDataSourceImpl( Get.find(), @@ -293,8 +289,8 @@ class MailboxDashBoardBindings extends BaseBindings { Get.find()) ); Get.lazyPut(() => GetComposerCacheOnWebInteractor(Get.find())); - Get.lazyPut(() => GetComposedEmailFromLocalStorageBrowserInteractor(Get.find())); - Get.lazyPut(() => DeleteComposedEmailOnLocalStorageBrowserInteractor(Get.find())); + Get.lazyPut(() => GetComposerCacheInLocalStorageBrowserInteractor(Get.find())); + Get.lazyPut(() => DeleteComposerCacheInLocalStorageBrowserInteractor(Get.find())); Get.lazyPut(() => RemoveComposerCacheOnWebInteractor(Get.find())); Get.lazyPut(() => MarkAsEmailReadInteractor( Get.find(), @@ -401,6 +397,7 @@ class MailboxDashBoardBindings extends BaseBindings { Get.lazyPut(() => ComposerCacheRepositoryImpl( Get.find(), Get.find(), + Get.find(), )); Get.lazyPut(() => SpamReportRepositoryImpl( { diff --git a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart index 8ffa948820..932b48c75a 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart @@ -79,14 +79,14 @@ import 'package:tmail_ui_user/features/mailbox/presentation/extensions/presentat import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/spam_report_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_app_dashboard_configuration_state.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_composer_cache_in_local_storage_browser_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_composer_cache_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/remove_email_drafts_state.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_composed_email_from_local_storage_browser_state.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/delete_composed_email_on_local_storage_browser_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/delete_composer_cache_in_local_storage_browser_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_composer_cache_in_local_storage_browser_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_composer_cache_on_web_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_composer_cache_on_web_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_email_drafts_interactor.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_composed_email_from_local_storage_browser_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/dashboard_action.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/app_grid_dashboard_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/download/download_controller.dart'; @@ -192,8 +192,8 @@ class MailboxDashBoardController extends ReloadableController { final GetRestoredDeletedMessageInterator _getRestoredDeletedMessageInteractor; final RemoveComposerCacheOnWebInteractor _removeComposerCacheOnWebInteractor; final GetAllIdentitiesInteractor _getAllIdentitiesInteractor; - final GetComposedEmailFromLocalStorageBrowserInteractor _getComposedEmailFromLocalStorageBrowserInteractor; - final DeleteComposedEmailOnLocalStorageBrowserInteractor _deleteComposedEmailOnLocalStorageBrowserInteractor; + final GetComposerCacheInLocalStorageBrowserInteractor _getComposerCacheInLocalStorageBrowserInteractor; + final DeleteComposerCacheInLocalStorageBrowserInteractor _deleteComposerCacheInLocalStorageBrowserInteractor; GetAllVacationInteractor? _getAllVacationInteractor; UpdateVacationInteractor? _updateVacationInteractor; @@ -274,8 +274,8 @@ class MailboxDashBoardController extends ReloadableController { this._getRestoredDeletedMessageInteractor, this._removeComposerCacheOnWebInteractor, this._getAllIdentitiesInteractor, - this._getComposedEmailFromLocalStorageBrowserInteractor, - this._deleteComposedEmailOnLocalStorageBrowserInteractor, + this._getComposerCacheInLocalStorageBrowserInteractor, + this._deleteComposerCacheInLocalStorageBrowserInteractor, ); @override @@ -380,9 +380,9 @@ class MailboxDashBoardController extends ReloadableController { _handleGetAllIdentitiesSuccess(success); } else if (success is GetComposerCacheSuccess) { goToComposer(ComposerArguments.fromSessionStorageBrowser(success.composerCache)); - } else if (success is GetComposedEmailFromLocalStorageBrowserSuccess) { - goToComposer(ComposerArguments.fromLocalStorageBrowser(success.email)); - _deleteComposedEmailOnLocalStorageBrowser(); + } else if (success is GetComposerCacheInLocalStorageBrowserSuccess) { + goToComposer(ComposerArguments.fromLocalStorageBrowser(success.composerCache)); + _deleteComposerCacheInLocalStorageBrowser(); } } @@ -407,8 +407,8 @@ class MailboxDashBoardController extends ReloadableController { _handleRestoreDeletedMessageFailed(); } else if (failure is GetRestoredDeletedMessageFailure) { _handleRestoreDeletedMessageFailed(); - } else if (failure is GetComposedEmailFromLocalStorageBrowserFailure) { - _deleteComposedEmailOnLocalStorageBrowser(); + } else if (failure is GetComposerCacheInLocalStorageBrowserFailure) { + _deleteComposerCacheInLocalStorageBrowser(); } } @@ -1310,7 +1310,7 @@ class MailboxDashBoardController extends ReloadableController { _setUpComponentsFromSession(session); if (PlatformInfo.isWeb) { _handleComposerCache(); - _restoreComposedEmailFromLocalStorageBrowser(); + _restoreComposerCacheInLocalStorageBrowser(session); } } @@ -2562,12 +2562,14 @@ class MailboxDashBoardController extends ReloadableController { List get listIdentities => _identities ?? []; - void _restoreComposedEmailFromLocalStorageBrowser() { - consumeState(_getComposedEmailFromLocalStorageBrowserInteractor.execute()); + void _restoreComposerCacheInLocalStorageBrowser(Session session) { + consumeState(_getComposerCacheInLocalStorageBrowserInteractor.execute( + session.personalAccount.accountId, + session.username)); } - void _deleteComposedEmailOnLocalStorageBrowser() { - consumeState(_deleteComposedEmailOnLocalStorageBrowserInteractor.execute()); + void _deleteComposerCacheInLocalStorageBrowser() { + consumeState(_deleteComposerCacheInLocalStorageBrowserInteractor.execute()); } @override diff --git a/lib/features/offline_mode/model/detailed_email_hive_cache.dart b/lib/features/offline_mode/model/detailed_email_hive_cache.dart index f15f266db6..0eefebec65 100644 --- a/lib/features/offline_mode/model/detailed_email_hive_cache.dart +++ b/lib/features/offline_mode/model/detailed_email_hive_cache.dart @@ -35,6 +35,9 @@ class DetailedEmailHiveCache extends HiveObject with EquatableMixin { @HiveField(7) final List? references; + @HiveField(8) + final List? inlineImages; + DetailedEmailHiveCache({ required this.emailId, required this.timeSaved, @@ -44,6 +47,7 @@ class DetailedEmailHiveCache extends HiveObject with EquatableMixin { this.keywords, this.messageId, this.references, + this.inlineImages, }); @override @@ -56,5 +60,6 @@ class DetailedEmailHiveCache extends HiveObject with EquatableMixin { keywords, messageId, references, + inlineImages, ]; } \ No newline at end of file diff --git a/lib/features/upload/presentation/controller/upload_controller.dart b/lib/features/upload/presentation/controller/upload_controller.dart index ee62b3f3b0..057ccacff1 100644 --- a/lib/features/upload/presentation/controller/upload_controller.dart +++ b/lib/features/upload/presentation/controller/upload_controller.dart @@ -427,18 +427,6 @@ class UploadController extends BaseController { uploadInlineViewState.value = Right(UIState.idle); } - List get inlineAttachmentsUploaded { - if (_uploadingStateInlineFiles.uploadingStateFiles.isEmpty) { - return List.empty(); - } - return _uploadingStateInlineFiles.uploadingStateFiles - .whereNotNull() - .map((fileState) => fileState.attachment) - .whereNotNull() - .where((attachment) => attachment.cid != null) - .toList(); - } - List get inlineAttachmentsPicked { if (_uploadingStateInlineFiles.uploadingStateFiles.isEmpty) { return List.empty(); diff --git a/model/lib/email/email_action_type.dart b/model/lib/email/email_action_type.dart index 473aa4a3ff..65e83de4d5 100644 --- a/model/lib/email/email_action_type.dart +++ b/model/lib/email/email_action_type.dart @@ -29,5 +29,5 @@ enum EmailActionType { archiveMessage, printAll, downloadMessageAsEML, - restoreComposedEmailFromLocalStorage + composeEmailIntoNewTab } \ No newline at end of file diff --git a/model/lib/extensions/email_extension.dart b/model/lib/extensions/email_extension.dart index 7b7707abde..2a1a9cf519 100644 --- a/model/lib/extensions/email_extension.dart +++ b/model/lib/extensions/email_extension.dart @@ -151,8 +151,6 @@ extension EmailExtension on Email { List get allAttachments => attachments?.map((item) => item.toAttachment()).toList() ?? []; - List get attachmentsWithCid => allAttachments.where((attachment) => attachment.hasCid()).toList(); - PresentationMailbox? findMailboxContain(Map mapMailbox) { final newMailboxIds = mailboxIds; newMailboxIds?.removeWhere((key, value) => !value); diff --git a/model/lib/extensions/list_attachment_extension.dart b/model/lib/extensions/list_attachment_extension.dart index e8f788170a..d67cc6a67f 100644 --- a/model/lib/extensions/list_attachment_extension.dart +++ b/model/lib/extensions/list_attachment_extension.dart @@ -33,7 +33,7 @@ extension ListAttachmentExtension on List { required String downloadUrl }) { final mapUrlDownloadCID = { - for (var attachment in listAttachmentsDisplayedInContent) + for (var attachment in this) attachment.cid! : attachment.getDownloadUrl(downloadUrl, accountId) }; return mapUrlDownloadCID; diff --git a/test/features/composer/presentation/composer_controller_test.dart b/test/features/composer/presentation/composer_controller_test.dart index 099bf9a0d7..9758c186fc 100644 --- a/test/features/composer/presentation/composer_controller_test.dart +++ b/test/features/composer/presentation/composer_controller_test.dart @@ -7,6 +7,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:get/get.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; +import 'package:tmail_ui_user/features/base/before_unload_manager.dart'; import 'package:tmail_ui_user/features/base/state/button_state.dart'; import 'package:tmail_ui_user/features/caching/caching_manager.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/create_new_and_save_email_to_drafts_interactor.dart'; @@ -21,7 +22,7 @@ import 'package:tmail_ui_user/features/login/data/network/interceptors/authoriza import 'package:tmail_ui_user/features/login/domain/usecases/delete_authority_oidc_interactor.dart'; import 'package:tmail_ui_user/features/login/domain/usecases/delete_credential_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_composer_cache_on_web_interactor.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_composed_email_to_local_storage_browser_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/save_composer_cache_to_local_storage_browser_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; import 'package:tmail_ui_user/features/manage_account/data/local/language_cache_manager.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart'; @@ -57,7 +58,7 @@ const fallbackGenerators = { MockSpec(), MockSpec(), MockSpec(), - MockSpec(), + MockSpec(), MockSpec(fallbackGenerators: fallbackGenerators), MockSpec(fallbackGenerators: fallbackGenerators), MockSpec(), @@ -72,6 +73,7 @@ const fallbackGenerators = { MockSpec(), MockSpec(), MockSpec(), + MockSpec(), ]) void main() { TestWidgetsFlutterBinding.ensureInitialized(); @@ -89,7 +91,7 @@ void main() { late MockGetAlwaysReadReceiptSettingInteractor mockGetAlwaysReadReceiptSettingInteractor; late MockCreateNewAndSendEmailInteractor mockCreateNewAndSendEmailInteractor; late MockCreateNewAndSaveEmailToDraftsInteractor mockCreateNewAndSaveEmailToDraftsInteractor; - late MockStoreComposedEmailToLocalStorageBrowserInteractor mockStoreComposedEmailToLocalStorageBrowserInteractor; + late MockSaveComposerCacheToLocalStorageBrowserInteractor mockSaveComposerCacheToLocalStorageBrowserInteractor; late MockNetworkConnectionController mockNetworkConnectionController; late MockMailboxDashBoardController mockMailboxDashBoardController; @@ -106,6 +108,7 @@ void main() { late MockResponsiveUtils mockResponsiveUtils; late MockUuid mockUuid; late MockApplicationManager mockApplicationManager; + late MockBeforeUnloadManager mockBeforeUnloadManager; setUpAll(() { mockLocalFilePickerInteractor = MockLocalFilePickerInteractor(); @@ -120,7 +123,7 @@ void main() { mockGetAlwaysReadReceiptSettingInteractor = MockGetAlwaysReadReceiptSettingInteractor(); mockCreateNewAndSendEmailInteractor = MockCreateNewAndSendEmailInteractor(); mockCreateNewAndSaveEmailToDraftsInteractor = MockCreateNewAndSaveEmailToDraftsInteractor(); - mockStoreComposedEmailToLocalStorageBrowserInteractor = MockStoreComposedEmailToLocalStorageBrowserInteractor(); + mockSaveComposerCacheToLocalStorageBrowserInteractor = MockSaveComposerCacheToLocalStorageBrowserInteractor(); mockNetworkConnectionController = MockNetworkConnectionController(); mockMailboxDashBoardController = MockMailboxDashBoardController(); @@ -138,6 +141,7 @@ void main() { mockResponsiveUtils = MockResponsiveUtils(); mockUuid = MockUuid(); mockApplicationManager = MockApplicationManager(); + mockBeforeUnloadManager = MockBeforeUnloadManager(); Get.put(mockNetworkConnectionController); Get.put(mockMailboxDashBoardController); @@ -158,7 +162,8 @@ void main() { Get.put(mockResponsiveUtils); Get.put(mockUuid); Get.put(mockApplicationManager); - + Get.put(mockBeforeUnloadManager); + Get.testMode = true; composerController = ComposerController( @@ -174,7 +179,7 @@ void main() { mockGetAlwaysReadReceiptSettingInteractor, mockCreateNewAndSendEmailInteractor, mockCreateNewAndSaveEmailToDraftsInteractor, - mockStoreComposedEmailToLocalStorageBrowserInteractor, + mockSaveComposerCacheToLocalStorageBrowserInteractor, ); }); @@ -193,10 +198,10 @@ void main() { // Act composerController.onOpenNewTabAction(); - await untilCalled(mockStoreComposedEmailToLocalStorageBrowserInteractor.execute(any)); + await untilCalled(mockSaveComposerCacheToLocalStorageBrowserInteractor.execute(any, any, any)); // Assert - verify(mockStoreComposedEmailToLocalStorageBrowserInteractor.execute(any)).called(1); + verify(mockSaveComposerCacheToLocalStorageBrowserInteractor.execute(any, any, any)).called(1); }); }); diff --git a/test/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller_test.dart b/test/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller_test.dart index 24d41107aa..a419f26def 100644 --- a/test/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller_test.dart +++ b/test/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller_test.dart @@ -48,13 +48,13 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_multipl import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_controller.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_builder.dart'; import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/delete_composed_email_on_local_storage_browser_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/delete_composer_cache_in_local_storage_browser_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_all_recent_search_latest_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_composer_cache_in_local_storage_browser_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_composer_cache_on_web_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/quick_search_email_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_composer_cache_on_web_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_email_drafts_interactor.dart'; -import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_composed_email_from_local_storage_browser_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/save_recent_search_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/advanced_filter_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/app_grid_dashboard_controller.dart'; @@ -171,8 +171,8 @@ const fallbackGenerators = { MockSpec(), MockSpec(), MockSpec(), - MockSpec(), - MockSpec(), + MockSpec(), + MockSpec(), ]) void main() { // mock mailbox dashboard controller direct dependencies @@ -254,8 +254,8 @@ void main() { final refreshAllMailboxInteractor = MockRefreshAllMailboxInteractor(); final removeComposerCacheOnWebInteractor = MockRemoveComposerCacheOnWebInteractor(); final getAllIdentitiesInteractor = MockGetAllIdentitiesInteractor(); - final getComposedEmailFromLocalStorageBrowserInteractor = MockGetComposedEmailFromLocalStorageBrowserInteractor(); - final deleteComposedEmailOnLocalStorageBrowserInteractor = MockDeleteComposedEmailOnLocalStorageBrowserInteractor(); + final getComposedEmailFromLocalStorageBrowserInteractor = MockGetComposerCacheInLocalStorageBrowserInteractor(); + final deleteComposerCacheInLocalStorageBrowserInteractor = MockDeleteComposerCacheInLocalStorageBrowserInteractor(); late MailboxController mailboxController; // mock thread controller direct dependencies @@ -308,8 +308,8 @@ void main() { Get.put(updateAuthenticationAccountInteractor); Get.put(getAllIdentitiesInteractor); Get.put(removeComposerCacheOnWebInteractor); - Get.put(getComposedEmailFromLocalStorageBrowserInteractor); - Get.put(deleteComposedEmailOnLocalStorageBrowserInteractor); + Get.put(getComposedEmailFromLocalStorageBrowserInteractor); + Get.put(deleteComposerCacheInLocalStorageBrowserInteractor); Get.testMode = true; @@ -349,7 +349,7 @@ void main() { removeComposerCacheOnWebInteractor, getAllIdentitiesInteractor, getComposedEmailFromLocalStorageBrowserInteractor, - deleteComposedEmailOnLocalStorageBrowserInteractor, + deleteComposerCacheInLocalStorageBrowserInteractor, ); Get.put(mailboxDashboardController); mailboxDashboardController.onReady();