diff --git a/lib/features/thread/data/datasource/thread_datasource.dart b/lib/features/thread/data/datasource/thread_datasource.dart index 86096c815..fbb4fa334 100644 --- a/lib/features/thread/data/datasource/thread_datasource.dart +++ b/lib/features/thread/data/datasource/thread_datasource.dart @@ -8,6 +8,7 @@ import 'package:jmap_dart_client/jmap/core/state.dart'; import 'package:jmap_dart_client/jmap/core/unsigned_int.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; +import 'package:model/email/presentation_email.dart'; import 'package:tmail_ui_user/features/thread/data/model/email_change_response.dart'; import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart'; import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart'; @@ -41,4 +42,6 @@ abstract class ThreadDataSource { MailboxId mailboxId, Future Function(List? newDestroyed) updateDestroyedEmailCache, ); + + Future getEmailById(AccountId accountId, EmailId emailId, {Properties? properties}); } \ No newline at end of file diff --git a/lib/features/thread/data/datasource_impl/local_thread_datasource_impl.dart b/lib/features/thread/data/datasource_impl/local_thread_datasource_impl.dart index 7d6521b71..5130d0335 100644 --- a/lib/features/thread/data/datasource_impl/local_thread_datasource_impl.dart +++ b/lib/features/thread/data/datasource_impl/local_thread_datasource_impl.dart @@ -8,6 +8,7 @@ import 'package:jmap_dart_client/jmap/core/state.dart'; import 'package:jmap_dart_client/jmap/core/unsigned_int.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; +import 'package:model/email/presentation_email.dart'; import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart'; import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dart'; import 'package:tmail_ui_user/features/thread/data/model/email_change_response.dart'; @@ -89,4 +90,9 @@ class LocalThreadDataSourceImpl extends ThreadDataSource { ) { throw UnimplementedError(); } + + @override + Future getEmailById(AccountId accountId, EmailId emailId, {Properties? properties}) { + throw UnimplementedError(); + } } \ No newline at end of file diff --git a/lib/features/thread/data/datasource_impl/thread_datasource_impl.dart b/lib/features/thread/data/datasource_impl/thread_datasource_impl.dart index 2137cf8ef..71aa53470 100644 --- a/lib/features/thread/data/datasource_impl/thread_datasource_impl.dart +++ b/lib/features/thread/data/datasource_impl/thread_datasource_impl.dart @@ -8,6 +8,8 @@ import 'package:jmap_dart_client/jmap/core/state.dart'; import 'package:jmap_dart_client/jmap/core/unsigned_int.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; +import 'package:model/email/presentation_email.dart'; +import 'package:model/extensions/email_extension.dart'; import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart'; import 'package:tmail_ui_user/features/thread/data/model/email_change_response.dart'; import 'package:tmail_ui_user/features/thread/data/network/thread_isolate_worker.dart'; @@ -92,4 +94,14 @@ class ThreadDataSourceImpl extends ThreadDataSource { _exceptionThrower.throwException(error); }); } + + @override + Future getEmailById(AccountId accountId, EmailId emailId, {Properties? properties}) { + return Future.sync(() async { + final email = await threadAPI.getEmailById(accountId, emailId, properties: properties); + return email.toPresentationEmail(); + }).catchError((error) { + _exceptionThrower.throwException(error); + }); + } } \ No newline at end of file diff --git a/lib/features/thread/data/network/thread_api.dart b/lib/features/thread/data/network/thread_api.dart index 04d948d54..a00084af4 100644 --- a/lib/features/thread/data/network/thread_api.dart +++ b/lib/features/thread/data/network/thread_api.dart @@ -139,4 +139,29 @@ class ThreadAPI { hasMoreChanges: resultChanges?.hasMoreChanges ?? false, updatedProperties: propertiesUpdated); } + + Future getEmailById(AccountId accountId, EmailId emailId, {Properties? properties}) async { + final processingInvocation = ProcessingInvocation(); + final jmapRequestBuilder = JmapRequestBuilder(httpClient, processingInvocation); + + final getEmailMethod = GetEmailMethod(accountId) + ..addIds({emailId.id}); + + if (properties != null) { + getEmailMethod.addProperties(properties); + } + + final getEmailInvocation = jmapRequestBuilder.invocation(getEmailMethod); + + final result = await (jmapRequestBuilder + ..usings(getEmailMethod.requiredCapabilities)) + .build() + .execute(); + + final resultList = result.parse( + getEmailInvocation.methodCallId, + GetEmailResponse.deserialize); + + return resultList!.list.first; + } } \ No newline at end of file diff --git a/lib/features/thread/data/repository/thread_repository_impl.dart b/lib/features/thread/data/repository/thread_repository_impl.dart index 624f74911..3eabf97e5 100644 --- a/lib/features/thread/data/repository/thread_repository_impl.dart +++ b/lib/features/thread/data/repository/thread_repository_impl.dart @@ -335,4 +335,9 @@ class ThreadRepositoryImpl extends ThreadRepository { } } } + + @override + Future getEmailById(AccountId accountId, EmailId emailId, {Properties? properties}) { + return mapDataSource[DataSourceType.network]!.getEmailById(accountId, emailId, properties: properties); + } } \ No newline at end of file diff --git a/lib/features/thread/domain/repository/thread_repository.dart b/lib/features/thread/domain/repository/thread_repository.dart index d1da5e145..f82e836cc 100644 --- a/lib/features/thread/domain/repository/thread_repository.dart +++ b/lib/features/thread/domain/repository/thread_repository.dart @@ -8,6 +8,7 @@ import 'package:jmap_dart_client/jmap/core/state.dart' as jmap; import 'package:jmap_dart_client/jmap/core/unsigned_int.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; +import 'package:model/email/presentation_email.dart'; import 'package:tmail_ui_user/features/thread/domain/model/email_filter.dart'; import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart'; import 'package:tmail_ui_user/features/thread/domain/model/get_email_request.dart'; @@ -51,4 +52,6 @@ abstract class ThreadRepository { AccountId accountId, MailboxId trashMailboxId, ); + + Future getEmailById(AccountId accountId, EmailId emailId, {Properties? properties}); } \ No newline at end of file diff --git a/lib/features/thread/domain/state/get_email_by_id_state.dart b/lib/features/thread/domain/state/get_email_by_id_state.dart new file mode 100644 index 000000000..2bbeeaa69 --- /dev/null +++ b/lib/features/thread/domain/state/get_email_by_id_state.dart @@ -0,0 +1,23 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:model/model.dart'; + +class GetEmailByIdLoading extends LoadingState {} + +class GetEmailByIdSuccess extends UIState { + final PresentationEmail email; + + GetEmailByIdSuccess(this.email); + + @override + List get props => [email]; +} + +class GetEmailByIdFailure extends FeatureFailure { + final dynamic exception; + + GetEmailByIdFailure(this.exception); + + @override + List get props => [exception]; +} \ No newline at end of file diff --git a/lib/features/thread/domain/usecases/get_email_by_id_interactor.dart b/lib/features/thread/domain/usecases/get_email_by_id_interactor.dart new file mode 100644 index 000000000..91c2a9f30 --- /dev/null +++ b/lib/features/thread/domain/usecases/get_email_by_id_interactor.dart @@ -0,0 +1,30 @@ +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/properties/properties.dart'; +import 'package:jmap_dart_client/jmap/mail/email/email.dart'; +import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart'; +import 'package:tmail_ui_user/features/thread/domain/state/get_email_by_id_state.dart'; + +class GetEmailByIdInteractor { + final ThreadRepository _threadRepository; + + GetEmailByIdInteractor(this._threadRepository); + + Stream> execute( + AccountId accountId, + EmailId emailId, + { + Properties? properties, + } + ) async* { + try { + yield Right(GetEmailByIdLoading()); + final email = await _threadRepository.getEmailById(accountId, emailId, properties: properties); + yield Right(GetEmailByIdSuccess(email)); + } catch (e) { + yield Left(GetEmailByIdFailure(e)); + } + } +} \ No newline at end of file