feat: Implement get label changes

This commit is contained in:
dab246
2025-12-02 09:45:29 +07:00
committed by Dat H. Pham
parent 73134d2833
commit 987ea410c5
6 changed files with 314 additions and 23 deletions
@@ -0,0 +1,103 @@
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/id.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/jmap_request.dart';
import 'package:labels/method/get/get_label_method.dart';
import 'package:labels/method/get/get_label_response.dart';
import 'package:labels/model/label.dart';
import 'package:tmail_ui_user/features/base/mixin/handle_error_mixin.dart';
import 'package:tmail_ui_user/features/base/mixin/session_mixin.dart';
mixin BatchGetLabelProcessingMixin on HandleSetErrorMixin, SessionMixin {
Future<
({
List<Label> labels,
List<Id> notFoundIds,
State? state,
})> executeBatchGetLabel({
required Session session,
required AccountId accountId,
required List<Id> labelIds,
required HttpClient httpClient,
String debugLabel = 'executeBatchGetLabel',
}) async {
if (labelIds.isEmpty) {
return (labels: <Label>[], notFoundIds: <Id>[], state: null);
}
final maxObjects = getMaxObjectsInGetMethod(session, accountId);
final totalEmails = labelIds.length;
final batchSize = max(1, min(totalEmails, maxObjects));
final List<Label> allLabels = [];
final List<Id> allNotFoundIds = [];
State? latestState;
for (int start = 0; start < totalEmails; start += batchSize) {
int end =
(start + batchSize < totalEmails) ? start + batchSize : totalEmails;
final currentListIds = labelIds.sublist(start, end);
log('BatchGetLabelProcessingMixin::$debugLabel: processing batch ${start + 1} to $end');
try {
final response = await _executeGetLabelBatch(
accountId: accountId,
httpClient: httpClient,
labelIds: currentListIds,
);
if (response == null) {
throw Exception('GetLabelResponse is null');
}
if (response.list.isNotEmpty) {
allLabels.addAll(response.list);
}
latestState = response.state;
final notFoundIds = response.notFound ?? [];
if (notFoundIds.isNotEmpty) {
allNotFoundIds.addAll(notFoundIds);
}
} catch (e) {
logWarning(
'BatchGetLabelProcessingMixin::$debugLabel: Error processing batch ${start + 1}-$end: $e',
);
}
}
return (labels: allLabels, notFoundIds: allNotFoundIds, state: latestState);
}
Future<GetLabelResponse?> _executeGetLabelBatch({
required AccountId accountId,
required HttpClient httpClient,
required List<Id> labelIds,
}) async {
final getLabelMethod = GetLabelMethod(accountId)..addIds(labelIds.toSet());
final requestBuilder = JmapRequestBuilder(
httpClient,
ProcessingInvocation(),
);
final invocation = requestBuilder.invocation(getLabelMethod);
final response = await (requestBuilder
..usings(getLabelMethod.requiredCapabilities))
.build()
.execute();
return response.parse<GetLabelResponse>(
invocation.methodCallId,
GetLabelResponse.deserialize,
);
}
}
+2 -21
View File
@@ -7,8 +7,6 @@ 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';
@@ -33,8 +31,8 @@ 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/base/mixin/session_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';
@@ -43,24 +41,7 @@ import 'package:tmail_ui_user/features/thread/data/extensions/list_email_id_exte
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;
}
mixin MailAPIMixin on HandleSetErrorMixin, SessionMixin {
Future<({List<EmailId> emailIdsSuccess, Map<Id, SetError> mapErrors})>
moveEmailsBetweenMailboxes({
required HttpClient httpClient,
@@ -0,0 +1,41 @@
import 'dart:math' hide log;
import 'package:core/utils/app_logger.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/session/session.dart';
import 'package:model/extensions/session_extension.dart';
import 'package:tmail_ui_user/main/error/capability_validator.dart';
mixin SessionMixin {
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;
}
int getMaxObjectsInGetMethod(Session session, AccountId accountId) {
final maxObjectsInGetMethod =
session.getMaxObjectsInGet(accountId)?.value.toInt() ??
CapabilityIdentifierExtension.defaultMaxObjectsInGet;
final minOfMaxObjectsInGetMethod = min(
maxObjectsInGetMethod,
CapabilityIdentifierExtension.defaultMaxObjectsInGet,
);
log('$runtimeType::getMaxObjectsInGetMethod:minOfMaxObjectsInGetMethod = $minOfMaxObjectsInGetMethod');
return minOfMaxObjectsInGetMethod;
}
}