TF-1718 Show Unsubscribe action in context menu action on mobile

(cherry picked from commit 2d6b426f05bcfcc75d4e57f2443576a9f3f69689)
This commit is contained in:
dab246
2023-11-15 15:27:43 +07:00
committed by Dat Vu
parent 0c974e2316
commit 7cf5c08ef5
7 changed files with 119 additions and 208 deletions
+3
View File
@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20.4884 14.5382V5.49817C20.4884 4.39817 19.5884 3.49817 18.4884 3.49817H4.49844C3.39844 3.49817 2.49844 4.39817 2.49844 5.49817V15.4982C2.49844 16.5982 3.39844 17.4982 4.49844 17.4982H14.5484C14.8284 19.4182 16.6484 20.8482 18.7284 20.4282C20.0684 20.1582 21.1584 19.0582 21.4284 17.7182C21.6784 16.4782 21.2684 15.3282 20.4884 14.5382ZM18.4884 5.49817L11.4984 8.99817L4.49844 5.49817H18.4884ZM14.8484 15.4982H4.49844V7.49817L11.4984 10.9982L18.4984 7.49817V13.5482C18.3384 13.5282 18.1684 13.4982 17.9984 13.4982C16.6084 13.4982 15.4084 14.3182 14.8484 15.4982ZM19.9984 17.4982H15.9984V16.4982H19.9984V17.4982Z" fill="#0A84FF"/>
</svg>

After

Width:  |  Height:  |  Size: 743 B

