From 4d7ba01f002237e43e9f6e92e9a888c5e493ee78 Mon Sep 17 00:00:00 2001 From: dab246 Date: Wed, 19 Oct 2022 21:09:37 +0700 Subject: [PATCH] TF-657 Add `interactor/repository/datasource` for SendReceiptToSender --- .../email/data/datasource/mdn_datasource.dart | 9 ++++ .../datasource_impl/mdn_datasource_impl.dart | 23 +++++++++ .../email/data/network/email_api.dart | 3 +- lib/features/email/data/network/mdn_api.dart | 49 +++++++++++++++++++ .../data/repository/mdn_repository_impl.dart | 20 ++++++++ .../model/send_receipt_to_sender_request.dart | 21 ++++++++ .../domain/repository/mdn_repository.dart | 9 ++++ .../domain/state/get_email_content_state.dart | 7 +-- .../state/send_receipt_to_sender_state.dart | 25 ++++++++++ .../get_email_content_interactor.dart | 14 ++---- .../send_receipt_to_sender_interactor.dart | 26 ++++++++++ 11 files changed, 191 insertions(+), 15 deletions(-) create mode 100644 lib/features/email/data/datasource/mdn_datasource.dart create mode 100644 lib/features/email/data/datasource_impl/mdn_datasource_impl.dart create mode 100644 lib/features/email/data/network/mdn_api.dart create mode 100644 lib/features/email/data/repository/mdn_repository_impl.dart create mode 100644 lib/features/email/domain/model/send_receipt_to_sender_request.dart create mode 100644 lib/features/email/domain/repository/mdn_repository.dart create mode 100644 lib/features/email/domain/state/send_receipt_to_sender_state.dart create mode 100644 lib/features/email/domain/usecases/send_receipt_to_sender_interactor.dart diff --git a/lib/features/email/data/datasource/mdn_datasource.dart b/lib/features/email/data/datasource/mdn_datasource.dart new file mode 100644 index 000000000..9ad342fcf --- /dev/null +++ b/lib/features/email/data/datasource/mdn_datasource.dart @@ -0,0 +1,9 @@ +import 'dart:async'; + +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/mdn/mdn.dart'; +import 'package:tmail_ui_user/features/email/domain/model/send_receipt_to_sender_request.dart'; + +abstract class MdnDataSource { + Future sendReceiptToSender(AccountId accountId, SendReceiptToSenderRequest request); +} \ No newline at end of file diff --git a/lib/features/email/data/datasource_impl/mdn_datasource_impl.dart b/lib/features/email/data/datasource_impl/mdn_datasource_impl.dart new file mode 100644 index 000000000..279b209dd --- /dev/null +++ b/lib/features/email/data/datasource_impl/mdn_datasource_impl.dart @@ -0,0 +1,23 @@ +import 'dart:async'; + +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/mdn/mdn.dart'; +import 'package:tmail_ui_user/features/email/data/datasource/mdn_datasource.dart'; +import 'package:tmail_ui_user/features/email/data/network/mdn_api.dart'; +import 'package:tmail_ui_user/features/email/domain/model/send_receipt_to_sender_request.dart'; + +class MdnDataSourceImpl extends MdnDataSource { + + final MdnAPI _mdnAPI; + + MdnDataSourceImpl(this._mdnAPI); + + @override + Future sendReceiptToSender(AccountId accountId, SendReceiptToSenderRequest request) { + return Future.sync(() async { + return await _mdnAPI.sendReceiptToSender(accountId, request); + }).catchError((error) { + throw error; + }); + } +} \ No newline at end of file diff --git a/lib/features/email/data/network/email_api.dart b/lib/features/email/data/network/email_api.dart index 1b95b7d0c..f41e32f0c 100644 --- a/lib/features/email/data/network/email_api.dart +++ b/lib/features/email/data/network/email_api.dart @@ -55,7 +55,8 @@ class EmailAPI { EmailProperty.htmlBody, EmailProperty.attachments, EmailProperty.headers, - EmailProperty.keywords + EmailProperty.keywords, + EmailProperty.mailboxIds, })) ..addFetchHTMLBodyValues(true); diff --git a/lib/features/email/data/network/mdn_api.dart b/lib/features/email/data/network/mdn_api.dart new file mode 100644 index 000000000..fc82bdf58 --- /dev/null +++ b/lib/features/email/data/network/mdn_api.dart @@ -0,0 +1,49 @@ +import 'dart:async'; + +import 'package:jmap_dart_client/http/http_client.dart'; +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/core/patch_object.dart'; +import 'package:jmap_dart_client/jmap/core/reference_id.dart'; +import 'package:jmap_dart_client/jmap/core/reference_prefix.dart'; +import 'package:jmap_dart_client/jmap/jmap_request.dart'; +import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart'; +import 'package:jmap_dart_client/jmap/mail/email/submission/email_submission_id.dart'; +import 'package:jmap_dart_client/jmap/mdn/mdn.dart'; +import 'package:jmap_dart_client/jmap/mdn/send/mdn_send_method.dart'; +import 'package:jmap_dart_client/jmap/mdn/send/mdn_send_response.dart'; +import 'package:tmail_ui_user/features/email/domain/model/send_receipt_to_sender_request.dart'; + +class MdnAPI { + + final HttpClient _httpClient; + + MdnAPI(this._httpClient); + + Future sendReceiptToSender( + AccountId accountId, + SendReceiptToSenderRequest request, + ) async { + final mdnSendMethod = MDNSendMethod( + accountId, + {request.sendId: request.mdn}, + request.identityId + )..addOnSuccessUpdateEmail({ + EmailSubmissionId(ReferenceId(ReferencePrefix.defaultPrefix, request.sendId)): PatchObject({ + KeyWordIdentifier.mdnSent.toPatchObjectJson(): true + }) + }); + + final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation()); + final mdnSendInvocation = requestBuilder.invocation(mdnSendMethod); + final response = await (requestBuilder + ..usings(mdnSendMethod.requiredCapabilities)) + .build() + .execute(); + + final mdnSendResponse = response.parse( + mdnSendInvocation.methodCallId, + MDNSendResponse.deserialize); + + return mdnSendResponse?.sent?[request.sendId]; + } +} \ No newline at end of file diff --git a/lib/features/email/data/repository/mdn_repository_impl.dart b/lib/features/email/data/repository/mdn_repository_impl.dart new file mode 100644 index 000000000..67366e268 --- /dev/null +++ b/lib/features/email/data/repository/mdn_repository_impl.dart @@ -0,0 +1,20 @@ + +import 'dart:async'; + +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/mdn/mdn.dart'; +import 'package:tmail_ui_user/features/email/data/datasource/mdn_datasource.dart'; +import 'package:tmail_ui_user/features/email/domain/model/send_receipt_to_sender_request.dart'; +import 'package:tmail_ui_user/features/email/domain/repository/mdn_repository.dart'; + +class MdnRepositoryImpl extends MdnRepository { + + final MdnDataSource _dataSource; + + MdnRepositoryImpl(this._dataSource); + + @override + Future sendReceiptToSender(AccountId accountId, SendReceiptToSenderRequest request) { + return _dataSource.sendReceiptToSender(accountId, request); + } +} \ No newline at end of file diff --git a/lib/features/email/domain/model/send_receipt_to_sender_request.dart b/lib/features/email/domain/model/send_receipt_to_sender_request.dart new file mode 100644 index 000000000..c912b7d52 --- /dev/null +++ b/lib/features/email/domain/model/send_receipt_to_sender_request.dart @@ -0,0 +1,21 @@ + +import 'package:equatable/equatable.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/mdn/mdn.dart'; + +class SendReceiptToSenderRequest with EquatableMixin { + + final MDN mdn; + final IdentityId identityId; + final Id sendId; + + SendReceiptToSenderRequest({ + required this.mdn, + required this.identityId, + required this.sendId + }); + + @override + List get props => [mdn, identityId, sendId]; +} \ No newline at end of file diff --git a/lib/features/email/domain/repository/mdn_repository.dart b/lib/features/email/domain/repository/mdn_repository.dart new file mode 100644 index 000000000..3842f4936 --- /dev/null +++ b/lib/features/email/domain/repository/mdn_repository.dart @@ -0,0 +1,9 @@ +import 'dart:async'; + +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/mdn/mdn.dart'; +import 'package:tmail_ui_user/features/email/domain/model/send_receipt_to_sender_request.dart'; + +abstract class MdnRepository { + Future sendReceiptToSender(AccountId accountId, SendReceiptToSenderRequest request); +} \ 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 d7d19c85a..5440694e7 100644 --- a/lib/features/email/domain/state/get_email_content_state.dart +++ b/lib/features/email/domain/state/get_email_content_state.dart @@ -1,4 +1,5 @@ import 'package:core/core.dart'; +import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:model/model.dart'; class GetEmailContentLoading extends UIState { @@ -13,13 +14,13 @@ class GetEmailContentSuccess extends UIState { final List emailContents; final List emailContentsDisplayed; final List attachments; - final bool readReceiptRequested; + final Email? emailCurrent; GetEmailContentSuccess( this.emailContents, this.emailContentsDisplayed, this.attachments, - this.readReceiptRequested + this.emailCurrent ); @override @@ -27,7 +28,7 @@ class GetEmailContentSuccess extends UIState { emailContents, emailContentsDisplayed, attachments, - readReceiptRequested + emailCurrent ]; } diff --git a/lib/features/email/domain/state/send_receipt_to_sender_state.dart b/lib/features/email/domain/state/send_receipt_to_sender_state.dart new file mode 100644 index 000000000..08cb4ad83 --- /dev/null +++ b/lib/features/email/domain/state/send_receipt_to_sender_state.dart @@ -0,0 +1,25 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:jmap_dart_client/jmap/mdn/mdn.dart'; + +class SendReceiptToSenderLoading extends UIState {} + +class SendReceiptToSenderSuccess extends UIState { + + final MDN mdn; + + SendReceiptToSenderSuccess(this.mdn); + + @override + List get props => [mdn]; +} + +class SendReceiptToSenderFailure extends FeatureFailure { + + final dynamic exception; + + SendReceiptToSenderFailure(this.exception); + + @override + List get props => [exception]; +} \ No newline at end of file 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 90fafd256..92dc0a600 100644 --- a/lib/features/email/domain/usecases/get_email_content_interactor.dart +++ b/lib/features/email/domain/usecases/get_email_content_interactor.dart @@ -30,19 +30,11 @@ class GetEmailContentInteractor { newEmailContents, newEmailContentsDisplayed, email.allAttachments, - email.needShowNotificationMessageReadReceipt)); + email)); } else if (email.allAttachments.isNotEmpty) { - yield Right(GetEmailContentSuccess( - [], - [], - email.allAttachments, - email.needShowNotificationMessageReadReceipt)); + yield Right(GetEmailContentSuccess([], [], email.allAttachments, email)); } else if (email.headers?.isNotEmpty == true) { - yield Right(GetEmailContentSuccess( - [], - [], - [], - email.needShowNotificationMessageReadReceipt)); + yield Right(GetEmailContentSuccess([], [], [], email)); } else { yield Left(GetEmailContentFailure(null)); } diff --git a/lib/features/email/domain/usecases/send_receipt_to_sender_interactor.dart b/lib/features/email/domain/usecases/send_receipt_to_sender_interactor.dart new file mode 100644 index 000000000..5e0369581 --- /dev/null +++ b/lib/features/email/domain/usecases/send_receipt_to_sender_interactor.dart @@ -0,0 +1,26 @@ +import 'package:core/core.dart'; +import 'package:dartz/dartz.dart'; +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:tmail_ui_user/features/email/domain/model/send_receipt_to_sender_request.dart'; +import 'package:tmail_ui_user/features/email/domain/repository/mdn_repository.dart'; +import 'package:tmail_ui_user/features/email/domain/state/send_receipt_to_sender_state.dart'; + +class SendReceiptToSenderInteractor { + final MdnRepository _mdnRepository; + + SendReceiptToSenderInteractor(this._mdnRepository); + + Stream> execute(AccountId accountId, SendReceiptToSenderRequest request) async* { + try { + yield Right(SendReceiptToSenderLoading()); + final mdn = await _mdnRepository.sendReceiptToSender(accountId, request); + if (mdn != null) { + yield Right(SendReceiptToSenderSuccess(mdn)); + } else { + yield Left(SendReceiptToSenderFailure(null)); + } + } catch (e) { + yield Left(SendReceiptToSenderFailure(e)); + } + } +} \ No newline at end of file