TF-934 Implement open email in new tab

This commit is contained in:
dab246
2022-11-14 16:30:25 +07:00
committed by Dat H. Pham
parent 83f8049c48
commit 4f981878c3
13 changed files with 432 additions and 251 deletions
+1
View File
@@ -10,6 +10,7 @@ export 'presentation/extensions/html_extension.dart';
export 'presentation/extensions/compare_string_extension.dart'; export 'presentation/extensions/compare_string_extension.dart';
export 'presentation/extensions/compare_list_extensions.dart'; export 'presentation/extensions/compare_list_extensions.dart';
export 'presentation/extensions/string_extension.dart'; export 'presentation/extensions/string_extension.dart';
export 'presentation/extensions/tap_down_details_extension.dart';
export 'domain/extensions/media_type_extension.dart'; export 'domain/extensions/media_type_extension.dart';
// Exceptions // Exceptions
@@ -0,0 +1,17 @@
import 'package:flutter/material.dart';
extension TapDownDetailsExtension on TapDownDetails {
RelativeRect getPosition(BuildContext context) {
final screenSize = MediaQuery.of(context).size;
final offset = globalPosition;
final position = RelativeRect.fromLTRB(
offset.dx,
offset.dy,
screenSize.width - offset.dx,
screenSize.height - offset.dy,
);
return position;
}
}
@@ -1,9 +1,12 @@
import 'package:core/core.dart'; import 'package:core/core.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
typedef IconWebCallback = void Function(); typedef IconWebCallback = void Function();
typedef IconWebHasPositionCallback = void Function(RelativeRect); typedef IconWebHasPositionCallback = void Function(RelativeRect);
typedef OnTapIconButtonCallbackAction = void Function();
typedef OnTapDownIconButtonCallbackAction = void Function(TapDownDetails TapDetails);
Widget buildIconWeb({ Widget buildIconWeb({
required Widget icon, required Widget icon,
@@ -32,6 +35,47 @@ Widget buildIconWeb({
); );
} }
Widget buildSVGIconButton({
required String icon,
String? tooltip,
EdgeInsets? padding,
double? iconSize,
Color? iconColor,
OnTapIconButtonCallbackAction? onTap,
OnTapDownIconButtonCallbackAction? onTapDown,
}) {
Widget iconWidget = Padding(
padding: padding ?? const EdgeInsets.all(8),
child: SvgPicture.asset(
icon,
width: iconSize,
height: iconSize,
fit: BoxFit.fill,
color: iconColor,
),
);
Widget itemChild;
if (tooltip != null) {
itemChild = Tooltip(
message: tooltip,
child: iconWidget,
);
} else {
itemChild = iconWidget;
}
return Material(
color: Colors.transparent,
child: InkWell(
onTap: onTap,
onTapDown: onTapDown,
customBorder: const CircleBorder(),
child: itemChild,
)
);
}
Widget buildIconWebHasPosition(BuildContext context, { Widget buildIconWebHasPosition(BuildContext context, {
required Widget icon, required Widget icon,
String? tooltip, String? tooltip,
@@ -43,18 +87,10 @@ Widget buildIconWebHasPosition(BuildContext context, {
shape: const CircleBorder(), shape: const CircleBorder(),
child: InkWell( child: InkWell(
onTapDown: (detail) { onTapDown: (detail) {
final screenSize = MediaQuery.of(context).size; onTapDown?.call(detail.getPosition(context));
final offset = detail.globalPosition;
final position = RelativeRect.fromLTRB(
offset.dx,
offset.dy,
screenSize.width - offset.dx,
screenSize.height - offset.dy,
);
onTapDown?.call(position);
}, },
onTap: () => onTap?.call(), onTap: () => onTap?.call(),
borderRadius: const BorderRadius.all(const Radius.circular(12)), borderRadius: const BorderRadius.all(Radius.circular(12)),
child: Tooltip( child: Tooltip(
message: tooltip ?? '', message: tooltip ?? '',
child: icon, child: icon,
@@ -4,27 +4,39 @@ import 'package:flutter_svg/flutter_svg.dart';
mixin PopupMenuWidgetMixin { mixin PopupMenuWidgetMixin {
Widget popupItem(String iconAction, String nameAction, { Widget popupItem(
String iconAction,
String nameAction, {
Color? colorIcon, Color? colorIcon,
double? iconSize,
TextStyle? styleName, TextStyle? styleName,
Function? onCallbackAction EdgeInsets? padding,
Function()? onCallbackAction
}) { }) {
return InkWell( return InkWell(
onTap: () => onCallbackAction?.call(), onTap: onCallbackAction,
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16), padding: padding ?? const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
child: SizedBox( child: SizedBox(
child: Row(children: [ child: Row(children: [
SvgPicture.asset(iconAction, width: 20, height: 20, fit: BoxFit.fill, color: colorIcon), SvgPicture.asset(
const SizedBox(width: 12), iconAction,
Expanded(child: Text(nameAction, width: iconSize ?? 20,
style: styleName ?? const TextStyle( height: iconSize ?? 20,
fontSize: 17, fit: BoxFit.fill,
fontWeight: FontWeight.normal, color: colorIcon
color: Colors.black))), ),
]) const SizedBox(width: 12),
), Expanded(child: Text(
) nameAction,
style: styleName ?? const TextStyle(
fontSize: 17,
fontWeight: FontWeight.normal,
color: Colors.black)
)),
])
),
)
); );
} }
} }
+114 -112
View File
@@ -6,6 +6,7 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/model.dart'; import 'package:model/model.dart';
import 'package:tmail_ui_user/features/base/mixin/popup_menu_widget_mixin.dart';
import 'package:tmail_ui_user/features/composer/presentation/extensions/prefix_email_address_extension.dart'; import 'package:tmail_ui_user/features/composer/presentation/extensions/prefix_email_address_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/widgets/app_bar_mail_widget_builder.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/app_bar_mail_widget_builder.dart';
@@ -16,7 +17,8 @@ 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/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class EmailView extends GetWidget<SingleEmailController> { class EmailView extends GetWidget<SingleEmailController>
with PopupMenuWidgetMixin {
static const double maxSizeFullDisplayEmailAddressArrowDownButton = 30.0; static const double maxSizeFullDisplayEmailAddressArrowDownButton = 30.0;
@@ -766,49 +768,58 @@ class EmailView extends GetWidget<SingleEmailController> {
Widget _markAsEmailUnreadAction(BuildContext context, PresentationEmail email) { Widget _markAsEmailUnreadAction(BuildContext context, PresentationEmail email) {
return (EmailActionCupertinoActionSheetActionBuilder( return (EmailActionCupertinoActionSheetActionBuilder(
const Key('mark_as_unread_action'), const Key('mark_as_unread_action'),
SvgPicture.asset( SvgPicture.asset(
imagePaths.icUnreadEmail, imagePaths.icUnreadEmail,
width: 24, width: 24,
height: 24, height: 24,
fit: BoxFit.fill, fit: BoxFit.fill,
color: AppColor.colorTextButton), color: AppColor.colorTextButton
AppLocalizations.of(context).mark_as_unread, ),
email, AppLocalizations.of(context).mark_as_unread,
iconLeftPadding: responsiveUtils.isMobile(context) email,
? const EdgeInsets.only(left: 12, right: 16) iconLeftPadding: responsiveUtils.isMobile(context)
: const EdgeInsets.only(right: 12), ? const EdgeInsets.only(left: 12, right: 16)
iconRightPadding: responsiveUtils.isMobile(context) : const EdgeInsets.only(right: 12),
? const EdgeInsets.only(right: 12) iconRightPadding: responsiveUtils.isMobile(context)
: EdgeInsets.zero) ? const EdgeInsets.only(right: 12)
..onActionClick((email) => controller.handleEmailAction(context, email, EmailActionType.markAsUnread))) : EdgeInsets.zero)
.build(); ..onActionClick((email) => controller.handleEmailAction(
context,
email,
EmailActionType.markAsUnread)
)
).build();
} }
Widget _markAsEmailSpamOrUnSpamAction(BuildContext context, PresentationEmail email) { Widget _markAsEmailSpamOrUnSpamAction(BuildContext context, PresentationEmail email) {
final currentMailbox = controller.getMailboxContain(email); final currentMailbox = controller.getMailboxContain(email);
return (EmailActionCupertinoActionSheetActionBuilder( return (EmailActionCupertinoActionSheetActionBuilder(
const Key('mark_as_spam_or_un_spam_action'), const Key('mark_as_spam_or_un_spam_action'),
SvgPicture.asset( SvgPicture.asset(
currentMailbox?.isSpam == true ? imagePaths.icNotSpam : imagePaths.icMailboxSpam, currentMailbox?.isSpam == true ? imagePaths.icNotSpam : imagePaths.icSpam,
width: 24, width: 24,
height: 24, height: 24,
fit: BoxFit.fill, fit: BoxFit.fill,
color: AppColor.colorTextButton), color: AppColor.colorTextButton
currentMailbox?.isSpam == true ),
? AppLocalizations.of(context).remove_from_spam currentMailbox?.isSpam == true
: AppLocalizations.of(context).mark_as_spam, ? AppLocalizations.of(context).remove_from_spam
email, : AppLocalizations.of(context).mark_as_spam,
iconLeftPadding: responsiveUtils.isMobile(context) email,
? const EdgeInsets.only(left: 12, right: 16) iconLeftPadding: responsiveUtils.isMobile(context)
: const EdgeInsets.only(right: 12), ? const EdgeInsets.only(left: 12, right: 16)
iconRightPadding: responsiveUtils.isMobile(context) : const EdgeInsets.only(right: 12),
? const EdgeInsets.only(right: 12) iconRightPadding: responsiveUtils.isMobile(context)
: EdgeInsets.zero) ? const EdgeInsets.only(right: 12)
..onActionClick((email) => controller.handleEmailAction(context, email, : EdgeInsets.zero)
currentMailbox?.isSpam == true ? EmailActionType.unSpam : EmailActionType.moveToSpam))) ..onActionClick((email) => controller.handleEmailAction(
.build(); context,
email,
currentMailbox?.isSpam == true ? EmailActionType.unSpam : EmailActionType.moveToSpam)
)
).build();
} }
Widget _quickCreatingRuleAction(BuildContext context, PresentationEmail email) { Widget _quickCreatingRuleAction(BuildContext context, PresentationEmail email) {
@@ -833,85 +844,76 @@ class EmailView extends GetWidget<SingleEmailController> {
} }
List<PopupMenuEntry> _popupMenuEmailActionTile(BuildContext context, PresentationEmail email) { List<PopupMenuEntry> _popupMenuEmailActionTile(BuildContext context, PresentationEmail email) {
final mailboxContain = controller.getMailboxContain(email);
return [ return [
PopupMenuItem( _markAsEmailUnreadPopupItemAction(context, email),
padding: EdgeInsets.zero, _markAsEmailSpamOrUnSpamPopupItemAction(context, email, mailboxContain),
child: _markAsEmailUnreadPopupItemAction(context, email)), _quickCreatingRulePopupItemAction(context, email)
PopupMenuItem(
padding: EdgeInsets.zero,
child: _markAsEmailSpamOrUnSpamPopupItemAction(context, email)),
PopupMenuItem(
padding: EdgeInsets.zero,
child: _quickCreatingRulePopupItemAction(context, email)),
]; ];
} }
Widget _markAsEmailUnreadPopupItemAction(BuildContext context, PresentationEmail email) { PopupMenuEntry _markAsEmailUnreadPopupItemAction(BuildContext context, PresentationEmail email) {
return _popupMenuItem( return PopupMenuItem(
icon: imagePaths.icUnreadEmail, padding: EdgeInsets.zero,
title: AppLocalizations.of(context).mark_as_unread, child: popupItem(
onTapCallback: () => controller.handleEmailAction(context, email, EmailActionType.markAsUnread) imagePaths.icUnreadEmail,
); AppLocalizations.of(context).mark_as_unread,
} colorIcon: AppColor.colorTextButton,
styleName: const TextStyle(
Widget _markAsEmailSpamOrUnSpamPopupItemAction(BuildContext context, PresentationEmail email) { fontWeight: FontWeight.w500,
final currentMailbox = controller.getMailboxContain(email); fontSize: 16,
color: Colors.black
return _popupMenuItem( ),
icon: currentMailbox?.isSpam == true onCallbackAction: () => controller.handleEmailAction(
? imagePaths.icNotSpam context,
: imagePaths.icMailboxSpam, email,
title: currentMailbox?.isSpam == true EmailActionType.markAsUnread
? AppLocalizations.of(context).remove_from_spam
: AppLocalizations.of(context).mark_as_spam,
onTapCallback: () => controller.handleEmailAction(
context,
email,
currentMailbox?.isSpam == true ? EmailActionType.unSpam : EmailActionType.moveToSpam)
);
}
Widget _quickCreatingRulePopupItemAction(BuildContext context, PresentationEmail email) {
return _popupMenuItem(
icon: imagePaths.icQuickCreatingRule,
title: AppLocalizations.of(context).quickCreatingRule,
onTapCallback: () => controller.quickCreatingRule(context, email.from!.first)
);
}
Widget _popupMenuItem({
required String icon,
required String title,
Function()? onTapCallback
}) {
return Material(
color: Colors.transparent,
child: InkWell(
onTap: onTapCallback,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: SizedBox(
width: 300,
height: 44,
child: Row(children: [
SvgPicture.asset(
icon,
width: 20,
height: 20,
color: AppColor.colorTextButton,
fit: BoxFit.fill),
const SizedBox(width: 12),
Expanded(child: Text(
title,
style: const TextStyle(
fontSize: 15,
color: Colors.black,
fontWeight: FontWeight.normal)
)),
])
),
) )
), )
);
}
PopupMenuEntry _markAsEmailSpamOrUnSpamPopupItemAction(
BuildContext context,
PresentationEmail email,
PresentationMailbox? mailboxContain
) {
return PopupMenuItem(
padding: EdgeInsets.zero,
child: popupItem(
mailboxContain?.isSpam == true ? imagePaths.icNotSpam : imagePaths.icSpam,
mailboxContain?.isSpam == true
? AppLocalizations.of(context).remove_from_spam
: AppLocalizations.of(context).mark_as_spam,
colorIcon: AppColor.colorTextButton,
styleName: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 16,
color: Colors.black
),
onCallbackAction: () => controller.handleEmailAction(
context,
email,
mailboxContain?.isSpam == true ? EmailActionType.unSpam : EmailActionType.moveToSpam
)
)
);
}
PopupMenuEntry _quickCreatingRulePopupItemAction(BuildContext context, PresentationEmail email) {
return PopupMenuItem(
padding: EdgeInsets.zero,
child: popupItem(
imagePaths.icQuickCreatingRule,
AppLocalizations.of(context).quickCreatingRule,
colorIcon: AppColor.colorTextButton,
styleName: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 16,
color: Colors.black
),
onCallbackAction: () => controller.quickCreatingRule(context, email.from!.first)
)
); );
} }
} }
@@ -30,6 +30,7 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart'; import 'package:tmail_ui_user/main/routes/app_routes.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:tmail_ui_user/main/routes/route_utils.dart'; import 'package:tmail_ui_user/main/routes/route_utils.dart';
import 'package:url_launcher/url_launcher.dart';
mixin EmailActionController on ViewAsDialogActionMixin { mixin EmailActionController on ViewAsDialogActionMixin {
@@ -288,4 +289,15 @@ mixin EmailActionController on ViewAsDialogActionMixin {
mailboxCurrent: mailboxCurrent, mailboxCurrent: mailboxCurrent,
onCancelSelectionEmail: onCancelSelectionEmail); onCancelSelectionEmail: onCancelSelectionEmail);
} }
void openEmailInNewTabAction(BuildContext context, PresentationEmail email) {
launchLink(email.routeWebAsString);
}
Future<void> launchLink(String url, {bool isNewTab = true}) async {
await launchUrl(
Uri.parse(url),
webOnlyWindowName: isNewTab ? '_blank' : '_self',
);
}
} }
@@ -803,6 +803,9 @@ class ThreadController extends BaseController with EmailActionController {
popBack(); popBack();
unSpam(selectedEmail); unSpam(selectedEmail);
break; break;
case EmailActionType.openInNewTab:
openEmailInNewTabAction(context, selectedEmail);
break;
default: default:
break; break;
} }
@@ -821,7 +824,7 @@ class ThreadController extends BaseController with EmailActionController {
void calculateDragValue(PresentationEmail? currentPresentationEmail) { void calculateDragValue(PresentationEmail? currentPresentationEmail) {
if(currentPresentationEmail != null) { if(currentPresentationEmail != null) {
if(mailboxDashBoardController.listEmailSelected.contains(currentPresentationEmail)){ if(mailboxDashBoardController.listEmailSelected.findEmail(currentPresentationEmail.id) != null){
listEmailDrag.clear(); listEmailDrag.clear();
listEmailDrag.addAll(mailboxDashBoardController.listEmailSelected); listEmailDrag.addAll(mailboxDashBoardController.listEmailSelected);
} else { } else {
+120 -30
View File
@@ -6,6 +6,7 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:model/model.dart'; import 'package:model/model.dart';
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.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/email/presentation/model/composer_arguments.dart'; import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/email_action_cupertino_action_sheet_action_builder.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/email_action_cupertino_action_sheet_action_builder.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/mark_as_mailbox_read_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/mark_as_mailbox_read_state.dart';
@@ -24,9 +25,12 @@ import 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_bu
if (dart.library.html) 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_web_builder.dart'; if (dart.library.html) 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_web_builder.dart';
import 'package:tmail_ui_user/features/thread/presentation/widgets/filter_message_cupertino_action_sheet_action_builder.dart'; import 'package:tmail_ui_user/features/thread/presentation/widgets/filter_message_cupertino_action_sheet_action_builder.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin, class ThreadView extends GetWidget<ThreadController>
FilterEmailPopupMenuMixin { with AppLoaderMixin,
FilterEmailPopupMenuMixin,
PopupMenuWidgetMixin {
final _responsiveUtils = Get.find<ResponsiveUtils>(); final _responsiveUtils = Get.find<ResponsiveUtils>();
final _imagePaths = Get.find<ImagePaths>(); final _imagePaths = Get.find<ImagePaths>();
@@ -496,46 +500,132 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin,
} }
List<Widget> _contextMenuActionTile(BuildContext context, PresentationEmail email) { List<Widget> _contextMenuActionTile(BuildContext context, PresentationEmail email) {
final mailboxContain = controller.getMailboxContain(email);
return <Widget>[ return <Widget>[
_markAsEmailSpamOrUnSpamAction(context, email), _openInNewTabContextMenuItemAction(context, email),
if (mailboxContain?.isDrafts == false)
_markAsEmailSpamOrUnSpamContextMenuItemAction(context, email, mailboxContain),
]; ];
} }
Widget _markAsEmailSpamOrUnSpamAction(BuildContext context, PresentationEmail email) { Widget _markAsEmailSpamOrUnSpamContextMenuItemAction(
final mailboxContain = controller.getMailboxContain(email); BuildContext context,
PresentationEmail email,
PresentationMailbox? mailboxContain
) {
return (EmailActionCupertinoActionSheetActionBuilder( return (EmailActionCupertinoActionSheetActionBuilder(
const Key('mark_as_spam_or_un_spam_action'), const Key('mark_as_spam_or_un_spam_action'),
SvgPicture.asset( SvgPicture.asset(
mailboxContain?.isSpam == true ? _imagePaths.icNotSpam : _imagePaths.icSpam, mailboxContain?.isSpam == true ? _imagePaths.icNotSpam : _imagePaths.icSpam,
width: 28, width: 24,
height: 28, height: 24,
fit: BoxFit.fill, fit: BoxFit.fill,
color: AppColor.colorTextButton), color: AppColor.colorTextButton),
mailboxContain?.isSpam == true mailboxContain?.isSpam == true
? AppLocalizations.of(context).remove_from_spam ? AppLocalizations.of(context).remove_from_spam
: AppLocalizations.of(context).mark_as_spam, : AppLocalizations.of(context).mark_as_spam,
email, email,
iconLeftPadding: _responsiveUtils.isMobile(context) iconLeftPadding: _responsiveUtils.isMobile(context)
? const EdgeInsets.only(left: 12, right: 16) ? const EdgeInsets.only(left: 12, right: 16)
: const EdgeInsets.only(right: 12), : const EdgeInsets.only(right: 12),
iconRightPadding: _responsiveUtils.isMobile(context) iconRightPadding: _responsiveUtils.isMobile(context)
? const EdgeInsets.only(right: 12) ? const EdgeInsets.only(right: 12)
: EdgeInsets.zero) : EdgeInsets.zero)
..onActionClick((email) => controller.pressEmailAction(context, ..onActionClick((email) => controller.pressEmailAction(context,
mailboxContain?.isSpam == true mailboxContain?.isSpam == true ? EmailActionType.unSpam : EmailActionType.moveToSpam,
? EmailActionType.unSpam email,
: EmailActionType.moveToSpam, mailboxContain: mailboxContain)
email, )
mailboxContain: mailboxContain))) ).build();
.build(); }
Widget _openInNewTabContextMenuItemAction(BuildContext context, PresentationEmail email) {
return (EmailActionCupertinoActionSheetActionBuilder(
const Key('open_in_new_tab_action'),
SvgPicture.asset(
_imagePaths.icOpenInNewTab,
width: 24,
height: 24,
fit: BoxFit.fill,
color: AppColor.colorTextButton),
AppLocalizations.of(context).openInNewTab,
email,
iconLeftPadding: _responsiveUtils.isMobile(context)
? const EdgeInsets.only(left: 12, right: 16)
: const EdgeInsets.only(right: 12),
iconRightPadding: _responsiveUtils.isMobile(context)
? const EdgeInsets.only(right: 12)
: EdgeInsets.zero)
..onActionClick((email) {
popBack();
controller.openEmailInNewTabAction(context, email);
})
).build();
} }
List<PopupMenuEntry> _popupMenuActionTile(BuildContext context, PresentationEmail email) { List<PopupMenuEntry> _popupMenuActionTile(BuildContext context, PresentationEmail email) {
final mailboxContain = controller.getMailboxContain(email);
return [ return [
PopupMenuItem(padding: const EdgeInsets.symmetric(horizontal: 8), child: _markAsEmailSpamOrUnSpamAction(context, email)), _buildOpenInNewTabPopupMenuItem(context, email, mailboxContain),
if (mailboxContain?.isDrafts == false)
_buildMarkAsSpamPopupMenuItem(context, email, mailboxContain)
]; ];
} }
PopupMenuEntry _buildMarkAsSpamPopupMenuItem(
BuildContext context,
PresentationEmail email,
PresentationMailbox? mailboxContain
) {
return PopupMenuItem(
padding: EdgeInsets.zero,
child: popupItem(
mailboxContain?.isSpam == true ? _imagePaths.icNotSpam : _imagePaths.icSpam,
mailboxContain?.isSpam == true
? AppLocalizations.of(context).remove_from_spam
: AppLocalizations.of(context).mark_as_spam,
colorIcon: AppColor.colorTextButton,
styleName: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 16,
color: Colors.black
),
onCallbackAction: () => controller.pressEmailAction(
context,
mailboxContain?.isSpam == true ? EmailActionType.unSpam : EmailActionType.moveToSpam,
email,
mailboxContain: mailboxContain
)
)
);
}
PopupMenuEntry _buildOpenInNewTabPopupMenuItem(
BuildContext context,
PresentationEmail email,
PresentationMailbox? mailboxContain
) {
return PopupMenuItem(
padding: EdgeInsets.zero,
child: popupItem(
_imagePaths.icOpenInNewTab,
AppLocalizations.of(context).openInNewTab,
colorIcon: AppColor.colorTextButton,
styleName: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 16,
color: Colors.black
),
onCallbackAction: () {
popBack();
controller.openEmailInNewTabAction(context, email);
}
)
);
}
Widget _buildMarkAsMailboxReadLoading(BuildContext context) { Widget _buildMarkAsMailboxReadLoading(BuildContext context) {
return Obx(() { return Obx(() {
final viewState = controller.mailboxDashBoardController.viewStateMarkAsReadMailbox.value; final viewState = controller.mailboxDashBoardController.viewStateMarkAsReadMailbox.value;
@@ -1,5 +1,6 @@
import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/extensions/tap_down_details_extension.dart';
import 'package:core/presentation/views/button/icon_button_web.dart'; import 'package:core/presentation/views/button/icon_button_web.dart';
import 'package:core/presentation/views/responsive/responsive_widget.dart'; import 'package:core/presentation/views/responsive/responsive_widget.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -392,90 +393,84 @@ class EmailTileBuilder with BaseEmailItemTile {
}); });
} }
double _getIconSize() {
return responsiveUtils.isDesktop(_context) ? 18 : 16;
}
EdgeInsets _getPaddingIcon() {
return responsiveUtils.isDesktop(_context)
? const EdgeInsets.all(8)
: const EdgeInsets.all(5);
}
Widget _buildListActionButtonWhenHover() { Widget _buildListActionButtonWhenHover() {
return Row(children: [ return Row(children: [
buildSVGIconButton(
icon: imagePaths.icOpenInNewTab,
iconColor: AppColor.colorActionButtonHover,
iconSize: _getIconSize(),
padding: _getPaddingIcon(),
tooltip: AppLocalizations.of(_context).openInNewTab,
onTap: () => _emailActionClick?.call(
EmailActionType.openInNewTab,
_presentationEmail
)
),
if(!_presentationEmail.isDraft) if(!_presentationEmail.isDraft)
buildIconWeb( buildSVGIconButton(
minSize: 18, icon: _presentationEmail.hasRead ? imagePaths.icRead: imagePaths.icUnread,
iconSize: 18, iconColor: AppColor.colorActionButtonHover,
iconPadding: const EdgeInsets.all(5), iconSize: _getIconSize(),
splashRadius: 10, padding: _getPaddingIcon(),
icon: SvgPicture.asset( tooltip: _presentationEmail.hasRead
_presentationEmail.hasRead ? AppLocalizations.of(_context).mark_as_unread
? imagePaths.icRead : AppLocalizations.of(_context).mark_as_read,
: imagePaths.icUnread, onTap: () => _emailActionClick?.call(
color: AppColor.colorActionButtonHover, _presentationEmail.hasRead ? EmailActionType.markAsUnread : EmailActionType.markAsRead,
width: 16, _presentationEmail
height: 16, )
fit: BoxFit.fill), ),
tooltip: _presentationEmail.hasRead
? AppLocalizations.of(_context).mark_as_unread
: AppLocalizations.of(_context).mark_as_read,
onTap: () => _emailActionClick?.call(
_presentationEmail.hasRead
? EmailActionType.markAsUnread
: EmailActionType.markAsRead,
_presentationEmail)),
const SizedBox(width: 5),
if (mailboxContain != null && mailboxContain?.isDrafts == false) if (mailboxContain != null && mailboxContain?.isDrafts == false)
... [ ... [
buildIconWeb( buildSVGIconButton(
minSize: 18, icon: imagePaths.icMove,
iconSize: 18, iconColor: AppColor.colorActionButtonHover,
iconPadding: const EdgeInsets.all(5), iconSize: _getIconSize(),
splashRadius: 10, padding: _getPaddingIcon(),
icon: SvgPicture.asset( tooltip: AppLocalizations.of(_context).move,
imagePaths.icMove, onTap: () => _emailActionClick?.call(
width: 16, EmailActionType.moveToMailbox,
height: 16, _presentationEmail
color: AppColor.colorActionButtonHover, )
fit: BoxFit.fill), ),
tooltip: AppLocalizations.of(_context).move,
onTap: () => _emailActionClick?.call(
EmailActionType.moveToMailbox,
_presentationEmail)),
const SizedBox(width: 5),
], ],
buildIconWeb( buildSVGIconButton(
minSize: 18, icon: imagePaths.icDeleteComposer,
iconSize: 18, iconColor: AppColor.colorActionButtonHover,
iconPadding: const EdgeInsets.all(5), iconSize: responsiveUtils.isDesktop(_context) ? 16 : 14,
splashRadius: 10, padding: _getPaddingIcon(),
icon: SvgPicture.asset( tooltip: canDeletePermanently
canDeletePermanently ? imagePaths.icDeleteComposer : imagePaths.icDelete, ? AppLocalizations.of(_context).delete_permanently
width: canDeletePermanently ? 14 : 16, : AppLocalizations.of(_context).move_to_trash,
height: canDeletePermanently ? 14 : 16, onTap: () => _emailActionClick?.call(
color: AppColor.colorActionButtonHover, canDeletePermanently ? EmailActionType.deletePermanently : EmailActionType.moveToTrash,
fit: BoxFit.fill), _presentationEmail
tooltip: canDeletePermanently )
? AppLocalizations.of(_context).delete_permanently ),
: AppLocalizations.of(_context).move_to_trash, buildSVGIconButton(
onTap: () => _emailActionClick?.call( icon: imagePaths.icMore,
canDeletePermanently iconColor: AppColor.colorActionButtonHover,
? EmailActionType.deletePermanently iconSize: _getIconSize(),
: EmailActionType.moveToTrash, padding: _getPaddingIcon(),
_presentationEmail)), tooltip: AppLocalizations.of(_context).more,
const SizedBox(width: 5), onTapDown: (tapDetails) {
if (mailboxContain?.isDrafts == false) if (responsiveUtils.isScreenWithShortestSide(_context)) {
buildIconWebHasPosition( _onMoreActionClick?.call(_presentationEmail, null);
_context, } else {
icon: SvgPicture.asset( _onMoreActionClick?.call(_presentationEmail, tapDetails.getPosition(_context));
imagePaths.icMore, }
width: 16, }
height: 16, ),
color: AppColor.colorActionButtonHover,
fit: BoxFit.fill),
tooltip: AppLocalizations.of(_context).more,
onTap: () {
if (responsiveUtils.isMobile(_context)) {
_onMoreActionClick?.call(_presentationEmail, null);
}
},
onTapDown: (position) {
if (!responsiveUtils.isMobile(_context)) {
_onMoreActionClick?.call(_presentationEmail, position);
}
}),
if (responsiveUtils.isDesktop(_context)) const SizedBox(width: 16), if (responsiveUtils.isDesktop(_context)) const SizedBox(width: 16),
]); ]);
} }
@@ -510,7 +505,6 @@ class EmailTileBuilder with BaseEmailItemTile {
padding: const EdgeInsets.only(right: 4, left: 8), padding: const EdgeInsets.only(right: 4, left: 8),
child: buildDateTime(_context, _presentationEmail)), child: buildDateTime(_context, _presentationEmail)),
buildIconChevron() buildIconChevron()
]); ]);
} }
+7 -1
View File
@@ -1,5 +1,5 @@
{ {
"@@last_modified": "2022-11-11T02:15:40.658946", "@@last_modified": "2022-11-14T16:25:49.764077",
"initializing_data": "Initializing data...", "initializing_data": "Initializing data...",
"@initializing_data": { "@initializing_data": {
"type": "text", "type": "text",
@@ -2521,5 +2521,11 @@
"type": "text", "type": "text",
"placeholders_order": [], "placeholders_order": [],
"placeholders": {} "placeholders": {}
},
"openInNewTab": "Open in New Tab",
"@openInNewTab": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
} }
} }
@@ -2587,4 +2587,11 @@ class AppLocalizations {
'Page 404', 'Page 404',
name: 'page404'); name: 'page404');
} }
String get openInNewTab {
return Intl.message(
'Open in New Tab',
name: 'openInNewTab',
);
}
} }
+1
View File
@@ -17,4 +17,5 @@ enum EmailActionType {
selection, selection,
moveToSpam, moveToSpam,
unSpam, unSpam,
openInNewTab
} }
@@ -155,7 +155,7 @@ extension PresentationEmailExtension on PresentationEmail {
mailboxIds: mailboxIds, mailboxIds: mailboxIds,
mailboxNames: listMailboxName, mailboxNames: listMailboxName,
selectMode: selectMode, selectMode: selectMode,
routeWeb: routeWeb routeWeb: routeWeb
); );
} }