From 08b327737b3699703ee6d5cd71346558c2ff6896 Mon Sep 17 00:00:00 2001 From: dab246 Date: Tue, 31 May 2022 15:20:51 +0700 Subject: [PATCH] TF-599 Apply action context menu for mailbox --- ...firmation_dialog_action_sheet_builder.dart | 41 +++++++----- .../popup_context_menu_action_mixin.dart | 13 ++-- ...cupertino_action_sheet_action_builder.dart | 29 +++++---- .../presentation/mailbox_controller.dart | 22 +++++++ .../presentation/mailbox_view_web.dart | 64 ++++++++++++++++++- .../presentation/model/mailbox_actions.dart | 43 +++++++++++++ ...lbox_bottom_sheet_action_tile_builder.dart | 52 +++++++++++++++ ...tity_bottom_sheet_action_tile_builder.dart | 29 +++++---- .../app_action_sheet_action_builder.dart | 21 +++--- ...cupertino_action_sheet_action_builder.dart | 35 +++++----- lib/l10n/intl_messages.arb | 14 +++- lib/main/localizations/app_localizations.dart | 13 ++++ 12 files changed, 301 insertions(+), 75 deletions(-) create mode 100644 lib/features/mailbox/presentation/widgets/mailbox_bottom_sheet_action_tile_builder.dart diff --git a/core/lib/presentation/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart b/core/lib/presentation/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart index 40dc2a552..99c42906e 100644 --- a/core/lib/presentation/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart +++ b/core/lib/presentation/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart @@ -57,29 +57,38 @@ class ConfirmationDialogActionSheetBuilder { Container( padding: EdgeInsets.symmetric(vertical: 8, horizontal: 10), color: Colors.white, - child: CupertinoActionSheetAction( - child: Text( - _messageText ?? '', - textAlign: TextAlign.center, - style: _styleMessage ?? TextStyle(fontSize: 14, color: AppColor.colorMessageConfirmDialog)), - onPressed: () => {}, + child: MouseRegion( + cursor: BuildUtils.isWeb ? MaterialStateMouseCursor.clickable : MouseCursor.defer, + child: CupertinoActionSheetAction( + child: Text( + _messageText ?? '', + textAlign: TextAlign.center, + style: _styleMessage ?? TextStyle(fontSize: 14, color: AppColor.colorMessageConfirmDialog)), + onPressed: () => {}, + ), ) ), Container( color: Colors.white, - child: CupertinoActionSheetAction( - child: Text( - _confirmText ?? '', - style: _styleConfirmButton ?? TextStyle(fontWeight: FontWeight.w500, fontSize: 20, color: AppColor.colorActionDeleteConfirmDialog)), - onPressed: () => _onConfirmActionClick?.call(), + child: MouseRegion( + cursor: BuildUtils.isWeb ? MaterialStateMouseCursor.clickable : MouseCursor.defer, + child: CupertinoActionSheetAction( + child: Text( + _confirmText ?? '', + style: _styleConfirmButton ?? TextStyle(fontWeight: FontWeight.w500, fontSize: 20, color: AppColor.colorActionDeleteConfirmDialog)), + onPressed: () => _onConfirmActionClick?.call(), + ), ) ), ], - cancelButton: CupertinoActionSheetAction( - child: Text( - _cancelText ?? '', - style: _styleCancelButton ?? TextStyle(fontWeight: FontWeight.w500, fontSize: 20, color: AppColor.colorActionCancelDialog)), - onPressed: () => _onCancelActionClick?.call(), + cancelButton: MouseRegion( + cursor: BuildUtils.isWeb ? MaterialStateMouseCursor.clickable : MouseCursor.defer, + child: CupertinoActionSheetAction( + child: Text( + _cancelText ?? '', + style: _styleCancelButton ?? TextStyle(fontWeight: FontWeight.w500, fontSize: 20, color: AppColor.colorActionCancelDialog)), + onPressed: () => _onCancelActionClick?.call(), + ), ), )) ); diff --git a/lib/features/base/mixin/popup_context_menu_action_mixin.dart b/lib/features/base/mixin/popup_context_menu_action_mixin.dart index d31beb9ca..cff30589d 100644 --- a/lib/features/base/mixin/popup_context_menu_action_mixin.dart +++ b/lib/features/base/mixin/popup_context_menu_action_mixin.dart @@ -25,11 +25,14 @@ mixin PopupContextMenuActionMixin { } Widget buildCancelButton(BuildContext context) { - return CupertinoActionSheetAction( - child: Text( - AppLocalizations.of(context).cancel, - style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 20, color: AppColor.colorTextButton)), - onPressed: () => popBack(), + return MouseRegion( + cursor: BuildUtils.isWeb ? MaterialStateMouseCursor.clickable : MouseCursor.defer, + child: CupertinoActionSheetAction( + child: Text( + AppLocalizations.of(context).cancel, + style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 20, color: AppColor.colorTextButton)), + onPressed: () => popBack(), + ), ); } } \ No newline at end of file diff --git a/lib/features/email/presentation/widgets/email_action_cupertino_action_sheet_action_builder.dart b/lib/features/email/presentation/widgets/email_action_cupertino_action_sheet_action_builder.dart index 873a7d5e3..7c317fdb7 100644 --- a/lib/features/email/presentation/widgets/email_action_cupertino_action_sheet_action_builder.dart +++ b/lib/features/email/presentation/widgets/email_action_cupertino_action_sheet_action_builder.dart @@ -30,19 +30,22 @@ class EmailActionCupertinoActionSheetActionBuilder extends CupertinoActionSheetA Widget build() { return Container( color: bgColor ?? Colors.white, - 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!(presentationEmail); - } - }, + 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!(presentationEmail); + } + }, + ), ), ); } diff --git a/lib/features/mailbox/presentation/mailbox_controller.dart b/lib/features/mailbox/presentation/mailbox_controller.dart index 90f21a4d9..b6b21e7f8 100644 --- a/lib/features/mailbox/presentation/mailbox_controller.dart +++ b/lib/features/mailbox/presentation/mailbox_controller.dart @@ -684,6 +684,28 @@ class MailboxController extends BaseMailboxController { } } + void handleMailboxAction(BuildContext context, MailboxActions actions, + PresentationMailbox mailbox) { + popBack(); + + switch(actions) { + case MailboxActions.delete: + _openConfirmationDialogDeleteMailboxAction(context, mailbox); + break; + case MailboxActions.rename: + _openDialogRenameMailboxAction(context, mailbox); + break; + case MailboxActions.move: + _appToast.showToast(AppLocalizations.of(context).the_feature_is_under_development); + break; + case MailboxActions.markAsRead: + _appToast.showToast(AppLocalizations.of(context).the_feature_is_under_development); + break; + default: + break; + } + } + void closeMailboxScreen(BuildContext context) { _cancelSelectMailbox(); mailboxDashBoardController.closeMailboxMenuDrawer(); diff --git a/lib/features/mailbox/presentation/mailbox_view_web.dart b/lib/features/mailbox/presentation/mailbox_view_web.dart index 7621db990..a90a935ac 100644 --- a/lib/features/mailbox/presentation/mailbox_view_web.dart +++ b/lib/features/mailbox/presentation/mailbox_view_web.dart @@ -5,17 +5,20 @@ 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/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'; 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/mailbox_search_tile_builder.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/widgets/user_information_widget_builder.dart'; import 'package:tmail_ui_user/features/thread/presentation/widgets/search_app_bar_widget.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; -class MailboxView extends GetWidget with AppLoaderMixin { +class MailboxView extends GetWidget with AppLoaderMixin, PopupMenuWidgetMixin { final _imagePaths = Get.find(); final _responsiveUtils = Get.find(); @@ -350,6 +353,63 @@ class MailboxView extends GetWidget with AppLoaderMixin { } void _openMailboxMenuAction(BuildContext context, RelativeRect position, - PresentationMailbox presentationMailbox) { + PresentationMailbox mailbox) { + final listMailboxActions = [ + MailboxActions.markAsRead, + if (!mailbox.hasRole()) MailboxActions.move, + if (!mailbox.hasRole()) MailboxActions.rename, + if (!mailbox.hasRole()) MailboxActions.delete, + ]; + + if (_responsiveUtils.isScreenWithShortestSide(context)) { + controller.openContextMenuAction(context, + _bottomSheetIdentityActionTiles(context, mailbox, listMailboxActions)); + } else { + controller.openPopupMenuAction(context, position, + _popupMenuMailboxActionTiles(context, mailbox, listMailboxActions)); + } + } + + List _bottomSheetIdentityActionTiles(BuildContext context, + PresentationMailbox mailbox, List listMailboxActions) { + return listMailboxActions + .map((action) => _mailboxContextMenuActionTile(context, action, mailbox)) + .toList(); + } + + Widget _mailboxContextMenuActionTile(BuildContext context, MailboxActions actions, + PresentationMailbox mailbox) { + return (MailboxBottomSheetActionTileBuilder( + Key('${actions.name}_action'), + SvgPicture.asset( + actions.getContextMenuIcon(_imagePaths), + color: actions.getColorContextMenuIcon()), + actions.getTitleContextMenu(context), + mailbox) + ..onActionClick((mailbox) => + controller.handleMailboxAction(context, actions, mailbox))) + .build(); + } + + List _popupMenuMailboxActionTiles(BuildContext context, + PresentationMailbox mailbox, List listMailboxActions) { + return listMailboxActions + .map((action) => _mailboxPopupMenuActionTile(context, action, mailbox)) + .toList(); + } + + PopupMenuItem _mailboxPopupMenuActionTile(BuildContext context, MailboxActions actions, + 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))); } } \ 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 eaa0a84fa..c78048cc9 100644 --- a/lib/features/mailbox/presentation/model/mailbox_actions.dart +++ b/lib/features/mailbox/presentation/model/mailbox_actions.dart @@ -1,5 +1,7 @@ +import 'package:core/core.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; enum MailboxActions { @@ -7,6 +9,8 @@ enum MailboxActions { moveEmail, delete, rename, + move, + markAsRead, } extension MailboxActionsExtension on MailboxActions { @@ -21,4 +25,43 @@ extension MailboxActionsExtension on MailboxActions { return ''; } } + + String getTitleContextMenu(BuildContext context) { + switch(this) { + case MailboxActions.markAsRead: + return AppLocalizations.of(context).mark_as_read; + case MailboxActions.move: + return AppLocalizations.of(context).moveMailbox; + case MailboxActions.rename: + return AppLocalizations.of(context).rename_mailbox; + case MailboxActions.delete: + return AppLocalizations.of(context).deleteMailbox; + default: + return ''; + } + } + + String getContextMenuIcon(ImagePaths imagePaths) { + switch(this) { + case MailboxActions.markAsRead: + return imagePaths.icRead; + case MailboxActions.move: + return imagePaths.icMove; + case MailboxActions.rename: + return imagePaths.icRenameMailbox; + case MailboxActions.delete: + return imagePaths.icDelete; + default: + return ''; + } + } + + Color getColorContextMenuIcon() { + switch(this) { + case MailboxActions.delete: + return AppColor.colorActionDeleteConfirmDialog; + default: + return Colors.black; + } + } } \ 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 new file mode 100644 index 000000000..b39fa1890 --- /dev/null +++ b/lib/features/mailbox/presentation/widgets/mailbox_bottom_sheet_action_tile_builder.dart @@ -0,0 +1,52 @@ + +import 'package:core/core.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:model/mailbox/presentation_mailbox.dart'; + +class MailboxBottomSheetActionTileBuilder extends CupertinoActionSheetActionBuilder { + + final PresentationMailbox presentationMailbox; + final SvgPicture? actionSelected; + final Color? bgColor; + final EdgeInsets? iconLeftPadding; + final EdgeInsets? iconRightPadding; + + MailboxBottomSheetActionTileBuilder( + Key key, + SvgPicture actionIcon, + String actionName, + this.presentationMailbox, + { + this.actionSelected, + this.bgColor, + this.iconLeftPadding, + this.iconRightPadding, + } + ) : 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); + } + }, + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/features/manage_account/presentation/profiles/identities/widgets/identity_bottom_sheet_action_tile_builder.dart b/lib/features/manage_account/presentation/profiles/identities/widgets/identity_bottom_sheet_action_tile_builder.dart index 7b41110f9..14ea33ea4 100644 --- a/lib/features/manage_account/presentation/profiles/identities/widgets/identity_bottom_sheet_action_tile_builder.dart +++ b/lib/features/manage_account/presentation/profiles/identities/widgets/identity_bottom_sheet_action_tile_builder.dart @@ -30,19 +30,22 @@ class IdentityBottomSheetActionTileBuilder extends CupertinoActionSheetActionBui Widget build() { return Container( color: bgColor ?? Colors.white, - 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!(identity); - } - }, + 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!(identity); + } + }, + ), ), ); } diff --git a/lib/features/thread/presentation/widgets/app_action_sheet_action_builder.dart b/lib/features/thread/presentation/widgets/app_action_sheet_action_builder.dart index 22709f10b..fed7751fb 100644 --- a/lib/features/thread/presentation/widgets/app_action_sheet_action_builder.dart +++ b/lib/features/thread/presentation/widgets/app_action_sheet_action_builder.dart @@ -23,15 +23,18 @@ class AppActionSheetActionBuilder extends CupertinoActionSheetActionBuilder { Widget build() { return Container( color: bgColor ?? Colors.white, - 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: () => onCupertinoActionSheetActionClick?.call(null), + 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: () => onCupertinoActionSheetActionClick?.call(null), + ), ), ); } diff --git a/lib/features/thread/presentation/widgets/filter_message_cupertino_action_sheet_action_builder.dart b/lib/features/thread/presentation/widgets/filter_message_cupertino_action_sheet_action_builder.dart index 55d4a5021..d444618f4 100644 --- a/lib/features/thread/presentation/widgets/filter_message_cupertino_action_sheet_action_builder.dart +++ b/lib/features/thread/presentation/widgets/filter_message_cupertino_action_sheet_action_builder.dart @@ -33,23 +33,26 @@ class FilterMessageCupertinoActionSheetActionBuilder Widget build() { return Container( color: bgColor ?? Colors.white, - 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())), - if (optionCurrent == option && actionSelected != null) + child: MouseRegion( + cursor: BuildUtils.isWeb ? MaterialStateMouseCursor.clickable : MouseCursor.defer, + child: CupertinoActionSheetAction( + key: key, + child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Padding( - padding: iconRightPadding ?? const EdgeInsets.only(right: 12), - child: actionSelected!), - ]), - onPressed: () { - if (onCupertinoActionSheetActionClick != null) { - onCupertinoActionSheetActionClick!(option); - } - }, + padding: iconLeftPadding ?? const EdgeInsets.only(left: 12, right: 16), + child: actionIcon), + Expanded(child: Text(actionName, textAlign: TextAlign.left, style: actionTextStyle())), + if (optionCurrent == option && actionSelected != null) + Padding( + padding: iconRightPadding ?? const EdgeInsets.only(right: 12), + child: actionSelected!), + ]), + onPressed: () { + if (onCupertinoActionSheetActionClick != null) { + onCupertinoActionSheetActionClick!(option); + } + }, + ), ), ); } diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index ecfeee5e6..d50a5ca45 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -1,5 +1,5 @@ { - "@@last_modified": "2022-05-27T10:11:30.148525", + "@@last_modified": "2022-05-31T15:17:59.229845", "initializing_data": "Initializing data...", "@initializing_data": { "type": "text", @@ -1371,5 +1371,17 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "moveMailbox": "Move mailbox", + "@moveMailbox": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "deleteMailbox": "Delete mailbox", + "@deleteMailbox": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } \ No newline at end of file diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart index 31e41fc31..17fea2c4a 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -1405,4 +1405,17 @@ class AppLocalizations { 'Can not get token, please check with your system administrator', name: 'canNotGetToken'); } + + String get moveMailbox { + return Intl.message( + 'Move mailbox', + name: 'moveMailbox', + ); + } + + String get deleteMailbox { + return Intl.message( + 'Delete mailbox', + name: 'deleteMailbox'); + } } \ No newline at end of file