diff --git a/lib/features/email/data/datasource/email_datasource.dart b/lib/features/email/data/datasource/email_datasource.dart index c8bc6610d..f0c93160c 100644 --- a/lib/features/email/data/datasource/email_datasource.dart +++ b/lib/features/email/data/datasource/email_datasource.dart @@ -212,7 +212,10 @@ abstract class EmailDataSource { KeyWordIdentifier labelKeyword, ); - Future addLabelToThread( + Future<({ + List emailIdsSuccess, + Map mapErrors, + })> addLabelToThread( Session session, AccountId accountId, List emailIds, @@ -226,7 +229,10 @@ abstract class EmailDataSource { KeyWordIdentifier labelKeyword, ); - Future removeLabelFromThread( + Future<({ + List emailIdsSuccess, + Map mapErrors, + })> removeLabelFromThread( Session session, AccountId accountId, List emailIds, diff --git a/lib/features/email/data/datasource_impl/email_datasource_impl.dart b/lib/features/email/data/datasource_impl/email_datasource_impl.dart index 568a46e8d..05742c20e 100644 --- a/lib/features/email/data/datasource_impl/email_datasource_impl.dart +++ b/lib/features/email/data/datasource_impl/email_datasource_impl.dart @@ -572,7 +572,10 @@ class EmailDataSourceImpl extends EmailDataSource { } @override - Future addLabelToThread( + Future<({ + List emailIdsSuccess, + Map mapErrors, + })> addLabelToThread( Session session, AccountId accountId, List emailIds, @@ -606,7 +609,10 @@ class EmailDataSourceImpl extends EmailDataSource { } @override - Future removeLabelFromThread( + Future<({ + List emailIdsSuccess, + Map mapErrors, + })> removeLabelFromThread( Session session, AccountId accountId, List emailIds, diff --git a/lib/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart b/lib/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart index 7071d5a49..7eff2b7c2 100644 --- a/lib/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart +++ b/lib/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart @@ -582,7 +582,10 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource { } @override - Future addLabelToThread(Session session, AccountId accountId, List emailIds, KeyWordIdentifier labelKeyword) { + Future<({ + List emailIdsSuccess, + Map mapErrors, + })> addLabelToThread(Session session, AccountId accountId, List emailIds, KeyWordIdentifier labelKeyword) { throw UnimplementedError(); } @@ -592,7 +595,10 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource { } @override - Future removeLabelFromThread(Session session, AccountId accountId, List emailIds, KeyWordIdentifier labelKeyword) { + Future<({ + List emailIdsSuccess, + Map mapErrors, + })> removeLabelFromThread(Session session, AccountId accountId, List emailIds, KeyWordIdentifier labelKeyword) { throw UnimplementedError(); } } \ No newline at end of file diff --git a/lib/features/email/data/datasource_impl/email_local_storage_datasource_impl.dart b/lib/features/email/data/datasource_impl/email_local_storage_datasource_impl.dart index 6afa73b29..460cf1784 100644 --- a/lib/features/email/data/datasource_impl/email_local_storage_datasource_impl.dart +++ b/lib/features/email/data/datasource_impl/email_local_storage_datasource_impl.dart @@ -358,7 +358,10 @@ class EmailLocalStorageDataSourceImpl extends EmailDataSource { } @override - Future addLabelToThread(Session session, AccountId accountId, List emailIds, KeyWordIdentifier labelKeyword) { + Future<({ + List emailIdsSuccess, + Map mapErrors, + })> addLabelToThread(Session session, AccountId accountId, List emailIds, KeyWordIdentifier labelKeyword) { throw UnimplementedError(); } @@ -368,7 +371,10 @@ class EmailLocalStorageDataSourceImpl extends EmailDataSource { } @override - Future removeLabelFromThread(Session session, AccountId accountId, List emailIds, KeyWordIdentifier labelKeyword) { + Future<({ + List emailIdsSuccess, + Map mapErrors, + })> removeLabelFromThread(Session session, AccountId accountId, List emailIds, KeyWordIdentifier labelKeyword) { throw UnimplementedError(); } } \ No newline at end of file diff --git a/lib/features/email/data/datasource_impl/email_session_storage_datasource_impl.dart b/lib/features/email/data/datasource_impl/email_session_storage_datasource_impl.dart index eabfeaf8c..ac3bf691e 100644 --- a/lib/features/email/data/datasource_impl/email_session_storage_datasource_impl.dart +++ b/lib/features/email/data/datasource_impl/email_session_storage_datasource_impl.dart @@ -272,7 +272,10 @@ class EmailSessionStorageDatasourceImpl extends EmailDataSource { } @override - Future addLabelToThread(Session session, AccountId accountId, List emailIds, KeyWordIdentifier labelKeyword) { + Future<({ + List emailIdsSuccess, + Map mapErrors, + })> addLabelToThread(Session session, AccountId accountId, List emailIds, KeyWordIdentifier labelKeyword) { throw UnimplementedError(); } @@ -282,7 +285,10 @@ class EmailSessionStorageDatasourceImpl extends EmailDataSource { } @override - Future removeLabelFromThread(Session session, AccountId accountId, List emailIds, KeyWordIdentifier labelKeyword) { + Future<({ + List emailIdsSuccess, + Map mapErrors, + })> removeLabelFromThread(Session session, AccountId accountId, List emailIds, KeyWordIdentifier labelKeyword) { throw UnimplementedError(); } } \ No newline at end of file diff --git a/lib/features/email/data/network/email_api.dart b/lib/features/email/data/network/email_api.dart index 7ef5187d2..50da67658 100644 --- a/lib/features/email/data/network/email_api.dart +++ b/lib/features/email/data/network/email_api.dart @@ -53,23 +53,27 @@ import 'package:model/extensions/list_email_id_extension.dart'; import 'package:model/extensions/list_id_extension.dart'; import 'package:model/extensions/mailbox_id_extension.dart'; import 'package:path_provider/path_provider.dart'; +import 'package:tmail_ui_user/features/base/mixin/batch_set_email_processing_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/model/email_request.dart'; import 'package:tmail_ui_user/features/download/domain/model/download_source_view.dart'; +import 'package:tmail_ui_user/features/download/domain/state/download_all_attachments_for_web_state.dart'; +import 'package:tmail_ui_user/features/download/domain/state/download_attachment_for_web_state.dart'; import 'package:tmail_ui_user/features/email/domain/exceptions/email_exceptions.dart'; import 'package:tmail_ui_user/features/email/domain/model/move_to_mailbox_request.dart'; import 'package:tmail_ui_user/features/email/domain/model/restore_deleted_message_request.dart'; -import 'package:tmail_ui_user/features/download/domain/state/download_all_attachments_for_web_state.dart'; -import 'package:tmail_ui_user/features/download/domain/state/download_attachment_for_web_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart'; import 'package:tmail_ui_user/features/thread/domain/constants/thread_constants.dart'; import 'package:tmail_ui_user/main/error/capability_validator.dart'; import 'package:uri/uri.dart'; import 'package:uuid/uuid.dart'; -class EmailAPI with HandleSetErrorMixin, MailAPIMixin { +class EmailAPI with + HandleSetErrorMixin, + MailAPIMixin, + BatchSetEmailProcessingMixin { final HttpClient _httpClient; final DownloadManager _downloadManager; @@ -246,51 +250,15 @@ class EmailAPI with HandleSetErrorMixin, MailAPIMixin { List emailIds, ReadActions readActions, ) async { - final maxObjects = getMaxObjectsInSetMethod(session, accountId); - final totalEmails = emailIds.length; - final maxBatches = min(totalEmails, maxObjects); - - final List updatedEmailIds = List.empty(growable: true); - final Map mapErrors = {}; - - for (int start = 0; start < totalEmails; start += maxBatches) { - int end = (start + maxBatches < totalEmails) - ? start + maxBatches - : totalEmails; - log('EmailAPI::markAsRead:emails from ${start + 1} to $end'); - - final currentListEmailIds = emailIds.sublist(start, end); - - final setEmailMethod = SetEmailMethod(accountId) - ..addUpdates( - currentListEmailIds.generateMapUpdateObjectMarkAsRead(readActions) - ); - - 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); + return executeBatchSetEmail( + session: session, + accountId: accountId, + emailIds: emailIds, + httpClient: _httpClient, + debugLabel: 'markAsRead', + onGenerateUpdates: (batchIds) => + batchIds.generateMapUpdateObjectMarkAsRead(readActions), + ); } Future exportAttachment( @@ -486,51 +454,15 @@ class EmailAPI with HandleSetErrorMixin, MailAPIMixin { List emailIds, MarkStarAction markStarAction ) async { - final maxObjects = getMaxObjectsInSetMethod(session, accountId); - final totalEmails = emailIds.length; - final maxBatches = min(totalEmails, maxObjects); - - final List updatedEmailIds = List.empty(growable: true); - final Map mapErrors = {}; - - for (int start = 0; start < totalEmails; start += maxBatches) { - int end = (start + maxBatches < totalEmails) - ? start + maxBatches - : totalEmails; - log('EmailAPI::markAsStar:emails from ${start + 1} to $end'); - - final currentListEmailIds = emailIds.sublist(start, end); - - final setEmailMethod = SetEmailMethod(accountId) - ..addUpdates( - currentListEmailIds.generateMapUpdateObjectMarkAsStar(markStarAction), - ); - - 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); + return executeBatchSetEmail( + session: session, + accountId: accountId, + emailIds: emailIds, + httpClient: _httpClient, + debugLabel: 'markAsStar', + onGenerateUpdates: (batchIds) => + batchIds.generateMapUpdateObjectMarkAsStar(markStarAction), + ); } Future _emailSetCreateMethod( @@ -965,39 +897,24 @@ class EmailAPI with HandleSetErrorMixin, MailAPIMixin { } } - Future addLabelToThread( + Future<({ + List emailIdsSuccess, + Map mapErrors, + })> addLabelToThread( Session session, AccountId accountId, List emailIds, KeyWordIdentifier labelKeyword, ) async { - if (emailIds.isEmpty) { - throw ArgumentError.value(emailIds, 'emailIds', 'must not be empty'); - } - - final method = SetEmailMethod(accountId) - ..addUpdates(emailIds.generateMapUpdateObjectLabel(labelKeyword)); - - final builder = JmapRequestBuilder(_httpClient, ProcessingInvocation()); - final invocation = builder.invocation(method); - - final capabilities = method.requiredCapabilities - .toCapabilitiesSupportTeamMailboxes(session, accountId); - final result = await (builder..usings(capabilities)).build().execute(); - - final response = result.parse( - invocation.methodCallId, - SetEmailResponse.deserialize, + return executeBatchSetEmail( + session: session, + accountId: accountId, + emailIds: emailIds, + httpClient: _httpClient, + debugLabel: 'addLabelToThread', + onGenerateUpdates: (batchIds) => + batchIds.generateMapUpdateObjectLabel(labelKeyword), ); - - final emailIdsUpdated = response?.updated?.keys ?? []; - final ids = emailIds.toSetIds(); - final isUpdated = ids.every(emailIdsUpdated.contains) && - emailIdsUpdated.length == ids.length; - - if (emailIdsUpdated.isEmpty || !isUpdated) { - throw parseErrorForSetResponse(response, emailIds.first.id); - } } Future removeLabelFromEmail( @@ -1030,41 +947,25 @@ class EmailAPI with HandleSetErrorMixin, MailAPIMixin { } } - Future removeLabelFromThread( + Future<({ + List emailIdsSuccess, + Map mapErrors, + })> removeLabelFromThread( Session session, AccountId accountId, List emailIds, KeyWordIdentifier labelKeyword, ) async { - if (emailIds.isEmpty) { - throw ArgumentError.value(emailIds, 'emailIds', 'must not be empty'); - } - - final method = SetEmailMethod(accountId) - ..addUpdates(emailIds.generateMapUpdateObjectLabel( + return executeBatchSetEmail( + session: session, + accountId: accountId, + emailIds: emailIds, + httpClient: _httpClient, + debugLabel: 'removeLabelFromThread', + onGenerateUpdates: (batchIds) => batchIds.generateMapUpdateObjectLabel( labelKeyword, remove: true, - )); - - final builder = JmapRequestBuilder(_httpClient, ProcessingInvocation()); - final invocation = builder.invocation(method); - - final capabilities = method.requiredCapabilities - .toCapabilitiesSupportTeamMailboxes(session, accountId); - final result = await (builder..usings(capabilities)).build().execute(); - - final response = result.parse( - invocation.methodCallId, - SetEmailResponse.deserialize, + ), ); - - final emailIdsUpdated = response?.updated?.keys ?? []; - final ids = emailIds.toSetIds(); - final isUpdated = emailIdsUpdated.every(ids.contains) && - emailIdsUpdated.length == ids.length; - - if (emailIdsUpdated.isEmpty || !isUpdated) { - throw parseErrorForSetResponse(response, emailIds.first.id); - } } } \ No newline at end of file diff --git a/lib/features/email/data/repository/email_repository_impl.dart b/lib/features/email/data/repository/email_repository_impl.dart index 9aae2bb61..198a66585 100644 --- a/lib/features/email/data/repository/email_repository_impl.dart +++ b/lib/features/email/data/repository/email_repository_impl.dart @@ -497,7 +497,10 @@ class EmailRepositoryImpl extends EmailRepository { } @override - Future addLabelToThread( + Future<({ + List emailIdsSuccess, + Map mapErrors, + })> addLabelToThread( Session session, AccountId accountId, List emailIds, @@ -527,7 +530,10 @@ class EmailRepositoryImpl extends EmailRepository { } @override - Future removeLabelFromThread( + Future<({ + List emailIdsSuccess, + Map mapErrors, + })> removeLabelFromThread( Session session, AccountId accountId, List emailIds, diff --git a/lib/features/email/domain/exceptions/email_exceptions.dart b/lib/features/email/domain/exceptions/email_exceptions.dart index ffc6d02cd..329690e83 100644 --- a/lib/features/email/domain/exceptions/email_exceptions.dart +++ b/lib/features/email/domain/exceptions/email_exceptions.dart @@ -22,4 +22,6 @@ class NotParsableBlobIdToEmailException implements Exception { final List? ids; NotParsableBlobIdToEmailException({this.ids}); -} \ No newline at end of file +} + +class EmailIdListIsEmptyException implements Exception {} \ No newline at end of file diff --git a/lib/features/email/domain/repository/email_repository.dart b/lib/features/email/domain/repository/email_repository.dart index f1dd0e5cf..50542d791 100644 --- a/lib/features/email/domain/repository/email_repository.dart +++ b/lib/features/email/domain/repository/email_repository.dart @@ -169,7 +169,10 @@ abstract class EmailRepository { KeyWordIdentifier labelKeyword, ); - Future addLabelToThread( + Future<({ + List emailIdsSuccess, + Map mapErrors, + })> addLabelToThread( Session session, AccountId accountId, List emailIds, @@ -183,7 +186,10 @@ abstract class EmailRepository { KeyWordIdentifier labelKeyword, ); - Future removeLabelFromThread( + Future<({ + List emailIdsSuccess, + Map mapErrors, + })> removeLabelFromThread( Session session, AccountId accountId, List emailIds, diff --git a/lib/features/email/domain/state/add_a_label_to_a_thread_state.dart b/lib/features/email/domain/state/add_a_label_to_a_thread_state.dart index 0f3a0ad4d..04235a6b4 100644 --- a/lib/features/email/domain/state/add_a_label_to_a_thread_state.dart +++ b/lib/features/email/domain/state/add_a_label_to_a_thread_state.dart @@ -16,6 +16,14 @@ class AddALabelToAThreadSuccess extends UIState { List get props => [emailIds, labelKeyword, labelDisplay]; } +class AddALabelToAThreadHasSomeFailure extends AddALabelToAThreadSuccess { + AddALabelToAThreadHasSomeFailure( + super.emailIds, + super.labelKeyword, + super.labelDisplay, + ); +} + class AddALabelToAThreadFailure extends FeatureFailure { final String labelDisplay; diff --git a/lib/features/email/domain/state/labels/remove_a_label_from_a_thread_state.dart b/lib/features/email/domain/state/labels/remove_a_label_from_a_thread_state.dart index 8081f2abe..05fbd53c1 100644 --- a/lib/features/email/domain/state/labels/remove_a_label_from_a_thread_state.dart +++ b/lib/features/email/domain/state/labels/remove_a_label_from_a_thread_state.dart @@ -20,6 +20,15 @@ class RemoveALabelFromAThreadSuccess extends UIState { List get props => [emailIds, labelKeyword, labelDisplay]; } +class RemoveALabelFromAThreadHasSomeFailure + extends RemoveALabelFromAThreadSuccess { + RemoveALabelFromAThreadHasSomeFailure( + super.emailIds, + super.labelKeyword, + super.labelDisplay, + ); +} + class RemoveALabelFromAThreadFailure extends FeatureFailure { final String labelDisplay; diff --git a/lib/features/email/domain/usecases/add_a_label_to_a_thread_interactor.dart b/lib/features/email/domain/usecases/add_a_label_to_a_thread_interactor.dart index e917a2a47..62724db81 100644 --- a/lib/features/email/domain/usecases/add_a_label_to_a_thread_interactor.dart +++ b/lib/features/email/domain/usecases/add_a_label_to_a_thread_interactor.dart @@ -5,6 +5,7 @@ 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/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart'; +import 'package:tmail_ui_user/features/email/domain/exceptions/email_exceptions.dart'; import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart'; import 'package:tmail_ui_user/features/email/domain/state/add_a_label_to_a_thread_state.dart'; @@ -22,17 +23,30 @@ class AddALabelToAThreadInteractor { ) async* { try { yield Right(AddingALabelToAThread()); - await _emailRepository.addLabelToThread( + final result = await _emailRepository.addLabelToThread( session, accountId, emailIds, labelKeyword, ); - yield Right(AddALabelToAThreadSuccess( - emailIds, - labelKeyword, - labelDisplay, - )); + if (emailIds.length == result.emailIdsSuccess.length) { + yield Right(AddALabelToAThreadSuccess( + result.emailIdsSuccess, + labelKeyword, + labelDisplay, + )); + } else if (result.emailIdsSuccess.isEmpty) { + yield Left(AddALabelToAThreadFailure( + exception: EmailIdListIsEmptyException(), + labelDisplay: labelDisplay, + )); + } else { + yield Right(AddALabelToAThreadHasSomeFailure( + result.emailIdsSuccess, + labelKeyword, + labelDisplay, + )); + } } catch (e) { yield Left(AddALabelToAThreadFailure( exception: e, diff --git a/lib/features/email/domain/usecases/labels/remove_a_label_from_a_thread_interactor.dart b/lib/features/email/domain/usecases/labels/remove_a_label_from_a_thread_interactor.dart index 925104e28..02b107b7e 100644 --- a/lib/features/email/domain/usecases/labels/remove_a_label_from_a_thread_interactor.dart +++ b/lib/features/email/domain/usecases/labels/remove_a_label_from_a_thread_interactor.dart @@ -5,6 +5,7 @@ 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/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart'; +import 'package:tmail_ui_user/features/email/domain/exceptions/email_exceptions.dart'; import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart'; import 'package:tmail_ui_user/features/email/domain/state/labels/remove_a_label_from_a_thread_state.dart'; @@ -22,17 +23,30 @@ class RemoveALabelFromAThreadInteractor { ) async* { try { yield Right(RemovingALabelFromAThread()); - await _emailRepository.removeLabelFromThread( + final result = await _emailRepository.removeLabelFromThread( session, accountId, emailIds, labelKeyword, ); - yield Right(RemoveALabelFromAThreadSuccess( - emailIds, - labelKeyword, - labelDisplay, - )); + if (emailIds.length == result.emailIdsSuccess.length) { + yield Right(RemoveALabelFromAThreadSuccess( + result.emailIdsSuccess, + labelKeyword, + labelDisplay, + )); + } else if (result.emailIdsSuccess.isEmpty) { + yield Left(RemoveALabelFromAThreadFailure( + exception: EmailIdListIsEmptyException(), + labelDisplay: labelDisplay, + )); + } else { + yield Right(RemoveALabelFromAThreadHasSomeFailure( + result.emailIdsSuccess, + labelKeyword, + labelDisplay, + )); + } } catch (e) { yield Left(RemoveALabelFromAThreadFailure( exception: e, diff --git a/lib/features/email/presentation/extensions/handle_label_for_email_extension.dart b/lib/features/email/presentation/extensions/handle_label_for_email_extension.dart index db87a9dee..5e9c55762 100644 --- a/lib/features/email/presentation/extensions/handle_label_for_email_extension.dart +++ b/lib/features/email/presentation/extensions/handle_label_for_email_extension.dart @@ -169,7 +169,10 @@ extension HandleLabelForEmailExtension on SingleEmailController { final selectedEmail = mailboxDashBoardController.selectedEmail.value; if (selectedEmail?.id != emailId) return; - selectedEmail?.keywords?.toggleKeyword(labelKeyword, remove); + selectedEmail?.keywords?.toggleKeyword( + keyword: labelKeyword, + shouldRemove: remove, + ); } void _updateLabelOnThreadIfNeeded({ diff --git a/lib/features/thread/data/extensions/map_keywords_extension.dart b/lib/features/thread/data/extensions/map_keywords_extension.dart index 2990cae09..b74be997c 100644 --- a/lib/features/thread/data/extensions/map_keywords_extension.dart +++ b/lib/features/thread/data/extensions/map_keywords_extension.dart @@ -32,7 +32,10 @@ extension MapKeywordsExtension on Map? { this?.remove(keyword); } - void toggleKeyword(KeyWordIdentifier keyword, bool shouldRemove) { + void toggleKeyword({ + required KeyWordIdentifier keyword, + required bool shouldRemove, + }) { if (shouldRemove) { removeKeyword(keyword); } else { diff --git a/lib/features/thread_detail/presentation/extension/labels/add_label_to_thread_extension.dart b/lib/features/thread_detail/presentation/extension/labels/add_label_to_thread_extension.dart index 18286848d..a761faf27 100644 --- a/lib/features/thread_detail/presentation/extension/labels/add_label_to_thread_extension.dart +++ b/lib/features/thread_detail/presentation/extension/labels/add_label_to_thread_extension.dart @@ -37,7 +37,11 @@ extension AddLabelToThreadExtension on ThreadDetailController { emailLabels: threadLabels, emailIds: emailIds, onAddLabelToEmailsCallback: (emailIds, label, isSelected) { - toggleLabelToThread(label, isSelected, currentEmailIds: emailIds); + toggleLabelToThread( + label, + isSelected: isSelected, + currentEmailIds: emailIds, + ); }, ), dialogLabel: 'add-label-to-thread-modal', @@ -45,8 +49,8 @@ extension AddLabelToThreadExtension on ThreadDetailController { } void toggleLabelToThread( - Label label, - bool isSelected, { + Label label,{ + required bool isSelected, List? currentEmailIds, }) { final accountId = mailboxDashBoardController.accountId.value; diff --git a/lib/features/thread_detail/presentation/extension/on_thread_detail_action_click.dart b/lib/features/thread_detail/presentation/extension/on_thread_detail_action_click.dart index ef222d743..6f7459667 100644 --- a/lib/features/thread_detail/presentation/extension/on_thread_detail_action_click.dart +++ b/lib/features/thread_detail/presentation/extension/on_thread_detail_action_click.dart @@ -188,7 +188,7 @@ extension OnThreadDetailActionClick on ThreadDetailController { emailInThreadDetailInfos: emailsInThreadDetailInfo, labels: mailboxDashBoardController.labelController.labels, onSelectLabelAction: (label, isSelected) { - toggleLabelToThread(label, isSelected); + toggleLabelToThread(label, isSelected: isSelected); submenuController.hide(); popBack(); }, diff --git a/test/features/thread/presentation/extensions/map_keywords_extension_test.dart b/test/features/thread/presentation/extensions/map_keywords_extension_test.dart index d1fe7a19c..599cb6e80 100644 --- a/test/features/thread/presentation/extensions/map_keywords_extension_test.dart +++ b/test/features/thread/presentation/extensions/map_keywords_extension_test.dart @@ -253,7 +253,7 @@ void main() { final keyword = KeyWordIdentifier('\$seen'); final map = {}; - map.toggleKeyword(keyword, false); + map.toggleKeyword(keyword: keyword, shouldRemove: false); expect(map.length, 1); expect(map[keyword], true); @@ -265,7 +265,7 @@ void main() { KeyWordIdentifier('\$flagged'): true, }; - map.toggleKeyword(keyword, false); + map.toggleKeyword(keyword: keyword, shouldRemove: false); expect(map.length, 2); expect(map[keyword], true); @@ -277,7 +277,7 @@ void main() { keyword: false, }; - map.toggleKeyword(keyword, false); + map.toggleKeyword(keyword: keyword, shouldRemove: false); expect(map.length, 1); expect(map[keyword], true); @@ -290,7 +290,7 @@ void main() { KeyWordIdentifier('\$flagged'): true, }; - map.toggleKeyword(keyword, true); + map.toggleKeyword(keyword: keyword, shouldRemove: true); expect(map.length, 1); expect(map.containsKey(keyword), false); @@ -302,7 +302,7 @@ void main() { }; final keyword = KeyWordIdentifier('\$seen'); - map.toggleKeyword(keyword, true); + map.toggleKeyword(keyword: keyword, shouldRemove: true); expect(map.length, 1); expect(map.values.first, true); @@ -312,7 +312,7 @@ void main() { final map = {}; final keyword = KeyWordIdentifier('\$seen'); - expect(() => map.toggleKeyword(keyword, true), returnsNormally); + expect(() => map.toggleKeyword(keyword: keyword, shouldRemove: true), returnsNormally); expect(map.isEmpty, true); }); @@ -320,7 +320,7 @@ void main() { final map = {}; final keyword = KeyWordIdentifier('\$seen'); - expect(() => map.toggleKeyword(keyword, false), returnsNormally); + expect(() => map.toggleKeyword(keyword: keyword, shouldRemove: false), returnsNormally); expect(map.length, 1); expect(map[keyword], true); }); @@ -329,16 +329,16 @@ void main() { Map? map; final keyword = KeyWordIdentifier('\$seen'); - expect(() => map.toggleKeyword(keyword, true), returnsNormally); - expect(() => map.toggleKeyword(keyword, false), returnsNormally); + expect(() => map.toggleKeyword(keyword: keyword, shouldRemove: true), returnsNormally); + expect(() => map.toggleKeyword(keyword: keyword, shouldRemove: false), returnsNormally); }); test('calling toggleKeyword on null map has no side effects', () { Map? map; final keyword = KeyWordIdentifier('\$seen'); - map.toggleKeyword(keyword, false); - map.toggleKeyword(keyword, true); + map.toggleKeyword(keyword: keyword, shouldRemove: false); + map.toggleKeyword(keyword: keyword, shouldRemove: true); expect(map, isNull); }); @@ -351,7 +351,7 @@ void main() { final originalIdentity = identityHashCode(map); - map.toggleKeyword(keyword, true); + map.toggleKeyword(keyword: keyword, shouldRemove: true); expect(identityHashCode(map), originalIdentity); expect(map.isEmpty, true);