From 69e771573404ae6e72859f5f4116d47c20f1406d Mon Sep 17 00:00:00 2001 From: dab246 Date: Wed, 19 Oct 2022 21:16:04 +0700 Subject: [PATCH] TF-657 Implement send receipt to sender --- ios/Podfile.lock | 2 +- lib/features/base/base_controller.dart | 11 ++ .../presentation/composer_controller.dart | 2 +- .../email/data/network/email_api.dart | 13 +- .../email/presentation/email_bindings.dart | 4 + .../email/presentation/email_controller.dart | 168 +++++++++++++++++- .../presentation/mdn_interactor_bindings.dart | 36 ++++ lib/l10n/intl_messages.arb | 50 +++++- .../bindings/network/network_bindings.dart | 2 + lib/main/localizations/app_localizations.dart | 38 ++++ model/lib/extensions/email_extension.dart | 20 ++- 11 files changed, 337 insertions(+), 9 deletions(-) create mode 100644 lib/features/email/presentation/mdn_interactor_bindings.dart diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e02083e49..3ef56b7bf 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -246,4 +246,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 91efd4097cc41f032416d67ecaac21cc2de8dd55 -COCOAPODS: 1.11.2 +COCOAPODS: 1.11.3 diff --git a/lib/features/base/base_controller.dart b/lib/features/base/base_controller.dart index 8825cf611..839fee1df 100644 --- a/lib/features/base/base_controller.dart +++ b/lib/features/base/base_controller.dart @@ -3,9 +3,11 @@ import 'package:core/core.dart'; import 'package:dartz/dartz.dart'; import 'package:get/get.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart'; import 'package:jmap_dart_client/jmap/core/session/session.dart'; import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_mixin.dart'; import 'package:tmail_ui_user/features/base/mixin/popup_context_menu_action_mixin.dart'; +import 'package:tmail_ui_user/features/email/presentation/mdn_interactor_bindings.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/bindings/contact_autocomplete_bindings.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/bindings/tmail_autocomplete_bindings.dart'; import 'package:tmail_ui_user/main/error/capability_validator.dart'; @@ -72,4 +74,13 @@ abstract class BaseController extends GetxController with MessageDialogActionMix logError('BaseController::injectAutoCompleteBindings(): exception: $e'); } } + + void injectMdnBindings(Session? session, AccountId? accountId) { + try { + requireCapability(session!, accountId!, [CapabilityIdentifier.jmapMdn]); + MdnInteractorBindings().dependencies(); + } catch(e) { + logError('ReloadableController::injectVacationBindings(): exception: $e'); + } + } } \ No newline at end of file diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart index caf1ca4f3..9dba8b6a0 100644 --- a/lib/features/composer/presentation/composer_controller.dart +++ b/lib/features/composer/presentation/composer_controller.dart @@ -1037,7 +1037,7 @@ class ComposerController extends BaseController { if(arguments.emailContents != null && arguments.emailContents!.isNotEmpty) { _emailContents = arguments.emailContents; - emailContentsViewState.value = Right(GetEmailContentSuccess(_emailContents!, [], [], false)); + emailContentsViewState.value = Right(GetEmailContentSuccess(_emailContents!, [], [], null)); } else { final baseDownloadUrl = mailboxDashBoardController.sessionCurrent?.getDownloadUrl(); final accountId = mailboxDashBoardController.sessionCurrent?.accounts.keys.first; diff --git a/lib/features/email/data/network/email_api.dart b/lib/features/email/data/network/email_api.dart index f41e32f0c..68e08862d 100644 --- a/lib/features/email/data/network/email_api.dart +++ b/lib/features/email/data/network/email_api.dart @@ -27,7 +27,18 @@ import 'package:jmap_dart_client/jmap/mail/email/submission/envelope.dart'; import 'package:jmap_dart_client/jmap/mail/email/submission/set/set_email_submission_method.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/set/set_mailbox_method.dart'; -import 'package:model/model.dart'; +import 'package:model/account/account_request.dart'; +import 'package:model/account/authentication_type.dart'; +import 'package:model/download/download_task_id.dart'; +import 'package:model/email/attachment.dart'; +import 'package:model/email/email_property.dart'; +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_id_extension.dart'; +import 'package:model/extensions/mailbox_id_extension.dart'; +import 'package:model/oidc/token.dart'; import 'package:path_provider/path_provider.dart'; import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart'; import 'package:tmail_ui_user/features/email/domain/model/move_to_mailbox_request.dart'; diff --git a/lib/features/email/presentation/email_bindings.dart b/lib/features/email/presentation/email_bindings.dart index eeddd4bd9..f27ce6e33 100644 --- a/lib/features/email/presentation/email_bindings.dart +++ b/lib/features/email/presentation/email_bindings.dart @@ -44,6 +44,8 @@ import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_api.dart'; import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_isolate_worker.dart'; import 'package:tmail_ui_user/features/mailbox/data/repository/mailbox_repository_impl.dart'; import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/identity_interactors_bindings.dart'; class EmailBindings extends BaseBindings { @@ -58,6 +60,7 @@ class EmailBindings extends BaseBindings { Get.find(), Get.find(), Get.find(), + Get.find(), )); } @@ -122,6 +125,7 @@ class EmailBindings extends BaseBindings { Get.find(), Get.find(), )); + IdentityInteractorsBindings().dependencies(); } @override diff --git a/lib/features/email/presentation/email_controller.dart b/lib/features/email/presentation/email_controller.dart index 59d8d879d..c30a1e0e8 100644 --- a/lib/features/email/presentation/email_controller.dart +++ b/lib/features/email/presentation/email_controller.dart @@ -10,8 +10,12 @@ 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/core/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'; +import 'package:jmap_dart_client/jmap/mdn/disposition.dart'; +import 'package:jmap_dart_client/jmap/mdn/mdn.dart'; import 'package:model/model.dart'; import 'package:better_open_file/better_open_file.dart' as open_file; import 'package:permission_handler/permission_handler.dart'; @@ -23,6 +27,7 @@ import 'package:tmail_ui_user/features/composer/presentation/extensions/email_ac import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart'; import 'package:tmail_ui_user/features/email/domain/model/move_action.dart'; import 'package:tmail_ui_user/features/email/domain/model/move_to_mailbox_request.dart'; +import 'package:tmail_ui_user/features/email/domain/model/send_receipt_to_sender_request.dart'; import 'package:tmail_ui_user/features/email/domain/state/download_attachment_for_web_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/download_attachments_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/export_attachment_state.dart'; @@ -30,6 +35,7 @@ import 'package:tmail_ui_user/features/email/domain/state/get_email_content_stat import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_read_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_star_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/move_to_mailbox_state.dart'; +import 'package:tmail_ui_user/features/email/domain/state/send_receipt_to_sender_state.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/download_attachment_for_web_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/download_attachments_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/export_attachment_interactor.dart'; @@ -37,12 +43,16 @@ import 'package:tmail_ui_user/features/email/domain/usecases/get_email_content_i import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_email_read_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/move_to_mailbox_interactor.dart'; +import 'package:tmail_ui_user/features/email/domain/usecases/send_receipt_to_sender_interactor.dart'; import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/email_address_bottom_sheet_builder.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/email_address_dialog_builder.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.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/download/download_task_state.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_identities_state.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/extensions/datetime_extension.dart'; import 'package:tmail_ui_user/features/thread/presentation/model/delete_action_type.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/routes/app_routes.dart'; @@ -66,12 +76,16 @@ class EmailController extends BaseController with AppLoaderMixin { final MoveToMailboxInteractor _moveToMailboxInteractor; final MarkAsStarEmailInteractor _markAsStarEmailInteractor; final DownloadAttachmentForWebInteractor _downloadAttachmentForWebInteractor; + final GetAllIdentitiesInteractor _getAllIdentitiesInteractor; + + SendReceiptToSenderInteractor? _sendReceiptToSenderInteractor; final emailAddressExpandMode = ExpandMode.COLLAPSE.obs; final attachmentsExpandMode = ExpandMode.COLLAPSE.obs; final emailContents = [].obs; final attachments = [].obs; EmailId? _currentEmailId; + Identity? _identitySelected; List? initialEmailContents; late Worker emailWorker; @@ -95,6 +109,7 @@ class EmailController extends BaseController with AppLoaderMixin { this._moveToMailboxInteractor, this._markAsStarEmailInteractor, this._downloadAttachmentForWebInteractor, + this._getAllIdentitiesInteractor, ); @override @@ -104,6 +119,19 @@ class EmailController extends BaseController with AppLoaderMixin { super.onInit(); } + @override + void onReady() { + injectMdnBindings( + mailboxDashBoardController.sessionCurrent, + mailboxDashBoardController.accountId.value); + try { + _sendReceiptToSenderInteractor = Get.find(); + } catch (e) { + logError('EmailController::onReady(): SendReceiptToSenderInteractor not registered'); + } + super.onReady(); + } + @override void onClose() { _downloadProgressStateController.close(); @@ -121,6 +149,7 @@ class EmailController extends BaseController with AppLoaderMixin { if (!presentationEmail.hasRead) { markAsEmailRead(presentationEmail, ReadActions.markAsRead); } + _getAllIdentities(); } } }); @@ -167,6 +196,26 @@ class EmailController extends BaseController with AppLoaderMixin { }); } + void _getAllIdentities() { + final accountId = mailboxDashBoardController.accountId.value; + if (accountId != null) { + consumeState(_getAllIdentitiesInteractor.execute(accountId)); + } + } + + void _getAllIdentitiesSuccess(GetAllIdentitiesSuccess success) { + if (success.identities?.isNotEmpty == true) { + try { + final identityDefault = success.identities! + .firstWhere((identity) => identity.mayDelete == false); + _identitySelected = identityDefault; + } catch (e) { + logError('EmailController::_getAllIdentitiesSuccess(): ${e.toString()}'); + _identitySelected = success.identities!.first; + } + } + } + void _getEmailContentAction(EmailId emailId) async { final accountId = mailboxDashBoardController.accountId.value; final baseDownloadUrl = mailboxDashBoardController.sessionCurrent?.getDownloadUrl(); @@ -202,6 +251,10 @@ class EmailController extends BaseController with AppLoaderMixin { _markAsEmailStarSuccess(success); } else if (success is DownloadAttachmentForWebSuccess) { _downloadAttachmentForWebSuccessAction(success); + } else if (success is GetAllIdentitiesSuccess) { + _getAllIdentitiesSuccess(success); + } else if (success is SendReceiptToSenderSuccess) { + _sendReceiptToSenderSuccess(success); } }); } @@ -216,7 +269,9 @@ class EmailController extends BaseController with AppLoaderMixin { initialEmailContents = success.emailContents; attachments.value = success.attachments; - if (success.readReceiptRequested) { + final isShowMessageReadReceipt = success.emailCurrent + ?.hasReadReceipt(mailboxDashBoardController.mapMailboxById) == true; + if (isShowMessageReadReceipt) { _handleReadReceipt(); } } @@ -226,7 +281,7 @@ class EmailController extends BaseController with AppLoaderMixin { showConfirmDialogAction(currentContext!, AppLocalizations.of(currentContext!).subTitleReadReceiptRequestNotificationMessage, AppLocalizations.of(currentContext!).yes, - onConfirmAction: () => {}, + onConfirmAction: () => _handleSendReceiptToSenderAction(currentContext!), showAsBottomSheet: true, title: AppLocalizations.of(currentContext!).titleReadReceiptRequestNotificationMessage, cancelTitle: AppLocalizations.of(currentContext!).no, @@ -728,9 +783,116 @@ class EmailController extends BaseController with AppLoaderMixin { mailboxDashBoardController.deleteEmailPermanently(email); } + void _handleSendReceiptToSenderAction(BuildContext context) { + final accountId = mailboxDashBoardController.accountId.value; + if (accountId == null) { + return; + } + + if (_sendReceiptToSenderInteractor == null) { + _appToast.showBottomToast( + currentOverlayContext!, + AppLocalizations.of(context).toastMessageNotSupportMdnWhenSendReceipt, + leadingIcon: SvgPicture.asset( + imagePaths.icNotConnection, + width: 24, + height: 24, + color: Colors.white, + fit: BoxFit.fill), + backgroundColor: AppColor.toastErrorBackgroundColor, + textColor: Colors.white, + textActionColor: Colors.white, + maxWidth: responsiveUtils.getMaxWidthToast(currentContext!)); + return; + } + + if (_identitySelected == null || _identitySelected?.id == null) { + _appToast.showBottomToast( + currentOverlayContext!, + AppLocalizations.of(context).toastMessageCannotFoundIdentityWhenSendReceipt, + leadingIcon: SvgPicture.asset( + imagePaths.icNotConnection, + width: 24, + height: 24, + color: Colors.white, + fit: BoxFit.fill), + backgroundColor: AppColor.toastErrorBackgroundColor, + textColor: Colors.white, + textActionColor: Colors.white, + maxWidth: responsiveUtils.getMaxWidthToast(currentContext!)); + return; + } + + if (currentEmail == null || _currentEmailId == null) { + _appToast.showBottomToast( + currentOverlayContext!, + AppLocalizations.of(context).toastMessageCannotFoundEmailIdWhenSendReceipt, + leadingIcon: SvgPicture.asset( + imagePaths.icNotConnection, + width: 24, + height: 24, + color: Colors.white, + fit: BoxFit.fill), + backgroundColor: AppColor.toastErrorBackgroundColor, + textColor: Colors.white, + textActionColor: Colors.white, + maxWidth: responsiveUtils.getMaxWidthToast(currentContext!)); + return; + } + + final mdnToSender = _generateMDN(context, currentEmail!); + final sendReceiptRequest = SendReceiptToSenderRequest( + mdn: mdnToSender, + identityId: _identitySelected!.id!, + sendId: Id(_uuid.v1())); + log('EmailController::_handleSendReceiptToSenderAction(): sendReceiptRequest: $sendReceiptRequest'); + + consumeState(_sendReceiptToSenderInteractor!.execute(accountId, sendReceiptRequest)); + } + + MDN _generateMDN(BuildContext context, PresentationEmail email) { + final senderEmailAddress = email.from?.first.asFullString() ?? ''; + final subjectEmail = email.subject ?? ''; + final timeCurrent = DateTime.now(); + final timeAsString = '${timeCurrent.formatDate( + pattern: 'EEE, d MMM yyyy HH:mm:ss')} (${timeCurrent.timeZoneName})'; + + final mdnToSender = MDN( + forEmailId: email.id, + subject: AppLocalizations.of(context).subjectSendReceiptToSender(subjectEmail), + textBody: AppLocalizations.of(context).textBodySendReceiptToSender( + senderEmailAddress, + subjectEmail, + timeAsString), + disposition: Disposition( + ActionMode.manual, + SendingMode.manually, + DispositionType.displayed)); + + return mdnToSender; + } + + void _sendReceiptToSenderSuccess(SendReceiptToSenderSuccess success) { + log('EmailController::_sendReceiptToSenderSuccess(): ${success.mdn.toString()}'); + if (currentContext != null) { + _appToast.showBottomToast( + currentOverlayContext!, + AppLocalizations.of(currentContext!).toastMessageSendReceiptSuccess, + leadingIcon: SvgPicture.asset( + imagePaths.icReadReceiptMessage, + width: 24, + height: 24, + fit: BoxFit.fill), + backgroundColor: AppColor.toastSuccessBackgroundColor, + textColor: Colors.white, + textActionColor: Colors.white, + maxWidth: responsiveUtils.getMaxWidthToast(currentContext!)); + } + } + void closeEmailView(BuildContext context) { mailboxDashBoardController.clearSelectedEmail(); - + _currentEmailId = null; if (mailboxDashBoardController.searchController.isSearchEmailRunning) { if (responsiveUtils.isWebDesktop(context)) { mailboxDashBoardController.dispatchRoute(AppRoutes.THREAD); diff --git a/lib/features/email/presentation/mdn_interactor_bindings.dart b/lib/features/email/presentation/mdn_interactor_bindings.dart new file mode 100644 index 000000000..4a8f63a21 --- /dev/null +++ b/lib/features/email/presentation/mdn_interactor_bindings.dart @@ -0,0 +1,36 @@ +import 'package:get/get.dart'; +import 'package:tmail_ui_user/features/base/interactors_bindings.dart'; +import 'package:tmail_ui_user/features/email/data/datasource/mdn_datasource.dart'; +import 'package:tmail_ui_user/features/email/data/datasource_impl/mdn_datasource_impl.dart'; +import 'package:tmail_ui_user/features/email/data/network/mdn_api.dart'; +import 'package:tmail_ui_user/features/email/data/repository/mdn_repository_impl.dart'; +import 'package:tmail_ui_user/features/email/domain/repository/mdn_repository.dart'; +import 'package:tmail_ui_user/features/email/domain/usecases/send_receipt_to_sender_interactor.dart'; + +class MdnInteractorBindings extends InteractorsBindings { + + @override + void bindingsDataSource() { + Get.lazyPut(() => Get.find()); + } + + @override + void bindingsDataSourceImpl() { + Get.lazyPut(() => MdnDataSourceImpl(Get.find())); + } + + @override + void bindingsInteractor() { + Get.lazyPut(() => SendReceiptToSenderInteractor(Get.find())); + } + + @override + void bindingsRepository() { + Get.lazyPut(() => Get.find()); + } + + @override + void bindingsRepositoryImpl() { + Get.lazyPut(() => MdnRepositoryImpl(Get.find())); + } +} \ No newline at end of file diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index 066ab4e1e..1edcd578b 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -1,5 +1,5 @@ { - "@@last_modified": "2022-10-19T15:56:55.354560", + "@@last_modified": "2022-10-21T10:04:34.240729", "initializing_data": "Initializing data...", "@initializing_data": { "type": "text", @@ -2325,5 +2325,53 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "toastMessageNotSupportMdnWhenSendReceipt": "Your account does not support the MDN capability", + "@toastMessageNotSupportMdnWhenSendReceipt": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "toastMessageCannotFoundIdentityWhenSendReceipt": "Identity id given cannot be found", + "@toastMessageCannotFoundIdentityWhenSendReceipt": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "toastMessageCannotFoundEmailIdWhenSendReceipt": "Email id given cannot be found", + "@toastMessageCannotFoundEmailIdWhenSendReceipt": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "subjectSendReceiptToSender": "Read: {subject}", + "@subjectSendReceiptToSender": { + "type": "text", + "placeholders_order": [ + "subject" + ], + "placeholders": { + "subject": {} + } + }, + "textBodySendReceiptToSender": "Message was read by {sender} on {time} \n\nSubject: {subject} \n\nNote: This Return ReceiptReceipt only acknowledges that the message was displayed on the recipient's computer. There is no guarantee that the recipient has read or understood the message contents.", + "@textBodySendReceiptToSender": { + "type": "text", + "placeholders_order": [ + "sender", + "subject", + "time" + ], + "placeholders": { + "sender": {}, + "subject": {}, + "time": {} + } + }, + "toastMessageSendReceiptSuccess": "A read receipt has been sent.", + "@toastMessageSendReceiptSuccess": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } \ No newline at end of file diff --git a/lib/main/bindings/network/network_bindings.dart b/lib/main/bindings/network/network_bindings.dart index 7e2e6d592..88f11c9e9 100644 --- a/lib/main/bindings/network/network_bindings.dart +++ b/lib/main/bindings/network/network_bindings.dart @@ -9,6 +9,7 @@ import 'package:flutter_appauth/flutter_appauth.dart'; import 'package:get/get.dart'; import 'package:jmap_dart_client/http/http_client.dart' as JmapHttpClient; import 'package:tmail_ui_user/features/email/data/network/email_api.dart'; +import 'package:tmail_ui_user/features/email/data/network/mdn_api.dart'; import 'package:tmail_ui_user/features/login/data/local/account_cache_manager.dart'; import 'package:tmail_ui_user/features/login/data/local/token_oidc_cache_manager.dart'; import 'package:tmail_ui_user/features/login/data/network/authentication_client/authentication_client_base.dart'; @@ -81,6 +82,7 @@ class NetworkBindings extends Bindings { Get.put(VacationAPI(Get.find())); Get.put(ContactAPI(Get.find())); Get.put(IdentityAPI(Get.find())); + Get.put(MdnAPI(Get.find())); } void _bindingConnection() { diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart index 6a0d4b56f..6345a7d9c 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -2409,4 +2409,42 @@ class AppLocalizations { 'No', name: 'no'); } + + String get toastMessageNotSupportMdnWhenSendReceipt { + return Intl.message( + 'Your account does not support the MDN capability', + name: 'toastMessageNotSupportMdnWhenSendReceipt'); + } + + String get toastMessageCannotFoundIdentityWhenSendReceipt { + return Intl.message( + 'Identity id given cannot be found', + name: 'toastMessageCannotFoundIdentityWhenSendReceipt'); + } + + String get toastMessageCannotFoundEmailIdWhenSendReceipt { + return Intl.message( + 'Email id given cannot be found', + name: 'toastMessageCannotFoundEmailIdWhenSendReceipt'); + } + + String subjectSendReceiptToSender(String subject) { + return Intl.message( + 'Read: $subject', + name: 'subjectSendReceiptToSender', + args: [subject]); + } + + String textBodySendReceiptToSender(String sender, String subject, String time) { + return Intl.message( + 'Message was read by $sender on $time \n\nSubject: $subject \n\nNote: This Return ReceiptReceipt only acknowledges that the message was displayed on the recipient\'s computer. There is no guarantee that the recipient has read or understood the message contents.', + name: 'textBodySendReceiptToSender', + args: [sender, subject, time]); + } + + String get toastMessageSendReceiptSuccess { + return Intl.message( + 'A read receipt has been sent.', + name: 'toastMessageSendReceiptSuccess'); + } } \ No newline at end of file diff --git a/model/lib/extensions/email_extension.dart b/model/lib/extensions/email_extension.dart index 755600915..b67b78a00 100644 --- a/model/lib/extensions/email_extension.dart +++ b/model/lib/extensions/email_extension.dart @@ -17,8 +17,11 @@ extension EmailExtension on Email { bool get withAttachments => hasAttachment == true; - bool get needShowNotificationMessageReadReceipt { - return !hasMdnSent && headers.readReceiptHasBeenRequested; + bool hasReadReceipt(Map mapMailbox) { + final mailboxCurrent = findMailboxContain(mapMailbox); + return !hasMdnSent && + headers.readReceiptHasBeenRequested && + mailboxCurrent?.isSent == false; } Set getRecipientEmailAddressList() { @@ -119,4 +122,17 @@ extension EmailExtension on Email { } return []; } + + PresentationMailbox? findMailboxContain(Map mapMailbox) { + final newMailboxIds = mailboxIds; + newMailboxIds?.removeWhere((key, value) => !value); + + if (newMailboxIds?.isNotEmpty == true) { + final firstMailboxId = newMailboxIds!.keys.first; + if (mapMailbox.containsKey(firstMailboxId)) { + return mapMailbox[firstMailboxId]; + } + } + return null; + } } \ No newline at end of file