From c0f5c47346f03ab7aef393f2febcece26395ca3e Mon Sep 17 00:00:00 2001 From: dab246 Date: Fri, 25 Feb 2022 11:07:32 +0700 Subject: [PATCH] TF-235 Implement rename a mailbox --- .../data/datasource/mailbox_datasource.dart | 3 +++ .../mailbox_cache_datasource_impl.dart | 6 +++++ .../mailbox_datasource_impl.dart | 10 +++++++ .../mailbox/data/network/mailbox_api.dart | 26 +++++++++++++++++++ .../repository/mailbox_repository_impl.dart | 6 +++++ .../domain/model/rename_mailbox_request.dart | 14 ++++++++++ .../domain/repository/mailbox_repository.dart | 3 +++ .../domain/state/rename_mailbox_state.dart | 18 +++++++++++++ .../usecases/rename_mailbox_interactor.dart | 25 ++++++++++++++++++ .../presentation/mailbox_bindings.dart | 3 +++ .../presentation/mailbox_controller.dart | 15 +++++++++++ 11 files changed, 129 insertions(+) create mode 100644 lib/features/mailbox/domain/model/rename_mailbox_request.dart create mode 100644 lib/features/mailbox/domain/state/rename_mailbox_state.dart create mode 100644 lib/features/mailbox/domain/usecases/rename_mailbox_interactor.dart diff --git a/lib/features/mailbox/data/datasource/mailbox_datasource.dart b/lib/features/mailbox/data/datasource/mailbox_datasource.dart index d11cb3799..660ffc274 100644 --- a/lib/features/mailbox/data/datasource/mailbox_datasource.dart +++ b/lib/features/mailbox/data/datasource/mailbox_datasource.dart @@ -5,6 +5,7 @@ import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_change_response.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_response.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart'; abstract class MailboxDataSource { Future getAllMailbox(AccountId accountId, {Properties? properties}); @@ -18,4 +19,6 @@ abstract class MailboxDataSource { Future createNewMailbox(AccountId accountId, CreateNewMailboxRequest newMailboxRequest); Future deleteMultipleMailbox(AccountId accountId, List mailboxIds); + + Future renameMailbox(AccountId accountId, RenameMailboxRequest request); } \ No newline at end of file diff --git a/lib/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart b/lib/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart index fd9fbfbdd..c0cc203ea 100644 --- a/lib/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart +++ b/lib/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart @@ -8,6 +8,7 @@ import 'package:tmail_ui_user/features/mailbox/data/local/mailbox_cache_manager. import 'package:tmail_ui_user/features/mailbox/data/extensions/mailbox_extension.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_response.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart'; class MailboxCacheDataSourceImpl extends MailboxDataSource { @@ -54,4 +55,9 @@ class MailboxCacheDataSourceImpl extends MailboxDataSource { Future deleteMultipleMailbox(AccountId accountId, List mailboxIds) { throw UnimplementedError(); } + + @override + Future renameMailbox(AccountId accountId, RenameMailboxRequest request) { + throw UnimplementedError(); + } } \ No newline at end of file diff --git a/lib/features/mailbox/data/datasource_impl/mailbox_datasource_impl.dart b/lib/features/mailbox/data/datasource_impl/mailbox_datasource_impl.dart index 156d37911..90169a644 100644 --- a/lib/features/mailbox/data/datasource_impl/mailbox_datasource_impl.dart +++ b/lib/features/mailbox/data/datasource_impl/mailbox_datasource_impl.dart @@ -7,6 +7,7 @@ import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_change_respons import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_response.dart'; import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_api.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart'; class MailboxDataSourceImpl extends MailboxDataSource { @@ -59,4 +60,13 @@ class MailboxDataSourceImpl extends MailboxDataSource { throw error; }); } + + @override + Future renameMailbox(AccountId accountId, RenameMailboxRequest request) { + return Future.sync(() async { + return await mailboxAPI.renameMailbox(accountId, request); + }).catchError((error) { + throw error; + }); + } } \ No newline at end of file diff --git a/lib/features/mailbox/data/network/mailbox_api.dart b/lib/features/mailbox/data/network/mailbox_api.dart index 780767df3..758f8f493 100644 --- a/lib/features/mailbox/data/network/mailbox_api.dart +++ b/lib/features/mailbox/data/network/mailbox_api.dart @@ -2,6 +2,7 @@ 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/properties/properties.dart'; import 'package:jmap_dart_client/jmap/core/request/reference_path.dart'; import 'package:jmap_dart_client/jmap/core/state.dart'; @@ -18,6 +19,7 @@ import 'package:model/model.dart'; import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_change_response.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_response.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart'; class MailboxAPI { @@ -153,4 +155,28 @@ class MailboxAPI { throw error; }); } + + Future renameMailbox(AccountId accountId, RenameMailboxRequest request) async { + final setMailboxMethod = SetMailboxMethod(accountId) + ..addUpdates({request.mailboxId.id : PatchObject({'name' : request.newName.name})}); + + final requestBuilder = JmapRequestBuilder(httpClient, ProcessingInvocation()); + + final setMailboxInvocation = requestBuilder.invocation(setMailboxMethod); + + final response = await (requestBuilder + ..usings(setMailboxMethod.requiredCapabilities)) + .build() + .execute(); + + final setMailboxResponse = response.parse( + setMailboxInvocation.methodCallId, + SetMailboxResponse.deserialize); + + return Future.sync(() async { + return setMailboxResponse?.updated?.isNotEmpty == true; + }).catchError((error) { + throw error; + }); + } } \ No newline at end of file diff --git a/lib/features/mailbox/data/repository/mailbox_repository_impl.dart b/lib/features/mailbox/data/repository/mailbox_repository_impl.dart index 1d222f5c5..2c6318475 100644 --- a/lib/features/mailbox/data/repository/mailbox_repository_impl.dart +++ b/lib/features/mailbox/data/repository/mailbox_repository_impl.dart @@ -10,6 +10,7 @@ import 'package:tmail_ui_user/features/mailbox/data/extensions/state_extension.d import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_response.dart'; import 'package:tmail_ui_user/features/mailbox/data/model/state_type.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart'; class MailboxRepositoryImpl extends MailboxRepository { @@ -145,4 +146,9 @@ class MailboxRepositoryImpl extends MailboxRepository { Future deleteMultipleMailbox(AccountId accountId, List mailboxIds) { return mapDataSource[DataSourceType.network]!.deleteMultipleMailbox(accountId, mailboxIds); } + + @override + Future renameMailbox(AccountId accountId, RenameMailboxRequest request) { + return mapDataSource[DataSourceType.network]!.renameMailbox(accountId, request); + } } \ No newline at end of file diff --git a/lib/features/mailbox/domain/model/rename_mailbox_request.dart b/lib/features/mailbox/domain/model/rename_mailbox_request.dart new file mode 100644 index 000000000..83e859d6f --- /dev/null +++ b/lib/features/mailbox/domain/model/rename_mailbox_request.dart @@ -0,0 +1,14 @@ + +import 'package:equatable/equatable.dart'; +import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; + +class RenameMailboxRequest with EquatableMixin { + + final MailboxName newName; + final MailboxId mailboxId; + + RenameMailboxRequest(this.mailboxId, this.newName); + + @override + List get props => [mailboxId, newName]; +} \ No newline at end of file diff --git a/lib/features/mailbox/domain/repository/mailbox_repository.dart b/lib/features/mailbox/domain/repository/mailbox_repository.dart index 2e3f1885a..70bc98ad2 100644 --- a/lib/features/mailbox/domain/repository/mailbox_repository.dart +++ b/lib/features/mailbox/domain/repository/mailbox_repository.dart @@ -4,6 +4,7 @@ import 'package:jmap_dart_client/jmap/core/state.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_response.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart'; abstract class MailboxRepository { Stream getAllMailbox(AccountId accountId, {Properties? properties}); @@ -13,4 +14,6 @@ abstract class MailboxRepository { Future createNewMailbox(AccountId accountId, CreateNewMailboxRequest newMailboxRequest); Future deleteMultipleMailbox(AccountId accountId, List mailboxIds); + + Future renameMailbox(AccountId accountId, RenameMailboxRequest request); } \ No newline at end of file diff --git a/lib/features/mailbox/domain/state/rename_mailbox_state.dart b/lib/features/mailbox/domain/state/rename_mailbox_state.dart new file mode 100644 index 000000000..c83d68639 --- /dev/null +++ b/lib/features/mailbox/domain/state/rename_mailbox_state.dart @@ -0,0 +1,18 @@ +import 'package:core/core.dart'; + +class RenameMailboxSuccess extends UIState { + + RenameMailboxSuccess(); + + @override + List get props => []; +} + +class RenameMailboxFailure extends FeatureFailure { + final exception; + + RenameMailboxFailure(this.exception); + + @override + List get props => [exception]; +} \ No newline at end of file diff --git a/lib/features/mailbox/domain/usecases/rename_mailbox_interactor.dart b/lib/features/mailbox/domain/usecases/rename_mailbox_interactor.dart new file mode 100644 index 000000000..6c8d67433 --- /dev/null +++ b/lib/features/mailbox/domain/usecases/rename_mailbox_interactor.dart @@ -0,0 +1,25 @@ +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/mailbox/domain/model/rename_mailbox_request.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/state/rename_mailbox_state.dart'; + +class RenameMailboxInteractor { + final MailboxRepository mailboxRepository; + + RenameMailboxInteractor(this.mailboxRepository); + + Stream> execute(AccountId accountId, RenameMailboxRequest request) async* { + try { + final result = await mailboxRepository.renameMailbox(accountId, request); + if (result) { + yield Right(RenameMailboxSuccess()); + } else { + yield Left(RenameMailboxFailure(null)); + } + } catch (e) { + yield Left(RenameMailboxFailure(e)); + } + } +} \ No newline at end of file diff --git a/lib/features/mailbox/presentation/mailbox_bindings.dart b/lib/features/mailbox/presentation/mailbox_bindings.dart index aa0cdf642..a2b6b2a1e 100644 --- a/lib/features/mailbox/presentation/mailbox_bindings.dart +++ b/lib/features/mailbox/presentation/mailbox_bindings.dart @@ -20,6 +20,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/create_new_mailbo import 'package:tmail_ui_user/features/mailbox/domain/usecases/delete_multiple_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_all_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/usecases/rename_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/search_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_controller.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_builder.dart'; @@ -49,6 +50,7 @@ class MailboxBindings extends BaseBindings { Get.find(), Get.find(), Get.find(), + Get.find(), Get.find(), Get.find(), Get.find(), @@ -80,6 +82,7 @@ class MailboxBindings extends BaseBindings { Get.lazyPut(() => SearchMailboxInteractor()); Get.lazyPut(() => DeleteMultipleMailboxInteractor(Get.find())); Get.lazyPut(() => VerifyNameInteractor()); + Get.lazyPut(() => RenameMailboxInteractor(Get.find())); } @override diff --git a/lib/features/mailbox/presentation/mailbox_controller.dart b/lib/features/mailbox/presentation/mailbox_controller.dart index 64a48d4fe..eb315e64e 100644 --- a/lib/features/mailbox/presentation/mailbox_controller.dart +++ b/lib/features/mailbox/presentation/mailbox_controller.dart @@ -15,14 +15,17 @@ import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_read_state.dart'; import 'package:tmail_ui_user/features/login/domain/usecases/delete_credential_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/create_new_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/delete_multiple_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/get_all_mailboxes_state.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/state/rename_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/search_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/create_new_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/delete_multiple_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_all_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/usecases/rename_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/search_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart'; @@ -60,6 +63,7 @@ class MailboxController extends BaseController { final SearchMailboxInteractor _searchMailboxInteractor; final DeleteMultipleMailboxInteractor _deleteMultipleMailboxInteractor; final VerifyNameInteractor _verifyNameInteractor; + final RenameMailboxInteractor _renameMailboxInteractor; final TreeBuilder _treeBuilder; final Uuid _uuid; final AppToast _appToast; @@ -89,6 +93,7 @@ class MailboxController extends BaseController { this._searchMailboxInteractor, this._deleteMultipleMailboxInteractor, this._verifyNameInteractor, + this._renameMailboxInteractor, this._treeBuilder, this._uuid, this._appToast, @@ -171,6 +176,8 @@ class MailboxController extends BaseController { if (isSearchActive()) { _searchMailboxAction(allMailboxes, searchQuery.value); } + } else if (success is RenameMailboxSuccess) { + refreshMailboxChanges(); } } ); @@ -615,7 +622,15 @@ class MailboxController extends BaseController { } void _renameMailboxAction(PresentationMailbox presentationMailbox, String newName) { + final accountId = mailboxDashBoardController.accountId.value; + if (accountId != null) { + consumeState(_renameMailboxInteractor.execute( + accountId, + RenameMailboxRequest(presentationMailbox.id, MailboxName(newName)))); + } + + _cancelSelectMailbox(); } void closeMailboxScreen(BuildContext context) {