Files
workavia-mail-front/lib/features/base/base_mailbox_controller.dart
T
2025-07-02 14:22:15 +07:00

683 lines
27 KiB
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/bottom_popup/confirmation_dialog_action_sheet_builder.dart';
import 'package:core/presentation/views/dialog/confirmation_dialog_builder.dart';
import 'package:core/presentation/views/modal_sheets/edit_text_modal_sheet_builder.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/properties/properties.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/extensions/presentation_mailbox_extension.dart';
import 'package:model/mailbox/expand_mode.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:model/mailbox/select_mode.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/base/action/update_mailbox_properties_action/update_mailbox_name_action.dart';
import 'package:tmail_ui_user/features/base/action/update_mailbox_properties_action/update_mailbox_total_emails_count_action.dart';
import 'package:tmail_ui_user/features/base/action/update_mailbox_properties_action/update_mailbox_unread_count_action.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.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/model/subscribe_multiple_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_request.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/presentation/extensions/expand_mode_extension.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/extensions/list_mailbox_node_extension.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/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_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.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_builder.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/model/verification/duplicate_name_validator.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/model/verification/empty_name_validator.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/model/verification/name_with_space_only_validator.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/model/verification/special_character_validator.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/state/verify_name_view_state.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_creator/presentation/extensions/validator_failure_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart';
import 'package:tmail_ui_user/main/routes/dialog_router.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
typedef RenameMailboxActionCallback = void Function(PresentationMailbox mailbox, MailboxName newMailboxName);
typedef MovingMailboxActionCallback = void Function(PresentationMailbox mailboxSelected, PresentationMailbox? destinationMailbox);
typedef DeleteMailboxActionCallback = void Function(PresentationMailbox mailbox);
typedef AllowSubaddressingActionCallback = void Function(MailboxId, Map<String, List<String>?>?, MailboxActions);
abstract class BaseMailboxController extends BaseController {
final TreeBuilder _treeBuilder;
final VerifyNameInteractor verifyNameInteractor;
final GetAllMailboxInteractor? getAllMailboxInteractor;
final RefreshAllMailboxInteractor? refreshAllMailboxInteractor;
jmap.State? currentMailboxState;
final mailboxCategoriesExpandMode = MailboxCategoriesExpandMode.initial().obs;
BaseMailboxController(
this._treeBuilder,
this.verifyNameInteractor,
{
this.getAllMailboxInteractor,
this.refreshAllMailboxInteractor
}
);
final personalMailboxTree = MailboxTree(MailboxNode.root()).obs;
final defaultMailboxTree = MailboxTree(MailboxNode.root()).obs;
final teamMailboxesTree = MailboxTree(MailboxNode.root()).obs;
List<PresentationMailbox> allMailboxes = <PresentationMailbox>[];
Future<void> buildTree(
List<PresentationMailbox> allMailbox,
{MailboxId? mailboxIdSelected}
) async {
final recordTree = await _treeBuilder.generateMailboxTreeInUI(
allMailboxes: allMailbox,
currentDefaultTree: defaultMailboxTree.value,
currentPersonalTree: personalMailboxTree.value,
currentTeamMailboxTree: teamMailboxesTree.value,
mailboxIdSelected: mailboxIdSelected,
);
defaultMailboxTree.firstRebuild = true;
personalMailboxTree.firstRebuild = true;
teamMailboxesTree.firstRebuild = true;
defaultMailboxTree.value = recordTree.defaultTree;
personalMailboxTree.value = recordTree.personalTree;
teamMailboxesTree.value = recordTree.teamMailboxTree;
allMailboxes = recordTree.allMailboxes;
}
Future<void> refreshTree(List<PresentationMailbox> allMailbox) async {
final recordTree = await _treeBuilder.generateMailboxTreeInUIAfterRefreshChanges(
allMailboxes: allMailbox,
currentDefaultTree: defaultMailboxTree.value,
currentPersonalTree: personalMailboxTree.value,
currentTeamMailboxTree: teamMailboxesTree.value,
);
defaultMailboxTree.firstRebuild = true;
personalMailboxTree.firstRebuild = true;
teamMailboxesTree.firstRebuild = true;
defaultMailboxTree.value = recordTree.defaultTree;
personalMailboxTree.value = recordTree.personalTree;
teamMailboxesTree.value = recordTree.teamMailboxTree;
allMailboxes = allMailbox;
}
void syncAllMailboxWithDisplayName(BuildContext context) {
final syncedMailbox = allMailboxes
.map((mailbox) => mailbox.withDisplayName(mailbox.getDisplayName(context)))
.toList();
allMailboxes = syncedMailbox;
}
void toggleMailboxFolder(
MailboxNode selectedMailboxNode,
ScrollController scrollController,
GlobalKey itemKey,
) {
final newExpandMode = selectedMailboxNode.expandMode.toggle();
if (defaultMailboxTree.value.updateExpandedNode(selectedMailboxNode, newExpandMode) != null) {
log('toggleMailboxFolder() refresh defaultMailboxTree');
defaultMailboxTree.refresh();
triggerScrollWhenExpandFolder(
selectedMailboxNode.expandMode,
itemKey,
scrollController,
);
}
if (personalMailboxTree.value.updateExpandedNode(selectedMailboxNode, newExpandMode) != null) {
log('toggleMailboxFolder() refresh folderMailboxTree');
personalMailboxTree.refresh();
triggerScrollWhenExpandFolder(
selectedMailboxNode.expandMode,
itemKey,
scrollController,
);
}
if (teamMailboxesTree.value.updateExpandedNode(selectedMailboxNode, newExpandMode) != null) {
log('toggleMailboxFolder() refresh teamMailboxesTree');
teamMailboxesTree.refresh();
triggerScrollWhenExpandFolder(
selectedMailboxNode.expandMode,
itemKey,
scrollController,
);
}
}
void triggerScrollWhenExpandFolder(
ExpandMode expandMode,
GlobalKey itemKey,
ScrollController scrollController,
) {
if (expandMode == ExpandMode.COLLAPSE) return;
final context = itemKey.currentContext;
if (context == null) return;
WidgetsBinding.instance.addPostFrameCallback((_) {
_scrollToSelfIfNeeded(context, scrollController);
});
}
void _scrollToSelfIfNeeded(
BuildContext context,
ScrollController scrollController,
) {
final renderBox = context.findRenderObject() as RenderBox?;
if (renderBox == null) return;
final position = renderBox.localToGlobal(Offset.zero);
final screenHeight = MediaQuery.of(context).size.height;
const offsetY = 200;
final bottomY = position.dy + renderBox.size.height + offsetY;
log('BaseMailboxController::_scrollToSelfIfNeeded:position = $position |screenHeight = $screenHeight | bottomY = $bottomY');
if (bottomY > screenHeight) {
final scrollOffset = scrollController.offset + bottomY - screenHeight + 40;
log('BaseMailboxController::_scrollToSelfIfNeeded:scrollOffset = $scrollOffset:');
scrollController.animateTo(
scrollOffset,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
}
}
void selectMailboxNode(MailboxNode mailboxNodeSelected) {
final newSelectMode = mailboxNodeSelected.selectMode == SelectMode.INACTIVE
? SelectMode.ACTIVE
: SelectMode.INACTIVE;
if (defaultMailboxTree.value.updateSelectedNode(mailboxNodeSelected, newSelectMode) != null) {
log('selectMailboxNode() refresh defaultMailboxTree');
defaultMailboxTree.refresh();
}
if (personalMailboxTree.value.updateSelectedNode(mailboxNodeSelected, newSelectMode) != null) {
log('selectMailboxNode() refresh folderMailboxTree');
personalMailboxTree.refresh();
}
if (teamMailboxesTree.value.updateSelectedNode(mailboxNodeSelected, newSelectMode) != null) {
log('selectMailboxNode() refresh folderMailboxTree');
teamMailboxesTree.refresh();
}
}
void unAllSelectedMailboxNode() {
defaultMailboxTree.value.updateNodesUIMode(selectMode: SelectMode.INACTIVE);
personalMailboxTree.value.updateNodesUIMode(selectMode: SelectMode.INACTIVE);
teamMailboxesTree.value.updateNodesUIMode(selectMode: SelectMode.INACTIVE);
defaultMailboxTree.refresh();
personalMailboxTree.refresh();
teamMailboxesTree.refresh();
}
MailboxNode? findMailboxNodeById(MailboxId mailboxId) {
final mailboxNode = defaultMailboxTree.value.findNode((node) => node.item.id == mailboxId);
if (mailboxNode != null) {
return mailboxNode;
}
final mailboxPersonal = personalMailboxTree.value.findNode((node) => node.item.id == mailboxId);
if (mailboxPersonal != null) {
return mailboxPersonal;
}
return teamMailboxesTree.value.findNode((node) => node.item.id == mailboxId);
}
String? findNodePathWithSeparator(MailboxId mailboxId, String pathSeparator) {
var mailboxNodePath = defaultMailboxTree.value.getNodePath(mailboxId, pathSeparator)
?? personalMailboxTree.value.getNodePath(mailboxId, pathSeparator)
?? teamMailboxesTree.value.getNodePath(mailboxId, pathSeparator);
log('BaseMailboxController::findNodePath():mailboxNodePath: $mailboxNodePath');
return mailboxNodePath;
}
String? findNodePath(MailboxId mailboxId) {
return findNodePathWithSeparator(mailboxId, '/');
}
MailboxNode? findMailboxNodeByRole(Role role) {
final mailboxNode = defaultMailboxTree.value.findNode((node) => node.item.role == role);
return mailboxNode;
}
List<PresentationMailbox> findMailboxPath(List<PresentationMailbox> mailboxes) {
return mailboxes.map((presentationMailbox) {
if (!presentationMailbox.hasParentId()) {
return presentationMailbox;
} else {
final mailboxNodePath = findNodePath(presentationMailbox.id);
if (mailboxNodePath != null) {
return presentationMailbox.toPresentationMailboxWithMailboxPath(mailboxNodePath);
} else {
return presentationMailbox;
}
}
}).toList();
}
bool get defaultMailboxIsNotEmpty =>
defaultMailboxTree.value.root.childrenItems?.isNotEmpty ?? false;
bool get personalMailboxIsNotEmpty =>
personalMailboxTree.value.root.childrenItems?.isNotEmpty ?? false;
bool get teamMailboxesIsNotEmpty {
return (teamMailboxesTree.value.root.childrenItems?.isNotEmpty ?? false)
&& !teamMailboxesTree.value.root.item.isTeamMailboxes;
}
MailboxNode get defaultRootNode => defaultMailboxTree.value.root;
MailboxNode get personalRootNode => personalMailboxTree.value.root;
MailboxNode get teamMailboxesRootNode => teamMailboxesTree.value.root;
List<String> getListMailboxNameInParentMailbox(PresentationMailbox parentMailbox) {
if (parentMailbox.parentId == null) {
final allChildrenAtMailboxLocation = (defaultMailboxTree.value.root.childrenItems ?? <MailboxNode>[])
+ (personalMailboxTree.value.root.childrenItems ?? <MailboxNode>[])
+ (teamMailboxesTree.value.root.childrenItems ?? <MailboxNode>[]);
if (allChildrenAtMailboxLocation.isNotEmpty) {
final listMailboxNameAsStringExist = allChildrenAtMailboxLocation
.where((mailboxNode) => mailboxNode.nameNotEmpty)
.map((mailboxNode) => mailboxNode.mailboxNameAsString)
.toList();
return listMailboxNameAsStringExist;
} else {
return [];
}
} else {
final mailboxNodeLocation = findMailboxNodeById(parentMailbox.parentId!);
if (mailboxNodeLocation != null && mailboxNodeLocation.childrenItems?.isNotEmpty == true) {
final allChildrenAtMailboxLocation = mailboxNodeLocation.childrenItems!;
final listMailboxNameAsStringExist = allChildrenAtMailboxLocation
.where((mailboxNode) => mailboxNode.nameNotEmpty)
.map((mailboxNode) => mailboxNode.mailboxNameAsString)
.toList();
return listMailboxNameAsStringExist;
} else {
return [];
}
}
}
String? verifyMailboxNameAction(
BuildContext context,
String newName,
List<String> listMailboxName,
MailboxActions mailboxActions
) {
return verifyNameInteractor.execute(newName, [
EmptyNameValidator(),
NameWithSpaceOnlyValidator(),
DuplicateNameValidator(listMailboxName),
SpecialCharacterValidator()
]).fold((failure) {
if (failure is VerifyNameFailure) {
return failure.getMessage(context, actions: mailboxActions);
} else {
return null;
}
}, (success) => null);
}
void openDialogRenameMailboxAction(
BuildContext context,
PresentationMailbox presentationMailbox,
ResponsiveUtils responsiveUtils, {
required RenameMailboxActionCallback onRenameMailboxAction
}) {
final listMailboxName = getListMailboxNameInParentMailbox(presentationMailbox);
if (responsiveUtils.isMobile(context)) {
(EditTextModalSheetBuilder()
..key(const Key('rename_mailbox_dialog'))
..title(AppLocalizations.of(context).renameFolder)
..cancelText(AppLocalizations.of(context).cancel)
..boxConstraints(responsiveUtils.isLandscapeMobile(context)
? const BoxConstraints(maxWidth: 400)
: null)
..onConfirmAction(
AppLocalizations.of(context).rename,
(value) => onRenameMailboxAction(presentationMailbox, MailboxName(value))
)
..setErrorString((value) {
return verifyMailboxNameAction(
context,
value,
listMailboxName,
MailboxActions.rename
);
})
..setTextController(TextEditingController.fromValue(
TextEditingValue(
text: presentationMailbox.name?.name ?? '',
selection: TextSelection(
baseOffset: 0,
extentOffset: presentationMailbox.name?.name.length ?? 0
)
)))
).show(context);
} else {
showInputDialogAction(
key: const Key('rename_mailbox_dialog'),
context: context,
title: AppLocalizations.of(context).renameFolder,
value: presentationMailbox.name?.name ?? '',
negativeText: AppLocalizations.of(context).cancel,
positiveText: AppLocalizations.of(context).rename,
closeIcon: imagePaths.icComposerClose,
onPositiveButtonAction: (value) {
onRenameMailboxAction(presentationMailbox, MailboxName(value));
popBack();
},
onNegativeButtonAction: popBack,
onInputErrorChanged: (value) {
return verifyMailboxNameAction(
context,
value,
listMailboxName,
MailboxActions.rename,
);
},
);
}
}
void moveMailboxAction(
BuildContext context,
PresentationMailbox mailboxSelected,
MailboxDashBoardController dashBoardController, {
required MovingMailboxActionCallback onMovingMailboxAction
}) async {
final accountId = dashBoardController.accountId.value;
final session = dashBoardController.sessionCurrent;
if (accountId != null && session != null) {
final arguments = DestinationPickerArguments(
accountId,
MailboxActions.move,
session,
mailboxIdSelected: mailboxSelected.id
);
final destinationMailbox = PlatformInfo.isWeb
? await DialogRouter.pushGeneralDialog(routeName: AppRoutes.destinationPicker, arguments: arguments)
: await push(AppRoutes.destinationPicker, arguments: arguments);
if (destinationMailbox is PresentationMailbox) {
onMovingMailboxAction(
mailboxSelected,
destinationMailbox == PresentationMailbox.unifiedMailbox
? null
: destinationMailbox
);
}
}
}
void openConfirmationDialogDeleteMailboxAction(
BuildContext context,
ResponsiveUtils responsiveUtils,
ImagePaths imagePaths,
PresentationMailbox presentationMailbox, {
required DeleteMailboxActionCallback onDeleteMailboxAction
}) {
if (responsiveUtils.isLandscapeMobile(context) || responsiveUtils.isPortraitMobile(context)) {
(ConfirmationDialogActionSheetBuilder(context)
..messageText(AppLocalizations.of(context).message_confirmation_dialog_delete_folder(presentationMailbox.getDisplayName(context)))
..onCancelAction(AppLocalizations.of(context).cancel, () => popBack())
..onConfirmAction(AppLocalizations.of(context).delete, () => onDeleteMailboxAction(presentationMailbox))
).show();
} else {
Get.dialog(
PointerInterceptor(
child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_delete_mailbox'),
imagePath: imagePaths,
title: AppLocalizations.of(context).deleteFolders,
textContent: AppLocalizations.of(context).message_confirmation_dialog_delete_folder(presentationMailbox.getDisplayName(context)),
confirmText: AppLocalizations.of(context).delete,
cancelText: AppLocalizations.of(context).cancel,
onConfirmButtonAction: () => onDeleteMailboxAction(presentationMailbox),
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
),
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
);
}
}
List<MailboxNode> getAncestorOfMailboxNode(MailboxNode mailboxNode) {
final listAncestor = defaultMailboxTree.value.getAncestorList(mailboxNode)
?? personalMailboxTree.value.getAncestorList(mailboxNode)
?? teamMailboxesTree.value.getAncestorList(mailboxNode);
return listAncestor ?? [];
}
SubscribeRequest? generateSubscribeRequest(
MailboxId mailboxId,
MailboxSubscribeState subscribeState,
MailboxSubscribeAction subscribeAction
) {
switch(subscribeState) {
case MailboxSubscribeState.enabled:
return _generateSubscribeRequestWhenSubscribeEnabled(mailboxId, subscribeAction);
case MailboxSubscribeState.disabled:
return _generateSubscribeRequestWhenSubscribeDisabled(mailboxId, subscribeAction);
}
}
SubscribeRequest? _generateSubscribeRequestWhenSubscribeDisabled(
MailboxId mailboxId,
MailboxSubscribeAction subscribeAction
) {
final mailboxNode = findMailboxNodeById(mailboxId);
if (mailboxNode == null) return null;
if (mailboxNode.hasChildren()) {
final listDescendantMailboxIds = mailboxNode.descendantsAsList().mailboxIds;
log("BaseMailboxController::_generateSubscribeRequestWhenSubscribeDisabled:listDescendantMailboxIds $listDescendantMailboxIds");
return SubscribeMultipleMailboxRequest(
mailboxId,
listDescendantMailboxIds,
MailboxSubscribeState.disabled,
subscribeAction
);
} else {
return SubscribeMailboxRequest(
mailboxId,
MailboxSubscribeState.disabled,
subscribeAction
);
}
}
SubscribeRequest? _generateSubscribeRequestWhenSubscribeEnabled(
MailboxId mailboxId,
MailboxSubscribeAction subscribeAction
) {
final mailboxNode = findMailboxNodeById(mailboxId);
if (mailboxNode == null) return null;
if (mailboxNode.hasParents()) {
final listAncestorMailboxIds = getAncestorOfMailboxNode(mailboxNode).mailboxIds;
listAncestorMailboxIds.add(mailboxId);
log("BaseMailboxController::_generateSubscribeRequestWhenSubscribeEnabled:listAncestorMailboxIds $listAncestorMailboxIds");
if (listAncestorMailboxIds.isNotEmpty) {
return SubscribeMultipleMailboxRequest(
mailboxId,
listAncestorMailboxIds,
MailboxSubscribeState.enabled,
subscribeAction
);
} else {
return SubscribeMailboxRequest(
mailboxId,
MailboxSubscribeState.enabled,
subscribeAction
);
}
} else {
return SubscribeMailboxRequest(
mailboxId,
MailboxSubscribeState.enabled,
subscribeAction
);
}
}
void getAllMailbox(Session session, AccountId accountId) async {
if (getAllMailboxInteractor != null) {
consumeState(getAllMailboxInteractor!.execute(session, accountId));
}
}
void refreshMailboxChanges(
Session session,
AccountId accountId,
jmap.State currentMailboxState,
{Properties? properties}
) {
if (refreshAllMailboxInteractor != null) {
log('BaseMailboxController::refreshMailboxChanges(): currentMailboxState: $currentMailboxState');
consumeState(refreshAllMailboxInteractor!.execute(
session,
accountId,
currentMailboxState,
properties: properties
));
}
}
MailboxNode? findNodeByNameOnFirstLevel(String name) {
MailboxNode? mailboxNode = defaultMailboxTree.value.findNodeOnFirstLevel((node) => node.item.name?.name.toLowerCase() == name);
if (mailboxNode != null) {
return mailboxNode;
}
mailboxNode = personalMailboxTree.value.findNodeOnFirstLevel((node) => node.item.name?.name.toLowerCase() == name);
return mailboxNode;
}
void updateMailboxNameById(MailboxId mailboxId, MailboxName mailboxName) {
UpdateMailboxNameAction(
mailboxTrees: [defaultMailboxTree, personalMailboxTree, teamMailboxesTree],
mailboxId: mailboxId,
mailboxName: mailboxName,
).execute();
}
void updateUnreadCountOfMailboxById(
MailboxId mailboxId, {
required int unreadChanges,
}) {
UpdateMailboxUnreadCountAction(
mailboxTrees: [defaultMailboxTree, personalMailboxTree, teamMailboxesTree],
mailboxId: mailboxId,
unreadChanges: unreadChanges,
).execute();
}
void clearUnreadCount(MailboxId mailboxId) {
final mailboxTrees = [
defaultMailboxTree,
personalMailboxTree,
teamMailboxesTree,
];
for (var mailboxTree in mailboxTrees) {
final selectedNode = mailboxTree.value.findNode((node) => node.item.id == mailboxId);
if (selectedNode == null) continue;
final currentUnreadCount = selectedNode.item.unreadEmails?.value.value.toInt();
mailboxTree.value.updateMailboxUnreadCountById(
mailboxId,
-(currentUnreadCount ?? 0));
mailboxTree.refresh();
break;
}
}
void updateMailboxTotalEmailsCountById(MailboxId mailboxId, int totalEmails) {
UpdateMailboxTotalEmailsCountAction(
mailboxTrees: [defaultMailboxTree, personalMailboxTree, teamMailboxesTree],
mailboxId: mailboxId,
totalEmailsCountChanged: totalEmails,
).execute();
}
void toggleMailboxCategories(
MailboxCategories category,
ScrollController scrollController,
GlobalKey itemKey,
) {
switch (category) {
case MailboxCategories.exchange:
_toggleAndScroll(
currentExpandMode: mailboxCategoriesExpandMode.value.defaultMailbox,
updateExpandMode: (mode) => mailboxCategoriesExpandMode.value.defaultMailbox = mode,
hasChildren: defaultMailboxTree.value.root.hasChildren(),
itemKey: itemKey,
scrollController: scrollController,
);
break;
case MailboxCategories.personalFolders:
_toggleAndScroll(
currentExpandMode: mailboxCategoriesExpandMode.value.personalFolders,
updateExpandMode: (mode) => mailboxCategoriesExpandMode.value.personalFolders = mode,
hasChildren: personalMailboxTree.value.root.hasChildren(),
itemKey: itemKey,
scrollController: scrollController,
);
break;
case MailboxCategories.teamMailboxes:
_toggleAndScroll(
currentExpandMode: mailboxCategoriesExpandMode.value.teamMailboxes,
updateExpandMode: (mode) => mailboxCategoriesExpandMode.value.teamMailboxes = mode,
hasChildren: teamMailboxesTree.value.root.hasChildren(),
itemKey: itemKey,
scrollController: scrollController,
);
break;
}
}
void _toggleAndScroll({
required ExpandMode currentExpandMode,
required void Function(ExpandMode) updateExpandMode,
required bool hasChildren,
required GlobalKey itemKey,
required ScrollController scrollController,
}) {
final newExpandMode = currentExpandMode.toggle();
updateExpandMode(newExpandMode);
mailboxCategoriesExpandMode.refresh();
if (hasChildren) {
triggerScrollWhenExpandFolder(newExpandMode, itemKey, scrollController);
}
}
}