TF-1427 Handle show mailbox in search mailbox view

This commit is contained in:
dab246
2023-02-10 03:59:58 +07:00
committed by Dat Vu
parent 85a74039f6
commit b0273711ee
19 changed files with 766 additions and 441 deletions
+5
View File
@@ -0,0 +1,5 @@
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M14 6C19.9941 6 25.5 10.5566 25.5 14C25.5 17.4434 19.9941 22 14 22C8.00594 22 2.5 17.4434 2.5 14C2.5 10.5566 8.00594 6 14 6ZM14 8C9.03573 8 4.5 11.7537 4.5 14C4.5 16.2463 9.03573 20 14 20C18.9643 20 23.5 16.2463 23.5 14C23.5 11.7537 18.9643 8 14 8ZM14 10C16.2091 10 18 11.7909 18 14C18 16.2091 16.2091 18 14 18C11.7909 18 10 16.2091 10 14C10 11.7909 11.7909 10 14 10ZM14 12C12.8954 12 12 12.8954 12 14C12 15.1046 12.8954 16 14 16C15.1046 16 16 15.1046 16 14C16 12.8954 15.1046 12 14 12Z"
fill="#007AFF" />
</svg>

After

Width:  |  Height:  |  Size: 638 B

@@ -173,6 +173,7 @@ class ImagePaths {
String get icMarkAsRead => _getImagePath('ic_mark_as_read.svg');
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 _getImagePath(String imageName) {
return AssetsPaths.images + imageName;
@@ -17,6 +17,12 @@ import 'package:model/mailbox/select_mode.dart';
import 'package:pointer_interceptor/pointer_interceptor.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/presentation/extensions/list_mailbox_node_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/features/mailbox/presentation/model/mailbox_tree.dart';
@@ -392,4 +398,22 @@ abstract class BaseMailboxController extends BaseController {
);
}
}
SubscribeRequest? generateSubscribeRequest(
MailboxId mailboxId,
MailboxSubscribeState subscribeState,
MailboxSubscribeAction subscribeAction
) {
final mailboxNode = findMailboxNodeById(mailboxId);
if (mailboxNode != null) {
if (mailboxNode.hasChildren()) {
final listDescendantMailboxIds = mailboxNode.descendantsAsList().mailboxIds;
return SubscribeMultipleMailboxRequest(mailboxId, listDescendantMailboxIds, subscribeState, subscribeAction);
} else {
return SubscribeMailboxRequest(mailboxId, subscribeState, subscribeAction);
}
}
return null;
}
}
@@ -0,0 +1,57 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class PopupItemWidget extends StatelessWidget {
final String _iconAction;
final String _nameAction;
final Color? colorIcon;
final double? iconSize;
final TextStyle? styleName;
final EdgeInsets? padding;
final VoidCallback? onCallbackAction;
const PopupItemWidget(
this._iconAction,
this._nameAction,
{
Key? key,
this.colorIcon,
this.iconSize,
this.styleName,
this.padding,
this.onCallbackAction
}
) : super(key: key);
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onCallbackAction,
child: Padding(
padding: padding ?? const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
child: SizedBox(
child: Row(children: [
SvgPicture.asset(
_iconAction,
width: iconSize ?? 20,
height: iconSize ?? 20,
fit: BoxFit.fill,
color: colorIcon
),
const SizedBox(width: 12),
Expanded(child: Text(
_nameAction,
style: styleName ?? const TextStyle(
fontSize: 17,
fontWeight: FontWeight.normal,
color: Colors.black
)
)),
])
),
)
);
}
}
@@ -21,7 +21,7 @@ import 'package:model/extensions/list_attachment_extension.dart';
import 'package:model/extensions/list_email_content_extension.dart';
import 'package:model/extensions/presentation_email_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/base/mixin/popup_menu_widget_mixin.dart';
import 'package:tmail_ui_user/features/base/widget/popup_item_widget.dart';
import 'package:tmail_ui_user/features/email/presentation/controller/single_email_controller.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/app_bar_mail_widget_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_file_tile_builder.dart';
@@ -32,8 +32,7 @@ import 'package:tmail_ui_user/features/manage_account/presentation/extensions/va
import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class EmailView extends GetWidget<SingleEmailController>
with PopupMenuWidgetMixin {
class EmailView extends GetWidget<SingleEmailController> {
final responsiveUtils = Get.find<ResponsiveUtils>();
final imagePaths = Get.find<ImagePaths>();
@@ -554,7 +553,7 @@ class EmailView extends GetWidget<SingleEmailController>
PopupMenuEntry _markAsEmailUnreadPopupItemAction(BuildContext context, PresentationEmail email) {
return PopupMenuItem(
padding: EdgeInsets.zero,
child: popupItem(
child: PopupItemWidget(
imagePaths.icUnreadEmail,
AppLocalizations.of(context).mark_as_unread,
colorIcon: AppColor.colorTextButton,
@@ -579,7 +578,7 @@ class EmailView extends GetWidget<SingleEmailController>
) {
return PopupMenuItem(
padding: EdgeInsets.zero,
child: popupItem(
child: PopupItemWidget(
mailboxContain?.isSpam == true ? imagePaths.icNotSpam : imagePaths.icSpam,
mailboxContain?.isSpam == true
? AppLocalizations.of(context).remove_from_spam
@@ -602,7 +601,7 @@ class EmailView extends GetWidget<SingleEmailController>
PopupMenuEntry _quickCreatingRulePopupItemAction(BuildContext context, PresentationEmail email) {
return PopupMenuItem(
padding: EdgeInsets.zero,
child: popupItem(
child: PopupItemWidget(
imagePaths.icQuickCreatingRule,
AppLocalizations.of(context).quickCreatingRule,
colorIcon: AppColor.colorTextButton,
@@ -1,5 +1,19 @@
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
enum MailboxSubscribeAction {
subscribe,
unSubscribe,
undo
undo;
String getToastMessageSuccess(BuildContext context) {
switch(this) {
case MailboxSubscribeAction.subscribe:
return AppLocalizations.of(context).toastMessageShowMailboxSuccess;
case MailboxSubscribeAction.unSubscribe:
return AppLocalizations.of(context).toastMsgHideMailboxSuccess;
case MailboxSubscribeAction.undo:
return '';
}
}
}
@@ -52,7 +52,6 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/rename_mailbox_in
import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_multiple_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/action/mailbox_ui_action.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/extensions/list_mailbox_node_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';
@@ -993,29 +992,11 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM
await refreshTree(_mailboxList);
}
SubscribeRequest? _generateSubscribeRequest(
MailboxId mailboxId,
MailboxSubscribeState subscribeState,
MailboxSubscribeAction subscribeAction
) {
final mailboxNode = findMailboxNodeById(mailboxId);
if (mailboxNode != null) {
if (mailboxNode.hasChildren()) {
final listDescendantMailboxIds = mailboxNode.descendantsAsList().mailboxIds;
return SubscribeMultipleMailboxRequest(mailboxId, listDescendantMailboxIds, subscribeState, subscribeAction);
} else {
return SubscribeMailboxRequest(mailboxId, subscribeState, subscribeAction);
}
}
return null;
}
void _unsubscribeMailboxAction(MailboxId mailboxId) {
final _accountId = mailboxDashBoardController.accountId.value;
if (_accountId != null) {
final subscribeRequest = _generateSubscribeRequest(
final subscribeRequest = generateSubscribeRequest(
mailboxId,
MailboxSubscribeState.disabled,
MailboxSubscribeAction.unSubscribe
@@ -1146,25 +1127,4 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM
}
}
}
MailboxActions _mailboxActionForSpam() {
return mailboxDashBoardController.enableSpamReport
? MailboxActions.disableSpamReport
: MailboxActions.enableSpamReport;
}
List<MailboxActions> listActionForMailbox(PresentationMailbox mailbox) {
return [
if (BuildUtils.isWeb)
MailboxActions.openInNewTab,
if (mailbox.isSpam)
_mailboxActionForSpam(),
MailboxActions.markAsRead,
MailboxActions.move,
MailboxActions.rename,
MailboxActions.delete,
if (mailbox.isSupportedDisableMailbox)
MailboxActions.disableMailbox
];
}
}
@@ -6,18 +6,16 @@ import 'package:get/get.dart';
import 'package:model/model.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_controller.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/context_item_mailbox_action.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/mixin/mailbox_widget_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/mailbox/presentation/widgets/bottom_bar_selection_mailbox_widget.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_bottom_sheet_action_tile_builder.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_folder_tile_builder.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/user_information_widget_builder.dart';
import 'package:tmail_ui_user/features/quotas/presentation/widget/quotas_footer_widget.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class MailboxView extends GetWidget<MailboxController> {
class MailboxView extends GetWidget<MailboxController> with MailboxWidgetMixin {
final _imagePaths = Get.find<ImagePaths>();
final _responsiveUtils = Get.find<ResponsiveUtils>();
@@ -328,95 +326,54 @@ class MailboxView extends GetWidget<MailboxController> {
]);
}
MailboxActions _mailboxActionForSpam() {
return controller.mailboxDashBoardController.enableSpamReport
? MailboxActions.disableSpamReport
: MailboxActions.enableSpamReport;
}
List<MailboxActions> _listActionForMailbox(PresentationMailbox mailbox) {
return [
if (BuildUtils.isWeb)
MailboxActions.openInNewTab,
if (mailbox.isSpam)
_mailboxActionForSpam(),
MailboxActions.markAsRead,
MailboxActions.move,
MailboxActions.rename,
MailboxActions.delete,
if (mailbox.isSupportedDisableMailbox)
MailboxActions.disableMailbox
];
}
void _openBottomSheetMailboxMenuAction(BuildContext context, PresentationMailbox mailbox) {
final mailboxActionsSupported = _listActionForMailbox(mailbox);
final listContextMailboxPopupMenuItemAction = mailboxActionsSupported
.map((action) => ContextMenuItemMailboxAction(action, action.getContextMenuItemState(mailbox)))
.toList();
controller.openContextMenuAction(
context,
_bottomSheetMailboxActionTiles(
context,
mailbox,
listContextMailboxPopupMenuItemAction
)
);
}
List<Widget> _bottomSheetMailboxActionTiles(
BuildContext context,
PresentationMailbox mailbox,
List<ContextMenuItemMailboxAction> contextMenuActions
) {
return contextMenuActions
.map((action) => _openBottomSheetMailboxMenuActionTile(context, action, mailbox))
.toList();
}
Widget _openBottomSheetMailboxMenuActionTile(
BuildContext context,
ContextMenuItemMailboxAction contextMenuItem,
PresentationMailbox mailbox
) {
return (MailboxBottomSheetActionTileBuilder(
Key('${contextMenuItem.action.name}_action'),
SvgPicture.asset(
contextMenuItem.action.getContextMenuIcon(_imagePaths),
color: AppColor.primaryColor),
contextMenuItem.action.getTitleContextMenu(context),
mailbox,
absorbing: !contextMenuItem.isActivated,
opacity: !contextMenuItem.isActivated)
..onActionClick((mailbox) => controller.handleMailboxAction(context, contextMenuItem.action, mailbox)))
.build();
}
List<Widget> _buildListChildTileWidget(BuildContext context, MailboxNode parentNode, {MailboxNode? lastNode}) {
return parentNode.childrenItems
?.map((mailboxNode) => mailboxNode.hasChildren()
? TreeViewChild(
?.map((mailboxNode) {
if (mailboxNode.hasChildren()) {
return TreeViewChild(
context,
key: const Key('children_tree_mailbox_child'),
isExpanded: mailboxNode.expandMode == ExpandMode.EXPAND,
parent: Obx(() => (MailBoxFolderTileBuilder(
context,
_imagePaths,
mailboxNode,
lastNode: lastNode,
allSelectMode: controller.currentSelectMode.value)
..addOnLongPressMailboxNodeAction((mailboxNode) {
openMailboxMenuActionOnMobile(
context,
_imagePaths,
mailboxNode.item,
controller
);
})
..addOnClickOpenMailboxNodeAction((mailboxNode) => controller.openMailbox(context, mailboxNode.item))
..addOnClickExpandMailboxNodeAction((mailboxNode) => controller.toggleMailboxFolder(mailboxNode))
..addOnSelectMailboxNodeAction((mailboxNode) => controller.selectMailboxNode(mailboxNode))
).build()),
children: _buildListChildTileWidget(context, mailboxNode)
).build();
} else {
return Obx(() => (MailBoxFolderTileBuilder(
context,
key: const Key('children_tree_mailbox_child'),
isExpanded: mailboxNode.expandMode == ExpandMode.EXPAND,
parent: Obx(() => (MailBoxFolderTileBuilder(context, _imagePaths, mailboxNode, lastNode: lastNode,
allSelectMode: controller.currentSelectMode.value)
..addOnLongPressMailboxNodeAction((mailboxNode) => _openBottomSheetMailboxMenuAction(context, mailboxNode.item))
..addOnClickOpenMailboxNodeAction((mailboxNode) => controller.openMailbox(context, mailboxNode.item))
..addOnClickExpandMailboxNodeAction((mailboxNode) => controller.toggleMailboxFolder(mailboxNode))
..addOnSelectMailboxNodeAction((mailboxNode) => controller.selectMailboxNode(mailboxNode)))
.build()),
children: _buildListChildTileWidget(context, mailboxNode)
).build()
: Obx(() => (MailBoxFolderTileBuilder(context, _imagePaths, mailboxNode, lastNode: lastNode,
_imagePaths,
mailboxNode,
lastNode: lastNode,
allSelectMode: controller.currentSelectMode.value)
..addOnLongPressMailboxNodeAction((mailboxNode) => _openBottomSheetMailboxMenuAction(context, mailboxNode.item))
..addOnLongPressMailboxNodeAction((mailboxNode) {
openMailboxMenuActionOnMobile(
context,
_imagePaths,
mailboxNode.item,
controller
);
})
..addOnClickOpenMailboxNodeAction((mailboxNode) => controller.openMailbox(context, mailboxNode.item))
..addOnSelectMailboxNodeAction((mailboxNode) => controller.selectMailboxNode(mailboxNode)))
.build())
).toList() ?? <Widget>[];
..addOnSelectMailboxNodeAction((mailboxNode) => controller.selectMailboxNode(mailboxNode))
).build());
}
}).toList() ?? <Widget>[];
}
Widget _buildOptionSelectionMailbox(BuildContext context) {
@@ -5,13 +5,10 @@ import 'package:get/get.dart';
import 'package:model/model.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
import 'package:tmail_ui_user/features/base/mixin/popup_menu_widget_mixin.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_controller.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/context_item_mailbox_action.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/mixin/mailbox_widget_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/mailbox/presentation/widgets/mailbox_bottom_sheet_action_tile_builder.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_folder_tile_builder.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/user_information_widget_builder.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/app_dashboard/app_list_dashboard_item.dart';
@@ -19,7 +16,9 @@ import 'package:tmail_ui_user/features/quotas/presentation/widget/quotas_footer_
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/utils/app_config.dart';
class MailboxView extends GetWidget<MailboxController> with AppLoaderMixin, PopupMenuWidgetMixin {
class MailboxView extends GetWidget<MailboxController>
with AppLoaderMixin,
MailboxWidgetMixin {
final _imagePaths = Get.find<ImagePaths>();
final _responsiveUtils = Get.find<ResponsiveUtils>();
@@ -135,7 +134,10 @@ class MailboxView extends GetWidget<MailboxController> with AppLoaderMixin, Popu
const Divider(color: AppColor.colorDividerMailbox, height: 0.5, thickness: 0.2),
const SizedBox(height: 13),
Padding(
padding: EdgeInsets.only(left: _responsiveUtils.isDesktop(context) ? 0 : 12),
padding: EdgeInsets.only(
left: _responsiveUtils.isDesktop(context) ? 0 : 12,
bottom: 8
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@@ -170,24 +172,50 @@ class MailboxView extends GetWidget<MailboxController> with AppLoaderMixin, Popu
)),
]),
),
const SizedBox(height: 8),
Obx(() => controller.personalMailboxIsNotEmpty
? Column(
children: [
_buildHeaderMailboxCategory(context, MailboxCategories.personalMailboxes),
_buildMailboxCategory(context, MailboxCategories.personalMailboxes, controller.personalRootNode),
],
)
: const SizedBox.shrink()),
const SizedBox(height: 8),
Obx(() => controller.teamMailboxesIsNotEmpty
? Column(
children: [
_buildHeaderMailboxCategory(context, MailboxCategories.teamMailboxes),
_buildMailboxCategory(context, MailboxCategories.teamMailboxes, controller.teamMailboxesRootNode),
],
)
: const SizedBox.shrink()),
Obx(() {
if (controller.personalMailboxIsNotEmpty) {
return Padding(
padding: const EdgeInsets.only(bottom: 8),
child: Column(
children: [
_buildHeaderMailboxCategory(
context,
MailboxCategories.personalMailboxes
),
_buildMailboxCategory(
context,
MailboxCategories.personalMailboxes,
controller.personalRootNode
),
],
),
);
} else {
return const SizedBox.shrink();
}
}),
Obx(() {
if (controller.teamMailboxesIsNotEmpty) {
return Padding(
padding: const EdgeInsets.only(bottom: 8),
child: Column(
children: [
_buildHeaderMailboxCategory(
context,
MailboxCategories.teamMailboxes
),
_buildMailboxCategory(
context,
MailboxCategories.teamMailboxes,
controller.teamMailboxesRootNode
),
]
)
);
} else {
return const SizedBox.shrink();
}
})
])
),
Obx(() => controller.mailboxDashBoardController.isDraggingMailbox
@@ -284,39 +312,63 @@ class MailboxView extends GetWidget<MailboxController> with AppLoaderMixin, Popu
: const Offstage());
}
List<Widget> _buildListChildTileWidget(BuildContext context,
MailboxNode parentNode, {MailboxNode? lastNode}) {
return parentNode.childrenItems
?.map((mailboxNode) => mailboxNode.hasChildren()
? TreeViewChild(
List<Widget> _buildListChildTileWidget(
BuildContext context,
MailboxNode parentNode,
{MailboxNode? lastNode}
) {
return parentNode.childrenItems?.map((mailboxNode) {
if (mailboxNode.hasChildren()) {
return TreeViewChild(
context,
key: const Key('children_tree_mailbox_child'),
isExpanded: mailboxNode.expandMode == ExpandMode.EXPAND,
parent: Obx(() => (MailBoxFolderTileBuilder(
context,
key: const Key('children_tree_mailbox_child'),
isExpanded: mailboxNode.expandMode == ExpandMode.EXPAND,
parent: Obx(() => (MailBoxFolderTileBuilder(context, _imagePaths, mailboxNode, lastNode: lastNode,
mailboxNodeSelected: controller.mailboxDashBoardController.selectedMailbox.value)
..addOnClickOpenMailboxNodeAction((mailboxNode) =>
controller.openMailbox(context, mailboxNode.item))
..addOnClickExpandMailboxNodeAction((mailboxNode) =>
controller.toggleMailboxFolder(mailboxNode))
..addOnClickOpenMenuMailboxNodeAction((position, mailboxNode) =>
_openMailboxMenuAction(context, position, mailboxNode.item))
..addOnSelectMailboxNodeAction((mailboxNode) =>
controller.selectMailboxNode(mailboxNode))
..addOnDragEmailToMailboxAccepted(_handleDragItemAccepted))
.build()),
children: _buildListChildTileWidget(context, mailboxNode)
).build()
: Obx(() => (MailBoxFolderTileBuilder(context, _imagePaths, mailboxNode, lastNode: lastNode,
mailboxNodeSelected: controller.mailboxDashBoardController.selectedMailbox.value)
..addOnClickOpenMailboxNodeAction((mailboxNode) =>
controller.openMailbox(context, mailboxNode.item))
..addOnClickOpenMenuMailboxNodeAction((position, mailboxNode) =>
_openMailboxMenuAction(context, position, mailboxNode.item))
..addOnSelectMailboxNodeAction((mailboxNode) =>
controller.selectMailboxNode(mailboxNode))
..addOnDragEmailToMailboxAccepted(_handleDragItemAccepted))
.build())
).toList() ?? <Widget>[];
_imagePaths,
mailboxNode,
lastNode: lastNode,
mailboxNodeSelected: controller.mailboxDashBoardController.selectedMailbox.value)
..addOnClickOpenMailboxNodeAction((mailboxNode) => controller.openMailbox(context, mailboxNode.item))
..addOnClickExpandMailboxNodeAction((mailboxNode) => controller.toggleMailboxFolder(mailboxNode))
..addOnClickOpenMenuMailboxNodeAction((position, mailboxNode) {
openMailboxMenuActionOnWeb(
context,
_imagePaths,
_responsiveUtils,
position,
mailboxNode.item,
controller
);
})
..addOnSelectMailboxNodeAction((mailboxNode) => controller.selectMailboxNode(mailboxNode))
..addOnDragEmailToMailboxAccepted(_handleDragItemAccepted)
).build()),
children: _buildListChildTileWidget(context, mailboxNode)
).build();
} else {
return Obx(() => (MailBoxFolderTileBuilder(
context,
_imagePaths,
mailboxNode,
lastNode: lastNode,
mailboxNodeSelected: controller.mailboxDashBoardController.selectedMailbox.value)
..addOnClickOpenMailboxNodeAction((mailboxNode) => controller.openMailbox(context, mailboxNode.item))
..addOnClickOpenMenuMailboxNodeAction((position, mailboxNode) {
openMailboxMenuActionOnWeb(
context,
_imagePaths,
_responsiveUtils,
position,
mailboxNode.item,
controller
);
})
..addOnSelectMailboxNodeAction((mailboxNode) => controller.selectMailboxNode(mailboxNode))
..addOnDragEmailToMailboxAccepted(_handleDragItemAccepted)
).build());
}
}).toList() ?? <Widget>[];
}
void _handleDragItemAccepted(List<PresentationEmail> listEmails, PresentationMailbox presentationMailbox) {
@@ -342,109 +394,6 @@ class MailboxView extends GetWidget<MailboxController> with AppLoaderMixin, Popu
);
}
void _openMailboxMenuAction(
BuildContext context,
RelativeRect position,
PresentationMailbox mailbox
) {
final mailboxActionsSupported = controller.listActionForMailbox(mailbox);
final listContextMenuItemAction = mailboxActionsSupported
.map((action) => ContextMenuItemMailboxAction(
action,
action.getContextMenuItemState(mailbox)))
.toList();
if (_responsiveUtils.isScreenWithShortestSide(context)) {
controller.openContextMenuAction(
context,
_bottomSheetMailboxActionTiles(
context,
mailbox,
listContextMenuItemAction));
} else {
controller.openPopupMenuAction(
context,
position,
_popupMenuMailboxActionTiles(
context,
mailbox,
listContextMenuItemAction));
}
}
List<Widget> _bottomSheetMailboxActionTiles(
BuildContext context,
PresentationMailbox mailbox,
List<ContextMenuItemMailboxAction> contextMenuActions
) {
return contextMenuActions
.map((action) => _mailboxContextMenuActionTile(context, action, mailbox))
.toList();
}
Widget _mailboxContextMenuActionTile(
BuildContext context,
ContextMenuItemMailboxAction contextMenuItem,
PresentationMailbox mailbox
) {
return (MailboxBottomSheetActionTileBuilder(
Key('${contextMenuItem.action.name}_action'),
SvgPicture.asset(
contextMenuItem.action.getContextMenuIcon(_imagePaths),
color: contextMenuItem.action.getColorContextMenuIcon(),
width: 24,
height: 24
),
contextMenuItem.action.getTitleContextMenu(context),
mailbox,
absorbing: !contextMenuItem.isActivated,
opacity: !contextMenuItem.isActivated)
..actionTextStyle(textStyle: const TextStyle(
fontSize: 16,
color: Colors.black,
fontWeight: FontWeight.w500
))
..onActionClick((mailbox) => controller.handleMailboxAction(context, contextMenuItem.action, mailbox)))
.build();
}
List<PopupMenuEntry> _popupMenuMailboxActionTiles(
BuildContext context,
PresentationMailbox mailbox,
List<ContextMenuItemMailboxAction> contextMenuActions
) {
return contextMenuActions
.map((action) => _mailboxPopupMenuActionTile(context, action, mailbox))
.toList();
}
PopupMenuItem _mailboxPopupMenuActionTile(
BuildContext context,
ContextMenuItemMailboxAction contextMenuItem,
PresentationMailbox mailbox
) {
return PopupMenuItem(
padding: EdgeInsets.zero,
child: AbsorbPointer(
absorbing: !contextMenuItem.isActivated,
child: Opacity(
opacity: contextMenuItem.isActivated ? 1.0 : 0.3,
child: popupItem(
contextMenuItem.action.getContextMenuIcon(_imagePaths),
contextMenuItem.action.getTitleContextMenu(context),
colorIcon: contextMenuItem.action.getColorContextMenuIcon(),
styleName: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 16,
color: contextMenuItem.action.getColorContextMenuTitle()
),
onCallbackAction: () => controller.handleMailboxAction(context, contextMenuItem.action, mailbox)
),
),
));
}
Widget _buildAppGridDashboard(BuildContext context) {
return Column(
children: [
@@ -452,9 +401,12 @@ class MailboxView extends GetWidget<MailboxController> with AppLoaderMixin, Popu
AnimatedContainer(
padding: const EdgeInsets.only(top: 8),
duration: const Duration(milliseconds: 400),
child: controller.mailboxDashBoardController.appGridDashboardController.appDashboardExpandMode.value == ExpandMode.EXPAND
? _buildAppGridInMailboxView(context)
: const Offstage())
child: Obx(() {
return controller.mailboxDashBoardController.appGridDashboardController.appDashboardExpandMode.value == ExpandMode.EXPAND
? _buildAppGridInMailboxView(context)
: const Offstage();
})
)
]);
}
@@ -0,0 +1,217 @@
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/utils/build_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/base/widget/popup_item_widget.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_controller.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/context_item_mailbox_action.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_bottom_sheet_action_tile_builder.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
mixin MailboxWidgetMixin {
MailboxActions _mailboxActionForSpam(MailboxDashBoardController dashBoardController) {
return dashBoardController.enableSpamReport
? MailboxActions.disableSpamReport
: MailboxActions.enableSpamReport;
}
List<MailboxActions> listActionForMailbox(
PresentationMailbox mailbox,
MailboxDashBoardController dashBoardController
) {
return [
if (BuildUtils.isWeb)
MailboxActions.openInNewTab,
if (mailbox.isSpam)
_mailboxActionForSpam(dashBoardController),
MailboxActions.markAsRead,
MailboxActions.move,
MailboxActions.rename,
MailboxActions.delete,
if (mailbox.isSupportedDisableMailbox)
MailboxActions.disableMailbox
];
}
void openMailboxMenuActionOnMobile(
BuildContext context,
ImagePaths imagePaths,
PresentationMailbox mailbox,
MailboxController controller
) {
final contextMenuActions = listContextMenuItemAction(mailbox, controller.mailboxDashBoardController);
controller.openContextMenuAction(
context,
contextMenuMailboxActionTiles(
context,
imagePaths,
mailbox,
contextMenuActions,
handleMailboxAction: controller.handleMailboxAction
)
);
}
List<Widget> contextMenuMailboxActionTiles(
BuildContext context,
ImagePaths imagePaths,
PresentationMailbox mailbox,
List<ContextMenuItemMailboxAction> contextMenuActions,
{
required Function(BuildContext, MailboxActions, PresentationMailbox) handleMailboxAction
}
) {
return contextMenuActions
.map((action) => _buildContextMenuActionTile(
context,
imagePaths,
action,
mailbox,
handleMailboxAction: handleMailboxAction
))
.toList();
}
Widget _buildContextMenuActionTile(
BuildContext context,
ImagePaths imagePaths,
ContextMenuItemMailboxAction contextMenuItem,
PresentationMailbox mailbox,
{
required Function(BuildContext, MailboxActions, PresentationMailbox) handleMailboxAction
}
) {
return (MailboxBottomSheetActionTileBuilder(
Key('${contextMenuItem.action.name}_action'),
SvgPicture.asset(
contextMenuItem.action.getContextMenuIcon(imagePaths),
color: contextMenuItem.action.getColorContextMenuIcon(),
width: 24,
height: 24
),
contextMenuItem.action.getTitleContextMenu(context),
mailbox,
absorbing: !contextMenuItem.isActivated,
opacity: !contextMenuItem.isActivated)
..actionTextStyle(textStyle: TextStyle(
fontSize: 16,
color: contextMenuItem.action.getColorContextMenuTitle(),
fontWeight: FontWeight.w500
))
..onActionClick((mailbox) => handleMailboxAction(context, contextMenuItem.action, mailbox))
).build();
}
List<ContextMenuItemMailboxAction> listContextMenuItemAction(
PresentationMailbox mailbox,
MailboxDashBoardController dashBoardController,
{
List<MailboxActions>? mailboxActions
}
) {
final mailboxActionsSupported = mailboxActions ?? listActionForMailbox(
mailbox,
dashBoardController
);
final listContextMenuItemAction = mailboxActionsSupported
.map((action) => ContextMenuItemMailboxAction(action, action.getContextMenuItemState(mailbox)))
.toList();
return listContextMenuItemAction;
}
void openMailboxMenuActionOnWeb(
BuildContext context,
ImagePaths imagePaths,
ResponsiveUtils responsiveUtils,
RelativeRect position,
PresentationMailbox mailbox,
MailboxController controller
) {
final contextMenuActions = listContextMenuItemAction(mailbox, controller.mailboxDashBoardController);
if (responsiveUtils.isScreenWithShortestSide(context)) {
controller.openContextMenuAction(
context,
contextMenuMailboxActionTiles(
context,
imagePaths,
mailbox,
contextMenuActions,
handleMailboxAction: controller.handleMailboxAction
)
);
} else {
controller.openPopupMenuAction(
context,
position,
popupMenuMailboxActionTiles(
context,
imagePaths,
mailbox,
contextMenuActions,
handleMailboxAction: controller.handleMailboxAction
)
);
}
}
List<PopupMenuEntry> popupMenuMailboxActionTiles(
BuildContext context,
ImagePaths imagePaths,
PresentationMailbox mailbox,
List<ContextMenuItemMailboxAction> contextMenuActions,
{
required Function(BuildContext, MailboxActions, PresentationMailbox) handleMailboxAction
}
) {
return contextMenuActions
.map((action) => _buildPopupMenuItem(
context,
imagePaths,
action,
mailbox,
handleMailboxAction: handleMailboxAction
))
.toList();
}
PopupMenuItem _buildPopupMenuItem(
BuildContext context,
ImagePaths imagePaths,
ContextMenuItemMailboxAction contextMenuItem,
PresentationMailbox mailbox,
{
required Function(BuildContext, MailboxActions, PresentationMailbox) handleMailboxAction
}
) {
return PopupMenuItem(
padding: EdgeInsets.zero,
child: AbsorbPointer(
absorbing: !contextMenuItem.isActivated,
child: Opacity(
opacity: contextMenuItem.isActivated ? 1.0 : 0.3,
child: PopupItemWidget(
contextMenuItem.action.getContextMenuIcon(imagePaths),
contextMenuItem.action.getTitleContextMenu(context),
colorIcon: contextMenuItem.action.getColorContextMenuIcon(),
iconSize: 24,
styleName: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 16,
color: contextMenuItem.action.getColorContextMenuTitle()
),
onCallbackAction: () => handleMailboxAction(context, contextMenuItem.action, mailbox)
),
),
)
);
}
}
@@ -17,7 +17,8 @@ enum MailboxActions {
openInNewTab,
disableSpamReport,
enableSpamReport,
disableMailbox
disableMailbox,
enableMailbox
}
extension MailboxActionsExtension on MailboxActions {
@@ -55,6 +56,8 @@ extension MailboxActionsExtension on MailboxActions {
return AppLocalizations.of(context).deleteMailbox;
case MailboxActions.disableMailbox:
return AppLocalizations.of(context).hideMailBoxes;
case MailboxActions.enableMailbox:
return AppLocalizations.of(context).showMailbox;
default:
return '';
}
@@ -78,6 +81,8 @@ extension MailboxActionsExtension on MailboxActions {
return imagePaths.icDeleteMailbox;
case MailboxActions.disableMailbox:
return imagePaths.icHideMailbox;
case MailboxActions.enableMailbox:
return imagePaths.icShowMailbox;
default:
return '';
}
@@ -142,9 +147,10 @@ extension MailboxActionsExtension on MailboxActions {
case MailboxActions.openInNewTab:
case MailboxActions.disableSpamReport:
case MailboxActions.enableSpamReport:
return mailbox.isPersonal
? ContextMenuItemState.activated
: ContextMenuItemState.deactivated;
return mailbox.isPersonal
? ContextMenuItemState.activated
: ContextMenuItemState.deactivated;
case MailboxActions.enableMailbox:
case MailboxActions.disableMailbox:
return mailbox.hasRole()
? ContextMenuItemState.deactivated
@@ -156,7 +162,7 @@ extension MailboxActionsExtension on MailboxActions {
case MailboxActions.move:
case MailboxActions.rename:
case MailboxActions.delete:
return !mailbox.hasRole() && mailbox.isPersonal
return !mailbox.hasRole() && mailbox.isPersonal
? ContextMenuItemState.activated
: ContextMenuItemState.deactivated;
default:
@@ -133,7 +133,7 @@ class MailBoxFolderTileBuilder {
child: Material(
color: Colors.transparent,
child: InkWell(
onLongPress: () => _onLongPressMailboxFolderClick?.call(_mailboxNode),
onLongPress: () => _onLongPressMailboxNodeAction?.call(_mailboxNode),
onTap: () => allSelectMode == SelectMode.ACTIVE
? _onSelectMailboxFolderClick?.call(_mailboxNode)
: _onOpenMailboxFolderClick?.call(_mailboxNode),
@@ -191,7 +191,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
: const SizedBox.shrink()
),
Obx(() => controller.searchMailboxActivated.value == true && !responsiveUtils.isWebDesktop(context)
? const PointerInterceptor(child: SearchMailboxView())
? const SearchMailboxView()
: const SizedBox.shrink()
),
_buildDownloadTaskStateWidget(),
@@ -20,6 +20,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailb
import 'package:tmail_ui_user/features/mailbox/domain/usecases/rename_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/search_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_multiple_mailbox_interactor.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/search/mailbox/presentation/search_mailbox_controller.dart';
@@ -38,6 +39,7 @@ class SearchMailboxBindings extends BaseBindings {
Get.find<MoveMailboxInteractor>(),
Get.find<DeleteMultipleMailboxInteractor>(),
Get.find<SubscribeMailboxInteractor>(),
Get.find<SubscribeMultipleMailboxInteractor>(),
Get.find<TreeBuilder>(),
Get.find<VerifyNameInteractor>()
));
@@ -76,6 +78,7 @@ class SearchMailboxBindings extends BaseBindings {
Get.lazyPut(() => VerifyNameInteractor());
Get.lazyPut(() => SearchMailboxInteractor());
Get.lazyPut(() => SubscribeMailboxInteractor(Get.find<MailboxRepository>()));
Get.lazyPut(() => SubscribeMultipleMailboxInteractor(Get.find<MailboxRepository>()));
}
@override
@@ -13,6 +13,8 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/email/presentation_email.dart';
import 'package:model/extensions/presentation_email_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/base/base_mailbox_controller.dart';
import 'package:debounce_throttle/debounce_throttle.dart';
@@ -23,6 +25,8 @@ import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subscribe_st
import 'package:tmail_ui_user/features/mailbox/domain/model/move_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.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/state/delete_multiple_mailbox_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/get_all_mailboxes_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/mark_as_mailbox_read_state.dart';
@@ -31,6 +35,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/state/refresh_changes_all_
import 'package:tmail_ui_user/features/mailbox/domain/state/rename_mailbox_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/search_mailbox_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/subscribe_mailbox_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/subscribe_multiple_mailbox_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/delete_multiple_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_all_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_mailbox_interactor.dart';
@@ -38,12 +43,14 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailb
import 'package:tmail_ui_user/features/mailbox/domain/usecases/rename_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/search_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_multiple_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/action/mailbox_ui_action.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_builder.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_utils.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_routes.dart';
import 'package:tmail_ui_user/features/search/mailbox/presentation/search_mailbox_bindings.dart';
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
@@ -59,6 +66,7 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
final MoveMailboxInteractor _moveMailboxInteractor;
final DeleteMultipleMailboxInteractor _deleteMultipleMailboxInteractor;
final SubscribeMailboxInteractor _subscribeMailboxInteractor;
final SubscribeMultipleMailboxInteractor _subscribeMultipleMailboxInteractor;
final dashboardController = Get.find<MailboxDashBoardController>();
final responsiveUtils = Get.find<ResponsiveUtils>();
@@ -70,6 +78,10 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
final textInputSearchController = TextEditingController();
late Debouncer<String> _deBouncerTime;
PresentationMailbox? get selectedMailbox => dashboardController.selectedMailbox.value;
PresentationEmail? get selectedEmail => dashboardController.selectedEmail.value;
SearchMailboxController(
this._getAllMailboxInteractor,
this._refreshAllMailboxInteractor,
@@ -78,6 +90,7 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
this._moveMailboxInteractor,
this._deleteMultipleMailboxInteractor,
this._subscribeMailboxInteractor,
this._subscribeMultipleMailboxInteractor,
TreeBuilder treeBuilder,
VerifyNameInteractor verifyNameInteractor
) : super(treeBuilder, verifyNameInteractor);
@@ -126,12 +139,16 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
refreshMailboxChanges(mailboxState: success.currentMailboxState);
} else if (success is MoveMailboxSuccess) {
_moveMailboxSuccess(success);
}else if (success is DeleteMultipleMailboxAllSuccess) {
} else if (success is DeleteMultipleMailboxAllSuccess) {
_deleteMultipleMailboxSuccess(success.listMailboxIdDeleted, success.currentMailboxState);
} else if (success is DeleteMultipleMailboxHasSomeSuccess) {
_deleteMultipleMailboxSuccess(success.listMailboxIdDeleted, success.currentMailboxState);
} else if (success is SubscribeMailboxSuccess) {
_handleSubscribeMailboxSuccess(success);
} else if (success is SubscribeMultipleMailboxAllSuccess) {
_handleSubscribeMultipleMailboxAllSuccess(success);
} else if (success is SubscribeMultipleMailboxHasSomeSuccess) {
_handleSubscribeMultipleMailboxHasSomeSuccess(success);
}
}
@@ -222,7 +239,7 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
case MailboxActions.disableSpamReport:
case MailboxActions.enableSpamReport:
dashboardController.storeSpamReportStateAction();
return;
break;
case MailboxActions.markAsRead:
markAsReadMailboxAction(context, mailbox, dashboardController);
break;
@@ -252,11 +269,18 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
);
break;
case MailboxActions.disableMailbox:
_subscribeMailboxAction(SubscribeMailboxRequest(
_updateSubscribeStateOfMailboxAction(
mailbox.id,
MailboxSubscribeState.disabled,
MailboxSubscribeAction.unSubscribe
));
);
break;
case MailboxActions.enableMailbox:
_updateSubscribeStateOfMailboxAction(
mailbox.id,
MailboxSubscribeState.enabled,
MailboxSubscribeAction.subscribe
);
break;
default:
break;
@@ -394,26 +418,105 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
}
}
void _subscribeMailboxAction(SubscribeMailboxRequest subscribeMailboxRequest) {
void _updateSubscribeStateOfMailboxAction(
MailboxId mailboxId,
MailboxSubscribeState subscribeState,
MailboxSubscribeAction subscribeAction
) {
final _accountId = dashboardController.accountId.value;
if (_accountId != null) {
consumeState(_subscribeMailboxInteractor.execute(
_accountId,
subscribeMailboxRequest
));
final subscribeRequest = generateSubscribeRequest(mailboxId, subscribeState, subscribeAction);
if (subscribeRequest is SubscribeMultipleMailboxRequest) {
consumeState(_subscribeMultipleMailboxInteractor.execute(_accountId, subscribeRequest));
} else if (subscribeRequest is SubscribeMailboxRequest) {
consumeState(_subscribeMailboxInteractor.execute(_accountId, subscribeRequest));
}
}
}
void openMailboxAction(BuildContext context, PresentationMailbox mailbox) {
FocusScope.of(context).unfocus();
dashboardController.openMailboxAction(context, mailbox);
if (!responsiveUtils.isWebDesktop(context)) {
closeSearchView(context);
}
}
void _handleSubscribeMailboxSuccess(SubscribeMailboxSuccess success) {
if(success.mailboxSubscribeStateAction == MailboxSubscribeAction.unSubscribe
&& currentOverlayContext != null
&& currentContext != null
) {
if (success.subscribeAction != MailboxSubscribeAction.undo) {
_showToastSubscribeMailboxSuccess(success.mailboxId, success.subscribeAction);
if (success.mailboxId == selectedMailbox?.id) {
dashboardController.selectedMailbox.value = null;
dashboardController.dispatchMailboxUIAction(SelectMailboxDefaultAction());
_closeEmailViewIfMailboxDisabledOrNotExist([success.mailboxId]);
}
}
refreshMailboxChanges(mailboxState: success.currentMailboxState);
}
void _handleSubscribeMultipleMailboxAllSuccess(SubscribeMultipleMailboxAllSuccess success) {
if(success.subscribeAction != MailboxSubscribeAction.undo) {
_showToastSubscribeMailboxSuccess(
success.parentMailboxId,
success.subscribeAction,
listDescendantMailboxIds: success.mailboxIdsSubscribe
);
if (success.mailboxIdsSubscribe.contains(selectedMailbox?.id)) {
dashboardController.selectedMailbox.value = null;
dashboardController.dispatchMailboxUIAction(SelectMailboxDefaultAction());
_closeEmailViewIfMailboxDisabledOrNotExist(success.mailboxIdsSubscribe);
}
}
refreshMailboxChanges(mailboxState: success.currentMailboxState);
}
void _handleSubscribeMultipleMailboxHasSomeSuccess(SubscribeMultipleMailboxHasSomeSuccess success) {
if(success.subscribeAction != MailboxSubscribeAction.undo) {
_showToastSubscribeMailboxSuccess(
success.parentMailboxId,
success.subscribeAction,
listDescendantMailboxIds: success.mailboxIdsSubscribe
);
if (success.mailboxIdsSubscribe.contains(selectedMailbox?.id)) {
dashboardController.selectedMailbox.value = null;
dashboardController.dispatchMailboxUIAction(SelectMailboxDefaultAction());
_closeEmailViewIfMailboxDisabledOrNotExist(success.mailboxIdsSubscribe);
}
}
refreshMailboxChanges(mailboxState: success.currentMailboxState);
}
void _showToastSubscribeMailboxSuccess(
MailboxId mailboxIdSubscribed,
MailboxSubscribeAction subscribeAction,
{List<MailboxId>? listDescendantMailboxIds}
) {
if (currentOverlayContext != null && currentContext != null) {
_appToast.showBottomToast(
currentOverlayContext!,
AppLocalizations.of(currentContext!).toastMsgHideMailboxSuccess,
subscribeAction.getToastMessageSuccess(currentContext!),
actionName: AppLocalizations.of(currentContext!).undo,
onActionClick: () => _invokeUndoUnsubscribeMailboxAction(success.mailboxId),
onActionClick: () {
if (subscribeAction == MailboxSubscribeAction.unSubscribe) {
_undoUnsubscribeMailboxAction(
mailboxIdSubscribed,
listDescendantMailboxIds: listDescendantMailboxIds
);
} else {
_undoSubscribeMailboxAction(
mailboxIdSubscribed,
listDescendantMailboxIds: listDescendantMailboxIds
);
}
},
leadingIcon: SvgPicture.asset(
imagePaths.icFolderMailbox,
width: 24,
@@ -428,24 +531,79 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
maxWidth: responsiveUtils.getMaxWidthToast(currentContext!)
);
}
refreshMailboxChanges(mailboxState: success.currentMailboxState);
}
void _invokeUndoUnsubscribeMailboxAction(MailboxId mailboxId) {
_subscribeMailboxAction(SubscribeMailboxRequest(
mailboxId,
MailboxSubscribeState.enabled,
MailboxSubscribeAction.undo
));
void _undoUnsubscribeMailboxAction(
MailboxId mailboxIdSubscribed,
{List<MailboxId>? listDescendantMailboxIds}
) {
final _accountId = dashboardController.accountId.value;
if (_accountId != null) {
SubscribeRequest? subscribeRequest;
if (listDescendantMailboxIds != null) {
subscribeRequest = SubscribeMultipleMailboxRequest(
mailboxIdSubscribed,
listDescendantMailboxIds,
MailboxSubscribeState.enabled,
MailboxSubscribeAction.undo
);
} else {
subscribeRequest = SubscribeMailboxRequest(
mailboxIdSubscribed,
MailboxSubscribeState.enabled,
MailboxSubscribeAction.undo
);
}
if (subscribeRequest is SubscribeMultipleMailboxRequest) {
consumeState(_subscribeMultipleMailboxInteractor.execute(_accountId, subscribeRequest));
} else if (subscribeRequest is SubscribeMailboxRequest) {
consumeState(_subscribeMailboxInteractor.execute(_accountId, subscribeRequest));
}
}
}
void openMailboxAction(BuildContext context, PresentationMailbox mailbox) {
FocusScope.of(context).unfocus();
dashboardController.openMailboxAction(context, mailbox);
void _undoSubscribeMailboxAction(
MailboxId mailboxIdSubscribed,
{List<MailboxId>? listDescendantMailboxIds}
) {
final _accountId = dashboardController.accountId.value;
if (_accountId != null) {
SubscribeRequest? subscribeRequest;
if (!responsiveUtils.isWebDesktop(context)) {
closeSearchView(context);
if (listDescendantMailboxIds != null) {
subscribeRequest = SubscribeMultipleMailboxRequest(
mailboxIdSubscribed,
listDescendantMailboxIds,
MailboxSubscribeState.disabled,
MailboxSubscribeAction.undo
);
} else {
subscribeRequest = SubscribeMailboxRequest(
mailboxIdSubscribed,
MailboxSubscribeState.disabled,
MailboxSubscribeAction.undo
);
}
if (subscribeRequest is SubscribeMultipleMailboxRequest) {
consumeState(_subscribeMultipleMailboxInteractor.execute(_accountId, subscribeRequest));
} else if (subscribeRequest is SubscribeMailboxRequest) {
consumeState(_subscribeMailboxInteractor.execute(_accountId, subscribeRequest));
}
}
}
void _closeEmailViewIfMailboxDisabledOrNotExist(List<MailboxId> mailboxIdsDisabled) {
if (selectedEmail == null) {
return;
}
final mailboxContain = selectedEmail!.findMailboxContain(dashboardController.mapMailboxById);
if (mailboxContain != null && mailboxIdsDisabled.contains(mailboxContain.id)) {
dashboardController.clearSelectedEmail();
dashboardController.dispatchRoute(DashboardRoutes.thread);
}
}
@@ -8,19 +8,20 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:focused_menu_custom/modals.dart';
import 'package:get/get.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
import 'package:tmail_ui_user/features/base/mixin/popup_menu_widget_mixin.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/search_mailbox_state.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/mixin/mailbox_widget_mixin.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/context_item_mailbox_action.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_bottom_sheet_action_tile_builder.dart';
import 'package:tmail_ui_user/features/search/mailbox/presentation/search_mailbox_controller.dart';
import 'package:tmail_ui_user/features/search/mailbox/presentation/utils/search_mailbox_utils.dart';
import 'package:tmail_ui_user/features/search/mailbox/presentation/widgets/mailbox_searched_item_builder.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class SearchMailboxView extends GetWidget<SearchMailboxController>
with AppLoaderMixin, PopupMenuWidgetMixin {
with AppLoaderMixin,
MailboxWidgetMixin {
final Color? backgroundColor;
@@ -35,7 +36,7 @@ class SearchMailboxView extends GetWidget<SearchMailboxController>
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: BuildUtils.isWeb
? _buildSearchBody(context)
? PointerInterceptor(child: _buildSearchBody(context))
: SafeArea(child: _buildSearchBody(context)),
),
);
@@ -250,30 +251,14 @@ class SearchMailboxView extends GetWidget<SearchMailboxController>
);
}
MailboxActions _mailboxActionForSpam() {
return controller.dashboardController.enableSpamReport
? MailboxActions.disableSpamReport
: MailboxActions.enableSpamReport;
}
List<MailboxActions> _listActionForMailboxUnsubscribed() {
return [
MailboxActions.markAsRead
MailboxActions.enableMailbox
];
}
List<MailboxActions> _listActionForMailboxSubscribed(PresentationMailbox mailbox) {
return [
if (BuildUtils.isWeb)
MailboxActions.openInNewTab,
if (mailbox.isSpam)
_mailboxActionForSpam(),
MailboxActions.markAsRead,
MailboxActions.move,
MailboxActions.rename,
MailboxActions.delete,
MailboxActions.disableMailbox
];
return listActionForMailbox(mailbox, controller.dashboardController);
}
void _openMailboxMenuAction(
@@ -281,106 +266,39 @@ class SearchMailboxView extends GetWidget<SearchMailboxController>
PresentationMailbox mailbox,
{RelativeRect? position}
) {
final mailboxActionsSupported = mailbox.isSubscribed?.value == true
final mailboxActionsSupported = mailbox.supportedSubscribe
? _listActionForMailboxSubscribed(mailbox)
: _listActionForMailboxUnsubscribed();
final listContextMenuItemAction = mailboxActionsSupported
.map((action) => ContextMenuItemMailboxAction(action, action.getContextMenuItemState(mailbox)))
.toList();
final contextMenuActions = listContextMenuItemAction(
mailbox,
controller.dashboardController,
mailboxActions: mailboxActionsSupported
);
if (controller.responsiveUtils.isScreenWithShortestSide(context) || position == null) {
controller.openContextMenuAction(
context,
_bottomSheetMailboxActionTiles(
contextMenuMailboxActionTiles(
context,
controller.imagePaths,
mailbox,
listContextMenuItemAction
contextMenuActions,
handleMailboxAction: controller.handleMailboxAction
)
);
} else {
controller.openPopupMenuAction(
context,
position,
_popupMenuMailboxActionTiles(
popupMenuMailboxActionTiles(
context,
controller.imagePaths,
mailbox,
listContextMenuItemAction
contextMenuActions,
handleMailboxAction: controller.handleMailboxAction
)
);
}
}
List<Widget> _bottomSheetMailboxActionTiles(
BuildContext context,
PresentationMailbox mailbox,
List<ContextMenuItemMailboxAction> contextMenuActions
) {
return contextMenuActions
.map((action) => _mailboxContextMenuActionTile(context, action, mailbox))
.toList();
}
Widget _mailboxContextMenuActionTile(
BuildContext context,
ContextMenuItemMailboxAction contextMenuItem,
PresentationMailbox mailbox
) {
return (MailboxBottomSheetActionTileBuilder(
Key('${contextMenuItem.action.name}_action'),
SvgPicture.asset(
contextMenuItem.action.getContextMenuIcon(controller.imagePaths),
width: 24,
height: 24,
color: contextMenuItem.action.getColorContextMenuIcon()
),
contextMenuItem.action.getTitleContextMenu(context),
mailbox,
absorbing: !contextMenuItem.isActivated,
opacity: !contextMenuItem.isActivated)
..actionTextStyle(textStyle: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.black))
..onActionClick((mailbox) => controller.handleMailboxAction(context, contextMenuItem.action, mailbox))
).build();
}
List<PopupMenuEntry> _popupMenuMailboxActionTiles(
BuildContext context,
PresentationMailbox mailbox,
List<ContextMenuItemMailboxAction> contextMenuActions
) {
return contextMenuActions
.map((action) => _mailboxPopupMenuActionTile(context, action, mailbox))
.toList();
}
PopupMenuItem _mailboxPopupMenuActionTile(
BuildContext context,
ContextMenuItemMailboxAction contextMenuItem,
PresentationMailbox mailbox
) {
return PopupMenuItem(
padding: EdgeInsets.zero,
child: AbsorbPointer(
absorbing: !contextMenuItem.isActivated,
child: Opacity(
opacity: contextMenuItem.isActivated ? 1.0 : 0.3,
child: popupItem(
contextMenuItem.action.getContextMenuIcon(controller.imagePaths),
contextMenuItem.action.getTitleContextMenu(context),
colorIcon: contextMenuItem.action.getColorContextMenuIcon(),
iconSize: 24,
styleName: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 16,
color: contextMenuItem.action.getColorContextMenuTitle()
),
onCallbackAction: () => controller.handleMailboxAction(context, contextMenuItem.action, mailbox))
,
)
)
);
}
}
@@ -89,8 +89,7 @@ class _MailboxSearchedItemBuilderState extends State<MailboxSearchedItemBuilder>
]
)
)),
if (widget._presentationMailbox.isSubscribed?.value == true)
_buildMenuIcon(context)
_buildMenuIcon(context)
]
),
)
+45 -3
View File
@@ -1,5 +1,5 @@
{
"@@last_modified": "2023-02-03T16:28:53.514637",
"@@last_modified": "2023-02-10T03:40:25.843946",
"initializing_data": "Initializing data...",
"@initializing_data": {
"type": "text",
@@ -120,8 +120,8 @@
"placeholders_order": [],
"placeholders": {}
},
"myFolders": "My Folders",
"@myFolders": {
"personalMailboxes": "Personal mailboxes",
"@personalMailboxes": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
@@ -2680,10 +2680,52 @@
"placeholders_order": [],
"placeholders": {}
},
"mailBoxes": "Mailboxes",
"@mailBoxes": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"teamMailBoxes": "Team-mailboxes",
"@teamMailBoxes": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"hideMailBoxes": "Hide mailbox",
"@hideMailBoxes": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"thisImageCannotBeAdded": "This image cannot be added.",
"@thisImageCannotBeAdded": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"toastMsgHideMailboxSuccess": "This mailbox has been hidden from your primary mailbox",
"@toastMsgHideMailboxSuccess": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"searchForMailboxes": "Search for mailboxes",
"@searchForMailboxes": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"showMailbox": "Show mailbox",
"@showMailbox": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"toastMessageShowMailboxSuccess": "This mailbox is already displayed in your primary mailbox",
"@toastMessageShowMailboxSuccess": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
}
}
@@ -2792,4 +2792,17 @@ class AppLocalizations {
name: 'searchForMailboxes'
);
}
String get showMailbox {
return Intl.message(
'Show mailbox',
name: 'showMailbox'
);
}
String get toastMessageShowMailboxSuccess {
return Intl.message(
'This mailbox is already displayed in your primary mailbox',
name: 'toastMessageShowMailboxSuccess');
}
}