From 4097ab01d21283e7c6e86a80a573c2e4b7d163f7 Mon Sep 17 00:00:00 2001 From: dab246 Date: Thu, 6 Feb 2025 15:25:58 +0700 Subject: [PATCH] Handle contact support on mobile Signed-off-by: dab246 --- .../base/mixin/contact_support_mixin.dart | 22 +++-- .../manage_account_dashboard_controller.dart | 4 +- .../menu/manage_account_menu_view.dart | 99 ++++++------------- .../settings/settings_first_level_view.dart | 32 +++--- .../account_menu_item_tile_builder.dart | 64 ++++++------ .../presentation/model/account_menu_item.dart | 7 ++ lib/main/routes/route_utils.dart | 4 + 7 files changed, 103 insertions(+), 129 deletions(-) diff --git a/lib/features/base/mixin/contact_support_mixin.dart b/lib/features/base/mixin/contact_support_mixin.dart index cf78294cc..fb9aaaad3 100644 --- a/lib/features/base/mixin/contact_support_mixin.dart +++ b/lib/features/base/mixin/contact_support_mixin.dart @@ -1,9 +1,11 @@ +import 'package:core/utils/platform_info.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:model/extensions/contact_support_capability_extension.dart'; import 'package:model/support/contact_support_capability.dart'; import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.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_utils.dart'; import 'package:tmail_ui_user/main/utils/app_utils.dart'; @@ -12,22 +14,26 @@ typedef OnTapContactSupportAction = Function(ContactSupportCapability contactSup mixin ContactSupportMixin { - void onGetHelpOrReportBug(ContactSupportCapability contactSupport) { + void onGetHelpOrReportBug( + ContactSupportCapability contactSupport, + {String route = AppRoutes.dashboard} + ) { if (contactSupport.isMailAddressSupported) { - _handleMailAddress(contactSupport.supportMailAddress!); + _handleMailAddress(contactSupport.supportMailAddress!, route: route); } else if (contactSupport.isHttpLinkSupported) { _handleHttpLink(contactSupport.httpLink!); } } - void _handleMailAddress(String mailAddress) { - final mailboxDashBoardController = getBinding(); - if (mailboxDashBoardController != null) { - mailboxDashBoardController.goToComposer( + void _handleMailAddress(String mailAddress, {String route = AppRoutes.dashboard}) { + if (route == AppRoutes.settings && PlatformInfo.isWeb) { + final mailtoLink = RouteUtils.generateMailtoLink(mailAddress); + AppUtils.launchLink(mailtoLink); + } else { + final mailboxDashBoardController = getBinding(); + mailboxDashBoardController?.goToComposer( ComposerArguments.fromEmailAddress(EmailAddress(null, mailAddress)), ); - } else { - AppUtils.launchLink('${RouteUtils.mailtoPrefix}:$mailAddress'); } } diff --git a/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart b/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart index dc0c8274c..15cad8151 100644 --- a/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart +++ b/lib/features/manage_account/presentation/manage_account_dashboard_controller.dart @@ -195,9 +195,7 @@ class ManageAccountDashBoardController extends ReloadableController with UserSet case AccountMenuItem.notification: NotificationBinding().dependencies(); break; - case AccountMenuItem.vacation: - case AccountMenuItem.contactSupport: - case AccountMenuItem.none: + default: break; } } diff --git a/lib/features/manage_account/presentation/menu/manage_account_menu_view.dart b/lib/features/manage_account/presentation/menu/manage_account_menu_view.dart index 956662769..6725b7c61 100644 --- a/lib/features/manage_account/presentation/menu/manage_account_menu_view.dart +++ b/lib/features/manage_account/presentation/menu/manage_account_menu_view.dart @@ -1,15 +1,17 @@ -import 'package:core/core.dart'; +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/presentation/views/button/tmail_button_widget.dart'; import 'package:core/utils/direction_utils.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; import 'package:tmail_ui_user/features/base/widget/application_version_widget.dart'; import 'package:tmail_ui_user/features/base/widget/application_logo_with_text_widget.dart'; import 'package:tmail_ui_user/features/home/domain/extensions/session_extensions.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/menu/manage_account_menu_controller.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/menu/widgets/account_menu_item_tile_builder.dart'; +import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; +import 'package:tmail_ui_user/main/routes/app_routes.dart'; class ManageAccountMenuView extends GetWidget { @@ -84,8 +86,10 @@ class ManageAccountMenuView extends GetWidget { itemBuilder: (context, index) => Obx(() { final menuItem = controller.listAccountMenuItem[index]; return AccountMenuItemTileBuilder( - menuItem, - controller.dashBoardController.accountMenuItemSelected.value, + imagePaths: controller.imagePaths, + responsiveUtils: controller.responsiveUtils, + menuItem: menuItem, + menuItemSelected: controller.dashBoardController.accountMenuItemSelected.value, onSelectAccountMenuItemAction: controller.selectAccountMenuItem ); }) @@ -112,72 +116,31 @@ class ManageAccountMenuView extends GetWidget { if (contactSupportCapability?.isAvailable != true) return const SizedBox.shrink(); - return Padding( - padding: const EdgeInsetsDirectional.only(start: 20, end: 10), - child: Material( - color: Colors.transparent, - child: InkWell( - onTap: () => controller.onGetHelpOrReportBug(contactSupportCapability!), - borderRadius: const BorderRadius.all(Radius.circular(10)), - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 12, - vertical: 6, - ), - child: Row(children: [ - SvgPicture.asset( - controller.imagePaths.icHelp, - width: 20, - height: 20, - fit: BoxFit.fill, - ), - const SizedBox(width: 12), - Expanded( - child: Text( - AppLocalizations.of(context).contactSupport, - style: const TextStyle( - fontWeight: FontWeight.normal, - fontSize: 15, - color: Colors.black, - ), - ), - ) - ]), - ) - ), - ), + return AccountMenuItemTileBuilder( + imagePaths: controller.imagePaths, + responsiveUtils: controller.responsiveUtils, + menuItem: AccountMenuItem.contactSupport, + padding: const EdgeInsetsDirectional.only(start: 16, end: 8, bottom: 6), + onSelectAccountMenuItemAction: (_) { + controller.onGetHelpOrReportBug( + contactSupportCapability!, + route: AppRoutes.settings, + ); + }, ); }), - Padding( - padding: const EdgeInsetsDirectional.only(start: 20, end: 10), - child: Material( - color: Colors.transparent, - child: InkWell( - onTap: () { - controller.dashBoardController.logout( - context, - controller.dashBoardController.sessionCurrent, - controller.dashBoardController.accountId.value - ); - }, - borderRadius: BorderRadius.circular(10), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), - child: Row(children: [ - SvgPicture.asset(controller.imagePaths.icSignOut, width: 20, height: 20, fit: BoxFit.fill), - const SizedBox(width: 12), - Expanded(child: Text( - AppLocalizations.of(context).sign_out, - style: const TextStyle( - fontWeight: FontWeight.normal, - fontSize: 15, - color: Colors.black - ) - )) - ]), - ) - ), - ) + AccountMenuItemTileBuilder( + imagePaths: controller.imagePaths, + responsiveUtils: controller.responsiveUtils, + menuItem: AccountMenuItem.signOut, + padding: const EdgeInsetsDirectional.only(start: 16, end: 8), + onSelectAccountMenuItemAction: (_) { + controller.dashBoardController.logout( + context, + controller.dashBoardController.sessionCurrent, + controller.dashBoardController.accountId.value, + ); + } ), ] ), diff --git a/lib/features/manage_account/presentation/menu/settings/settings_first_level_view.dart b/lib/features/manage_account/presentation/menu/settings/settings_first_level_view.dart index 307fac875..ea1f7948c 100644 --- a/lib/features/manage_account/presentation/menu/settings/settings_first_level_view.dart +++ b/lib/features/manage_account/presentation/menu/settings/settings_first_level_view.dart @@ -9,6 +9,7 @@ import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings import 'package:tmail_ui_user/features/manage_account/presentation/menu/widgets/setting_first_level_tile_builder.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; +import 'package:tmail_ui_user/main/routes/app_routes.dart'; class SettingsFirstLevelView extends GetWidget { const SettingsFirstLevelView({Key? key}) : super(key: key); @@ -121,20 +122,18 @@ class SettingsFirstLevelView extends GetWidget { return const SizedBox.shrink(); } }), - Column(children: [ - SettingFirstLevelTileBuilder( - AccountMenuItem.mailboxVisibility.getName(context), - AccountMenuItem.mailboxVisibility.getIcon(controller.imagePaths), - subtitle: AppLocalizations.of(context).folderVisibilitySubtitle, - () => controller.selectSettings(AccountMenuItem.mailboxVisibility) - ), - Divider( - color: AppColor.colorDividerHorizontal, - height: 1, - indent: SettingsUtils.getHorizontalPadding(context, controller.responsiveUtils), - endIndent: SettingsUtils.getHorizontalPadding(context, controller.responsiveUtils) - ), - ]), + SettingFirstLevelTileBuilder( + AccountMenuItem.mailboxVisibility.getName(context), + AccountMenuItem.mailboxVisibility.getIcon(controller.imagePaths), + subtitle: AppLocalizations.of(context).folderVisibilitySubtitle, + () => controller.selectSettings(AccountMenuItem.mailboxVisibility) + ), + Divider( + color: AppColor.colorDividerHorizontal, + height: 1, + indent: SettingsUtils.getHorizontalPadding(context, controller.responsiveUtils), + endIndent: SettingsUtils.getHorizontalPadding(context, controller.responsiveUtils) + ), SettingFirstLevelTileBuilder( AccountMenuItem.languageAndRegion.getName(context), AccountMenuItem.languageAndRegion.getIcon(controller.imagePaths), @@ -185,7 +184,10 @@ class SettingsFirstLevelView extends GetWidget { SettingFirstLevelTileBuilder( AccountMenuItem.contactSupport.getName(context), AccountMenuItem.contactSupport.getIcon(controller.imagePaths), - () => controller.onGetHelpOrReportBug(contactSupportCapability!), + () => controller.onGetHelpOrReportBug( + contactSupportCapability!, + route: AppRoutes.settings, + ), ), ]); }), diff --git a/lib/features/manage_account/presentation/menu/widgets/account_menu_item_tile_builder.dart b/lib/features/manage_account/presentation/menu/widgets/account_menu_item_tile_builder.dart index 5f689cf60..458bfe9c8 100644 --- a/lib/features/manage_account/presentation/menu/widgets/account_menu_item_tile_builder.dart +++ b/lib/features/manage_account/presentation/menu/widgets/account_menu_item_tile_builder.dart @@ -1,53 +1,59 @@ -import 'package:core/core.dart'; +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:get/get.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart'; typedef OnSelectAccountMenuItemAction = void Function(AccountMenuItem); class AccountMenuItemTileBuilder extends StatelessWidget { - final AccountMenuItem _menuItem; - final AccountMenuItem? _menuItemSelected; - final OnSelectAccountMenuItemAction? onSelectAccountMenuItemAction; + final ImagePaths imagePaths; + final ResponsiveUtils responsiveUtils; + final AccountMenuItem menuItem; + final AccountMenuItem? menuItemSelected; + final EdgeInsetsGeometry? padding; + final OnSelectAccountMenuItemAction onSelectAccountMenuItemAction; - const AccountMenuItemTileBuilder( - this._menuItem, - this._menuItemSelected, - { - Key? key, - this.onSelectAccountMenuItemAction - } - ) : super(key: key); + const AccountMenuItemTileBuilder({ + Key? key, + required this.imagePaths, + required this.responsiveUtils, + required this.menuItem, + required this.onSelectAccountMenuItemAction, + this.menuItemSelected, + this.padding, + }) : super(key: key); @override Widget build(BuildContext context) { - final imagePaths = Get.find(); - return Padding( - key: const Key('account_menu_item_tile'), - padding: const EdgeInsets.only(top: 6), + key: Key('${menuItem.getAliasBrowser()}_account_menu_item_tile'), + padding: padding ?? const EdgeInsets.only(top: 6), child: Material( color: Colors.transparent, child: InkWell( - onTap: () => onSelectAccountMenuItemAction?.call(_menuItem), - borderRadius: BorderRadius.circular(10), + onTap: () => onSelectAccountMenuItemAction.call(menuItem), + borderRadius: const BorderRadius.all(Radius.circular(10)), child: Container( decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: _getBackgroundColorItem(context)), + borderRadius: const BorderRadius.all(Radius.circular(10)), + color: menuItemSelected == menuItem + ? AppColor.colorBgMailboxSelected + : Colors.transparent, + ), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), child: Column(children: [ Row(children: [ SvgPicture.asset( - _menuItem.getIcon(imagePaths), + menuItem.getIcon(imagePaths), width: 20, height: 20, fit: BoxFit.fill), const SizedBox(width: 12), Expanded(child: Text( - _menuItem.getName(context), + menuItem.getName(context), style: const TextStyle( fontWeight: FontWeight.normal, fontSize: 15, @@ -60,16 +66,4 @@ class AccountMenuItemTileBuilder extends StatelessWidget { ), ); } - - Color _getBackgroundColorItem(BuildContext context) { - final responsiveUtils = Get.find(); - - if (_menuItemSelected == _menuItem) { - return AppColor.colorBgMailboxSelected; - } else { - return responsiveUtils.isWebDesktop(context) - ? Colors.transparent - : Colors.transparent; - } - } } \ No newline at end of file diff --git a/lib/features/manage_account/presentation/model/account_menu_item.dart b/lib/features/manage_account/presentation/model/account_menu_item.dart index 15ca130f2..1c4a0ede6 100644 --- a/lib/features/manage_account/presentation/model/account_menu_item.dart +++ b/lib/features/manage_account/presentation/model/account_menu_item.dart @@ -13,6 +13,7 @@ enum AccountMenuItem { mailboxVisibility, notification, contactSupport, + signOut, none; String getIcon(ImagePaths imagePaths) { @@ -35,6 +36,8 @@ enum AccountMenuItem { return imagePaths.icNotification; case AccountMenuItem.contactSupport: return imagePaths.icHelp; + case AccountMenuItem.signOut: + return imagePaths.icSignOut; case AccountMenuItem.none: return imagePaths.icProfiles; } @@ -60,6 +63,8 @@ enum AccountMenuItem { return AppLocalizations.of(context).notification; case AccountMenuItem.contactSupport: return AppLocalizations.of(context).contactSupport; + case AccountMenuItem.signOut: + return AppLocalizations.of(context).sign_out; case AccountMenuItem.none: return AppLocalizations.of(context).profiles; } @@ -85,6 +90,8 @@ enum AccountMenuItem { return 'notification'; case AccountMenuItem.contactSupport: return 'contact-support'; + case AccountMenuItem.signOut: + return 'sign-out'; case AccountMenuItem.none: return 'profiles'; } diff --git a/lib/main/routes/route_utils.dart b/lib/main/routes/route_utils.dart index 2493cfb70..494539da4 100644 --- a/lib/main/routes/route_utils.dart +++ b/lib/main/routes/route_utils.dart @@ -255,4 +255,8 @@ abstract class RouteUtils { static String get emailEMLPreviewerRoutePath => _createEmailEMLPreviewerServicePath('$baseOriginUrl${AppRoutes.emailEMLPreviewer}').path; + + static String generateMailtoLink(String mailAddress) { + return '$baseOriginUrl/$mailtoPrefix/?uri=$mailtoPrefix:$mailAddress'; + } } \ No newline at end of file