TF-4053 Add interactor/datasource/repository for move folder content action
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import 'package:core/core.dart';
|
import 'package:core/utils/app_logger.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/error/set_error.dart';
|
import 'package:jmap_dart_client/jmap/core/error/set_error.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/id.dart';
|
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||||
|
|||||||
@@ -0,0 +1,304 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:math' hide log;
|
||||||
|
|
||||||
|
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';
|
||||||
|
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/capability/capability_identifier.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/capability/core_capability.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/error/set_error.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/filter/filter.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/id.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/session/session.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/sort/comparator.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/mail/email/email.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/email_comparator.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/email_comparator_property.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/email_filter_condition.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/get/get_email_method.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/get/get_email_response.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/query/query_email_method.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/query/query_email_response.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/set/set_email_method.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/set/set_email_response.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||||
|
import 'package:model/email/email_property.dart';
|
||||||
|
import 'package:model/extensions/list_email_extension.dart';
|
||||||
|
import 'package:model/extensions/list_email_id_extension.dart';
|
||||||
|
import 'package:model/extensions/list_id_extension.dart';
|
||||||
|
import 'package:model/extensions/session_extension.dart';
|
||||||
|
import 'package:tmail_ui_user/features/base/mixin/handle_error_mixin.dart';
|
||||||
|
import 'package:tmail_ui_user/features/email/domain/model/move_action.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox/domain/exceptions/mailbox_exception.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox/domain/state/move_folder_content_state.dart';
|
||||||
|
import 'package:tmail_ui_user/features/thread/data/extensions/list_email_extension.dart';
|
||||||
|
import 'package:tmail_ui_user/features/thread/data/extensions/list_email_id_extension.dart';
|
||||||
|
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart';
|
||||||
|
import 'package:tmail_ui_user/main/error/capability_validator.dart';
|
||||||
|
|
||||||
|
mixin MailAPIMixin on HandleSetErrorMixin {
|
||||||
|
int getMaxObjectsInSetMethod(Session session, AccountId accountId) {
|
||||||
|
final coreCapability = session.getCapabilityProperties<CoreCapability>(
|
||||||
|
accountId,
|
||||||
|
CapabilityIdentifier.jmapCore,
|
||||||
|
);
|
||||||
|
final maxObjectsInSetMethod =
|
||||||
|
coreCapability?.maxObjectsInSet?.value.toInt() ??
|
||||||
|
CapabilityIdentifierExtension.defaultMaxObjectsInSet;
|
||||||
|
|
||||||
|
final minOfMaxObjectsInSetMethod = min(
|
||||||
|
maxObjectsInSetMethod,
|
||||||
|
CapabilityIdentifierExtension.defaultMaxObjectsInSet,
|
||||||
|
);
|
||||||
|
log('$runtimeType::_getMaxObjectsInSetMethod:minOfMaxObjectsInSetMethod = $minOfMaxObjectsInSetMethod');
|
||||||
|
return minOfMaxObjectsInSetMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<({List<EmailId> emailIdsSuccess, Map<Id, SetError> mapErrors})>
|
||||||
|
moveEmailsBetweenMailboxes({
|
||||||
|
required HttpClient httpClient,
|
||||||
|
required Session session,
|
||||||
|
required AccountId accountId,
|
||||||
|
required List<EmailId> emailIds,
|
||||||
|
required MailboxId currentMailboxId,
|
||||||
|
required MailboxId destinationMailboxId,
|
||||||
|
bool markAsRead = false,
|
||||||
|
}) async {
|
||||||
|
final maxObjects = getMaxObjectsInSetMethod(session, accountId);
|
||||||
|
final totalEmails = emailIds.length;
|
||||||
|
final maxBatches = min(totalEmails, maxObjects);
|
||||||
|
|
||||||
|
final List<EmailId> updatedEmailIds = List.empty(growable: true);
|
||||||
|
final Map<Id, SetError> mapErrors = <Id, SetError>{};
|
||||||
|
|
||||||
|
for (int start = 0; start < totalEmails; start += maxBatches) {
|
||||||
|
int end =
|
||||||
|
(start + maxBatches < totalEmails) ? start + maxBatches : totalEmails;
|
||||||
|
log('$runtimeType::moveEmailsBetweenMailboxes:emails from ${start + 1} to $end');
|
||||||
|
|
||||||
|
final currentEmailIds = emailIds.sublist(start, end);
|
||||||
|
|
||||||
|
final moveProperties = currentEmailIds.generateMapUpdateObjectMoveToMailbox(
|
||||||
|
currentMailboxId: currentMailboxId,
|
||||||
|
destinationMailboxId: destinationMailboxId,
|
||||||
|
markAsRead: markAsRead,
|
||||||
|
);
|
||||||
|
|
||||||
|
final setEmailMethod = SetEmailMethod(accountId)
|
||||||
|
..addUpdates(moveProperties);
|
||||||
|
|
||||||
|
final requestBuilder =
|
||||||
|
JmapRequestBuilder(httpClient, ProcessingInvocation());
|
||||||
|
|
||||||
|
final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
|
||||||
|
|
||||||
|
final capabilities = setEmailMethod.requiredCapabilities
|
||||||
|
.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
||||||
|
|
||||||
|
final response =
|
||||||
|
await (requestBuilder..usings(capabilities)).build().execute();
|
||||||
|
|
||||||
|
final setEmailResponse = response.parse(
|
||||||
|
setEmailInvocation.methodCallId,
|
||||||
|
SetEmailResponse.deserialize,
|
||||||
|
);
|
||||||
|
|
||||||
|
final listEmailIds = setEmailResponse?.updated?.keys.toEmailIds() ?? [];
|
||||||
|
final mapErrors = handleSetResponse([setEmailResponse]);
|
||||||
|
|
||||||
|
updatedEmailIds.addAll(listEmailIds);
|
||||||
|
mapErrors.addAll(mapErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (emailIdsSuccess: updatedEmailIds, mapErrors: mapErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<EmailsResponse> fetchAllEmail({
|
||||||
|
required HttpClient httpClient,
|
||||||
|
required Session session,
|
||||||
|
required AccountId accountId,
|
||||||
|
UnsignedInt? limit,
|
||||||
|
int? position,
|
||||||
|
Set<Comparator>? sort,
|
||||||
|
Filter? filter,
|
||||||
|
Properties? properties,
|
||||||
|
}) async {
|
||||||
|
final processingInvocation = ProcessingInvocation();
|
||||||
|
|
||||||
|
final jmapRequestBuilder = JmapRequestBuilder(
|
||||||
|
httpClient,
|
||||||
|
processingInvocation,
|
||||||
|
);
|
||||||
|
|
||||||
|
final queryEmailMethod = QueryEmailMethod(accountId);
|
||||||
|
|
||||||
|
if (limit != null) queryEmailMethod.addLimit(limit);
|
||||||
|
|
||||||
|
if (position != null) queryEmailMethod.addPosition(position);
|
||||||
|
|
||||||
|
if (sort != null) queryEmailMethod.addSorts(sort);
|
||||||
|
|
||||||
|
if (filter != null) queryEmailMethod.addFilters(filter);
|
||||||
|
|
||||||
|
final queryEmailInvocation =
|
||||||
|
jmapRequestBuilder.invocation(queryEmailMethod);
|
||||||
|
|
||||||
|
final getEmailMethod = GetEmailMethod(accountId);
|
||||||
|
|
||||||
|
if (properties != null) getEmailMethod.addProperties(properties);
|
||||||
|
|
||||||
|
getEmailMethod.addReferenceIds(
|
||||||
|
processingInvocation.createResultReference(
|
||||||
|
queryEmailInvocation.methodCallId,
|
||||||
|
ReferencePath.idsPath,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final getEmailInvocation = jmapRequestBuilder.invocation(getEmailMethod);
|
||||||
|
|
||||||
|
final capabilities = getEmailMethod.requiredCapabilities
|
||||||
|
.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
||||||
|
|
||||||
|
final result =
|
||||||
|
await (jmapRequestBuilder..usings(capabilities)).build().execute();
|
||||||
|
|
||||||
|
final responseOfGetEmailMethod = result.parse<GetEmailResponse>(
|
||||||
|
getEmailInvocation.methodCallId,
|
||||||
|
GetEmailResponse.deserialize,
|
||||||
|
);
|
||||||
|
|
||||||
|
final responseOfQueryEmailMethod = result.parse<QueryEmailResponse>(
|
||||||
|
queryEmailInvocation.methodCallId,
|
||||||
|
QueryEmailResponse.deserialize,
|
||||||
|
);
|
||||||
|
|
||||||
|
final emailList = sortEmails(
|
||||||
|
getEmailResponse: responseOfGetEmailMethod,
|
||||||
|
queryEmailResponse: responseOfQueryEmailMethod,
|
||||||
|
);
|
||||||
|
|
||||||
|
final notFoundEmailIds =
|
||||||
|
responseOfGetEmailMethod?.notFound?.toEmailIds().toList();
|
||||||
|
log('$runtimeType::getAllEmail:notFoundEmailIds = ${notFoundEmailIds!.asListString.toString()} | NewState = ${responseOfGetEmailMethod?.state.value}');
|
||||||
|
return EmailsResponse(
|
||||||
|
emailList: emailList,
|
||||||
|
notFoundEmailIds: notFoundEmailIds,
|
||||||
|
state: responseOfGetEmailMethod?.state,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Email>? sortEmails({
|
||||||
|
GetEmailResponse? getEmailResponse,
|
||||||
|
QueryEmailResponse? queryEmailResponse,
|
||||||
|
}) {
|
||||||
|
final listEmails = getEmailResponse?.list;
|
||||||
|
final listIds = queryEmailResponse?.ids.toList();
|
||||||
|
|
||||||
|
if (listEmails?.isNotEmpty != true || listIds?.isNotEmpty != true) {
|
||||||
|
return listEmails;
|
||||||
|
}
|
||||||
|
|
||||||
|
final listSortedEmails = listEmails!.sortEmailsById(listIds!);
|
||||||
|
|
||||||
|
return listSortedEmails;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> moveAllEmailsBetweenFolders({
|
||||||
|
required HttpClient httpClient,
|
||||||
|
required Session session,
|
||||||
|
required AccountId accountId,
|
||||||
|
required MailboxId currentMailboxId,
|
||||||
|
required MailboxId destinationMailboxId,
|
||||||
|
required MoveAction moveAction,
|
||||||
|
int totalEmails = 0,
|
||||||
|
bool markAsRead = false,
|
||||||
|
StreamController<Either<Failure, Success>>? onProgressController,
|
||||||
|
}) async {
|
||||||
|
int countEmailsCompleted = 0;
|
||||||
|
bool hasEmails = true;
|
||||||
|
Email? lastEmail;
|
||||||
|
|
||||||
|
while (hasEmails) {
|
||||||
|
final listEmails = await getLatestEmails(
|
||||||
|
httpClient: httpClient,
|
||||||
|
session: session,
|
||||||
|
accountId: accountId,
|
||||||
|
mailboxId: currentMailboxId,
|
||||||
|
lastEmail: lastEmail,
|
||||||
|
);
|
||||||
|
log('$runtimeType::moveAllEmailsBetweenFolders(): Length of emails = ${listEmails.length}');
|
||||||
|
if (listEmails.isEmpty) {
|
||||||
|
hasEmails = false;
|
||||||
|
} else {
|
||||||
|
hasEmails = true;
|
||||||
|
lastEmail = listEmails.last;
|
||||||
|
|
||||||
|
final movedEmails = await moveEmailsBetweenMailboxes(
|
||||||
|
httpClient: httpClient,
|
||||||
|
session: session,
|
||||||
|
accountId: accountId,
|
||||||
|
emailIds: listEmails.listEmailIds,
|
||||||
|
currentMailboxId: currentMailboxId,
|
||||||
|
destinationMailboxId: destinationMailboxId,
|
||||||
|
markAsRead: markAsRead,
|
||||||
|
);
|
||||||
|
|
||||||
|
countEmailsCompleted += movedEmails.emailIdsSuccess.length;
|
||||||
|
|
||||||
|
onProgressController?.add(
|
||||||
|
Right<Failure, Success>(MoveFolderContentProgressState(
|
||||||
|
currentMailboxId,
|
||||||
|
countEmailsCompleted,
|
||||||
|
totalEmails,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log('$runtimeType::moveAllEmailsBetweenFolders(): Total emails moved = $countEmailsCompleted');
|
||||||
|
if (moveAction == MoveAction.moving &&
|
||||||
|
countEmailsCompleted < totalEmails &&
|
||||||
|
totalEmails > 0) {
|
||||||
|
throw CannotMoveAllEmailException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<Email>> getLatestEmails({
|
||||||
|
required HttpClient httpClient,
|
||||||
|
required Session session,
|
||||||
|
required AccountId accountId,
|
||||||
|
required MailboxId mailboxId,
|
||||||
|
Email? lastEmail,
|
||||||
|
}) async {
|
||||||
|
final response = await fetchAllEmail(
|
||||||
|
httpClient: httpClient,
|
||||||
|
session: session,
|
||||||
|
accountId: accountId,
|
||||||
|
sort: <Comparator>{}..add(
|
||||||
|
EmailComparator(
|
||||||
|
EmailComparatorProperty.receivedAt,
|
||||||
|
)..setIsAscending(false),
|
||||||
|
),
|
||||||
|
filter: EmailFilterCondition(
|
||||||
|
inMailbox: mailboxId,
|
||||||
|
before: lastEmail?.receivedAt,
|
||||||
|
),
|
||||||
|
properties: Properties({
|
||||||
|
EmailProperty.id,
|
||||||
|
EmailProperty.receivedAt,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (lastEmail?.id != null) {
|
||||||
|
return response.emailList?.withoutEmailWithId(lastEmail!.id!) ?? [];
|
||||||
|
} else {
|
||||||
|
return response.emailList ?? [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,8 +14,6 @@ import 'package:email_recovery/email_recovery/set/set_email_recovery_action_meth
|
|||||||
import 'package:email_recovery/email_recovery/set/set_email_recovery_action_response.dart';
|
import 'package:email_recovery/email_recovery/set/set_email_recovery_action_response.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/error/set_error.dart';
|
import 'package:jmap_dart_client/jmap/core/error/set_error.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/id.dart';
|
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/patch_object.dart';
|
import 'package:jmap_dart_client/jmap/core/patch_object.dart';
|
||||||
@@ -55,8 +53,10 @@ import 'package:model/extensions/list_email_id_extension.dart';
|
|||||||
import 'package:model/extensions/list_id_extension.dart';
|
import 'package:model/extensions/list_id_extension.dart';
|
||||||
import 'package:model/extensions/mailbox_id_extension.dart';
|
import 'package:model/extensions/mailbox_id_extension.dart';
|
||||||
import 'package:model/extensions/session_extension.dart';
|
import 'package:model/extensions/session_extension.dart';
|
||||||
|
import 'package:model/oidc/token_oidc.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:tmail_ui_user/features/base/mixin/handle_error_mixin.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/composer/domain/exceptions/set_method_exception.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
|
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
|
||||||
import 'package:tmail_ui_user/features/email/domain/exceptions/email_exceptions.dart';
|
import 'package:tmail_ui_user/features/email/domain/exceptions/email_exceptions.dart';
|
||||||
@@ -70,7 +70,7 @@ import 'package:tmail_ui_user/main/error/capability_validator.dart';
|
|||||||
import 'package:uri/uri.dart';
|
import 'package:uri/uri.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
class EmailAPI with HandleSetErrorMixin {
|
class EmailAPI with HandleSetErrorMixin, MailAPIMixin {
|
||||||
|
|
||||||
final HttpClient _httpClient;
|
final HttpClient _httpClient;
|
||||||
final DownloadManager _downloadManager;
|
final DownloadManager _downloadManager;
|
||||||
@@ -247,7 +247,7 @@ class EmailAPI with HandleSetErrorMixin {
|
|||||||
List<EmailId> emailIds,
|
List<EmailId> emailIds,
|
||||||
ReadActions readActions,
|
ReadActions readActions,
|
||||||
) async {
|
) async {
|
||||||
final maxObjects = _getMaxObjectsInSetMethod(session, accountId);
|
final maxObjects = getMaxObjectsInSetMethod(session, accountId);
|
||||||
final totalEmails = emailIds.length;
|
final totalEmails = emailIds.length;
|
||||||
final maxBatches = min(totalEmails, maxObjects);
|
final maxBatches = min(totalEmails, maxObjects);
|
||||||
|
|
||||||
@@ -455,13 +455,14 @@ class EmailAPI with HandleSetErrorMixin {
|
|||||||
final currentMailboxId = listMailboxIds[i];
|
final currentMailboxId = listMailboxIds[i];
|
||||||
final listEmailIds = moveRequest.currentMailboxes[currentMailboxId]!;
|
final listEmailIds = moveRequest.currentMailboxes[currentMailboxId]!;
|
||||||
log('EmailAPI::moveToMailbox:from mailbox ${currentMailboxId.asString} with ${listEmailIds.length} emails to mailbox ${moveRequest.destinationMailboxId.asString}');
|
log('EmailAPI::moveToMailbox:from mailbox ${currentMailboxId.asString} with ${listEmailIds.length} emails to mailbox ${moveRequest.destinationMailboxId.asString}');
|
||||||
final resultRecords = await _moveEmailsBetweenMailboxes(
|
final resultRecords = await moveEmailsBetweenMailboxes(
|
||||||
|
httpClient: _httpClient,
|
||||||
session: session,
|
session: session,
|
||||||
accountId: accountId,
|
accountId: accountId,
|
||||||
emailIds: listEmailIds,
|
emailIds: listEmailIds,
|
||||||
currentMailboxId: currentMailboxId,
|
currentMailboxId: currentMailboxId,
|
||||||
destinationMailboxId: moveRequest.destinationMailboxId,
|
destinationMailboxId: moveRequest.destinationMailboxId,
|
||||||
isMovingToSpam: moveRequest.isMovingToSpam,
|
markAsRead: moveRequest.isMovingToSpam,
|
||||||
);
|
);
|
||||||
|
|
||||||
listEmailIdResult.addAll(resultRecords.emailIdsSuccess);
|
listEmailIdResult.addAll(resultRecords.emailIdsSuccess);
|
||||||
@@ -471,88 +472,6 @@ class EmailAPI with HandleSetErrorMixin {
|
|||||||
return (emailIdsSuccess: listEmailIdResult, mapErrors: mapErrors);
|
return (emailIdsSuccess: listEmailIdResult, mapErrors: mapErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<({
|
|
||||||
List<EmailId> emailIdsSuccess,
|
|
||||||
Map<Id, SetError> mapErrors,
|
|
||||||
})> _moveEmailsBetweenMailboxes({
|
|
||||||
required Session session,
|
|
||||||
required AccountId accountId,
|
|
||||||
required List<EmailId> emailIds,
|
|
||||||
required MailboxId currentMailboxId,
|
|
||||||
required MailboxId destinationMailboxId,
|
|
||||||
bool isMovingToSpam = false,
|
|
||||||
}) async {
|
|
||||||
final maxObjects = _getMaxObjectsInSetMethod(session, accountId);
|
|
||||||
final totalEmails = emailIds.length;
|
|
||||||
final maxBatches = min(totalEmails, maxObjects);
|
|
||||||
|
|
||||||
final List<EmailId> updatedEmailIds = List.empty(growable: true);
|
|
||||||
final Map<Id, SetError> mapErrors = <Id, SetError>{};
|
|
||||||
|
|
||||||
for (int start = 0; start < totalEmails; start += maxBatches) {
|
|
||||||
int end = (start + maxBatches < totalEmails)
|
|
||||||
? start + maxBatches
|
|
||||||
: totalEmails;
|
|
||||||
log('EmailAPI::_moveEmailsBetweenMailboxes:emails from ${start + 1} to $end');
|
|
||||||
|
|
||||||
final currentEmailIds = emailIds.sublist(start, end);
|
|
||||||
|
|
||||||
final moveProperties = isMovingToSpam
|
|
||||||
? currentEmailIds.generateMapUpdateObjectMoveToSpam(
|
|
||||||
currentMailboxId,
|
|
||||||
destinationMailboxId,
|
|
||||||
)
|
|
||||||
: currentEmailIds.generateMapUpdateObjectMoveToMailbox(
|
|
||||||
currentMailboxId,
|
|
||||||
destinationMailboxId,
|
|
||||||
);
|
|
||||||
|
|
||||||
final setEmailMethod = SetEmailMethod(accountId)
|
|
||||||
..addUpdates(moveProperties);
|
|
||||||
|
|
||||||
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
|
|
||||||
|
|
||||||
final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
|
|
||||||
|
|
||||||
final capabilities = setEmailMethod.requiredCapabilities
|
|
||||||
.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
|
||||||
|
|
||||||
final response = await (requestBuilder
|
|
||||||
..usings(capabilities))
|
|
||||||
.build()
|
|
||||||
.execute();
|
|
||||||
|
|
||||||
final setEmailResponse = response.parse(
|
|
||||||
setEmailInvocation.methodCallId,
|
|
||||||
SetEmailResponse.deserialize,
|
|
||||||
);
|
|
||||||
|
|
||||||
final listEmailIds = setEmailResponse?.updated?.keys.toEmailIds() ?? [];
|
|
||||||
final mapErrors = handleSetResponse([setEmailResponse]);
|
|
||||||
|
|
||||||
updatedEmailIds.addAll(listEmailIds);
|
|
||||||
mapErrors.addAll(mapErrors);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (emailIdsSuccess: updatedEmailIds, mapErrors: mapErrors);
|
|
||||||
}
|
|
||||||
|
|
||||||
int _getMaxObjectsInSetMethod(Session session, AccountId accountId) {
|
|
||||||
final coreCapability = session.getCapabilityProperties<CoreCapability>(
|
|
||||||
accountId,
|
|
||||||
CapabilityIdentifier.jmapCore,
|
|
||||||
);
|
|
||||||
final maxObjectsInSetMethod = coreCapability?.maxObjectsInSet?.value.toInt()
|
|
||||||
?? CapabilityIdentifierExtension.defaultMaxObjectsInSet;
|
|
||||||
|
|
||||||
final minOfMaxObjectsInSetMethod = min(
|
|
||||||
maxObjectsInSetMethod,
|
|
||||||
CapabilityIdentifierExtension.defaultMaxObjectsInSet,
|
|
||||||
);
|
|
||||||
log('EmailAPI::_getMaxObjectsInSetMethod:minOfMaxObjectsInSetMethod = $minOfMaxObjectsInSetMethod');
|
|
||||||
return minOfMaxObjectsInSetMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<({
|
Future<({
|
||||||
List<EmailId> emailIdsSuccess,
|
List<EmailId> emailIdsSuccess,
|
||||||
Map<Id, SetError> mapErrors,
|
Map<Id, SetError> mapErrors,
|
||||||
@@ -562,7 +481,7 @@ class EmailAPI with HandleSetErrorMixin {
|
|||||||
List<EmailId> emailIds,
|
List<EmailId> emailIds,
|
||||||
MarkStarAction markStarAction
|
MarkStarAction markStarAction
|
||||||
) async {
|
) async {
|
||||||
final maxObjects = _getMaxObjectsInSetMethod(session, accountId);
|
final maxObjects = getMaxObjectsInSetMethod(session, accountId);
|
||||||
final totalEmails = emailIds.length;
|
final totalEmails = emailIds.length;
|
||||||
final maxBatches = min(totalEmails, maxObjects);
|
final maxBatches = min(totalEmails, maxObjects);
|
||||||
|
|
||||||
@@ -803,7 +722,7 @@ class EmailAPI with HandleSetErrorMixin {
|
|||||||
AccountId accountId,
|
AccountId accountId,
|
||||||
List<EmailId> emailIds
|
List<EmailId> emailIds
|
||||||
) async {
|
) async {
|
||||||
final maxObjects = _getMaxObjectsInSetMethod(session, accountId);
|
final maxObjects = getMaxObjectsInSetMethod(session, accountId);
|
||||||
final totalEmails = emailIds.length;
|
final totalEmails = emailIds.length;
|
||||||
final maxBatches = min(totalEmails, maxObjects);
|
final maxBatches = min(totalEmails, maxObjects);
|
||||||
|
|
||||||
|
|||||||
@@ -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/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/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/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/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/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/mailbox_right_request.dart';
|
||||||
@@ -40,6 +41,13 @@ abstract class MailboxDataSource {
|
|||||||
|
|
||||||
Future<bool> moveMailbox(Session session, AccountId accountId, MoveMailboxRequest request);
|
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(
|
Future<List<EmailId>> markAsMailboxRead(
|
||||||
Session session,
|
Session session,
|
||||||
AccountId accountId,
|
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/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/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/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/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/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/mailbox_right_request.dart';
|
||||||
@@ -166,4 +167,14 @@ class MailboxCacheDataSourceImpl extends MailboxDataSource {
|
|||||||
Future<UnsignedInt> clearMailbox(Session session, AccountId accountId, MailboxId mailboxId) {
|
Future<UnsignedInt> clearMailbox(Session session, AccountId accountId, MailboxId mailboxId) {
|
||||||
throw UnimplementedError();
|
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/failure.dart';
|
||||||
import 'package:core/presentation/state/success.dart';
|
import 'package:core/presentation/state/success.dart';
|
||||||
|
import 'package:core/utils/platform_info.dart';
|
||||||
import 'package:dartz/dartz.dart' as dartz;
|
import 'package:dartz/dartz.dart' as dartz;
|
||||||
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/error/set_error.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/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/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/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/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/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/mailbox_right_request.dart';
|
||||||
@@ -161,4 +163,33 @@ class MailboxDataSourceImpl extends MailboxDataSource {
|
|||||||
return await mailboxAPI.clearMailbox(session, accountId, mailboxId);
|
return await mailboxAPI.clearMailbox(session, accountId, mailboxId);
|
||||||
}).catchError(_exceptionThrower.throwException);
|
}).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 '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:core/utils/app_logger.dart';
|
||||||
|
import 'package:dartz/dartz.dart' hide State;
|
||||||
import 'package:flutter/material.dart' hide State;
|
import 'package:flutter/material.dart' hide State;
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:jmap_dart_client/http/http_client.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/mailbox/mailbox_constants.dart';
|
||||||
import 'package:model/model.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/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/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/data/model/mailbox_change_response.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox/domain/exceptions/mailbox_exception.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/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/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/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_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/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/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/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_mailbox_request.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_multiple_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:tmail_ui_user/main/error/capability_validator.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
class MailboxAPI with HandleSetErrorMixin {
|
class MailboxAPI with HandleSetErrorMixin, MailAPIMixin {
|
||||||
|
|
||||||
final HttpClient httpClient;
|
final HttpClient httpClient;
|
||||||
final Uuid _uuid;
|
final Uuid _uuid;
|
||||||
@@ -636,4 +641,23 @@ class MailboxAPI with HandleSetErrorMixin {
|
|||||||
throw NotFoundClearMailboxResponseException();
|
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/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/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/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/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/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/data/network/thread_api.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart';
|
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart';
|
||||||
import 'package:tmail_ui_user/main/exceptions/isolate_exception.dart';
|
import 'package:tmail_ui_user/main/exceptions/isolate_exception.dart';
|
||||||
@@ -213,4 +218,101 @@ class MailboxIsolateWorker {
|
|||||||
log('MailboxIsolateWorker::_handleMarkAsMailboxReadActionOnWeb(): TOTAL_READ: ${emailIdsCompleted.length}');
|
log('MailboxIsolateWorker::_handleMarkAsMailboxReadActionOnWeb(): TOTAL_READ: ${emailIdsCompleted.length}');
|
||||||
return emailIdsCompleted;
|
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/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/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/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/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/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/mailbox_right_request.dart';
|
||||||
@@ -305,4 +306,19 @@ class MailboxRepositoryImpl extends MailboxRepository {
|
|||||||
Future<UnsignedInt> clearMailbox(Session session, AccountId accountId, MailboxId mailboxId) {
|
Future<UnsignedInt> clearMailbox(Session session, AccountId accountId, MailboxId mailboxId) {
|
||||||
return mapDataSource[DataSourceType.network]!.clearMailbox(session, accountId, 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,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,3 +4,5 @@ class NotFoundInboxMailboxException implements Exception {}
|
|||||||
class NotFoundMailboxException implements Exception {}
|
class NotFoundMailboxException implements Exception {}
|
||||||
|
|
||||||
class NotFoundClearMailboxResponseException implements Exception {}
|
class NotFoundClearMailboxResponseException implements Exception {}
|
||||||
|
|
||||||
|
class CannotMoveAllEmailException implements Exception {}
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||||
|
import 'package:tmail_ui_user/features/email/domain/model/move_action.dart';
|
||||||
|
|
||||||
|
class MoveFolderContentRequest with EquatableMixin {
|
||||||
|
final MailboxId mailboxId;
|
||||||
|
final MoveAction moveAction;
|
||||||
|
final MailboxId destinationMailboxId;
|
||||||
|
final String destinationMailboxDisplayName;
|
||||||
|
final int totalEmails;
|
||||||
|
final bool markAsRead;
|
||||||
|
|
||||||
|
MoveFolderContentRequest({
|
||||||
|
required this.mailboxId,
|
||||||
|
required this.moveAction,
|
||||||
|
required this.destinationMailboxId,
|
||||||
|
required this.destinationMailboxDisplayName,
|
||||||
|
this.totalEmails = 0,
|
||||||
|
this.markAsRead = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [
|
||||||
|
mailboxId,
|
||||||
|
moveAction,
|
||||||
|
destinationMailboxId,
|
||||||
|
destinationMailboxDisplayName,
|
||||||
|
totalEmails,
|
||||||
|
markAsRead,
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@ 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';
|
||||||
import 'package:tmail_ui_user/features/mailbox/domain/model/get_mailbox_by_role_response.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/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/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/rename_mailbox_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_mailbox_request.dart';
|
||||||
@@ -41,6 +42,13 @@ abstract class MailboxRepository {
|
|||||||
|
|
||||||
Future<bool> moveMailbox(Session session, AccountId accountId, MoveMailboxRequest request);
|
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<State?> getMailboxState(Session session, AccountId accountId);
|
Future<State?> getMailboxState(Session session, AccountId accountId);
|
||||||
|
|
||||||
Future<bool> subscribeMailbox(Session session, AccountId accountId, SubscribeMailboxRequest request);
|
Future<bool> subscribeMailbox(Session session, AccountId accountId, SubscribeMailboxRequest request);
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import 'package:core/presentation/state/failure.dart';
|
||||||
|
import 'package:core/presentation/state/success.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox/domain/model/move_folder_content_request.dart';
|
||||||
|
|
||||||
|
class MovingFolderContent extends LoadingState {}
|
||||||
|
|
||||||
|
class MoveFolderContentProgressState extends UIState {
|
||||||
|
final MailboxId mailboxId;
|
||||||
|
final int countEmailsCompleted;
|
||||||
|
final int totalEmails;
|
||||||
|
|
||||||
|
MoveFolderContentProgressState(
|
||||||
|
this.mailboxId,
|
||||||
|
this.countEmailsCompleted,
|
||||||
|
this.totalEmails,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [
|
||||||
|
mailboxId,
|
||||||
|
countEmailsCompleted,
|
||||||
|
totalEmails,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
class MoveFolderContentSuccess extends UIState {
|
||||||
|
final MoveFolderContentRequest request;
|
||||||
|
|
||||||
|
MoveFolderContentSuccess(this.request);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [request];
|
||||||
|
}
|
||||||
|
|
||||||
|
class MoveFolderContentFailure extends FeatureFailure {
|
||||||
|
MoveFolderContentFailure(dynamic exception) : super(exception: exception);
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
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/session/session.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox/domain/model/move_folder_content_request.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox/domain/state/move_folder_content_state.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox/domain/state/move_mailbox_state.dart';
|
||||||
|
|
||||||
|
class MoveFolderContentInteractor {
|
||||||
|
final MailboxRepository _mailboxRepository;
|
||||||
|
|
||||||
|
MoveFolderContentInteractor(this._mailboxRepository);
|
||||||
|
|
||||||
|
Stream<void> execute({
|
||||||
|
required Session session,
|
||||||
|
required AccountId accountId,
|
||||||
|
required MoveFolderContentRequest request,
|
||||||
|
StreamController<Either<Failure, Success>>? onProgressController,
|
||||||
|
}) async* {
|
||||||
|
try {
|
||||||
|
yield Right<Failure, Success>(MovingFolderContent());
|
||||||
|
await _mailboxRepository.moveFolderContent(
|
||||||
|
session: session,
|
||||||
|
accountId: accountId,
|
||||||
|
request: request,
|
||||||
|
onProgressController: onProgressController,
|
||||||
|
);
|
||||||
|
yield Right<Failure, Success>(MoveFolderContentSuccess(request));
|
||||||
|
} catch (e) {
|
||||||
|
yield Left<Failure, Success>(MoveMailboxFailure(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -61,4 +61,7 @@ extension ListEmailExtension on List<Email> {
|
|||||||
),
|
),
|
||||||
).toList();
|
).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Email> withoutEmailWithId(EmailId emailId) =>
|
||||||
|
where((email) => email.id != emailId).toList();
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,8 @@ import 'package:jmap_dart_client/jmap/mail/email/get/get_email_response.dart';
|
|||||||
import 'package:jmap_dart_client/jmap/mail/email/query/query_email_method.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/query/query_email_method.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/query/query_email_response.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/query/query_email_response.dart';
|
||||||
import 'package:model/extensions/list_id_extension.dart';
|
import 'package:model/extensions/list_id_extension.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/data/extensions/list_email_extension.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:jmap_dart_client/jmap/mail/email/search_snippet/search_snippet.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/search_snippet/search_snippet.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/search_snippet/search_snippet_get_method.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/search_snippet/search_snippet_get_method.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/search_snippet/search_snippet_get_response.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/search_snippet/search_snippet_get_response.dart';
|
||||||
@@ -31,7 +32,7 @@ import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart';
|
|||||||
import 'package:tmail_ui_user/features/thread/domain/model/search_emails_response.dart';
|
import 'package:tmail_ui_user/features/thread/domain/model/search_emails_response.dart';
|
||||||
import 'package:tmail_ui_user/main/error/capability_validator.dart';
|
import 'package:tmail_ui_user/main/error/capability_validator.dart';
|
||||||
|
|
||||||
class ThreadAPI {
|
class ThreadAPI with HandleSetErrorMixin, MailAPIMixin {
|
||||||
|
|
||||||
final HttpClient httpClient;
|
final HttpClient httpClient;
|
||||||
|
|
||||||
@@ -48,81 +49,16 @@ class ThreadAPI {
|
|||||||
Properties? properties
|
Properties? properties
|
||||||
}
|
}
|
||||||
) async {
|
) async {
|
||||||
final processingInvocation = ProcessingInvocation();
|
return await fetchAllEmail(
|
||||||
|
httpClient: httpClient,
|
||||||
final jmapRequestBuilder = JmapRequestBuilder(httpClient, processingInvocation);
|
session: session,
|
||||||
|
accountId: accountId,
|
||||||
final queryEmailMethod = QueryEmailMethod(accountId);
|
limit: limit,
|
||||||
|
position: position,
|
||||||
if (limit != null) queryEmailMethod.addLimit(limit);
|
sort: sort,
|
||||||
|
filter: filter,
|
||||||
if (position != null) queryEmailMethod.addPosition(position);
|
properties: properties,
|
||||||
|
|
||||||
if (sort != null) queryEmailMethod.addSorts(sort);
|
|
||||||
|
|
||||||
if (filter != null) queryEmailMethod.addFilters(filter);
|
|
||||||
|
|
||||||
final queryEmailInvocation = jmapRequestBuilder.invocation(queryEmailMethod);
|
|
||||||
|
|
||||||
final getEmailMethod = GetEmailMethod(accountId);
|
|
||||||
|
|
||||||
if (properties != null) getEmailMethod.addProperties(properties);
|
|
||||||
|
|
||||||
getEmailMethod.addReferenceIds(processingInvocation.createResultReference(
|
|
||||||
queryEmailInvocation.methodCallId,
|
|
||||||
ReferencePath.idsPath));
|
|
||||||
|
|
||||||
final getEmailInvocation = jmapRequestBuilder.invocation(getEmailMethod);
|
|
||||||
|
|
||||||
final capabilities = getEmailMethod.requiredCapabilities
|
|
||||||
.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
|
||||||
|
|
||||||
final result = await (jmapRequestBuilder
|
|
||||||
..usings(capabilities))
|
|
||||||
.build()
|
|
||||||
.execute();
|
|
||||||
|
|
||||||
final responseOfGetEmailMethod = result.parse<GetEmailResponse>(
|
|
||||||
getEmailInvocation.methodCallId,
|
|
||||||
GetEmailResponse.deserialize,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
final responseOfQueryEmailMethod = result.parse<QueryEmailResponse>(
|
|
||||||
queryEmailInvocation.methodCallId,
|
|
||||||
QueryEmailResponse.deserialize,
|
|
||||||
);
|
|
||||||
|
|
||||||
final emailList = sortEmails(
|
|
||||||
getEmailResponse: responseOfGetEmailMethod,
|
|
||||||
queryEmailResponse: responseOfQueryEmailMethod,
|
|
||||||
);
|
|
||||||
|
|
||||||
final notFoundEmailIds = responseOfGetEmailMethod
|
|
||||||
?.notFound
|
|
||||||
?.toEmailIds()
|
|
||||||
.toList();
|
|
||||||
log('ThreadAPI::getAllEmail:notFoundEmailIds = ${notFoundEmailIds!.asListString.toString()} | NewState = ${responseOfGetEmailMethod?.state.value}');
|
|
||||||
return EmailsResponse(
|
|
||||||
emailList: emailList,
|
|
||||||
notFoundEmailIds: notFoundEmailIds,
|
|
||||||
state: responseOfGetEmailMethod?.state,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Email>? sortEmails({
|
|
||||||
GetEmailResponse? getEmailResponse,
|
|
||||||
QueryEmailResponse? queryEmailResponse,
|
|
||||||
}) {
|
|
||||||
final listEmails = getEmailResponse?.list;
|
|
||||||
final listIds = queryEmailResponse?.ids.toList();
|
|
||||||
|
|
||||||
if (listEmails?.isNotEmpty != true || listIds?.isNotEmpty != true) {
|
|
||||||
return listEmails;
|
|
||||||
}
|
|
||||||
|
|
||||||
final listSortedEmails = listEmails!.sortEmailsById(listIds!);
|
|
||||||
|
|
||||||
return listSortedEmails;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<SearchEmailsResponse> searchEmails(
|
Future<SearchEmailsResponse> searchEmails(
|
||||||
|
|||||||
@@ -16,10 +16,17 @@ extension ListEmailIdExtension on List<EmailId> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<Id, PatchObject> generateMapUpdateObjectMoveToMailbox(MailboxId currentMailboxId, MailboxId destinationMailboxId) {
|
Map<Id, PatchObject> generateMapUpdateObjectMoveToMailbox({
|
||||||
|
required MailboxId currentMailboxId,
|
||||||
|
required MailboxId destinationMailboxId,
|
||||||
|
bool markAsRead = false,
|
||||||
|
}) {
|
||||||
return {
|
return {
|
||||||
for (var emailId in this)
|
for (var emailId in this)
|
||||||
emailId.id: currentMailboxId.generateMoveToMailboxActionPath(destinationMailboxId)
|
emailId.id: currentMailboxId.generateMoveToMailboxActionPath(
|
||||||
|
destinationMailboxId: destinationMailboxId,
|
||||||
|
markAsRead: markAsRead,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,13 +37,6 @@ extension ListEmailIdExtension on List<EmailId> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<Id, PatchObject> generateMapUpdateObjectMoveToSpam(MailboxId currentMailboxId, MailboxId spamMailboxId) {
|
|
||||||
return {
|
|
||||||
for (var emailId in this)
|
|
||||||
emailId.id: currentMailboxId.generateMoveToSpamActionPath(currentMailboxId, spamMailboxId)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<Id, PatchObject> generateMapUpdateObjectMarkAsAnswered() {
|
Map<Id, PatchObject> generateMapUpdateObjectMarkAsAnswered() {
|
||||||
return {
|
return {
|
||||||
for (var emailId in this)
|
for (var emailId in this)
|
||||||
|
|||||||
@@ -13,10 +13,14 @@ extension MailboxIdExtension on MailboxId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PatchObject generateMoveToMailboxActionPath(MailboxId destinationMailboxId) {
|
PatchObject generateMoveToMailboxActionPath({
|
||||||
|
required MailboxId destinationMailboxId,
|
||||||
|
bool markAsRead = false,
|
||||||
|
}) {
|
||||||
return PatchObject({
|
return PatchObject({
|
||||||
generatePath(): null,
|
generatePath(): null,
|
||||||
destinationMailboxId.generatePath(): true
|
destinationMailboxId.generatePath(): true,
|
||||||
|
if (markAsRead) KeyWordIdentifier.emailSeen.generatePath(): true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,13 +30,5 @@ extension MailboxIdExtension on MailboxId {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
PatchObject generateMoveToSpamActionPath(MailboxId currentMailboxId, MailboxId spamMailboxId) {
|
|
||||||
return PatchObject({
|
|
||||||
currentMailboxId.generatePath(): null,
|
|
||||||
spamMailboxId.generatePath(): true,
|
|
||||||
KeyWordIdentifier.emailSeen.generatePath(): true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
String get asString => id.value;
|
String get asString => id.value;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user