TF-4053 Add interactor/datasource/repository for move folder content action
This commit is contained in:
@@ -17,6 +17,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/get_mailbox_by_role_response.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/jmap_mailbox_response.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/move_folder_content_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/move_mailbox_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_right_request.dart';
|
||||
@@ -40,6 +41,13 @@ abstract class MailboxDataSource {
|
||||
|
||||
Future<bool> moveMailbox(Session session, AccountId accountId, MoveMailboxRequest request);
|
||||
|
||||
Future<void> moveFolderContent({
|
||||
required Session session,
|
||||
required AccountId accountId,
|
||||
required MoveFolderContentRequest request,
|
||||
StreamController<dartz.Either<Failure, Success>>? onProgressController,
|
||||
});
|
||||
|
||||
Future<List<EmailId>> markAsMailboxRead(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
|
||||
@@ -21,6 +21,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/get_mailbox_by_role_response.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/jmap_mailbox_response.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/move_folder_content_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/move_mailbox_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_right_request.dart';
|
||||
@@ -166,4 +167,14 @@ class MailboxCacheDataSourceImpl extends MailboxDataSource {
|
||||
Future<UnsignedInt> clearMailbox(Session session, AccountId accountId, MailboxId mailboxId) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<EmailId>> moveFolderContent({
|
||||
required Session session,
|
||||
required AccountId accountId,
|
||||
required MoveFolderContentRequest request,
|
||||
StreamController<dartz.Either<Failure, Success>>? onProgressController,
|
||||
}) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import 'dart:async';
|
||||
|
||||
import 'package:core/presentation/state/failure.dart';
|
||||
import 'package:core/presentation/state/success.dart';
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:dartz/dartz.dart' as dartz;
|
||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/error/set_error.dart';
|
||||
@@ -20,6 +21,7 @@ import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_isolate_work
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/get_mailbox_by_role_response.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/jmap_mailbox_response.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/move_folder_content_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/move_mailbox_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_right_request.dart';
|
||||
@@ -161,4 +163,33 @@ class MailboxDataSourceImpl extends MailboxDataSource {
|
||||
return await mailboxAPI.clearMailbox(session, accountId, mailboxId);
|
||||
}).catchError(_exceptionThrower.throwException);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> moveFolderContent({
|
||||
required Session session,
|
||||
required AccountId accountId,
|
||||
required MoveFolderContentRequest request,
|
||||
StreamController<dartz.Either<Failure, Success>>? onProgressController,
|
||||
}) {
|
||||
return Future.sync(() async {
|
||||
if (PlatformInfo.isWeb) {
|
||||
return await mailboxAPI.moveFolderContent(
|
||||
session: session,
|
||||
accountId: accountId,
|
||||
request: request,
|
||||
onProgressController: onProgressController,
|
||||
);
|
||||
} else {
|
||||
return await _mailboxIsolateWorker.moveFolderContent(
|
||||
session: session,
|
||||
accountId: accountId,
|
||||
request: request,
|
||||
onProgressController: onProgressController,
|
||||
);
|
||||
}
|
||||
}).catchError((error, stackTrace) async {
|
||||
await _exceptionThrower.throwException(error, stackTrace);
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import 'package:equatable/equatable.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:tmail_ui_user/features/base/isolate/background_isolate_binary_messenger/background_isolate_binary_messenger.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/network/email_api.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/network/thread_api.dart';
|
||||
|
||||
class MoveFolderContentIsolateArguments with EquatableMixin {
|
||||
final Session session;
|
||||
final AccountId accountId;
|
||||
final MailboxId currentMailboxId;
|
||||
final MailboxId destinationMailboxId;
|
||||
final bool markAsRead;
|
||||
final ThreadAPI threadAPI;
|
||||
final EmailAPI emailAPI;
|
||||
final RootIsolateToken isolateToken;
|
||||
|
||||
MoveFolderContentIsolateArguments({
|
||||
required this.session,
|
||||
required this.threadAPI,
|
||||
required this.emailAPI,
|
||||
required this.accountId,
|
||||
required this.currentMailboxId,
|
||||
required this.destinationMailboxId,
|
||||
required this.isolateToken,
|
||||
this.markAsRead = false,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
session,
|
||||
accountId,
|
||||
threadAPI,
|
||||
emailAPI,
|
||||
currentMailboxId,
|
||||
destinationMailboxId,
|
||||
isolateToken,
|
||||
markAsRead,
|
||||
];
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:core/presentation/state/failure.dart';
|
||||
import 'package:core/presentation/state/success.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:dartz/dartz.dart' hide State;
|
||||
import 'package:flutter/material.dart' hide State;
|
||||
import 'package:get/get.dart';
|
||||
import 'package:jmap_dart_client/http/http_client.dart';
|
||||
@@ -32,6 +35,7 @@ import 'package:model/error_type_handler/set_method_error_handler_mixin.dart';
|
||||
import 'package:model/mailbox/mailbox_constants.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/base/mixin/handle_error_mixin.dart';
|
||||
import 'package:tmail_ui_user/features/base/mixin/mail_api_mixin.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/exceptions/set_method_exception.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_change_response.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/exceptions/mailbox_exception.dart';
|
||||
@@ -41,17 +45,18 @@ import 'package:tmail_ui_user/features/mailbox/domain/extensions/role_extension.
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/get_mailbox_by_role_response.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/jmap_mailbox_response.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_right_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subaddressing_action.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subscribe_state.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/move_folder_content_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/move_mailbox_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_right_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_mailbox_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_multiple_mailbox_request.dart';
|
||||
import 'package:tmail_ui_user/main/error/capability_validator.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class MailboxAPI with HandleSetErrorMixin {
|
||||
class MailboxAPI with HandleSetErrorMixin, MailAPIMixin {
|
||||
|
||||
final HttpClient httpClient;
|
||||
final Uuid _uuid;
|
||||
@@ -636,4 +641,23 @@ class MailboxAPI with HandleSetErrorMixin {
|
||||
throw NotFoundClearMailboxResponseException();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> moveFolderContent({
|
||||
required Session session,
|
||||
required AccountId accountId,
|
||||
required MoveFolderContentRequest request,
|
||||
StreamController<Either<Failure, Success>>? onProgressController,
|
||||
}) async {
|
||||
return await moveAllEmailsBetweenFolders(
|
||||
httpClient: httpClient,
|
||||
accountId: accountId,
|
||||
session: session,
|
||||
moveAction: request.moveAction,
|
||||
currentMailboxId: request.mailboxId,
|
||||
destinationMailboxId: request.destinationMailboxId,
|
||||
totalEmails: request.totalEmails,
|
||||
markAsRead: request.markAsRead,
|
||||
onProgressController: onProgressController,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -23,8 +23,13 @@ import 'package:model/extensions/list_email_extension.dart';
|
||||
import 'package:tmail_ui_user/features/base/isolate/background_isolate_binary_messenger/background_isolate_binary_messenger.dart';
|
||||
import 'package:tmail_ui_user/features/caching/config/hive_cache_config.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/network/email_api.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/model/move_action.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_mark_as_read_arguments.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/data/model/move_folder_content_isolate_arguments.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/exceptions/mailbox_exception.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/move_folder_content_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/state/mark_as_mailbox_read_state.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/state/move_folder_content_state.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/network/thread_api.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart';
|
||||
import 'package:tmail_ui_user/main/exceptions/isolate_exception.dart';
|
||||
@@ -213,4 +218,101 @@ class MailboxIsolateWorker {
|
||||
log('MailboxIsolateWorker::_handleMarkAsMailboxReadActionOnWeb(): TOTAL_READ: ${emailIdsCompleted.length}');
|
||||
return emailIdsCompleted;
|
||||
}
|
||||
|
||||
Future<void> moveFolderContent({
|
||||
required Session session,
|
||||
required AccountId accountId,
|
||||
required MoveFolderContentRequest request,
|
||||
StreamController<Either<Failure, Success>>? onProgressController,
|
||||
}) async {
|
||||
final rootIsolateToken = RootIsolateToken.instance;
|
||||
if (rootIsolateToken == null) {
|
||||
throw CanNotGetRootIsolateToken();
|
||||
}
|
||||
|
||||
final countEmailsCompleted = await _isolateExecutor.execute(
|
||||
arg1: MoveFolderContentIsolateArguments(
|
||||
session: session,
|
||||
accountId: accountId,
|
||||
threadAPI: _threadApi,
|
||||
emailAPI: _emailApi,
|
||||
currentMailboxId: request.mailboxId,
|
||||
destinationMailboxId: request.destinationMailboxId,
|
||||
isolateToken: rootIsolateToken,
|
||||
markAsRead: request.markAsRead,
|
||||
),
|
||||
fun1: _moveFolderContentIsolateMethod,
|
||||
notification: (value) {
|
||||
if (value is int) {
|
||||
log('$runtimeType::moveFolderContent(): Progress percent is ${value / request.totalEmails}');
|
||||
onProgressController?.add(
|
||||
Right<Failure, Success>(MoveFolderContentProgressState(
|
||||
request.mailboxId,
|
||||
value,
|
||||
request.totalEmails,
|
||||
)),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (request.moveAction == MoveAction.moving &&
|
||||
countEmailsCompleted < request.totalEmails &&
|
||||
request.totalEmails > 0) {
|
||||
throw CannotMoveAllEmailException();
|
||||
}
|
||||
}
|
||||
|
||||
static Future<int> _moveFolderContentIsolateMethod(
|
||||
MoveFolderContentIsolateArguments args,
|
||||
TypeSendPort sendPort,
|
||||
) async {
|
||||
final rootIsolateToken = args.isolateToken;
|
||||
BackgroundIsolateBinaryMessenger.ensureInitialized(rootIsolateToken);
|
||||
await HiveCacheConfig.instance.setUp();
|
||||
|
||||
int countEmailsCompleted = 0;
|
||||
bool hasEmails = true;
|
||||
Email? lastEmail;
|
||||
|
||||
final threadAPI = args.threadAPI;
|
||||
final httpClient = threadAPI.httpClient;
|
||||
final session = args.session;
|
||||
final accountId = args.accountId;
|
||||
final currentMailboxId = args.currentMailboxId;
|
||||
final destinationMailboxId = args.destinationMailboxId;
|
||||
final markAsRead = args.markAsRead;
|
||||
|
||||
while (hasEmails) {
|
||||
final listEmails = await threadAPI.getLatestEmails(
|
||||
httpClient: httpClient,
|
||||
session: session,
|
||||
accountId: accountId,
|
||||
mailboxId: currentMailboxId,
|
||||
lastEmail: lastEmail,
|
||||
);
|
||||
log('MailboxIsolateWorker::_moveFolderContentIsolateMethod(): Length of emails = ${listEmails.length}');
|
||||
if (listEmails.isEmpty) {
|
||||
hasEmails = false;
|
||||
} else {
|
||||
hasEmails = true;
|
||||
lastEmail = listEmails.last;
|
||||
|
||||
final movedEmails = await threadAPI.moveEmailsBetweenMailboxes(
|
||||
httpClient: httpClient,
|
||||
session: session,
|
||||
accountId: accountId,
|
||||
emailIds: listEmails.listEmailIds,
|
||||
currentMailboxId: currentMailboxId,
|
||||
destinationMailboxId: destinationMailboxId,
|
||||
markAsRead: markAsRead,
|
||||
);
|
||||
|
||||
countEmailsCompleted += movedEmails.emailIdsSuccess.length;
|
||||
sendPort.send(countEmailsCompleted);
|
||||
}
|
||||
}
|
||||
log('MailboxIsolateWorker::_moveFolderContentIsolateMethod(): Total emails moved = $countEmailsCompleted');
|
||||
return countEmailsCompleted;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_r
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/get_mailbox_by_role_response.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/jmap_mailbox_response.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_response.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/move_folder_content_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/move_mailbox_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_right_request.dart';
|
||||
@@ -305,4 +306,19 @@ class MailboxRepositoryImpl extends MailboxRepository {
|
||||
Future<UnsignedInt> clearMailbox(Session session, AccountId accountId, MailboxId mailboxId) {
|
||||
return mapDataSource[DataSourceType.network]!.clearMailbox(session, accountId, mailboxId);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> moveFolderContent({
|
||||
required Session session,
|
||||
required AccountId accountId,
|
||||
required MoveFolderContentRequest request,
|
||||
StreamController<dartz.Either<Failure, Success>>? onProgressController,
|
||||
}) {
|
||||
return mapDataSource[DataSourceType.network]!.moveFolderContent(
|
||||
session: session,
|
||||
accountId: accountId,
|
||||
request: request,
|
||||
onProgressController: onProgressController,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user