TF-320 Delete mailbox with sub-mailbox

This commit is contained in:
Dat PHAM HOANG
2022-03-14 12:16:26 +07:00
committed by Dat H. Pham
parent 0c1d069856
commit 5636625fa5
8 changed files with 70 additions and 39 deletions
@@ -1,5 +1,6 @@
import 'package:jmap_dart_client/jmap/account_id.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/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/core/state.dart'; import 'package:jmap_dart_client/jmap/core/state.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; 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/data/model/mailbox_change_response.dart';
@@ -18,7 +19,7 @@ abstract class MailboxDataSource {
Future<Mailbox?> createNewMailbox(AccountId accountId, CreateNewMailboxRequest newMailboxRequest); Future<Mailbox?> createNewMailbox(AccountId accountId, CreateNewMailboxRequest newMailboxRequest);
Future<bool> deleteMultipleMailbox(AccountId accountId, List<MailboxId> mailboxIds); Future<bool> deleteMultipleMailbox(Session session, AccountId accountId, List<MailboxId> mailboxIds);
Future<bool> renameMailbox(AccountId accountId, RenameMailboxRequest request); Future<bool> renameMailbox(AccountId accountId, RenameMailboxRequest request);
} }
@@ -1,11 +1,12 @@
import 'package:jmap_dart_client/jmap/account_id.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/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/core/state.dart'; import 'package:jmap_dart_client/jmap/core/state.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:tmail_ui_user/features/mailbox/data/datasource/mailbox_datasource.dart'; import 'package:tmail_ui_user/features/mailbox/data/datasource/mailbox_datasource.dart';
import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_change_response.dart';
import 'package:tmail_ui_user/features/mailbox/data/local/mailbox_cache_manager.dart';
import 'package:tmail_ui_user/features/mailbox/data/extensions/mailbox_extension.dart'; import 'package:tmail_ui_user/features/mailbox/data/extensions/mailbox_extension.dart';
import 'package:tmail_ui_user/features/mailbox/data/local/mailbox_cache_manager.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/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/mailbox_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart';
@@ -52,7 +53,7 @@ class MailboxCacheDataSourceImpl extends MailboxDataSource {
} }
@override @override
Future<bool> deleteMultipleMailbox(AccountId accountId, List<MailboxId> mailboxIds) { Future<bool> deleteMultipleMailbox(Session session, AccountId accountId, List<MailboxId> mailboxIds) {
throw UnimplementedError(); throw UnimplementedError();
} }
@@ -1,12 +1,13 @@
import 'package:jmap_dart_client/jmap/account_id.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/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/core/state.dart'; import 'package:jmap_dart_client/jmap/core/state.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:tmail_ui_user/features/mailbox/data/datasource/mailbox_datasource.dart'; import 'package:tmail_ui_user/features/mailbox/data/datasource/mailbox_datasource.dart';
import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_change_response.dart'; import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_change_response.dart';
import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_api.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.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/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'; import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart';
class MailboxDataSourceImpl extends MailboxDataSource { class MailboxDataSourceImpl extends MailboxDataSource {
@@ -53,9 +54,9 @@ class MailboxDataSourceImpl extends MailboxDataSource {
} }
@override @override
Future<bool> deleteMultipleMailbox(AccountId accountId, List<MailboxId> mailboxIds) { Future<bool> deleteMultipleMailbox(Session session, AccountId accountId, List<MailboxId> mailboxIds) {
return Future.sync(() async { return Future.sync(() async {
return await mailboxAPI.deleteMultipleMailbox(accountId, mailboxIds); return await mailboxAPI.deleteMultipleMailbox(session, accountId, mailboxIds);
}).catchError((error) { }).catchError((error) {
throw error; throw error;
}); });
@@ -1,10 +1,14 @@
import 'dart:async'; import 'dart:async';
import 'package:core/utils/app_logger.dart';
import 'package:jmap_dart_client/http/http_client.dart'; import 'package:jmap_dart_client/http/http_client.dart';
import 'package:jmap_dart_client/jmap/account_id.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/capability/core_capability.dart';
import 'package:jmap_dart_client/jmap/core/patch_object.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/properties/properties.dart';
import 'package:jmap_dart_client/jmap/core/request/reference_path.dart'; import 'package:jmap_dart_client/jmap/core/request/reference_path.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/core/state.dart'; 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/core/unsigned_int.dart';
import 'package:jmap_dart_client/jmap/jmap_request.dart'; import 'package:jmap_dart_client/jmap/jmap_request.dart';
@@ -20,6 +24,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/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/mailbox_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart';
import 'package:tmail_ui_user/main/error/capability_validator.dart';
class MailboxAPI { class MailboxAPI {
@@ -131,29 +136,46 @@ class MailboxAPI {
}); });
} }
Future<bool> deleteMultipleMailbox(AccountId accountId, List<MailboxId> mailboxIds) async { Future<bool> deleteMultipleMailbox(Session session, AccountId accountId, List<MailboxId> mailboxIds) async {
final setMailboxMethod = SetMailboxMethod(accountId) requireCapability(session, [CapabilityIdentifier.jmapCore, CapabilityIdentifier.jmapMail]);
..addDestroy(mailboxIds.map((mailboxId) => mailboxId.id).toSet())
..addOnDestroyRemoveEmails(true);
final requestBuilder = JmapRequestBuilder(httpClient, ProcessingInvocation()); final coreCapability = (session.capabilities[CapabilityIdentifier.jmapCore] as CoreCapability);
final maxMethodCount = coreCapability.maxCallsInRequest.value.toInt();
final setMailboxInvocation = requestBuilder.invocation(setMailboxMethod); var finalResult = true;
var start = 0;
var end = 0;
while (end < mailboxIds.length) {
start = end;
if (mailboxIds.length - start >= maxMethodCount) {
end = maxMethodCount;
} else {
end = mailboxIds.length;
}
log('MailboxAPI::deleteMultipleMailbox(): delete from $start to $end / ${mailboxIds.length}');
final currentExecuteList = mailboxIds.sublist(start, end);
final response = await (requestBuilder final requestBuilder = JmapRequestBuilder(httpClient, ProcessingInvocation());
..usings(setMailboxMethod.requiredCapabilities)) final currentSetMailboxInvocations = currentExecuteList.map((mailboxId) {
.build() return SetMailboxMethod(accountId)
.execute(); ..addDestroy(Set.of([mailboxId.id]))
..addOnDestroyRemoveEmails(true);
})
.map(requestBuilder.invocation)
.toList();
final setMailboxResponse = response.parse<SetMailboxResponse>( final response = await (requestBuilder
setMailboxInvocation.methodCallId, ..usings(Set.of([CapabilityIdentifier.jmapCore, CapabilityIdentifier.jmapMail])))
SetMailboxResponse.deserialize); .build()
.execute();
return Future.sync(() async { finalResult = currentSetMailboxInvocations
return setMailboxResponse?.destroyed?.isNotEmpty == true; .map((currentInvocation) => response.parse(currentInvocation.methodCallId, SetMailboxResponse.deserialize))
}).catchError((error) { .map((response) => response?.destroyed?.isNotEmpty ?? false)
throw error; .every((element) => element == true);
}); }
return finalResult;
} }
Future<bool> renameMailbox(AccountId accountId, RenameMailboxRequest request) async { Future<bool> renameMailbox(AccountId accountId, RenameMailboxRequest request) async {
@@ -1,15 +1,16 @@
import 'package:core/core.dart'; import 'package:core/core.dart';
import 'package:jmap_dart_client/jmap/account_id.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/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/core/state.dart'; import 'package:jmap_dart_client/jmap/core/state.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/model.dart'; import 'package:model/model.dart';
import 'package:tmail_ui_user/features/mailbox/data/datasource/mailbox_datasource.dart'; import 'package:tmail_ui_user/features/mailbox/data/datasource/mailbox_datasource.dart';
import 'package:tmail_ui_user/features/mailbox/data/datasource/state_datasource.dart'; import 'package:tmail_ui_user/features/mailbox/data/datasource/state_datasource.dart';
import 'package:tmail_ui_user/features/mailbox/data/extensions/state_extension.dart'; import 'package:tmail_ui_user/features/mailbox/data/extensions/state_extension.dart';
import 'package:tmail_ui_user/features/mailbox/data/model/state_type.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.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/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/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/repository/mailbox_repository.dart';
@@ -143,8 +144,8 @@ class MailboxRepositoryImpl extends MailboxRepository {
} }
@override @override
Future<bool> deleteMultipleMailbox(AccountId accountId, List<MailboxId> mailboxIds) { Future<bool> deleteMultipleMailbox(Session session, AccountId accountId, List<MailboxId> mailboxIds) {
return mapDataSource[DataSourceType.network]!.deleteMultipleMailbox(accountId, mailboxIds); return mapDataSource[DataSourceType.network]!.deleteMultipleMailbox(session, accountId, mailboxIds);
} }
@override @override
@@ -1,5 +1,6 @@
import 'package:jmap_dart_client/jmap/account_id.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/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/core/state.dart'; import 'package:jmap_dart_client/jmap/core/state.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.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/create_new_mailbox_request.dart';
@@ -13,7 +14,7 @@ abstract class MailboxRepository {
Future<Mailbox?> createNewMailbox(AccountId accountId, CreateNewMailboxRequest newMailboxRequest); Future<Mailbox?> createNewMailbox(AccountId accountId, CreateNewMailboxRequest newMailboxRequest);
Future<bool> deleteMultipleMailbox(AccountId accountId, List<MailboxId> mailboxIds); Future<bool> deleteMultipleMailbox(Session session, AccountId accountId, List<MailboxId> mailboxIds);
Future<bool> renameMailbox(AccountId accountId, RenameMailboxRequest request); Future<bool> renameMailbox(AccountId accountId, RenameMailboxRequest request);
} }
@@ -1,6 +1,7 @@
import 'package:core/core.dart'; import 'package:core/core.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart'; import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/delete_multiple_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/delete_multiple_mailbox_state.dart';
@@ -10,9 +11,9 @@ class DeleteMultipleMailboxInteractor {
DeleteMultipleMailboxInteractor(this.mailboxRepository); DeleteMultipleMailboxInteractor(this.mailboxRepository);
Stream<Either<Failure, Success>> execute(AccountId accountId, List<MailboxId> mailboxIds) async* { Stream<Either<Failure, Success>> execute(Session session, AccountId accountId, List<MailboxId> mailboxIds) async* {
try { try {
final result = await mailboxRepository.deleteMultipleMailbox(accountId, mailboxIds); final result = await mailboxRepository.deleteMultipleMailbox(session, accountId, mailboxIds);
if (result) { if (result) {
yield Right<Failure, Success>(DeleteMultipleMailboxSuccess()); yield Right<Failure, Success>(DeleteMultipleMailboxSuccess());
} else { } else {
@@ -464,16 +464,19 @@ class MailboxController extends BaseMailboxController {
final matchedNode = findMailboxNodeById(presentationMailbox.id); final matchedNode = findMailboxNodeById(presentationMailbox.id);
final accountId = mailboxDashBoardController.accountId.value; final accountId = mailboxDashBoardController.accountId.value;
final session = mailboxDashBoardController.sessionCurrent;
if (matchedNode != null && accountId != null) { if (session != null) {
final descendantIds = matchedNode.descendantsAsList() if (matchedNode != null && accountId != null) {
.map((node) => node.item.id) final descendantIds = matchedNode.descendantsAsList()
.toList(); .map((node) => node.item.id)
.toList();
final descendantIdsReversed = descendantIds.reversed.toList(); final descendantIdsReversed = descendantIds.reversed.toList();
consumeState(_deleteMultipleMailboxInteractor.execute(accountId, descendantIdsReversed)); consumeState(_deleteMultipleMailboxInteractor.execute(session, accountId, descendantIdsReversed));
} else { } else {
_deleteMailboxFailure(DeleteMultipleMailboxFailure(null)); _deleteMailboxFailure(DeleteMultipleMailboxFailure(null));
}
} }
_cancelSelectMailbox(); _cancelSelectMailbox();