diff --git a/lib/features/mailbox/data/datasource/mailbox_datasource.dart b/lib/features/mailbox/data/datasource/mailbox_datasource.dart index 4b9f30c7ef..bf7c91b285 100644 --- a/lib/features/mailbox/data/datasource/mailbox_datasource.dart +++ b/lib/features/mailbox/data/datasource/mailbox_datasource.dart @@ -56,4 +56,6 @@ abstract class MailboxDataSource { Future getMailboxByRole(Session session, AccountId accountId, Role role); Future clearAllMailboxCache(AccountId accountId, UserName userName); + + Future> getListMailboxById(Session session, AccountId accountId, List mailboxIds); } \ No newline at end of file diff --git a/lib/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart b/lib/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart index b52e767b24..22f8b58261 100644 --- a/lib/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart +++ b/lib/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart @@ -118,4 +118,9 @@ class MailboxCacheDataSourceImpl extends MailboxDataSource { return await _mailboxCacheManager.clearAll(accountId, userName); }).catchError(_exceptionThrower.throwException); } + + @override + Future> getListMailboxById(Session session, AccountId accountId, List mailboxIds) { + throw UnimplementedError(); + } } \ No newline at end of file diff --git a/lib/features/mailbox/data/datasource_impl/mailbox_datasource_impl.dart b/lib/features/mailbox/data/datasource_impl/mailbox_datasource_impl.dart index 062e7effa3..08e11ec138 100644 --- a/lib/features/mailbox/data/datasource_impl/mailbox_datasource_impl.dart +++ b/lib/features/mailbox/data/datasource_impl/mailbox_datasource_impl.dart @@ -146,4 +146,11 @@ class MailboxDataSourceImpl extends MailboxDataSource { Future clearAllMailboxCache(AccountId accountId, UserName userName) { throw UnimplementedError(); } + + @override + Future> getListMailboxById(Session session, AccountId accountId, List mailboxIds) { + return Future.sync(() async { + return await mailboxAPI.getListMailboxById(session, accountId, mailboxIds); + }).catchError(_exceptionThrower.throwException); + } } \ No newline at end of file diff --git a/lib/features/mailbox/data/network/mailbox_api.dart b/lib/features/mailbox/data/network/mailbox_api.dart index 462b72ebc9..8501b9a260 100644 --- a/lib/features/mailbox/data/network/mailbox_api.dart +++ b/lib/features/mailbox/data/network/mailbox_api.dart @@ -32,6 +32,7 @@ import 'package:tmail_ui_user/features/composer/domain/exceptions/set_method_exc 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/set_mailbox_method_exception.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/extensions/list_mailbox_extension.dart'; import 'package:tmail_ui_user/features/mailbox/domain/extensions/list_mailbox_id_extension.dart'; import 'package:tmail_ui_user/features/mailbox/domain/extensions/role_extension.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart'; @@ -555,4 +556,34 @@ class MailboxAPI with HandleSetErrorMixin { throw NotFoundMailboxException(); } } + + Future> getListMailboxById(Session session, AccountId accountId, List mailboxIds) async { + final processingInvocation = ProcessingInvocation(); + + final jmapRequestBuilder = JmapRequestBuilder(httpClient, processingInvocation); + + final getMailboxCreated = GetMailboxMethod(accountId) + ..addIds(mailboxIds.ids) + ..addProperties(Properties({MailboxProperty.id})); + + final queryInvocation = jmapRequestBuilder.invocation(getMailboxCreated); + + final capabilities = getMailboxCreated.requiredCapabilities + .toCapabilitiesSupportTeamMailboxes(session, accountId); + + final result = await (jmapRequestBuilder + ..usings(capabilities)) + .build() + .execute(); + + final getMailboxResponse = result.parse( + queryInvocation.methodCallId, + GetMailboxResponse.deserialize); + + if (getMailboxResponse != null && getMailboxResponse.list.isNotEmpty) { + return getMailboxResponse.list.mailboxIds; + } else { + throw NotFoundMailboxException(); + } + } } \ No newline at end of file diff --git a/lib/features/mailbox/data/repository/mailbox_repository_impl.dart b/lib/features/mailbox/data/repository/mailbox_repository_impl.dart index a0fde06d72..8370d14ea3 100644 --- a/lib/features/mailbox/data/repository/mailbox_repository_impl.dart +++ b/lib/features/mailbox/data/repository/mailbox_repository_impl.dart @@ -264,4 +264,9 @@ class MailboxRepositoryImpl extends MailboxRepository { Future getMailboxByRole(Session session, AccountId accountId, Role role, {UnsignedInt? limit}) { return mapDataSource[DataSourceType.network]!.getMailboxByRole(session, accountId, role); } + + @override + Future> getListMailboxById(Session session, AccountId accountId, List mailboxIds) { + return mapDataSource[DataSourceType.network]!.getListMailboxById(session, accountId, mailboxIds); + } } \ No newline at end of file diff --git a/lib/features/mailbox/domain/extensions/list_mailbox_extension.dart b/lib/features/mailbox/domain/extensions/list_mailbox_extension.dart index d1827ca6b5..d11e37ade4 100644 --- a/lib/features/mailbox/domain/extensions/list_mailbox_extension.dart +++ b/lib/features/mailbox/domain/extensions/list_mailbox_extension.dart @@ -1,4 +1,5 @@ import 'package:built_collection/built_collection.dart'; +import 'package:collection/collection.dart'; import 'package:dartz/dartz.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:model/model.dart'; @@ -18,4 +19,6 @@ extension ListMailboxExtensions on List { validBuilder.build().toList(), invalidBuilder.build().toList()); } + + List get mailboxIds => map((mailbox) => mailbox.id).whereNotNull().toList(); } \ No newline at end of file diff --git a/lib/features/mailbox/domain/extensions/list_mailbox_id_extension.dart b/lib/features/mailbox/domain/extensions/list_mailbox_id_extension.dart index 0a9631f63b..695b45ad4c 100644 --- a/lib/features/mailbox/domain/extensions/list_mailbox_id_extension.dart +++ b/lib/features/mailbox/domain/extensions/list_mailbox_id_extension.dart @@ -15,4 +15,6 @@ extension ListMailboxIdExtension on List { }; return maps; } + + Set get ids => map((mailboxId) => mailboxId.id).toSet(); } \ No newline at end of file diff --git a/lib/features/mailbox/domain/repository/mailbox_repository.dart b/lib/features/mailbox/domain/repository/mailbox_repository.dart index a3f40851e4..0d42431661 100644 --- a/lib/features/mailbox/domain/repository/mailbox_repository.dart +++ b/lib/features/mailbox/domain/repository/mailbox_repository.dart @@ -51,4 +51,6 @@ abstract class MailboxRepository { Future setRoleDefaultMailbox(Session session, AccountId accountId, List listMailbox); Future getMailboxByRole(Session session, AccountId accountId, Role role, {UnsignedInt? limit}); + + Future> getListMailboxById(Session session, AccountId accountId, List mailboxIds); } \ No newline at end of file diff --git a/lib/features/mailbox/domain/state/get_list_mailbox_by_id_state.dart b/lib/features/mailbox/domain/state/get_list_mailbox_by_id_state.dart new file mode 100644 index 0000000000..1511118b3f --- /dev/null +++ b/lib/features/mailbox/domain/state/get_list_mailbox_by_id_state.dart @@ -0,0 +1,19 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; + +class GetListMailboxByIdLoading extends LoadingState {} + +class GetListMailboxByIdSuccess extends UIState { + final List mailboxIds; + + GetListMailboxByIdSuccess(this.mailboxIds); + + @override + List get props => [mailboxIds]; +} + +class GetListMailboxByIdFailure extends FeatureFailure { + + GetListMailboxByIdFailure(dynamic exception) : super(exception: exception); +} \ No newline at end of file diff --git a/lib/features/mailbox/domain/usecases/get_list_mailbox_by_id_interactor.dart b/lib/features/mailbox/domain/usecases/get_list_mailbox_by_id_interactor.dart new file mode 100644 index 0000000000..136f0d727d --- /dev/null +++ b/lib/features/mailbox/domain/usecases/get_list_mailbox_by_id_interactor.dart @@ -0,0 +1,28 @@ +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:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/state/get_list_mailbox_by_id_state.dart'; + +class GetListMailboxByIdInteractor { + final MailboxRepository _mailboxRepository; + + GetListMailboxByIdInteractor(this._mailboxRepository); + + Stream> execute( + Session session, + AccountId accountId, + List mailboxIds + ) async* { + try { + yield Right(GetListMailboxByIdLoading()); + final mailboxIdsExist = await _mailboxRepository.getListMailboxById(session, accountId, mailboxIds); + yield Right(GetListMailboxByIdSuccess(mailboxIdsExist)); + } catch (e) { + yield Left(GetListMailboxByIdFailure(e)); + } + } +} \ No newline at end of file diff --git a/lib/features/manage_account/domain/state/get_all_rules_state.dart b/lib/features/manage_account/domain/state/get_all_rules_state.dart index d512a2d4e8..c1aec266b9 100644 --- a/lib/features/manage_account/domain/state/get_all_rules_state.dart +++ b/lib/features/manage_account/domain/state/get_all_rules_state.dart @@ -2,13 +2,15 @@ import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/success.dart'; import 'package:rule_filter/rule_filter/tmail_rule.dart'; +class GetAllRulesLoading extends LoadingState {} + class GetAllRulesSuccess extends UIState { - final List? rules; + final List rules; GetAllRulesSuccess(this.rules); @override - List get props => [rules]; + List get props => [rules]; } class GetAllRulesFailure extends FeatureFailure { diff --git a/lib/features/manage_account/domain/usecases/delete_email_rule_interactor.dart b/lib/features/manage_account/domain/usecases/delete_email_rule_interactor.dart index e10c700980..1e6cc20fac 100644 --- a/lib/features/manage_account/domain/usecases/delete_email_rule_interactor.dart +++ b/lib/features/manage_account/domain/usecases/delete_email_rule_interactor.dart @@ -14,7 +14,7 @@ class DeleteEmailRuleInteractor { Stream> execute(AccountId accountId, DeleteEmailRuleRequest deleteEmailRuleRequest) async* { try { - final result = await _ruleFilterRepository.deleteTMailRule(accountId, deleteEmailRuleRequest); + final result = await _ruleFilterRepository.deleteTMailRule(accountId, deleteEmailRuleRequest); yield Right(DeleteEmailRuleSuccess(result)); } catch (exception) { yield Left(DeleteEmailRuleFailure(exception)); diff --git a/lib/features/manage_account/presentation/email_rules/bindings/email_rules_interactor_bindings.dart b/lib/features/manage_account/presentation/email_rules/bindings/email_rules_interactor_bindings.dart index 6f7f73ae49..322f4c3012 100644 --- a/lib/features/manage_account/presentation/email_rules/bindings/email_rules_interactor_bindings.dart +++ b/lib/features/manage_account/presentation/email_rules/bindings/email_rules_interactor_bindings.dart @@ -1,5 +1,18 @@ +import 'package:core/data/model/source_type/data_source_type.dart'; import 'package:get/get.dart'; import 'package:tmail_ui_user/features/base/interactors_bindings.dart'; +import 'package:tmail_ui_user/features/mailbox/data/datasource/mailbox_datasource.dart'; +import 'package:tmail_ui_user/features/mailbox/data/datasource/state_datasource.dart'; +import 'package:tmail_ui_user/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart'; +import 'package:tmail_ui_user/features/mailbox/data/datasource_impl/mailbox_datasource_impl.dart'; +import 'package:tmail_ui_user/features/mailbox/data/datasource_impl/state_datasource_impl.dart'; +import 'package:tmail_ui_user/features/mailbox/data/local/mailbox_cache_manager.dart'; +import 'package:tmail_ui_user/features/mailbox/data/local/state_cache_manager.dart'; +import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_api.dart'; +import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_isolate_worker.dart'; +import 'package:tmail_ui_user/features/mailbox/data/repository/mailbox_repository_impl.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_list_mailbox_by_id_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/data/datasource/rule_filter_datasource.dart'; import 'package:tmail_ui_user/features/manage_account/data/datasource_impl/rule_filter_datasource_impl.dart'; import 'package:tmail_ui_user/features/manage_account/data/network/rule_filter_api.dart'; @@ -9,13 +22,17 @@ import 'package:tmail_ui_user/features/manage_account/domain/usecases/delete_ema import 'package:tmail_ui_user/features/manage_account/domain/usecases/create_new_email_rule_filter_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/edit_email_rule_filter_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_rules_interactor.dart'; +import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart'; import 'package:tmail_ui_user/main/exceptions/remote_exception_thrower.dart'; +import 'package:tmail_ui_user/main/utils/ios_sharing_manager.dart'; class EmailRulesInteractorBindings extends InteractorsBindings { @override void bindingsDataSource() { Get.lazyPut(() => Get.find()); + Get.lazyPut(() => Get.find()); + Get.lazyPut(() => Get.find()); } @override @@ -23,6 +40,17 @@ class EmailRulesInteractorBindings extends InteractorsBindings { Get.lazyPut(() => RuleFilterDataSourceImpl( Get.find(), Get.find())); + Get.lazyPut(() => MailboxDataSourceImpl( + Get.find(), + Get.find(), + Get.find())); + Get.lazyPut(() => MailboxCacheDataSourceImpl( + Get.find(), + Get.find())); + Get.lazyPut(() => StateDataSourceImpl( + Get.find(), + Get.find(), + Get.find())); } @override @@ -31,15 +59,24 @@ class EmailRulesInteractorBindings extends InteractorsBindings { Get.lazyPut(() => DeleteEmailRuleInteractor(Get.find())); Get.lazyPut(() => CreateNewEmailRuleFilterInteractor(Get.find())); Get.lazyPut(() => EditEmailRuleFilterInteractor(Get.find())); + Get.lazyPut(() => GetListMailboxByIdInteractor(Get.find())); } @override void bindingsRepository() { Get.lazyPut(() => Get.find()); + Get.lazyPut(() => Get.find()); } @override void bindingsRepositoryImpl() { Get.lazyPut(() => RuleFilterRepositoryImpl(Get.find())); + Get.lazyPut(() => MailboxRepositoryImpl( + { + DataSourceType.network: Get.find(), + DataSourceType.local: Get.find() + }, + Get.find(), + )); } } \ No newline at end of file diff --git a/lib/features/manage_account/presentation/email_rules/email_rules_controller.dart b/lib/features/manage_account/presentation/email_rules/email_rules_controller.dart index b89bfad0ab..7831d2e1fc 100644 --- a/lib/features/manage_account/presentation/email_rules/email_rules_controller.dart +++ b/lib/features/manage_account/presentation/email_rules/email_rules_controller.dart @@ -1,4 +1,5 @@ import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/success.dart'; import 'package:core/presentation/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart'; import 'package:core/presentation/views/dialog/confirmation_dialog_builder.dart'; @@ -8,9 +9,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:pointer_interceptor/pointer_interceptor.dart'; import 'package:rule_filter/rule_filter/tmail_rule.dart'; import 'package:tmail_ui_user/features/base/base_controller.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/state/get_list_mailbox_by_id_state.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_list_mailbox_by_id_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_email_rule_filter_request.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/delete_email_rule_request.dart'; import 'package:tmail_ui_user/features/manage_account/domain/model/edit_email_rule_filter_request.dart'; @@ -23,6 +27,7 @@ import 'package:tmail_ui_user/features/manage_account/domain/usecases/delete_ema import 'package:tmail_ui_user/features/manage_account/domain/usecases/edit_email_rule_filter_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_rules_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/widgets/email_rule_bottom_sheet_action_tile_builder.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/extensions/list_tmail_rule_extension.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/model/creator_action_type.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/model/rules_filter_creator_arguments.dart'; @@ -37,19 +42,22 @@ class EmailRulesController extends BaseController { DeleteEmailRuleInteractor? _deleteEmailRuleInteractor; CreateNewEmailRuleFilterInteractor? _createNewEmailRuleFilterInteractor; EditEmailRuleFilterInteractor? _editEmailRuleFilterInteractor; + GetListMailboxByIdInteractor? _getListMailboxByIdInteractor; final _accountDashBoardController = Get.find(); final listEmailRule = [].obs; + final listMailboxIdsAppendIn = Rxn>(); @override void onInit() { super.onInit(); try { - _getAllRulesInteractor = Get.find(); - _deleteEmailRuleInteractor = Get.find(); - _createNewEmailRuleFilterInteractor = Get.find(); - _editEmailRuleFilterInteractor = Get.find(); + _getAllRulesInteractor = getBinding(); + _deleteEmailRuleInteractor = getBinding(); + _createNewEmailRuleFilterInteractor = getBinding(); + _editEmailRuleFilterInteractor = getBinding(); + _getListMailboxByIdInteractor = getBinding(); } catch (e) { logError('EmailRulesController::onInit(): ${e.toString()}'); } @@ -65,15 +73,29 @@ class EmailRulesController extends BaseController { void handleSuccessViewState(Success success) { super.handleSuccessViewState(success); if (success is GetAllRulesSuccess) { - if (success.rules?.isNotEmpty == true) { - listEmailRule.addAll(success.rules!); - } + listEmailRule.value = success.rules; + _validateRuleMailboxAppendInExist(); } else if (success is DeleteEmailRuleSuccess) { _handleDeleteEmailRuleSuccess(success); + _validateRuleMailboxAppendInExist(); } else if (success is CreateNewRuleFilterSuccess) { _createNewRuleFilterSuccess(success); + _validateRuleMailboxAppendInExist(); } else if (success is EditEmailRuleFilterSuccess) { _editEmailRuleFilterSuccess(success); + _validateRuleMailboxAppendInExist(); + } else if (success is GetListMailboxByIdSuccess) { + listMailboxIdsAppendIn.value = success.mailboxIds; + } + } + + @override + void handleFailureViewState(Failure failure) { + log('EmailRulesController::handleFailureViewState: ${failure.runtimeType}'); + if (failure is GetListMailboxByIdFailure) { + listMailboxIdsAppendIn.value = []; + } else { + super.handleFailureViewState(failure); } } @@ -109,6 +131,7 @@ class EmailRulesController extends BaseController { currentOverlayContext!, AppLocalizations.of(currentContext!).newFilterWasCreated); } + listMailboxIdsAppendIn.value = null; listEmailRule.value = success.newListRules; listEmailRule.refresh(); } @@ -150,6 +173,7 @@ class EmailRulesController extends BaseController { currentOverlayContext!, AppLocalizations.of(currentContext!).yourFilterHasBeenUpdated); } + listMailboxIdsAppendIn.value = null; listEmailRule.value = success.listRulesUpdated; listEmailRule.refresh(); } @@ -237,6 +261,7 @@ class EmailRulesController extends BaseController { } if (success.rules?.isNotEmpty == true) { + listMailboxIdsAppendIn.value = null; listEmailRule.clear(); listEmailRule.addAll(success.rules!); } @@ -290,4 +315,23 @@ class EmailRulesController extends BaseController { })) .build(); } + + void _validateRuleMailboxAppendInExist() { + final listMailboxIds = listEmailRule.mailboxesAppendIn; + final accountId = _accountDashBoardController.accountId.value; + final session = _accountDashBoardController.sessionCurrent; + + if (listMailboxIds.isEmpty || + accountId == null || + session == null || + _getListMailboxByIdInteractor == null) { + return; + } + + consumeState(_getListMailboxByIdInteractor!.execute( + session, + accountId, + listMailboxIds + )); + } } \ No newline at end of file diff --git a/lib/features/manage_account/presentation/email_rules/widgets/email_rule_item_widget.dart b/lib/features/manage_account/presentation/email_rules/widgets/email_rule_item_widget.dart index ce657ae35f..5e750f793a 100644 --- a/lib/features/manage_account/presentation/email_rules/widgets/email_rule_item_widget.dart +++ b/lib/features/manage_account/presentation/email_rules/widgets/email_rule_item_widget.dart @@ -1,20 +1,37 @@ -import 'package:core/core.dart'; +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/utils/responsive_utils.dart'; +import 'package:core/presentation/views/button/icon_button_web.dart'; +import 'package:core/presentation/views/button/tmail_button_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:get/get.dart'; +import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:rule_filter/rule_filter/tmail_rule.dart'; -import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/email_rules_controller.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +typedef EditRuleAction = Function(BuildContext context, TMailRule rule); +typedef DeleteRuleAction = Function(BuildContext context, TMailRule rule); +typedef OpenEditRuleMenuAction = Function(BuildContext context, TMailRule rule); class EmailRulesItemWidget extends StatelessWidget { - final _responsiveUtils = Get.find(); - final _imagePaths = Get.find(); - final _emailRuleController = Get.find(); + final ResponsiveUtils responsiveUtils; + final ImagePaths imagePaths; final TMailRule rule; + final List? mailboxIds; + final EditRuleAction? editRuleAction; + final DeleteRuleAction? deleteRuleAction; + final OpenEditRuleMenuAction? openEditRuleMenuAction; - EmailRulesItemWidget({ + const EmailRulesItemWidget({ Key? key, required this.rule, + required this.responsiveUtils, + required this.imagePaths, + this.mailboxIds, + this.editRuleAction, + this.deleteRuleAction, + this.openEditRuleMenuAction, }) : super(key: key); @override @@ -23,47 +40,68 @@ class EmailRulesItemWidget extends StatelessWidget { padding: EdgeInsets.only( top: 15, bottom: 15, - left: _responsiveUtils.isMobile(context) ? 16 : 24, - right: _responsiveUtils.isMobile(context) ? 0 : 24 + left: responsiveUtils.isMobile(context) ? 16 : 24, + right: responsiveUtils.isMobile(context) ? 0 : 24 ), color: Colors.white, child: Row(crossAxisAlignment: CrossAxisAlignment.center, children: [ - Text(rule.name, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w400, - color: Colors.black)), + Text( + rule.name, + style: Theme.of(context).textTheme.labelSmall?.copyWith( + fontSize: 16, + fontWeight: FontWeight.w400, + color: Colors.black + ) + ), + if (_isMailboxAppendInNotExist) + TMailButtonWidget.fromIcon( + icon: imagePaths.icQuotasWarning, + iconSize: 20, + margin: const EdgeInsetsDirectional.only(start: 4), + padding: const EdgeInsets.all(3), + iconColor: AppColor.colorBackgroundQuotasWarning, + tooltipMessage: AppLocalizations.of(context).warningRuleCannotAppliedWhenTargetFolderNoExist, + backgroundColor: Colors.transparent, + ), const Spacer(), - if (!_responsiveUtils.isMobile(context)) + if (!responsiveUtils.isMobile(context)) buildIconWeb( icon: SvgPicture.asset( - _imagePaths.icEditRule, + imagePaths.icEditRule, fit: BoxFit.fill, colorFilter: AppColor.primaryColor.asFilter(), ), onTap: () { - _emailRuleController.editEmailRule(context, rule); + editRuleAction?.call(context, rule); }), - if (!_responsiveUtils.isMobile(context)) + if (!responsiveUtils.isMobile(context)) buildIconWeb( icon: SvgPicture.asset( - _imagePaths.icDeleteRule, + imagePaths.icDeleteRule, fit: BoxFit.fill, ), onTap: () { - _emailRuleController.deleteEmailRule(context, rule); + deleteRuleAction?.call(context, rule); }), - if (_responsiveUtils.isMobile(context)) + if (responsiveUtils.isMobile(context)) buildIconWeb( icon: SvgPicture.asset( - _imagePaths.icOpenEditRule, + imagePaths.icOpenEditRule, fit: BoxFit.fill, ), iconPadding: const EdgeInsets.all(0), onTap: () { - _emailRuleController.openEditRuleMenuAction(context, rule); + openEditRuleMenuAction?.call(context, rule); }), ]), ); } + + bool get _isMailboxAppendInNotExist { + final ruleMailboxIds= rule.action.appendIn.mailboxIds; + + return mailboxIds != null + && ruleMailboxIds.isNotEmpty + && ruleMailboxIds.any((mailboxId) => !mailboxIds!.contains(mailboxId)); + } } diff --git a/lib/features/manage_account/presentation/email_rules/widgets/list_email_rules_widget.dart b/lib/features/manage_account/presentation/email_rules/widgets/list_email_rules_widget.dart index 483e9c582e..fbe6e02a29 100644 --- a/lib/features/manage_account/presentation/email_rules/widgets/list_email_rules_widget.dart +++ b/lib/features/manage_account/presentation/email_rules/widgets/list_email_rules_widget.dart @@ -1,5 +1,4 @@ import 'package:core/presentation/extensions/color_extension.dart'; -import 'package:core/utils/app_logger.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:jmap_dart_client/jmap/core/id.dart'; @@ -47,17 +46,25 @@ class ListEmailRulesWidget extends GetWidget { ), const Divider(), Obx(() { - log('ListEmailRulesWidget::build(): ${controller.listEmailRule}'); return ListView.separated( shrinkWrap: true, itemCount: controller.listEmailRule.length, primary: false, padding: EdgeInsets.zero, itemBuilder: (context, index) { - final ruleWithId = controller.listEmailRule[index] - .copyWith(id: RuleId(id: Id(index.toString()))); - log('ListEmailRulesWidget::build(): $ruleWithId'); - return EmailRulesItemWidget(rule: ruleWithId); + final ruleWithId = controller.listEmailRule[index].copyWith(id: RuleId(id: Id(index.toString()))); + + return Obx(() { + return EmailRulesItemWidget( + imagePaths: controller.imagePaths, + responsiveUtils: controller.responsiveUtils, + rule: ruleWithId, + mailboxIds: controller.listMailboxIdsAppendIn.value, + editRuleAction: controller.editEmailRule, + deleteRuleAction: controller.deleteEmailRule, + openEditRuleMenuAction: controller.openEditRuleMenuAction, + ); + }); }, separatorBuilder: (context, index) { if (controller.listEmailRule.isNotEmpty) { diff --git a/lib/features/manage_account/presentation/extensions/list_tmail_rule_extension.dart b/lib/features/manage_account/presentation/extensions/list_tmail_rule_extension.dart new file mode 100644 index 0000000000..9cf9fec82e --- /dev/null +++ b/lib/features/manage_account/presentation/extensions/list_tmail_rule_extension.dart @@ -0,0 +1,16 @@ + +import 'package:core/utils/app_logger.dart'; +import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; +import 'package:rule_filter/rule_filter/tmail_rule.dart'; + +extension ListTMailRuleExtension on List { + List get mailboxesAppendIn { + List mailboxIds = []; + for (var rule in this) { + mailboxIds.addAll(rule.action.appendIn.mailboxIds); + } + mailboxIds = mailboxIds.toSet().toList(); + log('ListTMailRuleExtension::_getAllMailboxAppendIn: mailboxIds = $mailboxIds'); + return mailboxIds; + } +} \ No newline at end of file diff --git a/lib/features/rules_filter_creator/presentation/rules_filter_creator_controller.dart b/lib/features/rules_filter_creator/presentation/rules_filter_creator_controller.dart index 5343988029..a038f944db 100644 --- a/lib/features/rules_filter_creator/presentation/rules_filter_creator_controller.dart +++ b/lib/features/rules_filter_creator/presentation/rules_filter_creator_controller.dart @@ -129,10 +129,7 @@ class RulesFilterCreatorController extends BaseMailboxController { await syncAllMailboxWithDisplayName(currentContext!); } } else if (success is GetAllRulesSuccess) { - log('RulesFilterCreatorController::handleSuccessViewState():GetAllRulesSuccess: ${success.rules}'); - if (success.rules?.isNotEmpty == true) { - _listEmailRule = success.rules!; - } + _listEmailRule = success.rules; } } diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index 04cf96ed56..a612fdf62f 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -4017,5 +4017,11 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "warningRuleCannotAppliedWhenTargetFolderNoExist": "The rule cannot be applied as the target folder do no longer exist.", + "@warningRuleCannotAppliedWhenTargetFolderNoExist": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } \ No newline at end of file diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart index 44cc48b95d..5a9c0ecfa9 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -4213,4 +4213,11 @@ class AppLocalizations { name: 'youAreOffline', ); } + + String get warningRuleCannotAppliedWhenTargetFolderNoExist { + return Intl.message( + 'The rule cannot be applied as the target folder do no longer exist.', + name: 'warningRuleCannotAppliedWhenTargetFolderNoExist', + ); + } } \ No newline at end of file