diff --git a/lib/features/base/widget/context_menu_item_action.dart b/lib/features/base/widget/context_menu_item_action.dart new file mode 100644 index 000000000..21df93a64 --- /dev/null +++ b/lib/features/base/widget/context_menu_item_action.dart @@ -0,0 +1,19 @@ + +import 'package:equatable/equatable.dart'; + +abstract class ContextMenuItemAction with EquatableMixin { + final T action; + final ContextMenuItemState state; + + ContextMenuItemAction(this.action, this.state); + + @override + List get props => [action, state]; + + bool get isActivated => state == ContextMenuItemState.activated; +} + +enum ContextMenuItemState { + activated, + deactivated +} \ No newline at end of file diff --git a/lib/features/mailbox/presentation/mailbox_view_web.dart b/lib/features/mailbox/presentation/mailbox_view_web.dart index 90fb3d141..dacbae15f 100644 --- a/lib/features/mailbox/presentation/mailbox_view_web.dart +++ b/lib/features/mailbox/presentation/mailbox_view_web.dart @@ -8,6 +8,7 @@ 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/email/presentation/model/composer_arguments.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/model/mailbox_categories.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart'; @@ -375,66 +376,102 @@ class MailboxView extends GetWidget with AppLoaderMixin, Popu ); } - void _openMailboxMenuAction(BuildContext context, RelativeRect position, - PresentationMailbox mailbox) { - final listMailboxActions = [ - if (mailbox.getCountUnReadEmails().isNotEmpty) MailboxActions.markAsRead, - if (!mailbox.hasRole()) MailboxActions.move, - if (!mailbox.hasRole()) MailboxActions.rename, - if (!mailbox.hasRole()) MailboxActions.delete, + void _openMailboxMenuAction( + BuildContext context, + RelativeRect position, + PresentationMailbox mailbox + ) { + final mailboxActionsSupported = [ + MailboxActions.markAsRead, + MailboxActions.move, + MailboxActions.rename, + MailboxActions.delete ]; - if (listMailboxActions.isNotEmpty) { - if (_responsiveUtils.isScreenWithShortestSide(context)) { - controller.openContextMenuAction(context, - _bottomSheetIdentityActionTiles(context, mailbox, listMailboxActions)); - } else { - controller.openPopupMenuAction(context, position, - _popupMenuMailboxActionTiles(context, mailbox, listMailboxActions)); - } + final listContextMenuItemAction = mailboxActionsSupported + .map((action) => ContextMenuItemMailboxAction( + action, + action.getContextMenuItemState(mailbox))) + .toList(); + + if (_responsiveUtils.isScreenWithShortestSide(context)) { + controller.openContextMenuAction( + context, + _bottomSheetIdentityActionTiles( + context, + mailbox, + listContextMenuItemAction)); + } else { + controller.openPopupMenuAction( + context, + position, + _popupMenuMailboxActionTiles( + context, + mailbox, + listContextMenuItemAction)); } } - List _bottomSheetIdentityActionTiles(BuildContext context, - PresentationMailbox mailbox, List listMailboxActions) { - return listMailboxActions + List _bottomSheetIdentityActionTiles( + BuildContext context, + PresentationMailbox mailbox, + List contextMenuActions + ) { + return contextMenuActions .map((action) => _mailboxContextMenuActionTile(context, action, mailbox)) .toList(); } - Widget _mailboxContextMenuActionTile(BuildContext context, MailboxActions actions, - PresentationMailbox mailbox) { + Widget _mailboxContextMenuActionTile( + BuildContext context, + ContextMenuItemMailboxAction contextMenuItem, + PresentationMailbox mailbox + ) { return (MailboxBottomSheetActionTileBuilder( - Key('${actions.name}_action'), + Key('${contextMenuItem.action.name}_action'), SvgPicture.asset( - actions.getContextMenuIcon(_imagePaths), - color: actions.getColorContextMenuIcon()), - actions.getTitleContextMenu(context), - mailbox) + contextMenuItem.action.getContextMenuIcon(_imagePaths), + color: contextMenuItem.action.getColorContextMenuIcon()), + contextMenuItem.action.getTitleContextMenu(context), + mailbox, + absorbing: !contextMenuItem.isActivated, + opacity: !contextMenuItem.isActivated) ..onActionClick((mailbox) => - controller.handleMailboxAction(context, actions, mailbox))) + controller.handleMailboxAction(context, contextMenuItem.action, mailbox))) .build(); } - List _popupMenuMailboxActionTiles(BuildContext context, - PresentationMailbox mailbox, List listMailboxActions) { - return listMailboxActions + List _popupMenuMailboxActionTiles( + BuildContext context, + PresentationMailbox mailbox, + List contextMenuActions + ) { + return contextMenuActions .map((action) => _mailboxPopupMenuActionTile(context, action, mailbox)) .toList(); } - PopupMenuItem _mailboxPopupMenuActionTile(BuildContext context, MailboxActions actions, - PresentationMailbox mailbox) { + PopupMenuItem _mailboxPopupMenuActionTile( + BuildContext context, + ContextMenuItemMailboxAction contextMenuItem, + PresentationMailbox mailbox + ) { return PopupMenuItem( padding: EdgeInsets.zero, - child: popupItem(actions.getContextMenuIcon(_imagePaths), - actions.getTitleContextMenu(context), - colorIcon: actions.getColorContextMenuIcon(), - styleName: TextStyle( - fontWeight: FontWeight.normal, - fontSize: 17, - color: actions.getColorContextMenuIcon()), - onCallbackAction: () => - controller.handleMailboxAction(context, actions, mailbox))); + 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.normal, + fontSize: 17, + color: contextMenuItem.action.getColorContextMenuIcon()), + onCallbackAction: () => + controller.handleMailboxAction(context, contextMenuItem.action, mailbox)), + ), + )); } } \ No newline at end of file diff --git a/lib/features/mailbox/presentation/model/context_item_mailbox_action.dart b/lib/features/mailbox/presentation/model/context_item_mailbox_action.dart new file mode 100644 index 000000000..60fba7bb1 --- /dev/null +++ b/lib/features/mailbox/presentation/model/context_item_mailbox_action.dart @@ -0,0 +1,7 @@ + +import 'package:tmail_ui_user/features/base/widget/context_menu_item_action.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart'; + +class ContextMenuItemMailboxAction extends ContextMenuItemAction { + ContextMenuItemMailboxAction(super.action, super.state); +} \ No newline at end of file diff --git a/lib/features/mailbox/presentation/model/mailbox_actions.dart b/lib/features/mailbox/presentation/model/mailbox_actions.dart index d7caeede0..e104b8e7e 100644 --- a/lib/features/mailbox/presentation/model/mailbox_actions.dart +++ b/lib/features/mailbox/presentation/model/mailbox_actions.dart @@ -1,6 +1,8 @@ import 'package:core/core.dart'; import 'package:flutter/material.dart'; +import 'package:model/mailbox/presentation_mailbox.dart'; +import 'package:tmail_ui_user/features/base/widget/context_menu_item_action.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; enum MailboxActions { @@ -113,4 +115,21 @@ extension MailboxActionsExtension on MailboxActions { return true; } } + + ContextMenuItemState getContextMenuItemState(PresentationMailbox mailbox) { + switch(this) { + case MailboxActions.markAsRead: + return mailbox.getCountUnReadEmails().isNotEmpty + ? ContextMenuItemState.activated + : ContextMenuItemState.deactivated; + case MailboxActions.move: + case MailboxActions.rename: + case MailboxActions.delete: + return mailbox.hasRole() + ? ContextMenuItemState.deactivated + : ContextMenuItemState.activated; + default: + return ContextMenuItemState.deactivated; + } + } } \ No newline at end of file diff --git a/lib/features/mailbox/presentation/widgets/mailbox_bottom_sheet_action_tile_builder.dart b/lib/features/mailbox/presentation/widgets/mailbox_bottom_sheet_action_tile_builder.dart index b39fa1890..5ce50281c 100644 --- a/lib/features/mailbox/presentation/widgets/mailbox_bottom_sheet_action_tile_builder.dart +++ b/lib/features/mailbox/presentation/widgets/mailbox_bottom_sheet_action_tile_builder.dart @@ -12,6 +12,8 @@ class MailboxBottomSheetActionTileBuilder extends CupertinoActionSheetActionBuil final Color? bgColor; final EdgeInsets? iconLeftPadding; final EdgeInsets? iconRightPadding; + final bool opacity; + final bool absorbing; MailboxBottomSheetActionTileBuilder( Key key, @@ -23,28 +25,36 @@ class MailboxBottomSheetActionTileBuilder extends CupertinoActionSheetActionBuil this.bgColor, this.iconLeftPadding, this.iconRightPadding, + this.opacity = false, + this.absorbing = false, } ) : super(key, actionIcon, actionName); @override Widget build() { - return Container( - color: bgColor ?? Colors.white, - child: MouseRegion( - cursor: BuildUtils.isWeb ? MaterialStateMouseCursor.clickable : MouseCursor.defer, - child: CupertinoActionSheetAction( - key: key, - child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ - Padding( - padding: iconLeftPadding ?? const EdgeInsets.only(left: 12, right: 16), - child: actionIcon), - Expanded(child: Text(actionName, textAlign: TextAlign.left, style: actionTextStyle())), - ]), - onPressed: () { - if (onCupertinoActionSheetActionClick != null) { - onCupertinoActionSheetActionClick!(presentationMailbox); - } - }, + return AbsorbPointer( + absorbing: absorbing, + child: Opacity( + opacity: opacity ? 0.3 : 1.0, + child: Container( + color: bgColor ?? Colors.white, + child: MouseRegion( + cursor: BuildUtils.isWeb ? MaterialStateMouseCursor.clickable : MouseCursor.defer, + child: CupertinoActionSheetAction( + key: key, + child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ + Padding( + padding: iconLeftPadding ?? const EdgeInsets.only(left: 12, right: 16), + child: actionIcon), + Expanded(child: Text(actionName, textAlign: TextAlign.left, style: actionTextStyle())), + ]), + onPressed: () { + if (onCupertinoActionSheetActionClick != null) { + onCupertinoActionSheetActionClick!(presentationMailbox); + } + }, + ), + ), ), ), );