TF-4284 Fix refreshing causes "virtual mailboxes" to be hidden (#4290)
This commit is contained in:
@@ -37,6 +37,7 @@ import 'package:tmail_ui_user/features/mailbox/presentation/extensions/presentat
|
||||
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_collection.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';
|
||||
@@ -62,6 +63,7 @@ typedef OnMoveFolderContentActionCallback = void Function(
|
||||
);
|
||||
typedef DeleteMailboxActionCallback = void Function(PresentationMailbox mailbox);
|
||||
typedef AllowSubaddressingActionCallback = void Function(MailboxId, Map<String, List<String>?>?, MailboxActions);
|
||||
typedef OnUpdateMailboxCollectionCallback = MailboxCollection Function(MailboxCollection);
|
||||
|
||||
abstract class BaseMailboxController extends BaseController
|
||||
with ExpandFolderTriggerScrollableMixin {
|
||||
@@ -87,40 +89,62 @@ abstract class BaseMailboxController extends BaseController
|
||||
|
||||
List<PresentationMailbox> allMailboxes = <PresentationMailbox>[];
|
||||
|
||||
MailboxCollection get currentMailboxCollection => MailboxCollection(
|
||||
allMailboxes: allMailboxes,
|
||||
defaultTree: defaultMailboxTree.value,
|
||||
personalTree: personalMailboxTree.value,
|
||||
teamMailboxTree: teamMailboxesTree.value,
|
||||
);
|
||||
|
||||
Future<void> buildTree(
|
||||
List<PresentationMailbox> allMailbox,
|
||||
{MailboxId? mailboxIdSelected}
|
||||
) async {
|
||||
final recordTree = await _treeBuilder.generateMailboxTreeInUI(
|
||||
List<PresentationMailbox> allMailbox, {
|
||||
MailboxId? mailboxIdSelected,
|
||||
OnUpdateMailboxCollectionCallback? onUpdateMailboxCollectionCallback,
|
||||
}) async {
|
||||
MailboxCollection mailboxCollection =
|
||||
await _treeBuilder.generateMailboxTreeInUI(
|
||||
allMailboxes: allMailbox,
|
||||
currentDefaultTree: defaultMailboxTree.value,
|
||||
currentPersonalTree: personalMailboxTree.value,
|
||||
currentTeamMailboxTree: teamMailboxesTree.value,
|
||||
currentCollection: currentMailboxCollection,
|
||||
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;
|
||||
|
||||
if (onUpdateMailboxCollectionCallback != null) {
|
||||
mailboxCollection = onUpdateMailboxCollectionCallback(mailboxCollection);
|
||||
}
|
||||
|
||||
Future<void> refreshTree(List<PresentationMailbox> allMailbox) async {
|
||||
final recordTree = await _treeBuilder.generateMailboxTreeInUIAfterRefreshChanges(
|
||||
updateMailboxTree(mailboxCollection: mailboxCollection);
|
||||
}
|
||||
|
||||
Future<void> refreshTree(
|
||||
List<PresentationMailbox> allMailbox, {
|
||||
OnUpdateMailboxCollectionCallback? onUpdateMailboxCollectionCallback,
|
||||
}) async {
|
||||
MailboxCollection mailboxCollection =
|
||||
await _treeBuilder.generateMailboxTreeInUIAfterRefreshChanges(
|
||||
allMailboxes: allMailbox,
|
||||
currentDefaultTree: defaultMailboxTree.value,
|
||||
currentPersonalTree: personalMailboxTree.value,
|
||||
currentTeamMailboxTree: teamMailboxesTree.value,
|
||||
currentCollection: currentMailboxCollection,
|
||||
);
|
||||
|
||||
if (onUpdateMailboxCollectionCallback != null) {
|
||||
mailboxCollection = onUpdateMailboxCollectionCallback(mailboxCollection);
|
||||
}
|
||||
|
||||
updateMailboxTree(mailboxCollection: mailboxCollection);
|
||||
}
|
||||
|
||||
void updateMailboxTree({
|
||||
required MailboxCollection mailboxCollection,
|
||||
bool isRefreshTrigger = true,
|
||||
}) {
|
||||
if (isRefreshTrigger) {
|
||||
defaultMailboxTree.firstRebuild = true;
|
||||
personalMailboxTree.firstRebuild = true;
|
||||
teamMailboxesTree.firstRebuild = true;
|
||||
defaultMailboxTree.value = recordTree.defaultTree;
|
||||
personalMailboxTree.value = recordTree.personalTree;
|
||||
teamMailboxesTree.value = recordTree.teamMailboxTree;
|
||||
allMailboxes = allMailbox;
|
||||
}
|
||||
defaultMailboxTree.value = mailboxCollection.defaultTree;
|
||||
personalMailboxTree.value = mailboxCollection.personalTree;
|
||||
teamMailboxesTree.value = mailboxCollection.teamMailboxTree;
|
||||
allMailboxes = mailboxCollection.allMailboxes;
|
||||
}
|
||||
|
||||
void syncAllMailboxWithDisplayName(BuildContext context) {
|
||||
@@ -675,10 +699,15 @@ abstract class BaseMailboxController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
void autoCreateVirtualFolder(bool isAINeedsActionEnabled) {
|
||||
addFavoriteFolderToMailboxList();
|
||||
bool get isAINeedsActionEnabled => false;
|
||||
|
||||
MailboxCollection updateMailboxCollection(MailboxCollection mailboxCollection) {
|
||||
MailboxCollection updated = addFavoriteFolderToMailboxList(
|
||||
mailboxCollection: mailboxCollection,
|
||||
);
|
||||
if (isAINeedsActionEnabled) {
|
||||
addActionRequiredFolder();
|
||||
updated = addActionRequiredFolder(mailboxCollection: updated);
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
}
|
||||
+70
-30
@@ -3,15 +3,26 @@ 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/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_collection.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/main/routes/route_navigation.dart';
|
||||
|
||||
extension HandleActionRequiredTabExtension on BaseMailboxController {
|
||||
void addActionRequiredFolder() {
|
||||
MailboxCollection addActionRequiredFolder({
|
||||
required MailboxCollection mailboxCollection,
|
||||
}) {
|
||||
final folder = _buildActionRequiredFolder();
|
||||
_addToDefaultMailboxTree(folder);
|
||||
_addToAllMailboxes(folder);
|
||||
return mailboxCollection.copyWith(
|
||||
defaultTree: _addToDefaultMailboxTree(
|
||||
folder: folder,
|
||||
currentDefaultTree: mailboxCollection.defaultTree,
|
||||
),
|
||||
allMailboxes: _addToAllMailboxes(
|
||||
folder: folder,
|
||||
currentAllMailboxes: mailboxCollection.allMailboxes,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
PresentationMailbox _buildActionRequiredFolder() {
|
||||
@@ -23,43 +34,72 @@ extension HandleActionRequiredTabExtension on BaseMailboxController {
|
||||
);
|
||||
}
|
||||
|
||||
void _addToDefaultMailboxTree(PresentationMailbox folder) {
|
||||
final root = defaultMailboxTree.value.root;
|
||||
MailboxTree _addToDefaultMailboxTree({
|
||||
required PresentationMailbox folder,
|
||||
required MailboxTree currentDefaultTree,
|
||||
}) {
|
||||
final root = currentDefaultTree.root;
|
||||
final children = List<MailboxNode>.from(root.childrenItems ?? []);
|
||||
if (children.any((node) => node.item.id == folder.id)) {
|
||||
return currentDefaultTree;
|
||||
}
|
||||
|
||||
children.insertAfterStarredOrInbox(MailboxNode(folder));
|
||||
|
||||
defaultMailboxTree.value = MailboxTree(
|
||||
root.copyWith(children: children),
|
||||
return MailboxTree(root.copyWith(children: children));
|
||||
}
|
||||
|
||||
List<PresentationMailbox> _addToAllMailboxes({
|
||||
required PresentationMailbox folder,
|
||||
required List<PresentationMailbox> currentAllMailboxes,
|
||||
}) {
|
||||
if (_allMailboxesContains(
|
||||
id: folder.id,
|
||||
currentAllMailboxes: currentAllMailboxes,
|
||||
)) {
|
||||
return currentAllMailboxes;
|
||||
}
|
||||
return [...currentAllMailboxes, folder];
|
||||
}
|
||||
|
||||
bool _allMailboxesContains({
|
||||
required MailboxId id,
|
||||
required List<PresentationMailbox> currentAllMailboxes,
|
||||
}) {
|
||||
return currentAllMailboxes.any((mailbox) => mailbox.id == id);
|
||||
}
|
||||
|
||||
MailboxCollection removeActionRequiredFolder({
|
||||
required MailboxCollection mailboxCollection,
|
||||
}) {
|
||||
return mailboxCollection.copyWith(
|
||||
defaultTree: _removeFromDefaultMailboxTree(
|
||||
folderId: PresentationMailbox.actionRequiredFolder.id,
|
||||
currentDefaultTree: mailboxCollection.defaultTree,
|
||||
),
|
||||
allMailboxes: _removeFromAllMailboxes(
|
||||
folderId: PresentationMailbox.actionRequiredFolder.id,
|
||||
currentAllMailboxes: mailboxCollection.allMailboxes,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _addToAllMailboxes(PresentationMailbox folder) {
|
||||
if (_allMailboxesContains(folder.id)) return;
|
||||
allMailboxes.add(folder);
|
||||
}
|
||||
|
||||
bool _allMailboxesContains(MailboxId id) {
|
||||
return allMailboxes.any((mailbox) => mailbox.id == id);
|
||||
}
|
||||
|
||||
void removeActionRequiredFolder() {
|
||||
final folder = PresentationMailbox.actionRequiredFolder;
|
||||
_removeFromDefaultMailboxTree(folder.id);
|
||||
_removeFromAllMailboxes(folder.id);
|
||||
}
|
||||
|
||||
void _removeFromDefaultMailboxTree(MailboxId folderId) {
|
||||
final root = defaultMailboxTree.value.root;
|
||||
MailboxTree _removeFromDefaultMailboxTree({
|
||||
required MailboxId folderId,
|
||||
required MailboxTree currentDefaultTree,
|
||||
}) {
|
||||
final root = currentDefaultTree.root;
|
||||
final children = List<MailboxNode>.from(root.childrenItems ?? [])
|
||||
..removeWhere((node) => node.item.id == folderId);
|
||||
|
||||
defaultMailboxTree.value = MailboxTree(
|
||||
root.copyWith(children: children),
|
||||
);
|
||||
return MailboxTree(root.copyWith(children: children));
|
||||
}
|
||||
|
||||
void _removeFromAllMailboxes(MailboxId folderId) {
|
||||
allMailboxes.removeWhere((mailbox) => mailbox.id == folderId);
|
||||
List<PresentationMailbox> _removeFromAllMailboxes({
|
||||
required MailboxId folderId,
|
||||
required List<PresentationMailbox> currentAllMailboxes,
|
||||
}) {
|
||||
return currentAllMailboxes
|
||||
.where((mailbox) => mailbox.id != folderId)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,15 @@ 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/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_collection.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/main/routes/route_navigation.dart';
|
||||
|
||||
extension HandleFavoriteTabExtension on BaseMailboxController {
|
||||
void addFavoriteFolderToMailboxList() {
|
||||
MailboxCollection addFavoriteFolderToMailboxList({
|
||||
required MailboxCollection mailboxCollection,
|
||||
}) {
|
||||
PresentationMailbox favoriteFolder = PresentationMailbox.favoriteFolder;
|
||||
if (currentContext != null) {
|
||||
favoriteFolder = favoriteFolder.copyWith(
|
||||
@@ -15,16 +18,28 @@ extension HandleFavoriteTabExtension on BaseMailboxController {
|
||||
);
|
||||
}
|
||||
|
||||
_addFavoriteFolderToDefaultMailboxTree(favoriteFolder);
|
||||
_addFavoriteFolderToAllMailboxes(favoriteFolder);
|
||||
final newDefaultTree = _addFavoriteFolderToDefaultMailboxTree(
|
||||
favoriteFolder: favoriteFolder,
|
||||
defaultTree: mailboxCollection.defaultTree,
|
||||
);
|
||||
final newAllMailboxes = _addFavoriteFolderToAllMailboxes(
|
||||
favoriteFolder: favoriteFolder,
|
||||
allMailboxes: mailboxCollection.allMailboxes,
|
||||
);
|
||||
|
||||
return mailboxCollection.copyWith(
|
||||
defaultTree: newDefaultTree,
|
||||
allMailboxes: newAllMailboxes,
|
||||
);
|
||||
}
|
||||
|
||||
void _addFavoriteFolderToDefaultMailboxTree(
|
||||
PresentationMailbox favoriteFolder,
|
||||
) {
|
||||
final defaultMailboxNode = defaultMailboxTree.value.root;
|
||||
List<MailboxNode> currentDefaultFolders =
|
||||
defaultMailboxNode.childrenItems ?? [];
|
||||
MailboxTree _addFavoriteFolderToDefaultMailboxTree({
|
||||
required PresentationMailbox favoriteFolder,
|
||||
required MailboxTree defaultTree,
|
||||
}) {
|
||||
final defaultMailboxNode = defaultTree.root;
|
||||
final currentDefaultFolders =
|
||||
List<MailboxNode>.from(defaultMailboxNode.childrenItems ?? []);
|
||||
|
||||
if (currentDefaultFolders.isEmpty) {
|
||||
currentDefaultFolders.add(MailboxNode(favoriteFolder));
|
||||
@@ -32,17 +47,20 @@ extension HandleFavoriteTabExtension on BaseMailboxController {
|
||||
currentDefaultFolders.insertAfterInbox(MailboxNode(favoriteFolder));
|
||||
}
|
||||
|
||||
defaultMailboxTree.value = MailboxTree(
|
||||
return MailboxTree(
|
||||
defaultMailboxNode.copyWith(children: currentDefaultFolders),
|
||||
);
|
||||
}
|
||||
|
||||
void _addFavoriteFolderToAllMailboxes(PresentationMailbox favoriteFolder) {
|
||||
List<PresentationMailbox> _addFavoriteFolderToAllMailboxes({
|
||||
required PresentationMailbox favoriteFolder,
|
||||
required List<PresentationMailbox> allMailboxes,
|
||||
}) {
|
||||
final alreadyExists = allMailboxes.any(
|
||||
(mailbox) => mailbox.id == favoriteFolder.id,
|
||||
);
|
||||
if (alreadyExists) return;
|
||||
if (alreadyExists) return allMailboxes;
|
||||
|
||||
allMailboxes.add(favoriteFolder);
|
||||
return [...allMailboxes, favoriteFolder];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,8 +257,9 @@ class MailboxController extends BaseMailboxController
|
||||
toastManager: toastManager,
|
||||
);
|
||||
} else if (failure is CreateDefaultMailboxFailure) {
|
||||
autoCreateVirtualFolder(
|
||||
mailboxDashBoardController.isAINeedsActionEnabled,
|
||||
updateMailboxTree(
|
||||
mailboxCollection: updateMailboxCollection(currentMailboxCollection),
|
||||
isRefreshTrigger: false,
|
||||
);
|
||||
} else {
|
||||
super.handleFailureViewState(failure);
|
||||
@@ -271,8 +272,9 @@ class MailboxController extends BaseMailboxController
|
||||
viewState.value.fold(
|
||||
(failure) {
|
||||
if (failure is GetAllMailboxFailure) {
|
||||
autoCreateVirtualFolder(
|
||||
mailboxDashBoardController.isAINeedsActionEnabled,
|
||||
updateMailboxTree(
|
||||
mailboxCollection: updateMailboxCollection(currentMailboxCollection),
|
||||
isRefreshTrigger: false,
|
||||
);
|
||||
mailboxDashBoardController.updateRefreshAllMailboxState(Left(RefreshAllMailboxFailure()));
|
||||
showRetryToast(failure);
|
||||
@@ -303,38 +305,7 @@ class MailboxController extends BaseMailboxController
|
||||
_handleNavigationRouteParameters
|
||||
);
|
||||
|
||||
ever(mailboxDashBoardController.mailboxUIAction, (action) {
|
||||
if (action is SelectMailboxDefaultAction) {
|
||||
_switchBackToMailboxDefault();
|
||||
mailboxDashBoardController.clearMailboxUIAction();
|
||||
} else if (action is RefreshChangeMailboxAction) {
|
||||
_refreshMailboxChanges(newState: action.newState);
|
||||
} else if (action is OpenMailboxAction) {
|
||||
if (currentContext != null) {
|
||||
_handleOpenMailbox(currentContext!, action.presentationMailbox);
|
||||
if (action.presentationMailbox.role == PresentationMailbox.roleInbox) {
|
||||
_autoScrollToTopMailboxList();
|
||||
}
|
||||
}
|
||||
mailboxDashBoardController.clearMailboxUIAction();
|
||||
} else if (action is SystemBackToInboxAction) {
|
||||
_disableAllSearchEmail();
|
||||
_switchBackToMailboxDefault();
|
||||
mailboxDashBoardController.clearMailboxUIAction();
|
||||
} else if (action is RefreshAllMailboxAction) {
|
||||
refreshAllMailbox();
|
||||
mailboxDashBoardController.clearMailboxUIAction();
|
||||
} else if (action is AutoCreateActionRequiredFolderMailboxAction) {
|
||||
addActionRequiredFolder();
|
||||
mailboxDashBoardController.clearMailboxUIAction();
|
||||
} else if (action is AutoRemoveActionRequiredFolderMailboxAction) {
|
||||
removeActionRequiredFolder();
|
||||
mailboxDashBoardController.clearMailboxUIAction();
|
||||
if (selectedMailbox?.isActionRequired == true) {
|
||||
_switchBackToMailboxDefault();
|
||||
}
|
||||
}
|
||||
});
|
||||
ever(mailboxDashBoardController.mailboxUIAction, _handleMailboxUIAction);
|
||||
|
||||
ever(mailboxDashBoardController.viewState, (viewState) {
|
||||
final reactionState = viewState.getOrElse(() => UIState.idle);
|
||||
@@ -452,6 +423,57 @@ class MailboxController extends BaseMailboxController
|
||||
});
|
||||
}
|
||||
|
||||
void _handleMailboxUIAction(MailboxUIAction? action) {
|
||||
if (action is SelectMailboxDefaultAction) {
|
||||
_switchBackToMailboxDefault();
|
||||
mailboxDashBoardController.clearMailboxUIAction();
|
||||
} else if (action is RefreshChangeMailboxAction) {
|
||||
_refreshMailboxChanges(newState: action.newState);
|
||||
} else if (action is OpenMailboxAction) {
|
||||
_onOpenMailboxAction(action);
|
||||
} else if (action is SystemBackToInboxAction) {
|
||||
_disableAllSearchEmail();
|
||||
_switchBackToMailboxDefault();
|
||||
mailboxDashBoardController.clearMailboxUIAction();
|
||||
} else if (action is RefreshAllMailboxAction) {
|
||||
refreshAllMailbox();
|
||||
mailboxDashBoardController.clearMailboxUIAction();
|
||||
} else if (action is AutoCreateActionRequiredFolderMailboxAction) {
|
||||
updateMailboxTree(
|
||||
mailboxCollection: addActionRequiredFolder(
|
||||
mailboxCollection: currentMailboxCollection,
|
||||
),
|
||||
isRefreshTrigger: false,
|
||||
);
|
||||
mailboxDashBoardController.clearMailboxUIAction();
|
||||
} else if (action is AutoRemoveActionRequiredFolderMailboxAction) {
|
||||
_onAutoRemoveActionRequiredFolderMailboxAction();
|
||||
}
|
||||
}
|
||||
|
||||
void _onOpenMailboxAction(OpenMailboxAction action) {
|
||||
if (currentContext != null) {
|
||||
_handleOpenMailbox(currentContext!, action.presentationMailbox);
|
||||
if (action.presentationMailbox.role == PresentationMailbox.roleInbox) {
|
||||
_autoScrollToTopMailboxList();
|
||||
}
|
||||
}
|
||||
mailboxDashBoardController.clearMailboxUIAction();
|
||||
}
|
||||
|
||||
void _onAutoRemoveActionRequiredFolderMailboxAction() {
|
||||
updateMailboxTree(
|
||||
mailboxCollection: removeActionRequiredFolder(
|
||||
mailboxCollection: currentMailboxCollection,
|
||||
),
|
||||
isRefreshTrigger: false,
|
||||
);
|
||||
mailboxDashBoardController.clearMailboxUIAction();
|
||||
if (selectedMailbox?.isActionRequired == true) {
|
||||
_switchBackToMailboxDefault();
|
||||
}
|
||||
}
|
||||
|
||||
void _handleMarkEmailsAsReadOrUnread({
|
||||
required MailboxId? affectedMailboxId,
|
||||
int? readCount,
|
||||
@@ -614,14 +636,14 @@ class MailboxController extends BaseMailboxController
|
||||
.mailboxList
|
||||
.listSubscribedMailboxesAndDefaultMailboxes;
|
||||
|
||||
await refreshTree(listMailboxDisplayed.withoutVirtualMailbox);
|
||||
await refreshTree(
|
||||
listMailboxDisplayed.withoutVirtualMailbox,
|
||||
onUpdateMailboxCollectionCallback: updateMailboxCollection,
|
||||
);
|
||||
|
||||
if (currentContext != null) {
|
||||
syncAllMailboxWithDisplayName(currentContext!);
|
||||
}
|
||||
autoCreateVirtualFolder(
|
||||
mailboxDashBoardController.isAINeedsActionEnabled,
|
||||
);
|
||||
_setMapMailbox();
|
||||
_setOutboxMailbox();
|
||||
_selectSelectedMailboxDefault();
|
||||
@@ -632,6 +654,10 @@ class MailboxController extends BaseMailboxController
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool get isAINeedsActionEnabled =>
|
||||
mailboxDashBoardController.isAINeedsActionEnabled;
|
||||
|
||||
void _setMapMailbox() {
|
||||
final mapDefaultMailboxIdByRole = {
|
||||
for (var mailboxNode in defaultMailboxTree.value.root.childrenItems ?? List<MailboxNode>.empty())
|
||||
@@ -706,8 +732,9 @@ class MailboxController extends BaseMailboxController
|
||||
.toList();
|
||||
|
||||
if (listRoleMissing.isEmpty || accountId == null || session == null) {
|
||||
autoCreateVirtualFolder(
|
||||
mailboxDashBoardController.isAINeedsActionEnabled,
|
||||
updateMailboxTree(
|
||||
mailboxCollection: updateMailboxCollection(currentMailboxCollection),
|
||||
isRefreshTrigger: false,
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -726,8 +753,9 @@ class MailboxController extends BaseMailboxController
|
||||
|
||||
Future<void> _handleCreateDefaultFolderIfMissingSuccess(CreateDefaultMailboxAllSuccess success) async {
|
||||
if (success.listMailbox.isEmpty) {
|
||||
autoCreateVirtualFolder(
|
||||
mailboxDashBoardController.isAINeedsActionEnabled,
|
||||
updateMailboxTree(
|
||||
mailboxCollection: updateMailboxCollection(currentMailboxCollection),
|
||||
isRefreshTrigger: false,
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -743,13 +771,13 @@ class MailboxController extends BaseMailboxController
|
||||
allMailboxes.add(mailbox.toPresentationMailbox());
|
||||
}
|
||||
|
||||
await buildTree(allMailboxes.withoutVirtualMailbox);
|
||||
await buildTree(
|
||||
allMailboxes.withoutVirtualMailbox,
|
||||
onUpdateMailboxCollectionCallback: updateMailboxCollection,
|
||||
);
|
||||
if (currentContext != null) {
|
||||
syncAllMailboxWithDisplayName(currentContext!);
|
||||
}
|
||||
autoCreateVirtualFolder(
|
||||
mailboxDashBoardController.isAINeedsActionEnabled,
|
||||
);
|
||||
_setMapMailbox();
|
||||
_setOutboxMailbox();
|
||||
}
|
||||
@@ -1339,7 +1367,10 @@ class MailboxController extends BaseMailboxController
|
||||
currentMailboxState = success.currentMailboxState;
|
||||
log('MailboxController::_handleGetAllMailboxSuccess:currentMailboxState: $currentMailboxState');
|
||||
final listMailboxDisplayed = success.mailboxList.listSubscribedMailboxesAndDefaultMailboxes;
|
||||
await buildTree(listMailboxDisplayed.withoutVirtualMailbox);
|
||||
await buildTree(
|
||||
listMailboxDisplayed.withoutVirtualMailbox,
|
||||
onUpdateMailboxCollectionCallback: updateMailboxCollection,
|
||||
);
|
||||
if (currentContext != null) {
|
||||
syncAllMailboxWithDisplayName(currentContext!);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:model/mailbox/presentation_mailbox.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';
|
||||
|
||||
class MailboxCollection with EquatableMixin {
|
||||
final List<PresentationMailbox> allMailboxes;
|
||||
final MailboxTree defaultTree;
|
||||
final MailboxTree personalTree;
|
||||
final MailboxTree teamMailboxTree;
|
||||
|
||||
const MailboxCollection({
|
||||
required this.allMailboxes,
|
||||
required this.defaultTree,
|
||||
required this.personalTree,
|
||||
required this.teamMailboxTree,
|
||||
});
|
||||
|
||||
factory MailboxCollection.empty() => MailboxCollection(
|
||||
allMailboxes: const [],
|
||||
defaultTree: MailboxTree(MailboxNode.root()),
|
||||
personalTree: MailboxTree(MailboxNode.root()),
|
||||
teamMailboxTree: MailboxTree(MailboxNode.root()),
|
||||
);
|
||||
|
||||
MailboxCollection copyWith({
|
||||
List<PresentationMailbox>? allMailboxes,
|
||||
MailboxTree? defaultTree,
|
||||
MailboxTree? personalTree,
|
||||
MailboxTree? teamMailboxTree,
|
||||
}) {
|
||||
return MailboxCollection(
|
||||
allMailboxes: allMailboxes ?? this.allMailboxes,
|
||||
defaultTree: defaultTree ?? this.defaultTree,
|
||||
personalTree: personalTree ?? this.personalTree,
|
||||
teamMailboxTree: teamMailboxTree ?? this.teamMailboxTree,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
allMailboxes,
|
||||
defaultTree,
|
||||
personalTree,
|
||||
teamMailboxTree,
|
||||
];
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import 'package:model/mailbox/expand_mode.dart';
|
||||
import 'package:model/mailbox/mailbox_state.dart';
|
||||
import 'package:model/mailbox/presentation_mailbox.dart';
|
||||
import 'package:model/mailbox/select_mode.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_collection.dart';
|
||||
|
||||
import 'mailbox_node.dart';
|
||||
import 'mailbox_tree.dart';
|
||||
@@ -37,16 +38,9 @@ class TreeBuilder {
|
||||
return tree;
|
||||
}
|
||||
|
||||
Future<({
|
||||
List<PresentationMailbox> allMailboxes,
|
||||
MailboxTree defaultTree,
|
||||
MailboxTree personalTree,
|
||||
MailboxTree teamMailboxTree
|
||||
})> generateMailboxTreeInUI({
|
||||
Future<MailboxCollection> generateMailboxTreeInUI({
|
||||
required List<PresentationMailbox> allMailboxes,
|
||||
required MailboxTree currentDefaultTree,
|
||||
required MailboxTree currentPersonalTree,
|
||||
required MailboxTree currentTeamMailboxTree,
|
||||
required MailboxCollection currentCollection,
|
||||
MailboxId? mailboxIdSelected,
|
||||
MailboxId? mailboxIdExpanded,
|
||||
}) async {
|
||||
@@ -61,9 +55,7 @@ class TreeBuilder {
|
||||
for (var mailbox in allMailboxes) {
|
||||
final currentMailboxNode = findExistingNode(
|
||||
id: mailbox.id,
|
||||
currentDefaultTree: currentDefaultTree,
|
||||
currentPersonalTree: currentPersonalTree,
|
||||
currentTeamMailboxTree: currentTeamMailboxTree,
|
||||
currentCollection: currentCollection,
|
||||
);
|
||||
|
||||
final isDeactivated = mailbox.id == mailboxIdSelected;
|
||||
@@ -85,19 +77,12 @@ class TreeBuilder {
|
||||
final parentNode = parentId != null ? mailboxDictionary[parentId] : null;
|
||||
|
||||
if (parentNode != null) {
|
||||
if (parentNode.nodeState == MailboxState.deactivated) {
|
||||
currentNode.updateItem(mailbox.withMailboxSate(MailboxState.deactivated));
|
||||
currentNode.updateNodeState(MailboxState.deactivated);
|
||||
}
|
||||
_propagateDeactivationIfNeeded(parentNode, currentNode, mailbox);
|
||||
parentNode.addChildNode(currentNode);
|
||||
|
||||
sortByMailboxNameNodeChildren(parentNode);
|
||||
} else {
|
||||
final targetTree = mailbox.hasRole()
|
||||
? newDefaultTree
|
||||
: (mailbox.isPersonal ? newPersonalTree : newTeamMailboxTree);
|
||||
final targetTree = _resolveTargetTree(mailbox, newDefaultTree, newPersonalTree, newTeamMailboxTree);
|
||||
targetTree.root.addChildNode(currentNode);
|
||||
|
||||
sortByMailboxNameNodeChildren(targetTree.root);
|
||||
}
|
||||
|
||||
@@ -106,7 +91,7 @@ class TreeBuilder {
|
||||
|
||||
sortNodeChildren(newDefaultTree.root);
|
||||
|
||||
return (
|
||||
return MailboxCollection(
|
||||
allMailboxes: newAllMailboxes,
|
||||
defaultTree: newDefaultTree,
|
||||
personalTree: newPersonalTree,
|
||||
@@ -114,15 +99,9 @@ class TreeBuilder {
|
||||
);
|
||||
}
|
||||
|
||||
Future<({
|
||||
MailboxTree defaultTree,
|
||||
MailboxTree personalTree,
|
||||
MailboxTree teamMailboxTree
|
||||
})> generateMailboxTreeInUIAfterRefreshChanges({
|
||||
Future<MailboxCollection> generateMailboxTreeInUIAfterRefreshChanges({
|
||||
required List<PresentationMailbox> allMailboxes,
|
||||
required MailboxTree currentDefaultTree,
|
||||
required MailboxTree currentPersonalTree,
|
||||
required MailboxTree currentTeamMailboxTree,
|
||||
required MailboxCollection currentCollection,
|
||||
}) async {
|
||||
final Map<MailboxId, MailboxNode> mailboxDictionary = HashMap();
|
||||
|
||||
@@ -133,9 +112,7 @@ class TreeBuilder {
|
||||
for (var mailbox in allMailboxes) {
|
||||
final currentMailboxNode = findExistingNode(
|
||||
id: mailbox.id,
|
||||
currentDefaultTree: currentDefaultTree,
|
||||
currentPersonalTree: currentPersonalTree,
|
||||
currentTeamMailboxTree: currentTeamMailboxTree,
|
||||
currentCollection: currentCollection,
|
||||
);
|
||||
|
||||
final newMailboxNode = MailboxNode(
|
||||
@@ -158,18 +135,16 @@ class TreeBuilder {
|
||||
parentNode.addChildNode(currentNode);
|
||||
sortByMailboxNameNodeChildren(parentNode);
|
||||
} else {
|
||||
final targetTree = mailbox.hasRole()
|
||||
? newDefaultTree
|
||||
: (mailbox.isPersonal ? newPersonalTree : newTeamMailboxTree);
|
||||
final targetTree = _resolveTargetTree(mailbox, newDefaultTree, newPersonalTree, newTeamMailboxTree);
|
||||
targetTree.root.addChildNode(currentNode);
|
||||
|
||||
sortByMailboxNameNodeChildren(targetTree.root);
|
||||
}
|
||||
}
|
||||
|
||||
sortNodeChildren(newDefaultTree.root);
|
||||
|
||||
return (
|
||||
return MailboxCollection(
|
||||
allMailboxes: allMailboxes,
|
||||
defaultTree: newDefaultTree,
|
||||
personalTree: newPersonalTree,
|
||||
teamMailboxTree: newTeamMailboxTree,
|
||||
@@ -189,12 +164,30 @@ class TreeBuilder {
|
||||
|
||||
MailboxNode? findExistingNode({
|
||||
required MailboxId id,
|
||||
required MailboxTree currentDefaultTree,
|
||||
required MailboxTree currentPersonalTree,
|
||||
required MailboxTree currentTeamMailboxTree,
|
||||
required MailboxCollection currentCollection,
|
||||
}) {
|
||||
return currentDefaultTree.findNode((node) => node.item.id == id) ??
|
||||
currentPersonalTree.findNode((node) => node.item.id == id) ??
|
||||
currentTeamMailboxTree.findNode((node) => node.item.id == id);
|
||||
return currentCollection.defaultTree.findNode((node) => node.item.id == id) ??
|
||||
currentCollection.personalTree.findNode((node) => node.item.id == id) ??
|
||||
currentCollection.teamMailboxTree.findNode((node) => node.item.id == id);
|
||||
}
|
||||
|
||||
MailboxTree _resolveTargetTree(
|
||||
PresentationMailbox mailbox,
|
||||
MailboxTree defaultTree,
|
||||
MailboxTree personalTree,
|
||||
MailboxTree teamMailboxTree,
|
||||
) {
|
||||
if (mailbox.hasRole()) return defaultTree;
|
||||
return mailbox.isPersonal ? personalTree : teamMailboxTree;
|
||||
}
|
||||
|
||||
void _propagateDeactivationIfNeeded(
|
||||
MailboxNode parentNode,
|
||||
MailboxNode currentNode,
|
||||
PresentationMailbox mailbox,
|
||||
) {
|
||||
if (parentNode.nodeState != MailboxState.deactivated) return;
|
||||
currentNode.updateItem(mailbox.withMailboxSate(MailboxState.deactivated));
|
||||
currentNode.updateNodeState(MailboxState.deactivated);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/base/base_controller.dart';
|
||||
import 'package:tmail_ui_user/features/base/mixin/expand_folder_trigger_scrollable_mixin.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/extensions/expand_mode_extension.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_collection.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';
|
||||
@@ -77,9 +78,12 @@ class MailboxCreatorController extends BaseController
|
||||
Future<void> _buildMailboxTree(MailboxCreatorArguments arguments) async {
|
||||
final recordTree = await _treeBuilder.generateMailboxTreeInUI(
|
||||
allMailboxes: arguments.listMailboxes,
|
||||
currentDefaultTree: defaultMailboxTree.value,
|
||||
currentPersonalTree: personalMailboxTree.value,
|
||||
currentTeamMailboxTree: MailboxTree(MailboxNode.root()),
|
||||
currentCollection: MailboxCollection(
|
||||
allMailboxes: const [],
|
||||
defaultTree: defaultMailboxTree.value,
|
||||
personalTree: personalMailboxTree.value,
|
||||
teamMailboxTree: MailboxTree(MailboxNode.root()),
|
||||
),
|
||||
);
|
||||
personalMailboxTree.value = recordTree.personalTree;
|
||||
defaultMailboxTree.value = recordTree.defaultTree;
|
||||
|
||||
@@ -165,13 +165,19 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
|
||||
void handleSuccessViewState(Success success) async {
|
||||
if (success is GetAllMailboxSuccess) {
|
||||
currentMailboxState = success.currentMailboxState;
|
||||
await buildTree(success.mailboxList);
|
||||
await buildTree(
|
||||
success.mailboxList,
|
||||
onUpdateMailboxCollectionCallback: updateMailboxCollection,
|
||||
);
|
||||
if (currentContext != null) {
|
||||
syncAllMailboxWithDisplayName(currentContext!);
|
||||
}
|
||||
} else if (success is RefreshChangesAllMailboxSuccess) {
|
||||
currentMailboxState = success.currentMailboxState;
|
||||
await refreshTree(success.mailboxList);
|
||||
await refreshTree(
|
||||
success.mailboxList,
|
||||
onUpdateMailboxCollectionCallback: updateMailboxCollection,
|
||||
);
|
||||
if (currentContext != null) {
|
||||
syncAllMailboxWithDisplayName(currentContext!);
|
||||
}
|
||||
@@ -213,19 +219,17 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
|
||||
super.onDone();
|
||||
viewState.value.fold((failure) {
|
||||
if (failure is GetAllMailboxFailure) {
|
||||
autoCreateVirtualFolder(
|
||||
dashboardController.isAINeedsActionEnabled,
|
||||
updateMailboxTree(
|
||||
mailboxCollection: updateMailboxCollection(currentMailboxCollection),
|
||||
isRefreshTrigger: false,
|
||||
);
|
||||
}
|
||||
}, (success) {
|
||||
if (success is GetAllMailboxSuccess) {
|
||||
autoCreateVirtualFolder(
|
||||
dashboardController.isAINeedsActionEnabled,
|
||||
);
|
||||
}
|
||||
});
|
||||
}, (success) {});
|
||||
}
|
||||
|
||||
@override
|
||||
bool get isAINeedsActionEnabled => dashboardController.isAINeedsActionEnabled;
|
||||
|
||||
void _initializeDebounceTimeTextSearchChange() {
|
||||
_deBouncerTime = Debouncer<String>(
|
||||
const Duration(milliseconds: 300),
|
||||
|
||||
@@ -8,6 +8,7 @@ import 'package:model/mailbox/expand_mode.dart';
|
||||
import 'package:model/mailbox/mailbox_state.dart';
|
||||
import 'package:model/mailbox/presentation_mailbox.dart';
|
||||
import 'package:model/mailbox/select_mode.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_collection.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';
|
||||
@@ -256,9 +257,7 @@ void main() {
|
||||
|
||||
final generatedTree = await TreeBuilder().generateMailboxTreeInUI(
|
||||
allMailboxes: testCase,
|
||||
currentDefaultTree: MailboxTree(MailboxNode.root()),
|
||||
currentPersonalTree: MailboxTree(MailboxNode.root()),
|
||||
currentTeamMailboxTree: MailboxTree(MailboxNode.root()),
|
||||
currentCollection: MailboxCollection.empty(),
|
||||
);
|
||||
|
||||
expect(
|
||||
@@ -323,9 +322,7 @@ void main() {
|
||||
() async {
|
||||
final generatedTrees = await TreeBuilder().generateMailboxTreeInUI(
|
||||
allMailboxes: filteredMailboxes,
|
||||
currentDefaultTree: MailboxTree(MailboxNode.root()),
|
||||
currentPersonalTree: MailboxTree(MailboxNode.root()),
|
||||
currentTeamMailboxTree: MailboxTree(MailboxNode.root()),
|
||||
currentCollection: MailboxCollection.empty(),
|
||||
);
|
||||
|
||||
expectNoVirtualFoldersRecursively(
|
||||
@@ -350,9 +347,7 @@ void main() {
|
||||
final generatedTrees =
|
||||
await TreeBuilder().generateMailboxTreeInUIAfterRefreshChanges(
|
||||
allMailboxes: filteredMailboxes,
|
||||
currentDefaultTree: MailboxTree(MailboxNode.root()),
|
||||
currentPersonalTree: MailboxTree(MailboxNode.root()),
|
||||
currentTeamMailboxTree: MailboxTree(MailboxNode.root()),
|
||||
currentCollection: MailboxCollection.empty(),
|
||||
);
|
||||
|
||||
expectNoVirtualFoldersRecursively(
|
||||
@@ -392,9 +387,7 @@ void main() {
|
||||
|
||||
final generatedTree = await TreeBuilder().generateMailboxTreeInUI(
|
||||
allMailboxes: filtered,
|
||||
currentDefaultTree: MailboxTree(MailboxNode.root()),
|
||||
currentPersonalTree: MailboxTree(MailboxNode.root()),
|
||||
currentTeamMailboxTree: MailboxTree(MailboxNode.root()),
|
||||
currentCollection: MailboxCollection.empty(),
|
||||
);
|
||||
|
||||
final children = generatedTree.defaultTree.root.childrenItems ?? [];
|
||||
@@ -437,9 +430,7 @@ void main() {
|
||||
|
||||
final generatedTree = await TreeBuilder().generateMailboxTreeInUI(
|
||||
allMailboxes: testCaseWithVirtualFolders,
|
||||
currentDefaultTree: MailboxTree(MailboxNode.root()),
|
||||
currentPersonalTree: MailboxTree(MailboxNode.root()),
|
||||
currentTeamMailboxTree: MailboxTree(MailboxNode.root()),
|
||||
currentCollection: MailboxCollection.empty(),
|
||||
);
|
||||
|
||||
final children = generatedTree.defaultTree.root.childrenItems ?? [];
|
||||
@@ -484,9 +475,7 @@ void main() {
|
||||
final result =
|
||||
await TreeBuilder().generateMailboxTreeInUIAfterRefreshChanges(
|
||||
allMailboxes: mailboxes,
|
||||
currentDefaultTree: MailboxTree(MailboxNode.root()),
|
||||
currentPersonalTree: MailboxTree(MailboxNode.root()),
|
||||
currentTeamMailboxTree: MailboxTree(MailboxNode.root()),
|
||||
currentCollection: MailboxCollection.empty(),
|
||||
);
|
||||
|
||||
expect(result.defaultTree.root.childrenItems?.length, equals(1));
|
||||
@@ -542,9 +531,12 @@ void main() {
|
||||
final result =
|
||||
await TreeBuilder().generateMailboxTreeInUIAfterRefreshChanges(
|
||||
allMailboxes: [mailbox],
|
||||
currentDefaultTree: currentDefaultTree,
|
||||
currentPersonalTree: MailboxTree(MailboxNode.root()),
|
||||
currentTeamMailboxTree: MailboxTree(MailboxNode.root()),
|
||||
currentCollection: MailboxCollection(
|
||||
allMailboxes: const [],
|
||||
defaultTree: currentDefaultTree,
|
||||
personalTree: MailboxTree(MailboxNode.root()),
|
||||
teamMailboxTree: MailboxTree(MailboxNode.root()),
|
||||
),
|
||||
);
|
||||
|
||||
final newNode = result.defaultTree.root.childrenItems?.first;
|
||||
@@ -561,6 +553,128 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
group('MailboxCollection allMailboxes field', () {
|
||||
final inbox = PresentationMailbox(
|
||||
MailboxId(Id('inbox')),
|
||||
name: MailboxName('Inbox'),
|
||||
role: Role('inbox'),
|
||||
);
|
||||
final sent = PresentationMailbox(
|
||||
MailboxId(Id('sent')),
|
||||
name: MailboxName('Sent'),
|
||||
role: Role('sent'),
|
||||
);
|
||||
|
||||
test(
|
||||
'generateMailboxTreeInUIAfterRefreshChanges: allMailboxes excludes virtual folders from previous collection',
|
||||
() async {
|
||||
final virtualFavorite = PresentationMailbox.favoriteFolder;
|
||||
final previousDefaultTree = MailboxTree(MailboxNode.root())
|
||||
..root.addChildNode(MailboxNode(virtualFavorite));
|
||||
|
||||
final previousCollection = MailboxCollection(
|
||||
allMailboxes: [inbox, virtualFavorite],
|
||||
defaultTree: previousDefaultTree,
|
||||
personalTree: MailboxTree(MailboxNode.root()),
|
||||
teamMailboxTree: MailboxTree(MailboxNode.root()),
|
||||
);
|
||||
|
||||
final result = await TreeBuilder().generateMailboxTreeInUIAfterRefreshChanges(
|
||||
allMailboxes: [inbox, sent],
|
||||
currentCollection: previousCollection,
|
||||
);
|
||||
|
||||
expect(
|
||||
result.allMailboxes.every((m) => !m.isVirtualFolder),
|
||||
isTrue,
|
||||
reason: 'Virtual folders from previousCollection must not bleed into result.allMailboxes',
|
||||
);
|
||||
expect(result.allMailboxes.length, equals(2));
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'generateMailboxTreeInUIAfterRefreshChanges: deleted server mailboxes are excluded from result',
|
||||
() async {
|
||||
final deleted = PresentationMailbox(
|
||||
MailboxId(Id('deleted')),
|
||||
name: MailboxName('Old Folder'),
|
||||
);
|
||||
final previousDefaultTree = MailboxTree(MailboxNode.root())
|
||||
..root.addChildNode(MailboxNode(deleted));
|
||||
|
||||
final previousCollection = MailboxCollection(
|
||||
allMailboxes: [inbox, deleted],
|
||||
defaultTree: previousDefaultTree,
|
||||
personalTree: MailboxTree(MailboxNode.root()),
|
||||
teamMailboxTree: MailboxTree(MailboxNode.root()),
|
||||
);
|
||||
|
||||
final result = await TreeBuilder().generateMailboxTreeInUIAfterRefreshChanges(
|
||||
allMailboxes: [inbox],
|
||||
currentCollection: previousCollection,
|
||||
);
|
||||
|
||||
expect(result.allMailboxes.length, equals(1));
|
||||
expect(
|
||||
result.allMailboxes.any((m) => m.id == deleted.id),
|
||||
isFalse,
|
||||
reason: 'Mailbox removed from server must not appear in result',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'generateMailboxTreeInUI: deleted server mailboxes are excluded from result',
|
||||
() async {
|
||||
final deleted = PresentationMailbox(
|
||||
MailboxId(Id('deleted')),
|
||||
name: MailboxName('Old Folder'),
|
||||
);
|
||||
final previousDefaultTree = MailboxTree(MailboxNode.root())
|
||||
..root.addChildNode(MailboxNode(deleted));
|
||||
|
||||
final previousCollection = MailboxCollection(
|
||||
allMailboxes: [inbox, deleted],
|
||||
defaultTree: previousDefaultTree,
|
||||
personalTree: MailboxTree(MailboxNode.root()),
|
||||
teamMailboxTree: MailboxTree(MailboxNode.root()),
|
||||
);
|
||||
|
||||
final result = await TreeBuilder().generateMailboxTreeInUI(
|
||||
allMailboxes: [inbox],
|
||||
currentCollection: previousCollection,
|
||||
);
|
||||
|
||||
expect(result.allMailboxes.length, equals(1));
|
||||
expect(
|
||||
result.allMailboxes.any((m) => m.id == deleted.id),
|
||||
isFalse,
|
||||
reason: 'Mailbox removed from server must not appear in result',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'generateMailboxTreeInUI: selected mailbox in allMailboxes has state deactivated',
|
||||
() async {
|
||||
final result = await TreeBuilder().generateMailboxTreeInUI(
|
||||
allMailboxes: [inbox, sent],
|
||||
currentCollection: MailboxCollection.empty(),
|
||||
mailboxIdSelected: inbox.id,
|
||||
);
|
||||
|
||||
final selectedInResult = result.allMailboxes.firstWhere((m) => m.id == inbox.id);
|
||||
expect(
|
||||
selectedInResult.state,
|
||||
equals(MailboxState.deactivated),
|
||||
reason: 'Selected mailbox must be deactivated in allMailboxes',
|
||||
);
|
||||
expect(result.allMailboxes.length, equals(2));
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
group('Cascading Deactivation (generateMailboxTreeInUI only)', () {
|
||||
test('Selecting a parent deactivates it and cascades to its children',
|
||||
() async {
|
||||
@@ -589,9 +703,7 @@ void main() {
|
||||
|
||||
final result = await TreeBuilder().generateMailboxTreeInUI(
|
||||
allMailboxes: mailboxes,
|
||||
currentDefaultTree: MailboxTree(MailboxNode.root()),
|
||||
currentPersonalTree: MailboxTree(MailboxNode.root()),
|
||||
currentTeamMailboxTree: MailboxTree(MailboxNode.root()),
|
||||
currentCollection: MailboxCollection.empty(),
|
||||
mailboxIdSelected: parentId,
|
||||
);
|
||||
|
||||
|
||||
+7
-14
@@ -60,6 +60,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_mailbox
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_multiple_mailbox_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_controller.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_view_web.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_collection.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';
|
||||
@@ -816,14 +817,12 @@ void main() {
|
||||
when(
|
||||
treeBuilder.generateMailboxTreeInUI(
|
||||
allMailboxes: anyNamed('allMailboxes'),
|
||||
currentDefaultTree: anyNamed('currentDefaultTree'),
|
||||
currentPersonalTree: anyNamed('currentPersonalTree'),
|
||||
currentTeamMailboxTree: anyNamed('currentTeamMailboxTree'),
|
||||
currentCollection: anyNamed('currentCollection'),
|
||||
mailboxIdSelected: anyNamed('mailboxIdSelected'),
|
||||
mailboxIdExpanded: anyNamed('mailboxIdExpanded'),
|
||||
),
|
||||
).thenAnswer(
|
||||
(_) async => (
|
||||
(_) async => MailboxCollection(
|
||||
allMailboxes: currentMailboxList,
|
||||
defaultTree: defaultTree,
|
||||
personalTree: personalTree,
|
||||
@@ -865,9 +864,7 @@ void main() {
|
||||
verify(
|
||||
treeBuilder.generateMailboxTreeInUI(
|
||||
allMailboxes: anyNamed('allMailboxes'),
|
||||
currentDefaultTree: anyNamed('currentDefaultTree'),
|
||||
currentPersonalTree: anyNamed('currentPersonalTree'),
|
||||
currentTeamMailboxTree: anyNamed('currentTeamMailboxTree'),
|
||||
currentCollection: anyNamed('currentCollection'),
|
||||
mailboxIdSelected: anyNamed('mailboxIdSelected'),
|
||||
mailboxIdExpanded: anyNamed('mailboxIdExpanded'),
|
||||
),
|
||||
@@ -958,14 +955,12 @@ void main() {
|
||||
when(
|
||||
treeBuilder.generateMailboxTreeInUI(
|
||||
allMailboxes: anyNamed('allMailboxes'),
|
||||
currentDefaultTree: anyNamed('currentDefaultTree'),
|
||||
currentPersonalTree: anyNamed('currentPersonalTree'),
|
||||
currentTeamMailboxTree: anyNamed('currentTeamMailboxTree'),
|
||||
currentCollection: anyNamed('currentCollection'),
|
||||
mailboxIdSelected: anyNamed('mailboxIdSelected'),
|
||||
mailboxIdExpanded: anyNamed('mailboxIdExpanded'),
|
||||
),
|
||||
).thenAnswer(
|
||||
(_) async => (
|
||||
(_) async => MailboxCollection(
|
||||
allMailboxes: currentMailboxList,
|
||||
defaultTree: defaultTree,
|
||||
personalTree: personalTree,
|
||||
@@ -1008,9 +1003,7 @@ void main() {
|
||||
verify(
|
||||
treeBuilder.generateMailboxTreeInUI(
|
||||
allMailboxes: anyNamed('allMailboxes'),
|
||||
currentDefaultTree: anyNamed('currentDefaultTree'),
|
||||
currentPersonalTree: anyNamed('currentPersonalTree'),
|
||||
currentTeamMailboxTree: anyNamed('currentTeamMailboxTree'),
|
||||
currentCollection: anyNamed('currentCollection'),
|
||||
mailboxIdSelected: anyNamed('mailboxIdSelected'),
|
||||
mailboxIdExpanded: anyNamed('mailboxIdExpanded'),
|
||||
),
|
||||
|
||||
+5
-8
@@ -32,6 +32,7 @@ import 'package:tmail_ui_user/features/login/domain/usecases/delete_authority_oi
|
||||
import 'package:tmail_ui_user/features/login/domain/usecases/delete_credential_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/state/get_all_mailboxes_state.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_all_mailbox_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_collection.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';
|
||||
@@ -211,11 +212,9 @@ void main() {
|
||||
|
||||
when(mockTreeBuilder.generateMailboxTreeInUI(
|
||||
allMailboxes: [spamMailbox],
|
||||
currentDefaultTree: MailboxTree(MailboxNode.root()),
|
||||
currentPersonalTree: MailboxTree(MailboxNode.root()),
|
||||
currentTeamMailboxTree: MailboxTree(MailboxNode.root()),
|
||||
currentCollection: MailboxCollection.empty(),
|
||||
)).thenAnswer((_) async {
|
||||
return (
|
||||
return MailboxCollection(
|
||||
allMailboxes: [spamMailbox],
|
||||
defaultTree: MailboxTree(MailboxNode(spamMailbox)),
|
||||
personalTree: MailboxTree(MailboxNode.root()),
|
||||
@@ -292,11 +291,9 @@ void main() {
|
||||
|
||||
when(mockTreeBuilder.generateMailboxTreeInUI(
|
||||
allMailboxes: [mailboxA],
|
||||
currentDefaultTree: MailboxTree(MailboxNode.root()),
|
||||
currentPersonalTree: MailboxTree(MailboxNode.root()),
|
||||
currentTeamMailboxTree: MailboxTree(MailboxNode.root()),
|
||||
currentCollection: MailboxCollection.empty(),
|
||||
)).thenAnswer((_) async {
|
||||
return (
|
||||
return MailboxCollection(
|
||||
allMailboxes: [mailboxA],
|
||||
defaultTree: MailboxTree(MailboxNode.root()),
|
||||
personalTree: MailboxTree(MailboxNode(mailboxA)),
|
||||
|
||||
Reference in New Issue
Block a user