diff --git a/lib/features/base/mixin/batch_set_email_processing_mixin.dart b/lib/features/base/mixin/batch_set_email_processing_mixin.dart new file mode 100644 index 000000000..257117891 --- /dev/null +++ b/lib/features/base/mixin/batch_set_email_processing_mixin.dart @@ -0,0 +1,90 @@ +import 'dart:math' hide log; + +import 'package:core/utils/app_logger.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/error/set_error.dart'; +import 'package:jmap_dart_client/jmap/core/id.dart'; +import 'package:jmap_dart_client/jmap/core/method/response/set_response.dart'; +import 'package:jmap_dart_client/jmap/core/patch_object.dart'; +import 'package:jmap_dart_client/jmap/core/session/session.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/set/set_email_method.dart'; +import 'package:jmap_dart_client/jmap/mail/email/set/set_email_response.dart'; +import 'package:model/extensions/list_id_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:tmail_ui_user/main/error/capability_validator.dart'; + +typedef OnGeneratePatchObjectUpdates = Map Function( + List batchIds, +); + +mixin BatchSetEmailProcessingMixin on HandleSetErrorMixin, MailAPIMixin { + Future< + ({ + List emailIdsSuccess, + Map mapErrors, + })> executeBatchSetEmail({ + required Session session, + required AccountId accountId, + required List emailIds, + required HttpClient httpClient, + required OnGeneratePatchObjectUpdates onGenerateUpdates, + String debugLabel = 'executeBatchSetEmail', + }) async { + if (emailIds.isEmpty) { + return (emailIdsSuccess: [], mapErrors: {}); + } + + final maxObjects = getMaxObjectsInSetMethod(session, accountId); + final totalEmails = emailIds.length; + final maxBatches = min(totalEmails, maxObjects); + + final List updatedEmailIds = List.empty(growable: true); + final List listSetResponse = List.empty(growable: true); + + for (int start = 0; start < totalEmails; start += maxBatches) { + int end = + (start + maxBatches < totalEmails) ? start + maxBatches : totalEmails; + + log('EmailAPI::$debugLabel:emails from ${start + 1} to $end'); + + final currentListEmailIds = emailIds.sublist(start, end); + + final setEmailMethod = SetEmailMethod(accountId) + ..addUpdates(onGenerateUpdates(currentListEmailIds)); + + 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, + ); + + if (setEmailResponse == null) continue; + + final listEmailIds = setEmailResponse.updated?.keys.toEmailIds() ?? []; + updatedEmailIds.addAll(listEmailIds); + listSetResponse.add(setEmailResponse); + } + + Map mapErrors = {}; + if (listSetResponse.isNotEmpty) { + mapErrors = handleSetResponse(listSetResponse); + } + + return (emailIdsSuccess: updatedEmailIds, mapErrors: mapErrors); + } +}