From 0d77789c5fcf496295900368ff205bf4d202f866 Mon Sep 17 00:00:00 2001 From: dab246 Date: Tue, 21 Mar 2023 18:27:48 +0700 Subject: [PATCH] TF-1626 Remove `id` of email when call `Email/set` method (cherry picked from commit ce1d27d893fd406aa812d4e4ea9debe1ec265ddb) --- .../presentation/composer_controller.dart | 14 ++++--- .../email/data/network/email_api.dart | 34 ++++++++------- .../controller/single_email_controller.dart | 16 +++---- .../mailbox_dashboard_controller.dart | 25 ++++++----- .../listener/email_change_listener.dart | 2 +- .../extensions/email_cache_extension.dart | 2 +- .../data/extensions/email_extension.dart | 2 +- .../data/network/thread_isolate_worker.dart | 13 +++--- .../repository/thread_repository_impl.dart | 4 +- .../mixin/email_action_controller.dart | 12 +++--- .../presentation/thread_controller.dart | 4 +- .../bindings/network/network_bindings.dart | 5 ++- .../network/network_isolate_binding.dart | 5 ++- model/lib/email/presentation_email.dart | 42 +++++++++---------- model/lib/extensions/email_extension.dart | 6 +-- .../lib/extensions/list_email_extension.dart | 3 ++ .../list_presentation_email_extension.dart | 13 ++++-- .../presentation_email_extension.dart | 14 +++---- test/fixtures/email_fixtures.dart | 10 ++--- 19 files changed, 120 insertions(+), 106 deletions(-) diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart index d687d7f03..31a23c648 100644 --- a/lib/features/composer/presentation/composer_controller.dart +++ b/lib/features/composer/presentation/composer_controller.dart @@ -638,11 +638,9 @@ class ComposerController extends BaseController { mapKeywords[KeyWordIdentifier.emailSeen] = true; } - final generateEmailId = EmailId(Id(_uuid.v1())); final generatePartId = PartId(_uuid.v1()); return Email( - generateEmailId, mailboxIds: mailboxIds.isNotEmpty ? mailboxIds : null, from: listFromEmailAddress, to: listToEmailAddress.toSet(), @@ -988,12 +986,16 @@ class ComposerController extends BaseController { draftMailboxId: draftMailboxId); final oldEmail = arguments.presentationEmail; - if (arguments.emailActionType == EmailActionType.edit && oldEmail != null) { + if (arguments.emailActionType == EmailActionType.edit && oldEmail != null && oldEmail.id != null) { mailboxDashBoardController.consumeState( - _updateEmailDraftsInteractor.execute(accountId, newEmail, oldEmail.id)); + _updateEmailDraftsInteractor.execute( + accountId, + newEmail, + oldEmail.id! + ) + ); } else { - mailboxDashBoardController.consumeState( - _saveEmailAsDraftsInteractor.execute(accountId, newEmail)); + mailboxDashBoardController.consumeState(_saveEmailAsDraftsInteractor.execute(accountId, newEmail)); } uploadController.clearInlineFileUploaded(); diff --git a/lib/features/email/data/network/email_api.dart b/lib/features/email/data/network/email_api.dart index e3579aa9e..7fcb95e85 100644 --- a/lib/features/email/data/network/email_api.dart +++ b/lib/features/email/data/network/email_api.dart @@ -41,6 +41,7 @@ import 'package:model/email/mark_star_action.dart'; import 'package:model/email/read_actions.dart'; import 'package:model/extensions/email_extension.dart'; import 'package:model/extensions/keyword_identifier_extension.dart'; +import 'package:model/extensions/list_email_extension.dart'; import 'package:model/extensions/list_email_id_extension.dart'; import 'package:model/extensions/mailbox_id_extension.dart'; import 'package:model/extensions/session_extension.dart'; @@ -54,14 +55,16 @@ import 'package:tmail_ui_user/features/email/domain/state/download_attachment_fo import 'package:tmail_ui_user/features/login/domain/exceptions/authentication_exception.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart'; import 'package:tmail_ui_user/main/error/capability_validator.dart'; +import 'package:uuid/uuid.dart'; class EmailAPI with HandleSetErrorMixin { final HttpClient _httpClient; final DownloadManager _downloadManager; final DioClient _dioClient; + final Uuid _uuid; - EmailAPI(this._httpClient, this._downloadManager, this._dioClient); + EmailAPI(this._httpClient, this._downloadManager, this._dioClient, this._uuid); Future getEmailContent(AccountId accountId, EmailId emailId) async { final processingInvocation = ProcessingInvocation(); @@ -129,8 +132,9 @@ class EmailAPI with HandleSetErrorMixin { emailNeedsToBeCreated = emailRequest.email; } + final idCreateMethod = Id(_uuid.v1()); final setEmailMethod = SetEmailMethod(accountId) - ..addCreate(emailNeedsToBeCreated.id.id, emailNeedsToBeCreated); + ..addCreate(idCreateMethod, emailNeedsToBeCreated); if (emailRequest.emailIdDestroyed != null) { setEmailMethod.addDestroy({emailRequest.emailIdDestroyed!.id}); @@ -142,7 +146,7 @@ class EmailAPI with HandleSetErrorMixin { emailRequest.submissionCreateId, EmailSubmission( identityId: emailRequest.identity?.id?.id, - emailId: EmailId(ReferenceId(ReferencePrefix.defaultPrefix, emailNeedsToBeCreated.id.id)), + emailId: EmailId(ReferenceId(ReferencePrefix.defaultPrefix, idCreateMethod)), envelope: Envelope( Address(emailNeedsToBeCreated.from?.first.email ?? ''), emailNeedsToBeCreated.getRecipientEmailAddressList().map((emailAddress) => Address(emailAddress)).toSet() @@ -173,7 +177,7 @@ class EmailAPI with HandleSetErrorMixin { SetEmailSubmissionResponse.deserialize, methodName: setEmailInvocation.methodName); - final emailCreated = setEmailResponse?.created?[emailNeedsToBeCreated.id.id]; + final emailCreated = setEmailResponse?.created?[idCreateMethod]; final listEntriesErrors = _handleSetEmailResponse( response: setEmailResponse, submissionResponse: setEmailSubmissionResponse @@ -218,13 +222,11 @@ class EmailAPI with HandleSetErrorMixin { } Future> markAsRead(AccountId accountId, List emails, ReadActions readActions) async { - final emailIds = emails.map((email) => email.id).toList(); - final setEmailMethod = SetEmailMethod(accountId) - ..addUpdates(emailIds.generateMapUpdateObjectMarkAsRead(readActions)); + ..addUpdates(emails.listEmailIds.generateMapUpdateObjectMarkAsRead(readActions)); final getEmailMethod = GetEmailMethod(accountId) - ..addIds(emailIds.toIds().toSet()) + ..addIds(emails.listEmailIds.toIds().toSet()) ..addProperties(Properties({'keywords'})); final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation()); @@ -406,13 +408,11 @@ class EmailAPI with HandleSetErrorMixin { Future> markAsStar(AccountId accountId, List emails, MarkStarAction markStarAction) async { - final emailIds = emails.map((email) => email.id).toList(); - final setEmailMethod = SetEmailMethod(accountId) - ..addUpdates(emailIds.generateMapUpdateObjectMarkAsStar(markStarAction)); + ..addUpdates(emails.listEmailIds.generateMapUpdateObjectMarkAsStar(markStarAction)); final getEmailMethod = GetEmailMethod(accountId) - ..addIds(emailIds.toIds().toSet()) + ..addIds(emails.listEmailIds.toIds().toSet()) ..addProperties(Properties({'keywords'})); final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation()); @@ -438,8 +438,9 @@ class EmailAPI with HandleSetErrorMixin { } Future saveEmailAsDrafts(AccountId accountId, Email email) async { + final idCreateMethod = Id(_uuid.v1()); final setEmailMethod = SetEmailMethod(accountId) - ..addCreate(email.id.id, email); + ..addCreate(idCreateMethod, email); final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation()); @@ -455,7 +456,7 @@ class EmailAPI with HandleSetErrorMixin { SetEmailResponse.deserialize ); - final emailCreated = setEmailResponse?.created?[email.id.id]; + final emailCreated = setEmailResponse?.created?[idCreateMethod]; final listEntriesErrors = _handleSetEmailResponse(response: setEmailResponse); final mapErrors = Map.fromEntries(listEntriesErrors); @@ -491,8 +492,9 @@ class EmailAPI with HandleSetErrorMixin { } Future updateEmailDrafts(AccountId accountId, Email newEmail, EmailId oldEmailId) async { + final idCreateMethod = Id(_uuid.v1()); final setEmailMethod = SetEmailMethod(accountId) - ..addCreate(newEmail.id.id, newEmail) + ..addCreate(idCreateMethod, newEmail) ..addDestroy({oldEmailId.id}); final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation()); @@ -509,7 +511,7 @@ class EmailAPI with HandleSetErrorMixin { SetEmailResponse.deserialize ); - final emailUpdated = setEmailResponse?.created?[newEmail.id.id]; + final emailUpdated = setEmailResponse?.created?[idCreateMethod]; final isEmailDestroyedSuccess = setEmailResponse?.destroyed?.contains(oldEmailId.id) ?? false; final listEntriesErrors = _handleSetEmailResponse(response: setEmailResponse); final mapErrors = Map.fromEntries(listEntriesErrors); diff --git a/lib/features/email/presentation/controller/single_email_controller.dart b/lib/features/email/presentation/controller/single_email_controller.dart index f19ab5c1c..9f8ae0ac7 100644 --- a/lib/features/email/presentation/controller/single_email_controller.dart +++ b/lib/features/email/presentation/controller/single_email_controller.dart @@ -170,9 +170,9 @@ class SingleEmailController extends BaseController with AppLoaderMixin { _resetToOriginalValue(); if (isListEmailContainSelectedEmail(selectedEmail)) { - _createMultipleEmailViewAsPageView(selectedEmail.id); + _createMultipleEmailViewAsPageView(selectedEmail.id!); } else { - _createSingleEmailView(selectedEmail.id); + _createSingleEmailView(selectedEmail.id!); } if (!selectedEmail.hasRead) { @@ -663,21 +663,21 @@ class SingleEmailController extends BaseController with AppLoaderMixin { ) { if (destinationMailbox.isTrash) { _moveToTrashAction(context, accountId, MoveToMailboxRequest( - {currentMailbox.id: [emailSelected.id]}, + {currentMailbox.id: [emailSelected.id!]}, destinationMailbox.id, MoveAction.moving, session, EmailActionType.moveToTrash)); } else if (destinationMailbox.isSpam) { _moveToSpamAction(context, accountId, MoveToMailboxRequest( - {currentMailbox.id: [emailSelected.id]}, + {currentMailbox.id: [emailSelected.id!]}, destinationMailbox.id, MoveAction.moving, session, EmailActionType.moveToSpam)); } else { _moveToMailbox(context, accountId, MoveToMailboxRequest( - {currentMailbox.id: [emailSelected.id]}, + {currentMailbox.id: [emailSelected.id!]}, destinationMailbox.id, MoveAction.moving, session, @@ -729,7 +729,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin { if (accountId != null && currentMailbox != null && trashMailboxId != null) { _moveToTrashAction(context, accountId, MoveToMailboxRequest( - {currentMailbox.id: [email.id]}, + {currentMailbox.id: [email.id!]}, trashMailboxId, MoveAction.moving, mailboxDashBoardController.sessionCurrent!, @@ -750,7 +750,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin { if (accountId != null && currentMailbox != null && spamMailboxId != null) { _moveToSpamAction(context, accountId, MoveToMailboxRequest( - {currentMailbox.id: [email.id]}, + {currentMailbox.id: [email.id!]}, spamMailboxId, MoveAction.moving, mailboxDashBoardController.sessionCurrent!, @@ -766,7 +766,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin { if (accountId != null && spamMailboxId != null && inboxMailboxId != null) { _moveToSpamAction(context, accountId, MoveToMailboxRequest( - {spamMailboxId: [email.id]}, + {spamMailboxId: [email.id!]}, inboxMailboxId, MoveAction.moving, mailboxDashBoardController.sessionCurrent!, 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 b7d70b0f1..0a6be2e44 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart @@ -235,7 +235,7 @@ class MailboxDashBoardController extends ReloadableController { final ComposerArguments composerArguments = ComposerArguments( emailActionType: EmailActionType.edit, presentationEmail: PresentationEmail( - success.composerCache.id, + id: success.composerCache.id, subject: success.composerCache.subject, from: success.composerCache.from, to: success.composerCache.to, @@ -519,7 +519,7 @@ class MailboxDashBoardController extends ReloadableController { dispatchRoute(DashboardRoutes.emailDetailed); if (BuildUtils.isWeb && presentationEmail.routeWeb != null) { RouteUtils.updateRouteOnBrowser( - 'Email-${presentationEmail.id.id.value}', + 'Email-${presentationEmail.id?.id.value ?? ''}', presentationEmail.routeWeb! ); } @@ -628,15 +628,15 @@ class MailboxDashBoardController extends ReloadableController { void _discardEmail(Email email) { final currentAccountId = accountId.value; - if (currentAccountId != null) { - consumeState(_removeEmailDraftsInteractor.execute(currentAccountId, email.id)); + if (currentAccountId != null && email.id != null) { + consumeState(_removeEmailDraftsInteractor.execute(currentAccountId, email.id!)); } } void deleteEmailPermanently(PresentationEmail email) { final currentAccountId = accountId.value; - if (currentAccountId != null) { - consumeState(_deleteEmailPermanentlyInteractor.execute(currentAccountId, email.id)); + if (currentAccountId != null && email.id != null) { + consumeState(_deleteEmailPermanentlyInteractor.execute(currentAccountId, email.id!)); } } @@ -825,22 +825,21 @@ class MailboxDashBoardController extends ReloadableController { List listEmails, PresentationMailbox destinationMailbox, ) { - if(searchController.isSearchEmailRunning){ + if (searchController.isSearchEmailRunning){ final Map> mapListEmailSelectedByMailBoxId = {}; for (var element in listEmails) { final mailbox = element.findMailboxContain(mapMailboxById); - if(mailbox != null) { - if(mapListEmailSelectedByMailBoxId.containsKey(mailbox.id)) { - mapListEmailSelectedByMailBoxId[mailbox.id]?.add(element.id); + if (mailbox != null && element.id != null) { + if (mapListEmailSelectedByMailBoxId.containsKey(mailbox.id)) { + mapListEmailSelectedByMailBoxId[mailbox.id]?.add(element.id!); } else { - mapListEmailSelectedByMailBoxId.addAll({mailbox.id: [element.id]}); + mapListEmailSelectedByMailBoxId.addAll({mailbox.id: [element.id!]}); } } } _handleDragSelectedMultipleEmailToMailboxAction(mapListEmailSelectedByMailBoxId, destinationMailbox); - } else { - if(selectedMailbox.value != null) { + if (selectedMailbox.value != null) { _handleDragSelectedMultipleEmailToMailboxAction({selectedMailbox.value!.id: listEmails.listEmailIds}, destinationMailbox); } } diff --git a/lib/features/push_notification/presentation/listener/email_change_listener.dart b/lib/features/push_notification/presentation/listener/email_change_listener.dart index 0ba5def29..253e34993 100644 --- a/lib/features/push_notification/presentation/listener/email_change_listener.dart +++ b/lib/features/push_notification/presentation/listener/email_change_listener.dart @@ -136,7 +136,7 @@ class EmailChangeListener extends ChangeListener { final notificationPayload = NotificationPayload(emailId: presentationEmail.id); log('EmailChangeListener::_showLocalNotification():notificationPayload: $notificationPayload'); LocalNotificationManager.instance.showPushNotification( - id: presentationEmail.id.id.value, + id: presentationEmail.id?.id.value ?? '', title: presentationEmail.subject ?? '', message: presentationEmail.preview, emailAddress: presentationEmail.from?.first, diff --git a/lib/features/thread/data/extensions/email_cache_extension.dart b/lib/features/thread/data/extensions/email_cache_extension.dart index 83ba6ce7a..914f57612 100644 --- a/lib/features/thread/data/extensions/email_cache_extension.dart +++ b/lib/features/thread/data/extensions/email_cache_extension.dart @@ -13,7 +13,7 @@ import 'package:tmail_ui_user/features/thread/data/extensions/email_address_hive extension EmailCacheExtension on EmailCache { Email toEmail() { return Email( - EmailId(Id(id)), + id: EmailId(Id(id)), keywords: keywords != null ? Map.fromIterables(keywords!.keys.map((value) => KeyWordIdentifier(value)), keywords!.values) : null, diff --git a/lib/features/thread/data/extensions/email_extension.dart b/lib/features/thread/data/extensions/email_extension.dart index f5a295399..304c6eeba 100644 --- a/lib/features/thread/data/extensions/email_extension.dart +++ b/lib/features/thread/data/extensions/email_extension.dart @@ -8,7 +8,7 @@ extension EmailExtension on Email { EmailCache toEmailCache() { return EmailCache( - id.id.value, + id!.id.value, keywords: keywords?.toMapString(), size: size?.value.round(), receivedAt: receivedAt?.value, diff --git a/lib/features/thread/data/network/thread_isolate_worker.dart b/lib/features/thread/data/network/thread_isolate_worker.dart index 56faa37ee..26b9f92e6 100644 --- a/lib/features/thread/data/network/thread_isolate_worker.dart +++ b/lib/features/thread/data/network/thread_isolate_worker.dart @@ -11,6 +11,7 @@ import 'package:jmap_dart_client/jmap/mail/email/email_comparator_property.dart' import 'package:jmap_dart_client/jmap/mail/email/email_filter_condition.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:model/email/email_property.dart'; +import 'package:model/extensions/list_email_extension.dart'; import 'package:tmail_ui_user/features/email/data/network/email_api.dart'; import 'package:tmail_ui_user/features/thread/data/model/empty_trash_folder_arguments.dart'; import 'package:tmail_ui_user/features/thread/data/network/thread_api.dart'; @@ -68,11 +69,9 @@ class ThreadIsolateWorker { if (newEmailList.isNotEmpty) { lastEmail = newEmailList.last; hasEmails = true; - final emailIds = newEmailList.map((email) => email.id).toList(); + final listEmailIdDeleted = await args.emailAPI.deleteMultipleEmailsPermanently(args.accountId, newEmailList.listEmailIds); - final listEmailIdDeleted = await args.emailAPI.deleteMultipleEmailsPermanently(args.accountId, emailIds); - - if (listEmailIdDeleted.isNotEmpty && listEmailIdDeleted.length == emailIds.length) { + if (listEmailIdDeleted.isNotEmpty && listEmailIdDeleted.length == newEmailList.listEmailIds.length) { sendPort.send(listEmailIdDeleted); } emailListCompleted.addAll(listEmailIdDeleted); @@ -117,11 +116,9 @@ class ThreadIsolateWorker { if (newEmailList.isNotEmpty) { lastEmail = newEmailList.last; hasEmails = true; - final emailIds = newEmailList.map((email) => email.id).toList(); + final listEmailIdDeleted = await _emailAPI.deleteMultipleEmailsPermanently(accountId, newEmailList.listEmailIds); - final listEmailIdDeleted = await _emailAPI.deleteMultipleEmailsPermanently(accountId, emailIds); - - if (listEmailIdDeleted.isNotEmpty && listEmailIdDeleted.length == emailIds.length) { + if (listEmailIdDeleted.isNotEmpty && listEmailIdDeleted.length == newEmailList.listEmailIds.length) { await updateDestroyedEmailCache(listEmailIdDeleted); } emailListCompleted.addAll(listEmailIdDeleted); diff --git a/lib/features/thread/data/repository/thread_repository_impl.dart b/lib/features/thread/data/repository/thread_repository_impl.dart index 7c3404142..79ca91efe 100644 --- a/lib/features/thread/data/repository/thread_repository_impl.dart +++ b/lib/features/thread/data/repository/thread_repository_impl.dart @@ -157,7 +157,9 @@ class ThreadRepositoryImpl extends ThreadRepository { } dartz.Tuple2 _combineUpdatedWithEmailInCache(Email updatedEmail, List? emailCacheList) { - final emailOld = emailCacheList?.findEmailById(updatedEmail.id); + final emailOld = updatedEmail.id != null + ? emailCacheList?.findEmailById(updatedEmail.id!) + : null; if (emailOld != null) { log('ThreadRepositoryImpl::_combineUpdatedWithEmailInCache(): cache hit'); return dartz.Tuple2(updatedEmail, emailOld); diff --git a/lib/features/thread/presentation/mixin/email_action_controller.dart b/lib/features/thread/presentation/mixin/email_action_controller.dart index df91e3cca..b3d233784 100644 --- a/lib/features/thread/presentation/mixin/email_action_controller.dart +++ b/lib/features/thread/presentation/mixin/email_action_controller.dart @@ -56,7 +56,7 @@ mixin EmailActionController on ViewAsDialogActionMixin { if (mailboxContain != null && accountId != null && trashMailboxId != null) { _moveToTrashAction(accountId, MoveToMailboxRequest( - {mailboxContain.id: [email.id]}, + {mailboxContain.id: email.id != null ? [email.id!] : []}, trashMailboxId, MoveAction.moving, mailboxDashBoardController.sessionCurrent!, @@ -75,7 +75,7 @@ mixin EmailActionController on ViewAsDialogActionMixin { if (mailboxContain != null && accountId != null && spamMailboxId != null) { moveToSpamAction(accountId, MoveToMailboxRequest( - {mailboxContain.id: [email.id]}, + {mailboxContain.id: email.id != null ? [email.id!] : []}, spamMailboxId, MoveAction.moving, mailboxDashBoardController.sessionCurrent!, @@ -91,7 +91,7 @@ mixin EmailActionController on ViewAsDialogActionMixin { if (inboxMailboxId != null && accountId != null && spamMailboxId != null) { moveToSpamAction(accountId, MoveToMailboxRequest( - {spamMailboxId: [email.id]}, + {spamMailboxId: email.id != null ? [email.id!] : []}, inboxMailboxId, MoveAction.moving, mailboxDashBoardController.sessionCurrent!, @@ -161,21 +161,21 @@ mixin EmailActionController on ViewAsDialogActionMixin { ) { if (destinationMailbox.isTrash) { moveToSpamAction(accountId, MoveToMailboxRequest( - {currentMailbox.id: [emailSelected.id]}, + {currentMailbox.id: emailSelected.id != null ? [emailSelected.id!] : []}, destinationMailbox.id, MoveAction.moving, session, EmailActionType.moveToTrash)); } else if (destinationMailbox.isSpam) { moveToSpamAction(accountId, MoveToMailboxRequest( - {currentMailbox.id: [emailSelected.id]}, + {currentMailbox.id: emailSelected.id != null ? [emailSelected.id!] : []}, destinationMailbox.id, MoveAction.moving, session, EmailActionType.moveToSpam)); } else { _moveToMailboxAction(accountId, MoveToMailboxRequest( - {currentMailbox.id: [emailSelected.id]}, + {currentMailbox.id: emailSelected.id != null ? [emailSelected.id!] : []}, destinationMailbox.id, MoveAction.moving, session, diff --git a/lib/features/thread/presentation/thread_controller.dart b/lib/features/thread/presentation/thread_controller.dart index de4f923e5..fe9a7964d 100644 --- a/lib/features/thread/presentation/thread_controller.dart +++ b/lib/features/thread/presentation/thread_controller.dart @@ -887,8 +887,8 @@ class ThreadController extends BaseController with EmailActionController { } void calculateDragValue(PresentationEmail? currentPresentationEmail) { - if(currentPresentationEmail != null) { - if(mailboxDashBoardController.listEmailSelected.findEmail(currentPresentationEmail.id) != null){ + if (currentPresentationEmail != null) { + if (currentPresentationEmail.id != null && mailboxDashBoardController.listEmailSelected.findEmail(currentPresentationEmail.id!) != null){ listEmailDrag.clear(); listEmailDrag.addAll(mailboxDashBoardController.listEmailSelected); } else { diff --git a/lib/main/bindings/network/network_bindings.dart b/lib/main/bindings/network/network_bindings.dart index c7110e766..0bff9870f 100644 --- a/lib/main/bindings/network/network_bindings.dart +++ b/lib/main/bindings/network/network_bindings.dart @@ -27,6 +27,7 @@ import 'package:tmail_ui_user/features/quotas/data/network/quotas_api.dart'; import 'package:tmail_ui_user/features/session/data/network/session_api.dart'; import 'package:tmail_ui_user/features/thread/data/network/thread_api.dart'; import 'package:tmail_ui_user/main/exceptions/remote_exception_thrower.dart'; +import 'package:uuid/uuid.dart'; class NetworkBindings extends Bindings { @@ -82,7 +83,9 @@ class NetworkBindings extends Bindings { Get.put(EmailAPI( Get.find(), Get.find(), - Get.find())); + Get.find(), + Get.find(), + )); Get.put(RuleFilterAPI(Get.find())); Get.put(VacationAPI(Get.find())); Get.put(ContactAPI(Get.find())); diff --git a/lib/main/bindings/network/network_isolate_binding.dart b/lib/main/bindings/network/network_isolate_binding.dart index d251ef138..256354ced 100644 --- a/lib/main/bindings/network/network_isolate_binding.dart +++ b/lib/main/bindings/network/network_isolate_binding.dart @@ -12,6 +12,7 @@ import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_isolate_work import 'package:tmail_ui_user/features/thread/data/network/thread_api.dart'; import 'package:tmail_ui_user/features/thread/data/network/thread_isolate_worker.dart'; import 'package:tmail_ui_user/main/bindings/network/binding_tag.dart'; +import 'package:uuid/uuid.dart'; import 'package:worker_manager/worker_manager.dart'; class NetworkIsolateBindings extends Bindings { @@ -51,7 +52,9 @@ class NetworkIsolateBindings extends Bindings { Get.put(EmailAPI( httpClient, Get.find(tag: BindingTag.isolateTag), - Get.find(tag: BindingTag.isolateTag)), tag: BindingTag.isolateTag); + Get.find(tag: BindingTag.isolateTag), + Get.find() + ), tag: BindingTag.isolateTag); } void _bindingIsolateWorker() { diff --git a/model/lib/email/presentation_email.dart b/model/lib/email/presentation_email.dart index 126e3a108..6b2f0b67c 100644 --- a/model/lib/email/presentation_email.dart +++ b/model/lib/email/presentation_email.dart @@ -13,7 +13,7 @@ import 'package:model/mailbox/select_mode.dart'; class PresentationEmail with EquatableMixin { - final EmailId id; + final EmailId? id; final Map? keywords; final UnsignedInt? size; final UTCDate? receivedAt; @@ -32,28 +32,26 @@ class PresentationEmail with EquatableMixin { final Uri? routeWeb; final PresentationMailbox? mailboxContain; - PresentationEmail( + PresentationEmail({ this.id, - { - this.keywords, - this.size, - this.receivedAt, - this.hasAttachment, - this.preview, - this.subject, - this.sentAt, - this.from, - this.to, - this.cc, - this.bcc, - this.replyTo, - this.mailboxIds, - this.mailboxNames, - this.selectMode = SelectMode.INACTIVE, - this.routeWeb, - this.mailboxContain - } - ); + this.keywords, + this.size, + this.receivedAt, + this.hasAttachment, + this.preview, + this.subject, + this.sentAt, + this.from, + this.to, + this.cc, + this.bcc, + this.replyTo, + this.mailboxIds, + this.mailboxNames, + this.selectMode = SelectMode.INACTIVE, + this.routeWeb, + this.mailboxContain + }); String getSenderName() { if (from?.isNotEmpty == true) { diff --git a/model/lib/extensions/email_extension.dart b/model/lib/extensions/email_extension.dart index f525f561a..a91cc8408 100644 --- a/model/lib/extensions/email_extension.dart +++ b/model/lib/extensions/email_extension.dart @@ -34,7 +34,7 @@ extension EmailExtension on Email { Email updatedEmail({Map? newKeywords, Map? newMailboxIds}) { return Email( - id, + id: id, keywords: newKeywords ?? keywords, size: size, receivedAt: receivedAt, @@ -57,7 +57,7 @@ extension EmailExtension on Email { PresentationEmail toPresentationEmail({SelectMode selectMode = SelectMode.INACTIVE}) { return PresentationEmail( - id, + id: id, keywords: keywords, size: size, receivedAt: receivedAt, @@ -77,7 +77,7 @@ extension EmailExtension on Email { Email combineEmail(Email newEmail, Properties updatedProperties) { return Email( - newEmail.id, + id: newEmail.id, keywords: updatedProperties.contain(EmailProperty.keywords) ? newEmail.keywords : keywords, size: updatedProperties.contain(EmailProperty.size) ? newEmail.size : size, receivedAt: updatedProperties.contain(EmailProperty.receivedAt) ? newEmail.receivedAt : receivedAt, diff --git a/model/lib/extensions/list_email_extension.dart b/model/lib/extensions/list_email_extension.dart index f0bd55d5e..a4a609e48 100644 --- a/model/lib/extensions/list_email_extension.dart +++ b/model/lib/extensions/list_email_extension.dart @@ -1,4 +1,5 @@ +import 'package:collection/collection.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/core/sort/comparator.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_comparator_property.dart'; @@ -8,6 +9,8 @@ import 'package:jmap_dart_client/jmap/core/extensions/unsigned_int_extension.dar extension ListEmailExtension on List { + List get listEmailIds => map((email) => email.id).whereNotNull().toList(); + Email? findEmailById(EmailId emailId) { try { return firstWhere((email) => email.id == emailId); diff --git a/model/lib/extensions/list_presentation_email_extension.dart b/model/lib/extensions/list_presentation_email_extension.dart index 4cac4d68b..7ea74e274 100644 --- a/model/lib/extensions/list_presentation_email_extension.dart +++ b/model/lib/extensions/list_presentation_email_extension.dart @@ -1,4 +1,5 @@ +import 'package:collection/collection.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:model/model.dart'; @@ -18,7 +19,7 @@ extension ListPresentationEmailExtension on List { return where((email) => email.selectMode == SelectMode.ACTIVE).toList(); } - List get listEmailIds => map((email) => email.id).toList(); + List get listEmailIds => map((email) => email.id).whereNotNull().toList(); bool isAllCanDeletePermanently(Map mapMailbox) { final listMailboxContain = map((email) => email.findMailboxContain(mapMailbox)) @@ -88,9 +89,13 @@ extension ListPresentationEmailExtension on List { List combine(List listEmailBefore) { return map((presentationEmail) { - final emailBefore = listEmailBefore.findEmail(presentationEmail.id); - if (emailBefore != null) { - return presentationEmail.toSelectedEmail(selectMode: emailBefore.selectMode); + if (presentationEmail.id != null) { + final emailBefore = listEmailBefore.findEmail(presentationEmail.id!); + if (emailBefore != null) { + return presentationEmail.toSelectedEmail(selectMode: emailBefore.selectMode); + } else { + return presentationEmail; + } } else { return presentationEmail; } diff --git a/model/lib/extensions/presentation_email_extension.dart b/model/lib/extensions/presentation_email_extension.dart index 857626eed..80750d7c7 100644 --- a/model/lib/extensions/presentation_email_extension.dart +++ b/model/lib/extensions/presentation_email_extension.dart @@ -35,7 +35,7 @@ extension PresentationEmailExtension on PresentationEmail { PresentationEmail toggleSelect() { return PresentationEmail( - this.id, + id: this.id, keywords: keywords, size: size, receivedAt: receivedAt, @@ -58,7 +58,7 @@ extension PresentationEmailExtension on PresentationEmail { PresentationEmail toSelectedEmail({required SelectMode selectMode}) { return PresentationEmail( - this.id, + id: this.id, keywords: keywords, size: size, receivedAt: receivedAt, @@ -81,7 +81,7 @@ extension PresentationEmailExtension on PresentationEmail { Email toEmail() { return Email( - this.id, + id: this.id, keywords: keywords, size: size, receivedAt: receivedAt, @@ -141,7 +141,7 @@ extension PresentationEmailExtension on PresentationEmail { .toList(); return PresentationEmail( - this.id, + id: this.id, keywords: keywords, size: size, receivedAt: receivedAt, @@ -177,7 +177,7 @@ extension PresentationEmailExtension on PresentationEmail { PresentationEmail withRouteWeb(Uri routeWeb) { return PresentationEmail( - this.id, + id: this.id, keywords: keywords, size: size, receivedAt: receivedAt, @@ -200,7 +200,7 @@ extension PresentationEmailExtension on PresentationEmail { PresentationEmail updateKeywords(Map? newKeywords) { return PresentationEmail( - this.id, + id: this.id, keywords: newKeywords, size: size, receivedAt: receivedAt, @@ -223,7 +223,7 @@ extension PresentationEmailExtension on PresentationEmail { PresentationEmail syncPresentationEmail({PresentationMailbox? mailboxContain, Uri? routeWeb}) { return PresentationEmail( - this.id, + id: this.id, keywords: keywords, size: size, receivedAt: receivedAt, diff --git a/test/fixtures/email_fixtures.dart b/test/fixtures/email_fixtures.dart index 401418a40..41e0d10df 100644 --- a/test/fixtures/email_fixtures.dart +++ b/test/fixtures/email_fixtures.dart @@ -8,7 +8,7 @@ import 'mailbox_fixtures.dart'; class EmailFixtures { static final email1 = Email( - EmailId(Id("382312d0-fa5c-11eb-b647-2fef1ee78d9e")), + id: EmailId(Id("382312d0-fa5c-11eb-b647-2fef1ee78d9e")), preview: "Dear QA,I attached image here", hasAttachment: false, subject: "test inline image", @@ -21,7 +21,7 @@ class EmailFixtures { ); static final email2 = Email( - EmailId(Id("bc8a5320-fa58-11eb-b647-2fef1ee78d9e")), + id: EmailId(Id("bc8a5320-fa58-11eb-b647-2fef1ee78d9e")), preview: "This event is about to begin Noti check TimeFriday 23 October 2020 12:00 - 12:30 Europe/Paris (See in Calendar)Location1 thai ha (See in Map)Attendees - User A (Organizer) - Lê Nguyễn - User C (Organizer) - User A Resourc", hasAttachment: false, subject: "Notification: Recurrencr", @@ -46,7 +46,7 @@ class EmailFixtures { ); static final email4 = Email( - EmailId(Id("d9b3b880-fa6f-11eb-b647-2fef1ee78d9e")), + id: EmailId(Id("d9b3b880-fa6f-11eb-b647-2fef1ee78d9e")), preview: "alo -- desktop signature", hasAttachment: true, subject: "test attachment", @@ -59,7 +59,7 @@ class EmailFixtures { ); static final email5 = Email( - EmailId(Id("637f1ef0-fa5d-11eb-b647-2fef1ee78d9e")), + id: EmailId(Id("637f1ef0-fa5d-11eb-b647-2fef1ee78d9e")), preview: "Dear, test inline Thanks and BRs-- desktop signature", hasAttachment: false, subject: "test inline image",