From f2bb1638c0829ecd4c0d0ca6208afc197b90c3e4 Mon Sep 17 00:00:00 2001 From: Dat PHAM HOANG Date: Fri, 11 Mar 2022 14:10:51 +0700 Subject: [PATCH] TF-189 Refactor mailbox components: observe only Tree variable --- .../presentation/mailbox_controller.dart | 132 ++++++------------ .../mailbox/presentation/mailbox_view.dart | 58 ++++---- 2 files changed, 67 insertions(+), 123 deletions(-) diff --git a/lib/features/mailbox/presentation/mailbox_controller.dart b/lib/features/mailbox/presentation/mailbox_controller.dart index 025a36767..9629af39d 100644 --- a/lib/features/mailbox/presentation/mailbox_controller.dart +++ b/lib/features/mailbox/presentation/mailbox_controller.dart @@ -5,9 +5,10 @@ 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/id.dart'; +import 'package:jmap_dart_client/jmap/core/state.dart' as jmapState; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:model/model.dart'; -import 'package:tmail_ui_user/features/base/base_controller.dart'; +import 'package:tmail_ui_user/features/base/base_mailbox_controller.dart'; import 'package:tmail_ui_user/features/caching/caching_manager.dart'; import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_drafts_state.dart'; import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart'; @@ -30,8 +31,6 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/search_mailbox_in 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/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/presentation/extensions/list_mailbox_node_extension.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/special_character_validator.dart'; @@ -50,10 +49,9 @@ import 'package:tmail_ui_user/features/thread/presentation/model/search_status.d 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/route_navigation.dart'; -import 'package:jmap_dart_client/jmap/core/state.dart' as jmapState; import 'package:uuid/uuid.dart'; -class MailboxController extends BaseController { +class MailboxController extends BaseMailboxController { final mailboxDashBoardController = Get.find(); final GetAllMailboxInteractor _getAllMailboxInteractor; @@ -64,21 +62,17 @@ class MailboxController extends BaseController { final DeleteMultipleMailboxInteractor _deleteMultipleMailboxInteractor; final VerifyNameInteractor _verifyNameInteractor; final RenameMailboxInteractor _renameMailboxInteractor; - final TreeBuilder _treeBuilder; final Uuid _uuid; final AppToast _appToast; final ImagePaths _imagePaths; final ResponsiveUtils responsiveUtils; final CachingManager _cachingManager; - final defaultMailboxList = [].obs; - final folderMailboxNodeList = [].obs; final listMailboxSearched = [].obs; final searchState = SearchState.initial().obs; final searchQuery = SearchQuery.initial().obs; final currentSelectMode = SelectMode.INACTIVE.obs; - MailboxTree folderMailboxTree = MailboxTree(MailboxNode.root()); List allMailboxes = []; TextEditingController searchInputController = TextEditingController(); FocusNode searchFocus = FocusNode(); @@ -94,13 +88,13 @@ class MailboxController extends BaseController { this._deleteMultipleMailboxInteractor, this._verifyNameInteractor, this._renameMailboxInteractor, - this._treeBuilder, + treeBuilder, this._uuid, this._appToast, this._imagePaths, this.responsiveUtils, this._cachingManager, - ); + ) : super(treeBuilder); @override void onReady() { @@ -144,11 +138,11 @@ class MailboxController extends BaseController { super.onData(newState); newState.map((success) { if (success is GetAllMailboxSuccess) { - allMailboxes = success.defaultMailboxList + success.folderMailboxList; + allMailboxes = success.mailboxList; currentMailboxState = success.currentMailboxState; - defaultMailboxList.value = success.defaultMailboxList; - _setUpMapMailboxIdDefault(success.defaultMailboxList, success.folderMailboxList); - _buildTree(success.folderMailboxList); + buildTree(allMailboxes); + + _setUpMapMailboxIdDefault(allMailboxes, defaultMailboxTree.value, folderMailboxTree.value); } }); } @@ -208,34 +202,17 @@ class MailboxController extends BaseController { } } - void _buildTree(List folderMailboxList) async { - folderMailboxTree = await _treeBuilder.generateMailboxTree(folderMailboxList); - folderMailboxNodeList.value = folderMailboxTree.root.childrenItems ?? []; - } - - void toggleMailboxFolder(MailboxNode mailboxNode) { - final newExpandMode = mailboxNode.expandMode == ExpandMode.COLLAPSE - ? ExpandMode.EXPAND - : ExpandMode.COLLAPSE; - - final newMailboxNodeList = folderMailboxNodeList.updateNode( - mailboxNode.item.id, - mailboxNode.copyWith(newExpandMode: newExpandMode)); - folderMailboxNodeList.value = newMailboxNodeList; - } - - void _setUpMapMailboxIdDefault(List defaultMailboxList, List folderMailboxList) { - final allMailbox = defaultMailboxList + folderMailboxList; + void _setUpMapMailboxIdDefault(List allMailbox, MailboxTree defaultTree, MailboxTree folderTree) { final mapDefaultMailboxId = Map.fromIterable( - defaultMailboxList, - key: (presentationMailbox) => presentationMailbox.role!, - value: (presentationMailbox) => presentationMailbox.id); + defaultTree.root.childrenItems ?? List.empty(), + key: (mailboxNode) => mailboxNode.item.role!, + value: (mailboxNode) => mailboxNode.item.id); final mapDefaultMailbox = Map.fromIterable( - defaultMailboxList, - key: (presentationMailbox) => presentationMailbox.role!, - value: (presentationMailbox) => presentationMailbox); + defaultTree.root.childrenItems ?? List.empty(), + key: (mailboxNode) => mailboxNode.item.role!, + value: (mailboxNode) => mailboxNode.item); final mapMailbox = Map.fromIterable( allMailbox, @@ -381,13 +358,9 @@ class MailboxController extends BaseController { if (!presentationMailbox.hasParentId()) { return presentationMailbox; } else { - final mailboxNode = folderMailboxTree.findNode(presentationMailbox.id); - if (mailboxNode != null) { - String mailboxPath = mailboxNode.getPathMailboxNode(folderMailboxTree, defaultMailboxList); - if (mailboxPath.contains('/')) { - mailboxPath = mailboxPath.substring(0, mailboxPath.lastIndexOf('/')).replaceAll('/', ' / '); - } - return presentationMailbox.toPresentationMailboxWithMailboxPath(mailboxPath); + final mailboxNodePath = findNodePath(presentationMailbox.id); + if (mailboxNodePath != null) { + return presentationMailbox.toPresentationMailboxWithMailboxPath(mailboxNodePath); } else { return presentationMailbox; } @@ -416,34 +389,17 @@ class MailboxController extends BaseController { ? mailbox.toggleSelectPresentationMailbox() : mailbox) .toList(); - } else { - defaultMailboxList.value = defaultMailboxList - .map((mailbox) => mailbox.id == mailboxSelected.id - ? mailbox.toggleSelectPresentationMailbox() - : mailbox) - .toList(); } } - void selectMailboxNode(BuildContext context, MailboxNode mailboxNodeSelected) { - final newMailboxNodeList = folderMailboxNodeList.toggleSelectMailboxNode(mailboxNodeSelected); - folderMailboxNodeList.value = newMailboxNodeList; - } - void _cancelSelectMailbox() { if (isSearchActive()) { listMailboxSearched.value = listMailboxSearched .map((mailbox) => mailbox.toSelectedPresentationMailbox(selectMode: SelectMode.INACTIVE)) .toList(); } else { - defaultMailboxList.value = defaultMailboxList - .map((mailbox) => mailbox.toSelectedPresentationMailbox(selectMode: SelectMode.INACTIVE)) - .toList(); - - final newMailboxNodeList = folderMailboxNodeList.toSelectMailboxNode( - selectMode: SelectMode.INACTIVE, - newExpandMode: ExpandMode.COLLAPSE); - folderMailboxNodeList.value = newMailboxNodeList; + defaultMailboxTree.value.updateNodesUIMode(SelectMode.INACTIVE, ExpandMode.COLLAPSE); + folderMailboxTree.value.updateNodesUIMode(SelectMode.INACTIVE, ExpandMode.COLLAPSE); } currentSelectMode.value = SelectMode.INACTIVE; } @@ -451,26 +407,19 @@ class MailboxController extends BaseController { List get listMailboxSelected { if (isSearchActive()) { return listMailboxSearched - .where((mailbox) => mailbox.selectMode == SelectMode.ACTIVE) - .toList(); + .where((mailbox) => mailbox.selectMode == SelectMode.ACTIVE) + .toList(); } else { - final defaultMailboxSelected = defaultMailboxList - .where((mailbox) => mailbox.selectMode == SelectMode.ACTIVE) - .toList(); + final defaultMailboxSelected = defaultMailboxTree.value + .findNodes((node) => node.selectMode == SelectMode.ACTIVE); - final newFolderMailboxTree = MailboxTree(MailboxNode( - MailboxNode.rootItem(), - childrenItems: folderMailboxNodeList)); - final folderMailboxList = allMailboxes.where((mailbox) => !mailbox.hasRole()).toList(); + final folderMailboxSelected = folderMailboxTree.value + .findNodes((node) => node.selectMode == SelectMode.ACTIVE); - final folderMailboxSelected = folderMailboxList - .where((mailbox) { - final node = newFolderMailboxTree.findNode(mailbox.id); - return node != null && node.selectMode == SelectMode.ACTIVE; - }) - .toList(); - - return defaultMailboxSelected + folderMailboxSelected; + return [defaultMailboxSelected, folderMailboxSelected] + .expand((node) => node) + .map((node) => node.item) + .toList(); } } @@ -512,20 +461,17 @@ class MailboxController extends BaseController { } void _deleteMailboxAction(PresentationMailbox presentationMailbox) { - final newFolderMailboxTree = MailboxTree(MailboxNode( - MailboxNode.rootItem(), - childrenItems: folderMailboxNodeList)); - final mailboxNode = newFolderMailboxTree.findNode(presentationMailbox.id); + final matchedNode = findMailboxNodeById(presentationMailbox.id); final accountId = mailboxDashBoardController.accountId.value; - if (mailboxNode != null && accountId != null) { - final allMailboxId = newFolderMailboxTree - .getAllNodes(mailboxNode) - .map((node) => node.item.id) - .toList(); - final allMailboxIdReversed = allMailboxId.reversed.toList(); - consumeState(_deleteMultipleMailboxInteractor.execute(accountId, allMailboxIdReversed)); + if (matchedNode != null && accountId != null) { + final descendantIds = matchedNode.descendantsAsList() + .map((node) => node.item.id) + .toList(); + + final descendantIdsReversed = descendantIds.reversed.toList(); + consumeState(_deleteMultipleMailboxInteractor.execute(accountId, descendantIdsReversed)); } else { _deleteMailboxFailure(DeleteMultipleMailboxFailure(null)); } diff --git a/lib/features/mailbox/presentation/mailbox_view.dart b/lib/features/mailbox/presentation/mailbox_view.dart index 585847737..478e9ce7a 100644 --- a/lib/features/mailbox/presentation/mailbox_view.dart +++ b/lib/features/mailbox/presentation/mailbox_view.dart @@ -180,13 +180,13 @@ class MailboxView extends GetWidget { : _buildLineSpaceUserInformation()), _buildSearchBarWidget(context), _buildLoadingView(), - Obx(() => controller.defaultMailboxList.isNotEmpty + Obx(() => controller.defaultMailboxTree.value.root.childrenItems?.isNotEmpty ?? false ? Container( decoration: BoxDecoration( - borderRadius: BorderRadius.circular(14), - color: Colors.white), + borderRadius: BorderRadius.circular(14), + color: Colors.white), margin: EdgeInsets.only(left: 16, right: 16, top: 4), - child: _buildDefaultMailbox(context, controller.defaultMailboxList)) + child: _buildDefaultMailbox(context)) : SizedBox.shrink()), Padding( padding: EdgeInsets.only(left: 25, top: 26, bottom: 12), @@ -212,26 +212,23 @@ class MailboxView extends GetWidget { child: Divider(color: AppColor.colorDividerMailbox, height: 0.5, thickness: 0.2)); } - Widget _buildDefaultMailbox(BuildContext context, List defaultMailbox) { - return ListView.builder( - padding: EdgeInsets.all(8), - key: PageStorageKey('default_mailbox_list'), - itemCount: defaultMailbox.length, - shrinkWrap: true, - primary: false, - itemBuilder: (context, index) => - Obx(() => (MailboxTileBuilder( - imagePaths, - defaultMailbox[index], - allSelectMode: controller.currentSelectMode.value, - isLastElement: index == defaultMailbox.length - 1) - ..addOnOpenMailboxAction((mailbox) => controller.openMailbox(context, mailbox)) - ..addOnSelectMailboxActionClick((mailbox) => controller.selectMailbox(context, mailbox))) - .build())); + Widget _buildDefaultMailbox(BuildContext context) { + return Obx(() => controller.defaultMailboxTree.value.root.childrenItems?.isNotEmpty ?? false + ? Transform( + transform: Matrix4.translationValues(-4.0, 0.0, 0.0), + child: Padding( + padding: EdgeInsets.only(top: 10, bottom: 10), + child: TreeView( + startExpanded: false, + key: Key('default_mailbox_list'), + children: _buildListChildTileWidget(context, controller.defaultMailboxTree.value.root))) + ) + : SizedBox.shrink() + ); } Widget _buildFolderMailbox(BuildContext context) { - return Obx(() => controller.folderMailboxNodeList.isNotEmpty + return Obx(() => controller.folderMailboxTree.value.root.childrenItems?.isNotEmpty ?? false ? Transform( transform: Matrix4.translationValues(-4.0, 0.0, 0.0), child: Padding( @@ -239,15 +236,15 @@ class MailboxView extends GetWidget { child: TreeView( startExpanded: false, key: Key('folder_mailbox_list'), - children: _buildListChildTileWidget(context, controller.folderMailboxNodeList))) + children: _buildListChildTileWidget(context, controller.folderMailboxTree.value.root))) ) : SizedBox.shrink() ); } - List _buildListChildTileWidget(BuildContext context, List listMailboxNode) { - return listMailboxNode - .map((mailboxNode) => mailboxNode.hasChildren() + List _buildListChildTileWidget(BuildContext context, MailboxNode parentNode) { + return parentNode.childrenItems + ?.map((mailboxNode) => mailboxNode.hasChildren() ? Padding( padding: EdgeInsets.only(left: 16), child: TreeViewChild( @@ -261,9 +258,9 @@ class MailboxView extends GetWidget { allSelectMode: controller.currentSelectMode.value) ..addOnOpenMailboxFolderClick((mailboxNode) => controller.openMailbox(context, mailboxNode.item)) ..addOnExpandFolderActionClick((mailboxNode) => controller.toggleMailboxFolder(mailboxNode)) - ..addOnSelectMailboxFolderClick((mailboxNode) => controller.selectMailboxNode(context, mailboxNode))) + ..addOnSelectMailboxFolderClick((mailboxNode) => controller.selectMailboxNode(mailboxNode))) .build()), - children: _buildListChildTileWidget(context, mailboxNode.childrenItems!) + children: _buildListChildTileWidget(context, mailboxNode) ).build()) : Padding( padding: EdgeInsets.only(left: 16), @@ -273,10 +270,11 @@ class MailboxView extends GetWidget { mailboxNode, allSelectMode: controller.currentSelectMode.value) ..addOnOpenMailboxFolderClick((mailboxNode) => controller.openMailbox(context, mailboxNode.item)) - ..addOnSelectMailboxFolderClick((mailboxNode) => controller.selectMailboxNode(context, mailboxNode))) + ..addOnSelectMailboxFolderClick((mailboxNode) => controller.selectMailboxNode(mailboxNode))) .build(), - ))) - .toList(); + ) + ) + ).toList() ?? []; } Widget _buildInputSearchFormWidget(BuildContext context) {