diff --git a/assets/images/ic_mailbox_visibility.svg b/assets/images/ic_mailbox_visibility.svg
new file mode 100644
index 000000000..87feb0a80
--- /dev/null
+++ b/assets/images/ic_mailbox_visibility.svg
@@ -0,0 +1,5 @@
+
diff --git a/core/lib/presentation/resources/image_paths.dart b/core/lib/presentation/resources/image_paths.dart
index 8e1b00117..7084a8f7b 100644
--- a/core/lib/presentation/resources/image_paths.dart
+++ b/core/lib/presentation/resources/image_paths.dart
@@ -174,6 +174,7 @@ class ImagePaths {
String get icDeleteMailbox => _getImagePath('ic_delete_mailbox.svg');
String get icHideMailbox => _getImagePath('ic_hide_mailbox.svg');
String get icShowMailbox => _getImagePath('ic_show_mailbox.svg');
+ String get icMailboxVisibility => _getImagePath('ic_mailbox_visibility.svg');
String _getImagePath(String imageName) {
return AssetsPaths.images + imageName;
diff --git a/lib/features/base/base_controller.dart b/lib/features/base/base_controller.dart
index 43005ef6a..44eca34d6 100644
--- a/lib/features/base/base_controller.dart
+++ b/lib/features/base/base_controller.dart
@@ -27,6 +27,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/bindings/c
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/bindings/tmail_autocomplete_bindings.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/bindings/email_rules_interactor_bindings.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/forward/bindings/forwarding_interactors_bindings.dart';
+import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/bindings/mailbox_visibility_interactor_bindings.dart';
import 'package:tmail_ui_user/features/push_notification/domain/exceptions/fcm_exception.dart';
import 'package:tmail_ui_user/features/push_notification/presentation/bindings/fcm_interactor_bindings.dart';
import 'package:tmail_ui_user/features/push_notification/presentation/config/fcm_configuration.dart';
@@ -163,6 +164,10 @@ abstract class BaseController extends GetxController
}
}
+ void injectMailboxVisibilityBindings() {
+ MailboxVisibilityInteractorBindings().dependencies();
+ }
+
void injectFCMBindings(Session? session, AccountId? accountId) async {
try {
requireCapability(session!, accountId!, [FirebaseCapability.fcmIdentifier]);
diff --git a/lib/features/manage_account/presentation/mailbox_visibility/bindings/mailbox_visibility_bindings.dart b/lib/features/manage_account/presentation/mailbox_visibility/bindings/mailbox_visibility_bindings.dart
new file mode 100644
index 000000000..07e7a578e
--- /dev/null
+++ b/lib/features/manage_account/presentation/mailbox_visibility/bindings/mailbox_visibility_bindings.dart
@@ -0,0 +1,20 @@
+import 'package:get/get.dart';
+import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_builder.dart';
+import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart';
+import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/mailbox_visibility_controller.dart';
+
+class MailboxVisibilityBindings extends Bindings {
+
+ @override
+ void dependencies() {
+ Get.lazyPut(() => MailboxVisibilityController(
+ Get.find(),
+ Get.find()
+ ));
+ _bindingsUtils();
+ }
+
+ void _bindingsUtils() {
+ Get.lazyPut(() => TreeBuilder());
+ }
+}
\ No newline at end of file
diff --git a/lib/features/manage_account/presentation/mailbox_visibility/bindings/mailbox_visibility_interactor_bindings.dart b/lib/features/manage_account/presentation/mailbox_visibility/bindings/mailbox_visibility_interactor_bindings.dart
new file mode 100644
index 000000000..176e8774b
--- /dev/null
+++ b/lib/features/manage_account/presentation/mailbox_visibility/bindings/mailbox_visibility_interactor_bindings.dart
@@ -0,0 +1,63 @@
+import 'package:get/get.dart';
+import 'package:tmail_ui_user/features/base/interactors_bindings.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/features/caching/state_cache_client.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/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_all_mailbox_interactor.dart';
+import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart';
+import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_mailbox_interactor.dart';
+import 'package:core/data/model/source_type/data_source_type.dart';
+
+class MailboxVisibilityInteractorBindings extends InteractorsBindings {
+
+ @override
+ void bindingsDataSource() {
+ Get.lazyPut(() => Get.find());
+ Get.lazyPut(() => Get.find());
+ }
+
+ @override
+ void bindingsDataSourceImpl() {
+ Get.lazyPut(() => MailboxDataSourceImpl(
+ Get.find(),
+ Get.find(),
+ Get.find()));
+ Get.lazyPut(() => MailboxCacheDataSourceImpl(
+ Get.find(),
+ Get.find()));
+ Get.lazyPut(() => StateDataSourceImpl(Get.find(), Get.find()));
+ }
+
+ @override
+ void bindingsInteractor() {
+ Get.lazyPut(() => GetAllMailboxInteractor(Get.find()));
+ Get.lazyPut(() => RefreshAllMailboxInteractor(Get.find()));
+ Get.lazyPut(() => SubscribeMailboxInteractor(Get.find()));
+ }
+
+ @override
+ void bindingsRepository() {
+ Get.lazyPut(() => Get.find());
+ }
+
+ @override
+ void bindingsRepositoryImpl() {
+ 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/mailbox_visibility/mailbox_visibility_controller.dart b/lib/features/manage_account/presentation/mailbox_visibility/mailbox_visibility_controller.dart
new file mode 100644
index 000000000..07e9b6a05
--- /dev/null
+++ b/lib/features/manage_account/presentation/mailbox_visibility/mailbox_visibility_controller.dart
@@ -0,0 +1,197 @@
+import 'package:core/presentation/extensions/color_extension.dart';
+import 'package:core/presentation/resources/image_paths.dart';
+import 'package:core/presentation/utils/app_toast.dart';
+import 'package:core/presentation/utils/responsive_utils.dart';
+import 'package:core/utils/app_logger.dart';
+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/core/session/session.dart';
+import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
+import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
+import 'package:model/mailbox/expand_mode.dart';
+import 'package:model/mailbox/presentation_mailbox.dart';
+import 'package:tmail_ui_user/features/base/base_mailbox_controller.dart';
+import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subscribe_action_state.dart';
+import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subscribe_state.dart';
+import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_mailbox_request.dart';
+import 'package:tmail_ui_user/features/mailbox/domain/state/get_all_mailboxes_state.dart';
+import 'package:tmail_ui_user/features/mailbox/domain/state/refresh_changes_all_mailboxes_state.dart';
+import 'package:tmail_ui_user/features/mailbox/domain/state/subscribe_mailbox_state.dart';
+import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_all_mailbox_interactor.dart';
+import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart';
+import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_mailbox_interactor.dart';
+import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_categories.dart';
+import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_categories_expand_mode.dart';
+import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart';
+import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_builder.dart';
+import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart';
+import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart';
+import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
+import 'package:tmail_ui_user/main/routes/route_navigation.dart';
+
+class MailboxVisibilityController extends BaseMailboxController {
+ GetAllMailboxInteractor? _getAllMailboxInteractor;
+ RefreshAllMailboxInteractor? _refreshAllMailboxInteractor;
+ SubscribeMailboxInteractor? _subscribeMailboxInteractor;
+ final _accountDashBoardController = Get.find();
+ final _appToast = Get.find();
+ final _imagePaths = Get.find();
+ final _responsiveUtils = Get.find();
+ final mailboxCategoriesExpandMode = MailboxCategoriesExpandMode.initial().obs;
+ final mailboxListScrollController = ScrollController();
+
+ Map mapDefaultMailboxIdByRole = {};
+ Map mapMailboxById = {};
+ PresentationMailbox? outboxMailbox;
+
+ jmap.State? _currentMailboxState;
+
+ MailboxVisibilityController(
+ TreeBuilder treeBuilder,
+ VerifyNameInteractor verifyNameInteractor,
+ ) : super(treeBuilder, verifyNameInteractor);
+
+ @override
+ void onInit() {
+ super.onInit();
+ try {
+ _getAllMailboxInteractor = Get.find();
+ _refreshAllMailboxInteractor = Get.find();
+ _subscribeMailboxInteractor = Get.find();
+ } catch (e) {
+ logError('MailboxVisibilityController::onInit(): ${e.toString()}');
+ }
+ }
+
+ @override
+ void onDone() {
+ viewState.value.fold((failure) {}, (success) {
+ if (success is GetAllMailboxSuccess) {
+ _currentMailboxState = success.currentMailboxState;
+ _buildMailboxTreeHasSubscribed(success.mailboxList);
+ } else if (success is RefreshChangesAllMailboxSuccess) {
+ _currentMailboxState = success.currentMailboxState;
+ _refreshMailboxTreeHasSubscribed(success.mailboxList);
+ } else if (success is SubscribeMailboxSuccess) {
+ _subscribeMailboxSuccess(success);
+ }
+ });
+
+ }
+
+ @override
+ void onReady() {
+ final _session = _accountDashBoardController.sessionCurrent.value;
+ final _accountId = _accountDashBoardController.accountId.value;
+ if(_session != null && _accountId != null) {
+ getAllMailboxAction(_session, _accountId);
+ }
+ super.onReady();
+ }
+
+ void getAllMailboxAction(Session session, AccountId accountId) async {
+ if(_getAllMailboxInteractor != null){
+ consumeState(_getAllMailboxInteractor!.execute(session, accountId));
+ }
+ }
+
+ void refreshMailboxChanges({jmap.State? currentMailboxState}) {
+ log('MailboxVisibilityController::refreshMailboxChanges(): currentMailboxState: $currentMailboxState');
+ final newMailboxState = currentMailboxState ?? _currentMailboxState;
+ log('MailboxVisibilityController::refreshMailboxChanges(): newMailboxState: $newMailboxState');
+ final session = _accountDashBoardController.sessionCurrent.value;
+ final accountId = _accountDashBoardController.accountId.value;
+ if (accountId != null && session != null && newMailboxState != null) {
+ consumeState(_refreshAllMailboxInteractor!.execute(session, accountId, newMailboxState));
+ }
+ }
+
+ void _buildMailboxTreeHasSubscribed(List mailboxList) async {
+ final _mailboxList = mailboxList;
+ await buildTree(_mailboxList);
+ }
+
+ void _refreshMailboxTreeHasSubscribed(List mailboxList) async {
+ final _mailboxList = mailboxList;
+ await refreshTree(_mailboxList);
+ }
+
+ void subscribeMailbox(MailboxNode mailboxNode) {
+ final _mailboxSubscribeState = mailboxNode.item.isSubscribedMailbox
+ ? MailboxSubscribeState.disabled : MailboxSubscribeState.enabled;
+ final _mailboxSubscribeStateAction = mailboxNode.item.isSubscribedMailbox
+ ? MailboxSubscribeAction.unSubscribe : MailboxSubscribeAction.subscribe;
+ if (mailboxNode.item.isSubscribedMailbox) {
+ _subscribeMailboxAction(
+ SubscribeMailboxRequest(
+ mailboxNode.item.id,
+ _mailboxSubscribeState,
+ _mailboxSubscribeStateAction,
+ )
+ );
+ }
+ }
+
+ void _subscribeMailboxAction(SubscribeMailboxRequest subscribeMailboxRequest) {
+ final _accountId = _accountDashBoardController.accountId.value;
+ if (_accountId != null) {
+ consumeState(_subscribeMailboxInteractor!.execute(_accountId, subscribeMailboxRequest));
+ }
+ }
+
+ void toggleMailboxCategories(MailboxCategories categories) {
+ switch(categories) {
+ case MailboxCategories.exchange:
+ final newExpandMode = mailboxCategoriesExpandMode.value.defaultMailbox == ExpandMode.EXPAND ? ExpandMode.COLLAPSE : ExpandMode.EXPAND;
+ mailboxCategoriesExpandMode.value.defaultMailbox = newExpandMode;
+ mailboxCategoriesExpandMode.refresh();
+ break;
+ case MailboxCategories.personalMailboxes:
+ final newExpandMode = mailboxCategoriesExpandMode.value.personalMailboxes == ExpandMode.EXPAND ? ExpandMode.COLLAPSE : ExpandMode.EXPAND;
+ mailboxCategoriesExpandMode.value.personalMailboxes = newExpandMode;
+ mailboxCategoriesExpandMode.refresh();
+ break;
+ case MailboxCategories.teamMailboxes:
+ final newExpandMode = mailboxCategoriesExpandMode.value.teamMailboxes == ExpandMode.EXPAND ? ExpandMode.COLLAPSE : ExpandMode.EXPAND;
+ mailboxCategoriesExpandMode.value.teamMailboxes = newExpandMode;
+ mailboxCategoriesExpandMode.refresh();
+ break;
+ case MailboxCategories.appGrid:
+ break;
+ }
+ }
+
+ void _subscribeMailboxSuccess(SubscribeMailboxSuccess subscribeMailboxSuccess) {
+ if (subscribeMailboxSuccess.subscribeAction == MailboxSubscribeAction.unSubscribe
+ && currentOverlayContext != null
+ && currentContext != null) {
+ _appToast.showBottomToast(
+ currentOverlayContext!,
+ AppLocalizations.of(currentContext!).toastMsgHideMailboxSuccess,
+ actionName: AppLocalizations.of(currentContext!).undo,
+ onActionClick: () {
+ _subscribeMailboxAction(
+ SubscribeMailboxRequest(
+ subscribeMailboxSuccess.mailboxId,
+ MailboxSubscribeState.enabled,
+ MailboxSubscribeAction.undo)
+ );
+ },
+ leadingIcon: SvgPicture.asset(
+ _imagePaths.icFolderMailbox,
+ width: 24,
+ height: 24,
+ color: Colors.white,
+ fit: BoxFit.fill),
+ backgroundColor: AppColor.toastSuccessBackgroundColor,
+ textColor: Colors.white,
+ textActionColor: Colors.white,
+ actionIcon: SvgPicture.asset(_imagePaths.icUndo),
+ maxWidth: _responsiveUtils.getMaxWidthToast(currentContext!));
+ }
+
+ refreshMailboxChanges(currentMailboxState: subscribeMailboxSuccess.currentMailboxState);
+ }
+}
diff --git a/lib/features/manage_account/presentation/mailbox_visibility/mailbox_visibility_view.dart b/lib/features/manage_account/presentation/mailbox_visibility/mailbox_visibility_view.dart
new file mode 100644
index 000000000..1764fc2ca
--- /dev/null
+++ b/lib/features/manage_account/presentation/mailbox_visibility/mailbox_visibility_view.dart
@@ -0,0 +1,196 @@
+import 'package:core/presentation/extensions/color_extension.dart';
+import 'package:core/presentation/resources/image_paths.dart';
+import 'package:core/presentation/state/success.dart';
+import 'package:core/presentation/utils/responsive_utils.dart';
+import 'package:core/presentation/views/button/icon_button_web.dart';
+import 'package:core/presentation/views/list/tree_view.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:get/get.dart';
+import 'package:model/mailbox/expand_mode.dart';
+import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
+import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_categories.dart';
+import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart';
+import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/mailbox_visibility_controller.dart';
+import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/widgets/mailbox_visibility_folder_tile_builder.dart';
+import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/widgets/mailbox_visibility_header_widget.dart';
+import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.dart';
+import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
+
+class MailboxVisibilityView extends GetWidget with AppLoaderMixin {
+ final _responsiveUtils = Get.find();
+ final _imagePaths = Get.find();
+
+ MailboxVisibilityView({Key? key}) : super(key: key);
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ backgroundColor: _responsiveUtils.isWebDesktop(context)
+ ? AppColor.colorBgDesktop
+ : Colors.white,
+ body: Container(
+ width: double.infinity,
+ margin: _responsiveUtils.isWebDesktop(context)
+ ? const EdgeInsets.all(24)
+ : EdgeInsets.symmetric(horizontal: SettingsUtils.getHorizontalPadding(context, _responsiveUtils)),
+ color: _responsiveUtils.isWebDesktop(context) ? null : Colors.white,
+ decoration: _responsiveUtils.isWebDesktop(context)
+ ? BoxDecoration(
+ borderRadius: BorderRadius.circular(20),
+ border: Border.all(color: AppColor.colorBorderBodyThread, width: 1),
+ color: Colors.white)
+ : null,
+ child: ClipRRect(
+ borderRadius: BorderRadius.circular(
+ _responsiveUtils.isWebDesktop(context) ? 20 : 0),
+ child: Padding(
+ padding: const EdgeInsets.only(top: 24),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ if (_responsiveUtils.isWebDesktop(context))...[
+ const MailboxVisibilityHeaderWidget(),
+ _buildLoadingView(),
+ const Padding(
+ padding: EdgeInsets.symmetric(vertical: 16),
+ child: Divider(color: AppColor.colorDividerMailbox, height: 0.5, thickness: 0.2),
+ ),
+ ],
+ Expanded(child: _buildListMailbox(context)),
+ ]
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+ Widget _buildLoadingView() {
+ return Obx(() => controller.viewState.value.fold(
+ (failure) => const SizedBox.shrink(),
+ (success) => success is LoadingState
+ ? const Center(
+ child: Padding(
+ padding: EdgeInsets.only(top: 16),
+ child: SizedBox(
+ height: 24,
+ width: 24,
+ child: CupertinoActivityIndicator(
+ color: AppColor.colorTextButton,
+ ),
+ )),
+ )
+ : const SizedBox.shrink()));
+ }
+
+ Widget _buildListMailbox(BuildContext context) {
+ return SingleChildScrollView(
+ controller: controller.mailboxListScrollController,
+ key: const PageStorageKey('mailbox_list'),
+ physics: const ClampingScrollPhysics(),
+ child: Column(children: [
+ Obx(() => controller.defaultMailboxIsNotEmpty
+ ? _buildMailboxCategory(context, MailboxCategories.exchange, controller.defaultRootNode)
+ : const SizedBox.shrink()),
+ const SizedBox(height: 13),
+ Obx(() => controller.teamMailboxesIsNotEmpty
+ ? _buildMailboxCategory(context, MailboxCategories.teamMailboxes, controller.teamMailboxesRootNode)
+ : const SizedBox.shrink()),
+ const SizedBox(height: 8),
+ Obx(() => controller.personalMailboxIsNotEmpty
+ ? _buildMailboxCategory(context, MailboxCategories.personalMailboxes, controller.personalRootNode)
+ : const SizedBox.shrink()),
+
+ ])
+ );
+ }
+
+ Widget _buildHeaderMailboxCategory(BuildContext context, MailboxCategories categories) {
+ return Padding(
+ padding: const EdgeInsets.only(top: 10),
+ child: Row(children: [
+ buildIconWeb(
+ splashRadius: 5,
+ iconPadding: EdgeInsets.zero,
+ minSize: 12,
+ icon: SvgPicture.asset(
+ categories.getExpandMode(controller.mailboxCategoriesExpandMode.value) == ExpandMode.EXPAND
+ ? _imagePaths.icExpandFolder
+ : _imagePaths.icCollapseFolder,
+ color: AppColor.primaryColor,
+ fit: BoxFit.fill),
+ tooltip: AppLocalizations.of(context).collapse,
+ onTap: () => controller.toggleMailboxCategories(categories)),
+ Expanded(child: Text(categories.getTitle(context),
+ maxLines: 1,
+ overflow: TextOverflow.ellipsis,
+ style: const TextStyle(
+ fontSize: 17,
+ color: Colors.black,
+ fontWeight: FontWeight.bold))),
+ ]));
+ }
+
+ Widget _buildMailboxCategory(BuildContext context, MailboxCategories categories, MailboxNode mailboxNode) {
+ if (categories == MailboxCategories.exchange) {
+ return Padding(
+ padding: EdgeInsets.symmetric(horizontal: _responsiveUtils.isDesktop(context) ? 24 : 0),
+ child: _buildBodyMailboxCategory(context, categories, mailboxNode),
+ );
+ }
+ return Padding(
+ padding: EdgeInsets.symmetric(horizontal: _responsiveUtils.isDesktop(context) ? 24 : 0),
+ child: Column(children: [
+ _buildHeaderMailboxCategory(context, categories),
+ AnimatedContainer(
+ duration: const Duration(milliseconds: 400),
+ child: categories.getExpandMode(controller.mailboxCategoriesExpandMode.value) == ExpandMode.EXPAND
+ ? _buildBodyMailboxCategory(context, categories, mailboxNode)
+ : const Offstage())
+ ]),
+ );
+ }
+
+ Widget _buildBodyMailboxCategory(
+ BuildContext context,
+ MailboxCategories categories,
+ MailboxNode mailboxNode,
+ ) {
+ final lastNode = mailboxNode.childrenItems?.last;
+
+ return Container(
+ padding: EdgeInsets.only(
+ right: _responsiveUtils.isDesktop(context) ? 0 : 12,
+ left: _responsiveUtils.isDesktop(context) ? 0 : 12),
+ child: TreeView(
+ key: Key('${categories.keyValue}_mailbox_list'),
+ children: _buildListChildTileWidget(
+ context,
+ mailboxNode,
+ lastNode: lastNode)));
+ }
+
+ List _buildListChildTileWidget(
+ BuildContext context,
+ MailboxNode parentNode,
+ {MailboxNode? lastNode}
+ ) {
+ return parentNode.childrenItems
+ ?.map((mailboxNode) => mailboxNode.hasChildren()
+ ? TreeViewChild(
+ context,
+ key: const Key('children_tree_mailbox_child'),
+ isExpanded: mailboxNode.expandMode == ExpandMode.EXPAND,
+ parent: Obx(() => controller.defaultMailboxIsNotEmpty ? (MailBoxVisibilityFolderTileBuilder(context, _imagePaths, mailboxNode, lastNode: lastNode)
+ ..addOnExpandFolderActionClick((mailboxNode) => controller.toggleMailboxFolder(mailboxNode))
+ ..addOnSubscribeMailboxActionClick((mailboxNode) => controller.subscribeMailbox(mailboxNode)))
+ .build(context) : const SizedBox.shrink()) ,
+ children: _buildListChildTileWidget(context, mailboxNode)
+ ).build()
+ : Obx(() => controller.defaultMailboxIsNotEmpty ? (MailBoxVisibilityFolderTileBuilder(context, _imagePaths, mailboxNode, lastNode: lastNode)
+ ..addOnExpandFolderActionClick((mailboxNode) => controller.toggleMailboxFolder(mailboxNode))
+ ..addOnSubscribeMailboxActionClick((mailboxNode) => controller.subscribeMailbox(mailboxNode)))
+ .build(context) : const SizedBox.shrink())).toList() ?? [];
+ }
+}
\ No newline at end of file
diff --git a/lib/features/manage_account/presentation/mailbox_visibility/widgets/mailbox_visibility_folder_tile_builder.dart b/lib/features/manage_account/presentation/mailbox_visibility/widgets/mailbox_visibility_folder_tile_builder.dart
new file mode 100644
index 000000000..8bcd7762c
--- /dev/null
+++ b/lib/features/manage_account/presentation/mailbox_visibility/widgets/mailbox_visibility_folder_tile_builder.dart
@@ -0,0 +1,258 @@
+import 'package:core/core.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:model/mailbox/expand_mode.dart';
+import 'package:tmail_ui_user/features/mailbox/domain/extensions/presentation_mailbox_extension.dart';
+import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
+import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart';
+import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
+
+typedef OnExpandFolderActionClick = void Function(MailboxNode);
+typedef OnSubscribeMailboxActionClick = void Function(MailboxNode);
+
+class MailBoxVisibilityFolderTileBuilder {
+ final MailboxNode _mailboxNode;
+ final BuildContext _context;
+ final ImagePaths _imagePaths;
+ final MailboxNode? lastNode;
+ final MailboxActions? mailboxActions;
+
+ OnSubscribeMailboxActionClick? _onSubscribeMailboxActionClick;
+ OnExpandFolderActionClick? _onExpandFolderActionClick;
+ bool isHoverItem = false;
+
+ MailBoxVisibilityFolderTileBuilder(
+ this._context,
+ this._imagePaths,
+ this._mailboxNode, {
+ this.lastNode,
+ this.mailboxActions,
+ });
+
+ void addOnExpandFolderActionClick(OnExpandFolderActionClick onExpandFolderActionClick) {
+ _onExpandFolderActionClick = onExpandFolderActionClick;
+ }
+
+ void addOnSubscribeMailboxActionClick(OnSubscribeMailboxActionClick onSubscribeMailboxActionClick) {
+ _onSubscribeMailboxActionClick = onSubscribeMailboxActionClick;
+ }
+
+ Widget build(BuildContext context) => _buildMailboxItem(context);
+
+ Widget _buildMailboxItem(BuildContext context) {
+ if (BuildUtils.isWeb) {
+ return Theme(
+ data: ThemeData(
+ splashColor: Colors.transparent,
+ highlightColor: Colors.transparent),
+ child: StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ return InkWell(
+ onTap: () {},
+ onHover: (value) => setState(() => isHoverItem = value),
+ child: Container(
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(10),
+ color: backgroundColorItem),
+ padding: EdgeInsets.only(
+ left: _mailboxNode.item.hasRole() ? 0 : 4,
+ right: 4,
+ top: 8,
+ bottom: 8),
+ margin: const EdgeInsets.only(bottom: 4),
+ child: Row(
+ children: [
+ _buildLeadingMailboxItem(),
+ const SizedBox(width: 4),
+ Expanded(child: _buildTitleFolderItem()),
+ if (!_mailboxNode.item.hasRole())
+ _buildSubscribeMailboxItem(context, _mailboxNode),
+ const SizedBox(width: 32),
+ ]),
+ ),
+ );
+ }),
+ );
+ } else {
+ return ClipRRect(
+ borderRadius: const BorderRadius.all(Radius.circular(14)),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Container(
+ padding: EdgeInsets.symmetric(
+ vertical: _mailboxNode.hasChildren() ? 8 : 15),
+ child: Row(
+ crossAxisAlignment:
+ _mailboxNode.item.isTeamMailboxes
+ ? CrossAxisAlignment.start
+ : CrossAxisAlignment.center,
+ children: [
+ if (_mailboxNode.item.isTeamMailboxes)
+ const SizedBox(width: 16),
+ _buildLeadingMailboxItem(),
+ const SizedBox(width: 8),
+ Expanded(child: _buildTitleFolderItem()),
+ if (!_mailboxNode.item.hasRole())
+ _buildSubscribeMailboxItem(context, _mailboxNode),
+ ]),
+ ),
+ ]));
+ }
+ }
+
+ Widget _buildLeadingMailboxItem() {
+ if (BuildUtils.isWeb) {
+ return Row(mainAxisSize: MainAxisSize.min, children: [
+ if (_mailboxNode.hasChildren() && _mailboxNode.item.isPersonal)
+ Row(
+ children: [
+ const SizedBox(width: 8),
+ buildIconWeb(
+ icon: SvgPicture.asset(
+ _mailboxNode.expandMode == ExpandMode.EXPAND
+ ? _imagePaths.icExpandFolder
+ : _imagePaths.icCollapseFolder,
+ color: _mailboxNode.expandMode == ExpandMode.EXPAND
+ ? AppColor.colorExpandMailbox
+ : AppColor.colorCollapseMailbox,
+ fit: BoxFit.fill),
+ minSize: 12,
+ splashRadius: 10,
+ iconPadding: EdgeInsets.zero,
+ tooltip: _mailboxNode.expandMode == ExpandMode.EXPAND
+ ? AppLocalizations.of(_context).collapse
+ : AppLocalizations.of(_context).expand,
+ onTap: () => _onExpandFolderActionClick?.call(_mailboxNode)),
+ ],
+ )
+ else
+ SizedBox(width: _mailboxNode.item.isPersonal ? 32 : 24),
+ Transform(
+ transform: Matrix4.translationValues(-4.0, 0.0, 0.0),
+ child: _buildLeadingIconTeamMailboxes()),
+ ]);
+ } else {
+ return Row(mainAxisSize: MainAxisSize.min, children: [
+ if (_mailboxNode.hasChildren())
+ Row(
+ children: [
+ SizedBox(width: _mailboxNode.item.hasRole() ? 0 : 0),
+ if (!_mailboxNode.item.isTeamMailboxes)
+ buildIconWeb(
+ icon: SvgPicture.asset(
+ _mailboxNode.expandMode == ExpandMode.EXPAND
+ ? _imagePaths.icExpandFolder
+ : _imagePaths.icCollapseFolder,
+ color: _mailboxNode.expandMode == ExpandMode.EXPAND
+ ? AppColor.colorExpandMailbox
+ : AppColor.colorCollapseMailbox,
+ fit: BoxFit.fill),
+ minSize: 12,
+ splashRadius: 10,
+ iconPadding: EdgeInsets.zero,
+ tooltip: _mailboxNode.expandMode == ExpandMode.EXPAND
+ ? AppLocalizations.of(_context).collapse
+ : AppLocalizations.of(_context).expand,
+ onTap: () => _onExpandFolderActionClick?.call(_mailboxNode)),
+ ],
+ )
+ else
+ const SizedBox(width: 24),
+ _buildLeadingIconTeamMailboxes(),
+ ]);
+ }
+ }
+
+ Widget _buildLeadingIconTeamMailboxes() {
+ if (!_mailboxNode.item.isPersonal) {
+ return _buildLeadingIconForChildOfTeamMailboxes();
+ } else {
+ return _buildMailboxIcon();
+ }
+ }
+
+ Widget _buildLeadingIconForChildOfTeamMailboxes() {
+ if (_mailboxNode.item.hasParentId()) {
+ return _buildMailboxIcon();
+ } else {
+ return const SizedBox();
+ }
+ }
+
+ Color get backgroundColorItem {
+ if (BuildUtils.isWeb && isHoverItem) {
+ return AppColor.colorBgMailboxSelected;
+ } else {
+ return Colors.white;
+ }
+ }
+
+ Widget _buildTitleFolderItem() {
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ _mailboxNode.item.name?.name ?? '',
+ maxLines: 1,
+ softWrap: CommonTextStyle.defaultSoftWrap,
+ overflow: CommonTextStyle.defaultTextOverFlow,
+ style: TextStyle(
+ fontSize: _mailboxNode.item.isTeamMailboxes ? 16 : 15,
+ color: _mailboxNode.item.isSubscribedMailbox
+ ? _getColorTextTitleFolderItem()
+ : AppColor.colorItemAlreadySelected,
+ fontWeight: _mailboxNode.item.isTeamMailboxes
+ ? FontWeight.w500
+ : FontWeight.normal),
+ ),
+ if (_mailboxNode.item.isTeamMailboxes)
+ Text(
+ _mailboxNode.item.emailTeamMailBoxes ?? '',
+ maxLines: 1,
+ softWrap: CommonTextStyle.defaultSoftWrap,
+ overflow: CommonTextStyle.defaultTextOverFlow,
+ style: const TextStyle(
+ fontSize: 13,
+ color: AppColor.colorEmailAddressFull,
+ fontWeight: FontWeight.w400),
+ ),
+ ],
+ );
+ }
+
+ Color _getColorTextTitleFolderItem() {
+ if (_mailboxNode.item.isTeamMailboxes) {
+ return Colors.black;
+ } else {
+ return AppColor.colorNameEmail;
+ }
+ }
+
+ Widget _buildMailboxIcon() {
+ return SvgPicture.asset(_mailboxNode.item.getMailboxIcon(_imagePaths),
+ width: BuildUtils.isWeb ? 20 : 24,
+ height: BuildUtils.isWeb ? 20 : 24,
+ color: !_mailboxNode.item.isSubscribedMailbox
+ ? AppColor.colorDeleteContactIcon
+ : null,
+ fit: BoxFit.fill);
+ }
+
+ Widget _buildSubscribeMailboxItem(BuildContext context, MailboxNode _mailboxNode) {
+ return InkWell(
+ onTap: () => _onSubscribeMailboxActionClick?.call(_mailboxNode),
+ child: Text(
+ _mailboxNode.item.isSubscribedMailbox
+ ? AppLocalizations.of(context).hide
+ : AppLocalizations.of(context).show,
+ maxLines: 1,
+ softWrap: CommonTextStyle.defaultSoftWrap,
+ overflow: CommonTextStyle.defaultTextOverFlow,
+ style: const TextStyle(
+ fontSize: 15, color: Colors.blue, fontWeight: FontWeight.normal),
+ ),
+ );
+ }
+}
diff --git a/lib/features/manage_account/presentation/mailbox_visibility/widgets/mailbox_visibility_header_widget.dart b/lib/features/manage_account/presentation/mailbox_visibility/widgets/mailbox_visibility_header_widget.dart
new file mode 100644
index 000000000..db732aeb4
--- /dev/null
+++ b/lib/features/manage_account/presentation/mailbox_visibility/widgets/mailbox_visibility_header_widget.dart
@@ -0,0 +1,30 @@
+import 'package:core/presentation/extensions/color_extension.dart';
+import 'package:flutter/material.dart';
+import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
+
+class MailboxVisibilityHeaderWidget extends StatelessWidget {
+
+ const MailboxVisibilityHeaderWidget({Key? key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return Padding(
+ padding: const EdgeInsets.only(left: 24),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(AppLocalizations.of(context).mailboxVisibility,
+ style: const TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ color: Colors.black)),
+ const SizedBox(height: 4),
+ Text(AppLocalizations.of(context).mailboxVisibilitySubtitle,
+ style: const TextStyle(
+ fontSize: 16,
+ fontWeight: FontWeight.w500,
+ color: AppColor.colorSettingExplanation))
+ ]),
+ );
+ }
+}
\ No newline at end of file
diff --git a/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart b/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart
index 5f2a3d00f..d5dfc4c54 100644
--- a/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart
+++ b/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart
@@ -26,6 +26,7 @@ import 'package:tmail_ui_user/features/manage_account/presentation/action/dashbo
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/bindings/email_rules_bindings.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/forward/bindings/forward_bindings.dart';
+import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/bindings/mailbox_visibility_bindings.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/manage_account_arguments.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/settings_page_level.dart';
@@ -103,6 +104,7 @@ class ManageAccountDashBoardController extends ReloadableController {
injectAutoCompleteBindings(sessionCurrent.value, accountId.value);
injectForwardBindings(sessionCurrent.value, accountId.value);
injectRuleFilterBindings(sessionCurrent.value, accountId.value);
+ injectMailboxVisibilityBindings();
injectVacationBindings(sessionCurrent.value, accountId.value);
_getVacationResponse();
}
@@ -117,6 +119,7 @@ class ManageAccountDashBoardController extends ReloadableController {
injectAutoCompleteBindings(sessionCurrent.value, accountId.value);
injectForwardBindings(sessionCurrent.value, accountId.value);
injectRuleFilterBindings(sessionCurrent.value, accountId.value);
+ injectMailboxVisibilityBindings();
injectVacationBindings(sessionCurrent.value, accountId.value);
_getVacationResponse();
if (arguments.menuSettingCurrent != null) {
@@ -182,12 +185,15 @@ class ManageAccountDashBoardController extends ReloadableController {
void selectAccountMenuItem(AccountMenuItem newAccountMenuItem) {
clearInputFormView();
- if(newAccountMenuItem == AccountMenuItem.emailRules) {
+ if (newAccountMenuItem == AccountMenuItem.emailRules) {
EmailRulesBindings().dependencies();
}
- if(newAccountMenuItem == AccountMenuItem.forward) {
+ if (newAccountMenuItem == AccountMenuItem.forward) {
ForwardBindings().dependencies();
}
+ if (newAccountMenuItem == AccountMenuItem.mailboxVisibility) {
+ MailboxVisibilityBindings().dependencies();
+ }
accountMenuItemSelected.value = newAccountMenuItem;
if (isMenuDrawerOpen) {
closeMenuDrawer();
@@ -205,12 +211,15 @@ class ManageAccountDashBoardController extends ReloadableController {
}
void _goToSettingMenuCurrent(AccountMenuItem accountMenuItem) {
- if(accountMenuItem == AccountMenuItem.emailRules) {
+ if (accountMenuItem == AccountMenuItem.emailRules) {
EmailRulesBindings().dependencies();
}
- if(accountMenuItem == AccountMenuItem.forward) {
+ if (accountMenuItem == AccountMenuItem.forward) {
ForwardBindings().dependencies();
}
+ if (accountMenuItem == AccountMenuItem.mailboxVisibility) {
+ MailboxVisibilityBindings().dependencies();
+ }
accountMenuItemSelected.value = accountMenuItem;
if (currentContext != null &&
!_responsiveUtils.isDesktop(currentContext!)) {
diff --git a/lib/features/manage_account/presentation/manage_account_dashboard_view.dart b/lib/features/manage_account/presentation/manage_account_dashboard_view.dart
index 3f8b66810..cf2460d97 100644
--- a/lib/features/manage_account/presentation/manage_account_dashboard_view.dart
+++ b/lib/features/manage_account/presentation/manage_account_dashboard_view.dart
@@ -10,6 +10,7 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mixin/user_setting_popup_menu_mixin.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
+import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/mailbox_visibility_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/email_rules_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/forward/forward_view.dart';
@@ -179,6 +180,8 @@ class ManageAccountDashBoardView extends GetWidget {
return const SizedBox.shrink();
}
}),
+ Column(children: [
+ SettingFirstLevelTileBuilder(
+ AccountMenuItem.mailboxVisibility.getName(context),
+ AccountMenuItem.mailboxVisibility.getIcon(_imagePaths),
+ subtitle: AppLocalizations.of(context).mailboxVisibilitySubtitle,
+ () => controller.selectSettings(AccountMenuItem.mailboxVisibility)
+ ),
+ Divider(
+ color: AppColor.colorDividerComposer,
+ height: 1,
+ indent: SettingsUtils.getHorizontalPadding(context, _responsiveUtils),
+ endIndent: SettingsUtils.getHorizontalPadding(context, _responsiveUtils)
+ ),
+ ]),
SettingFirstLevelTileBuilder(
AccountMenuItem.languageAndRegion.getName(context),
AccountMenuItem.languageAndRegion.getIcon(_imagePaths),
diff --git a/lib/features/manage_account/presentation/menu/settings/settings_view.dart b/lib/features/manage_account/presentation/menu/settings/settings_view.dart
index bd2e0028a..c49e02d3c 100644
--- a/lib/features/manage_account/presentation/menu/settings/settings_view.dart
+++ b/lib/features/manage_account/presentation/menu/settings/settings_view.dart
@@ -11,6 +11,7 @@ import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/e
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/forward/forward_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/language_and_region/language_and_region_view.dart';
+import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/mailbox_visibility_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings/settings_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings/settings_first_level_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.dart';
@@ -193,13 +194,13 @@ class SettingsView extends GetWidget {
case AccountMenuItem.languageAndRegion:
return LanguageAndRegionView();
case AccountMenuItem.emailRules:
- if(controller.manageAccountDashboardController.checkAvailableRuleFilterInSession()){
+ if (controller.manageAccountDashboardController.checkAvailableRuleFilterInSession()) {
return EmailRulesView();
} else {
return const SizedBox.shrink();
}
case AccountMenuItem.forward:
- if(controller.manageAccountDashboardController.checkAvailableForwardInSession()){
+ if (controller.manageAccountDashboardController.checkAvailableForwardInSession()) {
return ForwardView();
} else {
return const SizedBox.shrink();
@@ -210,6 +211,8 @@ class SettingsView extends GetWidget {
} else {
return const SizedBox.shrink();
}
+ case AccountMenuItem.mailboxVisibility:
+ return MailboxVisibilityView();
default:
return const SizedBox.shrink();
}
diff --git a/lib/features/manage_account/presentation/model/account_menu_item.dart b/lib/features/manage_account/presentation/model/account_menu_item.dart
index fef3d31b5..265cb243b 100644
--- a/lib/features/manage_account/presentation/model/account_menu_item.dart
+++ b/lib/features/manage_account/presentation/model/account_menu_item.dart
@@ -9,6 +9,7 @@ enum AccountMenuItem {
emailRules,
forward,
vacation,
+ mailboxVisibility,
none;
String getIcon(ImagePaths imagePaths) {
@@ -23,6 +24,8 @@ enum AccountMenuItem {
return imagePaths.icForward;
case AccountMenuItem.vacation:
return imagePaths.icVacation;
+ case AccountMenuItem.mailboxVisibility:
+ return imagePaths.icMailboxVisibility;
case AccountMenuItem.none:
return imagePaths.icProfiles;
}
@@ -40,6 +43,8 @@ enum AccountMenuItem {
return AppLocalizations.of(context).forwarding;
case AccountMenuItem.vacation:
return AppLocalizations.of(context).vacation;
+ case AccountMenuItem.mailboxVisibility:
+ return AppLocalizations.of(context).mailboxVisibility;
case AccountMenuItem.none:
return AppLocalizations.of(context).profiles;
}
diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart
index e8b7dff44..9b4e9c70e 100644
--- a/lib/main/localizations/app_localizations.dart
+++ b/lib/main/localizations/app_localizations.dart
@@ -2805,4 +2805,17 @@ class AppLocalizations {
'This mailbox is already displayed in your primary mailbox',
name: 'toastMessageShowMailboxSuccess');
}
+ String get mailboxVisibility {
+ return Intl.message(
+ 'Mailbox visibility',
+ name: 'mailboxVisibility',
+ );
+ }
+
+ String get mailboxVisibilitySubtitle {
+ return Intl.message(
+ 'Show/ hide your mailboxes, including your personal and team mailboxes.',
+ name: 'mailboxVisibilitySubtitle',
+ );
+ }
}
\ No newline at end of file
diff --git a/model/lib/mailbox/presentation_mailbox.dart b/model/lib/mailbox/presentation_mailbox.dart
index 2c4da5dd2..cb888097d 100644
--- a/model/lib/mailbox/presentation_mailbox.dart
+++ b/model/lib/mailbox/presentation_mailbox.dart
@@ -89,6 +89,8 @@ class PresentationMailbox with EquatableMixin {
bool get isOutbox => name == lowerCaseOutboxMailboxName || role == roleOutbox;
+ bool get isSubscribedMailbox => isSubscribed != null && isSubscribed?.value == true;
+
bool matchCountingRules() {
if (isTrash || isDrafts || isTemplates || isSent) {
return false;