@@ -206,6 +206,7 @@ class ImagePaths {
String get icDropZoneIcon => _getImagePath('ic_drop_zone_icon.svg'); String get icDropZoneIcon => _getImagePath('ic_drop_zone_icon.svg');
String get icArrowUpOutline => _getImagePath('ic_arrow_up_outline.svg'); String get icArrowUpOutline => _getImagePath('ic_arrow_up_outline.svg');
String get icFilterSB => _getImagePath('ic_filter_sb.svg'); String get icFilterSB => _getImagePath('ic_filter_sb.svg');
String get icUnsubscribe => _getImagePath('ic_unsubscribe.svg');
String _getImagePath(String imageName) { String _getImagePath(String imageName) {
return AssetsPaths.images + imageName; return AssetsPaths.images + imageName;
@@ -1,5 +1,6 @@
import 'package:core/presentation/extensions/html_extension.dart'; import 'package:core/presentation/extensions/html_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:model/email/email_action_type.dart'; import 'package:model/email/email_action_type.dart';
import 'package:model/email/presentation_email.dart'; import 'package:model/email/presentation_email.dart';
@@ -117,4 +118,38 @@ extension EmailActionTypeExtension on EmailActionType {
return null; return null;
} }
} }
String getIcon(ImagePaths imagePaths) {
switch(this) {
case EmailActionType.markAsUnread:
return imagePaths.icUnreadEmail;
case EmailActionType.unSpam:
return imagePaths.icNotSpam;
case EmailActionType.moveToSpam:
return imagePaths.icSpam;
case EmailActionType.createRule:
return imagePaths.icQuickCreatingRule;
case EmailActionType.unsubscribe:
return imagePaths.icUnsubscribe;
default:
return '';
}
}
String getTitle(BuildContext context) {
switch(this) {
case EmailActionType.markAsUnread:
return AppLocalizations.of(context).mark_as_unread;
case EmailActionType.unSpam:
return AppLocalizations.of(context).remove_from_spam;
case EmailActionType.moveToSpam:
return AppLocalizations.of(context).mark_as_spam;
case EmailActionType.createRule:
return AppLocalizations.of(context).quickCreatingRule;
case EmailActionType.unsubscribe:
return AppLocalizations.of(context).unsubscribe;
default:
return '';
}
}
} }
@@ -968,6 +968,9 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
popBack(); popBack();
unSpam(context, presentationEmail); unSpam(context, presentationEmail);
break; break;
case EmailActionType.createRule:
quickCreatingRule(context, presentationEmail.from!.first);
break;
default: default:
break; break;
} }
+72 -205
View File
@@ -18,6 +18,7 @@ import 'package:model/extensions/presentation_mailbox_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart'; import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart'; import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/base/widget/popup_item_widget.dart'; import 'package:tmail_ui_user/features/base/widget/popup_item_widget.dart';
import 'package:tmail_ui_user/features/composer/presentation/extensions/email_action_type_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/controller/single_email_controller.dart'; import 'package:tmail_ui_user/features/email/presentation/controller/single_email_controller.dart';
import 'package:tmail_ui_user/features/email/presentation/extensions/calendar_event_extension.dart'; import 'package:tmail_ui_user/features/email/presentation/extensions/calendar_event_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/styles/email_view_styles.dart'; import 'package:tmail_ui_user/features/email/presentation/styles/email_view_styles.dart';
@@ -64,20 +65,7 @@ class EmailView extends GetWidget<SingleEmailController> {
isSearchActivated: controller.mailboxDashBoardController.searchController.isSearchEmailRunning, isSearchActivated: controller.mailboxDashBoardController.searchController.isSearchEmailRunning,
onBackAction: () => controller.closeEmailView(context), onBackAction: () => controller.closeEmailView(context),
onEmailActionClick: (email, action) => controller.handleEmailAction(context, email, action), onEmailActionClick: (email, action) => controller.handleEmailAction(context, email, action),
onMoreActionClick: (email, position) { onMoreActionClick: (presentationEmail, position) => _handleMoreEmailAction(context: context, presentationEmail: presentationEmail, position: position)
if (position == null) {
controller.openContextMenuAction(
context,
_emailActionMoreActionTile(context, email)
);
} else {
controller.openPopupMenuAction(
context,
position,
_popupMenuEmailActionTile(context, email)
);
}
},
), ),
); );
} else { } else {
@@ -111,20 +99,7 @@ class EmailView extends GetWidget<SingleEmailController> {
isSearchActivated: controller.mailboxDashBoardController.searchController.isSearchEmailRunning, isSearchActivated: controller.mailboxDashBoardController.searchController.isSearchEmailRunning,
onBackAction: () => controller.closeEmailView(context), onBackAction: () => controller.closeEmailView(context),
onEmailActionClick: (email, action) => controller.handleEmailAction(context, email, action), onEmailActionClick: (email, action) => controller.handleEmailAction(context, email, action),
onMoreActionClick: (email, position) { onMoreActionClick: (presentationEmail, position) => _handleMoreEmailAction(context: context, presentationEmail: presentationEmail, position: position),
if (position == null) {
controller.openContextMenuAction(
context,
_emailActionMoreActionTile(context, email)
);
} else {
controller.openPopupMenuAction(
context,
position,
_popupMenuEmailActionTile(context, email)
);
}
},
optionsWidget: PlatformInfo.isWeb && controller.emailSupervisorController.supportedPageView.isTrue optionsWidget: PlatformInfo.isWeb && controller.emailSupervisorController.supportedPageView.isTrue
? _buildNavigatorPageViewWidgets(context) ? _buildNavigatorPageViewWidgets(context)
: null, : null,
@@ -440,194 +415,86 @@ class EmailView extends GetWidget<SingleEmailController> {
); );
} }
List<Widget> _emailActionMoreActionTile(BuildContext context, PresentationEmail email) { void _handleMoreEmailAction({
return <Widget>[ required BuildContext context,
_markAsEmailUnreadAction(context, email), required PresentationEmail presentationEmail,
_markAsEmailSpamOrUnSpamAction(context, email), RelativeRect? position
if (email.from?.isNotEmpty == true) }) {
_quickCreatingRuleAction(context, email), final mailboxContain = controller.getMailboxContain(presentationEmail);
final moreActions = [
EmailActionType.markAsUnread,
if (mailboxContain?.isSpam == true)
EmailActionType.unSpam
else
EmailActionType.moveToSpam,
if (presentationEmail.from?.isNotEmpty == true)
EmailActionType.createRule,
EmailActionType.unsubscribe
]; ];
}
Widget _markAsEmailUnreadAction(BuildContext context, PresentationEmail email) { if (position == null) {
return (EmailActionCupertinoActionSheetActionBuilder( controller.openContextMenuAction(
const Key('mark_as_unread_action'),
SvgPicture.asset(
controller.imagePaths.icUnreadEmail,
width: 24,
height: 24,
fit: BoxFit.fill,
colorFilter: AppColor.colorTextButton.asFilter()
),
AppLocalizations.of(context).mark_as_unread,
email,
iconLeftPadding: controller.responsiveUtils.isMobile(context)
? EdgeInsets.only(
left: AppUtils.isDirectionRTL(context) ? 16 : 12,
right: AppUtils.isDirectionRTL(context) ? 12 : 16,
)
: EdgeInsets.only(
left: AppUtils.isDirectionRTL(context) ? 12 : 0,
right: AppUtils.isDirectionRTL(context) ? 0 : 12,
),
iconRightPadding: controller.responsiveUtils.isMobile(context)
? EdgeInsets.only(
left: AppUtils.isDirectionRTL(context) ? 12 : 0,
right: AppUtils.isDirectionRTL(context) ? 0 : 12,
)
: EdgeInsets.zero)
..onActionClick((email) => controller.handleEmailAction(
context, context,
email, _emailActionMoreActionTile(context, presentationEmail, moreActions)
EmailActionType.markAsUnread) );
) } else {
).build(); controller.openPopupMenuAction(
}
Widget _markAsEmailSpamOrUnSpamAction(BuildContext context, PresentationEmail email) {
final currentMailbox = controller.getMailboxContain(email);
return (EmailActionCupertinoActionSheetActionBuilder(
const Key('mark_as_spam_or_un_spam_action'),
SvgPicture.asset(
currentMailbox?.isSpam == true ? controller.imagePaths.icNotSpam : controller.imagePaths.icSpam,
width: 24,
height: 24,
fit: BoxFit.fill,
colorFilter: AppColor.colorTextButton.asFilter()
),
currentMailbox?.isSpam == true
? AppLocalizations.of(context).remove_from_spam
: AppLocalizations.of(context).mark_as_spam,
email,
iconLeftPadding: controller.responsiveUtils.isMobile(context)
? EdgeInsets.only(
left: AppUtils.isDirectionRTL(context) ? 16 : 12,
right: AppUtils.isDirectionRTL(context) ? 12 : 16,
)
: EdgeInsets.only(
left: AppUtils.isDirectionRTL(context) ? 12 : 0,
right: AppUtils.isDirectionRTL(context) ? 0 : 12,
),
iconRightPadding: controller.responsiveUtils.isMobile(context)
? EdgeInsets.only(
left: AppUtils.isDirectionRTL(context) ? 12 : 0,
right: AppUtils.isDirectionRTL(context) ? 0 : 12,
)
: EdgeInsets.zero)
..onActionClick((email) => controller.handleEmailAction(
context, context,
email, position,
currentMailbox?.isSpam == true ? EmailActionType.unSpam : EmailActionType.moveToSpam) _popupMenuEmailActionTile(context, presentationEmail, moreActions)
) );
).build(); }
} }
Widget _quickCreatingRuleAction(BuildContext context, PresentationEmail email) { List<Widget> _emailActionMoreActionTile(
return (EmailActionCupertinoActionSheetActionBuilder(
const Key('quick_creating_rule_action'),
SvgPicture.asset(
controller.imagePaths.icQuickCreatingRule,
width: 24,
height: 24,
fit: BoxFit.fill,
colorFilter: AppColor.colorTextButton.asFilter()),
AppLocalizations.of(context).quickCreatingRule,
email,
iconLeftPadding: controller.responsiveUtils.isMobile(context)
? EdgeInsets.only(
left: AppUtils.isDirectionRTL(context) ? 16 : 12,
right: AppUtils.isDirectionRTL(context) ? 12 : 16,
)
: EdgeInsets.only(
left: AppUtils.isDirectionRTL(context) ? 12 : 0,
right: AppUtils.isDirectionRTL(context) ? 0 : 12,
),
iconRightPadding: controller.responsiveUtils.isMobile(context)
? EdgeInsets.only(
left: AppUtils.isDirectionRTL(context) ? 12 : 0,
right: AppUtils.isDirectionRTL(context) ? 0 : 12,
)
: EdgeInsets.zero)
..onActionClick((email) => controller.quickCreatingRule(context, email.from!.first)))
.build();
}
List<PopupMenuEntry> _popupMenuEmailActionTile(BuildContext context, PresentationEmail email) {
final mailboxContain = controller.getMailboxContain(email);
return [
_markAsEmailUnreadPopupItemAction(context, email),
_markAsEmailSpamOrUnSpamPopupItemAction(context, email, mailboxContain),
if (email.from?.isNotEmpty == true)
_quickCreatingRulePopupItemAction(context, email)
];
}
PopupMenuEntry _markAsEmailUnreadPopupItemAction(BuildContext context, PresentationEmail email) {
return PopupMenuItem(
padding: EdgeInsets.zero,
child: PopupItemWidget(
controller.imagePaths.icUnreadEmail,
AppLocalizations.of(context).mark_as_unread,
colorIcon: AppColor.colorTextButton,
padding: const EdgeInsetsDirectional.only(start: 12),
styleName: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 16,
color: Colors.black
),
onCallbackAction: () => controller.handleEmailAction(
context,
email,
EmailActionType.markAsUnread
)
)
);
}
PopupMenuEntry _markAsEmailSpamOrUnSpamPopupItemAction(
BuildContext context, BuildContext context,
PresentationEmail email, PresentationEmail presentationEmail,
PresentationMailbox? mailboxContain List<EmailActionType> actionTypes,
) { ) {
return PopupMenuItem( return actionTypes.map((action) {
padding: EdgeInsets.zero, return (EmailActionCupertinoActionSheetActionBuilder(
child: PopupItemWidget( Key('${action.name}_action'),
mailboxContain?.isSpam == true ? controller.imagePaths.icNotSpam : controller.imagePaths.icSpam, SvgPicture.asset(
mailboxContain?.isSpam == true action.getIcon(controller.imagePaths),
? AppLocalizations.of(context).remove_from_spam width: 24,
: AppLocalizations.of(context).mark_as_spam, height: 24,
colorIcon: AppColor.colorTextButton, fit: BoxFit.fill,
padding: const EdgeInsetsDirectional.only(start: 12), colorFilter: AppColor.colorTextButton.asFilter()
styleName: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 16,
color: Colors.black
), ),
onCallbackAction: () => controller.handleEmailAction( action.getTitle(context),
context, presentationEmail,
email, iconLeftPadding: controller.responsiveUtils.isScreenWithShortestSide(context)
mailboxContain?.isSpam == true ? EmailActionType.unSpam : EmailActionType.moveToSpam ? const EdgeInsetsDirectional.only(start: 12, end: 16)
) : const EdgeInsetsDirectional.only(end: 12),
iconRightPadding: controller.responsiveUtils.isScreenWithShortestSide(context)
? const EdgeInsetsDirectional.only(end: 12)
: EdgeInsets.zero
) )
); ..onActionClick((presentationEmail) => controller.handleEmailAction(context, presentationEmail, action))).build();
}).toList();
} }
PopupMenuEntry _quickCreatingRulePopupItemAction(BuildContext context, PresentationEmail email) { List<PopupMenuEntry> _popupMenuEmailActionTile(
return PopupMenuItem( BuildContext context,
padding: EdgeInsets.zero, PresentationEmail presentationEmail,
child: PopupItemWidget( List<EmailActionType> actionTypes
controller.imagePaths.icQuickCreatingRule, ) {
AppLocalizations.of(context).quickCreatingRule, return actionTypes.map((action) {
colorIcon: AppColor.colorTextButton, return PopupMenuItem(
padding: const EdgeInsetsDirectional.only(start: 12), padding: EdgeInsets.zero,
styleName: const TextStyle( child: PopupItemWidget(
fontWeight: FontWeight.w500, action.getIcon(controller.imagePaths),
fontSize: 16, action.getTitle(context),
color: Colors.black colorIcon: AppColor.colorTextButton,
), padding: const EdgeInsetsDirectional.only(start: 12),
onCallbackAction: () => controller.quickCreatingRule(context, email.from!.first) styleName: const TextStyle(
) fontWeight: FontWeight.w500,
); fontSize: 16,
color: Colors.black
),
onCallbackAction: () => controller.handleEmailAction(context, presentationEmail, action)
)
);
}).toList();
} }
} }
@@ -10,8 +10,8 @@ class EmailActionCupertinoActionSheetActionBuilder extends CupertinoActionSheetA
final PresentationEmail presentationEmail; final PresentationEmail presentationEmail;
final SvgPicture? actionSelected; final SvgPicture? actionSelected;
final Color? bgColor; final Color? bgColor;
final EdgeInsets? iconLeftPadding; final EdgeInsetsGeometry? iconLeftPadding;
final EdgeInsets? iconRightPadding; final EdgeInsetsGeometry? iconRightPadding;
EmailActionCupertinoActionSheetActionBuilder( EmailActionCupertinoActionSheetActionBuilder(
Key key, Key key,
+3 -1
View File
@@ -22,5 +22,7 @@ enum EmailActionType {
selection, selection,
moveToSpam, moveToSpam,
unSpam, unSpam,
openInNewTab openInNewTab,
createRule,
unsubscribe,
} }