From 360027d7a10becd790bde33a75269ca54ef56837 Mon Sep 17 00:00:00 2001 From: dab246 Date: Fri, 6 Dec 2024 02:28:59 +0700 Subject: [PATCH] TF-3181 Handle on click contact support (cherry picked from commit 7a6a02f58f5194c7f8c8ad3c047a5b8938ba598e) --- .../base/mixin/contact_support_mixin.dart | 38 +++++++ .../presentation/mailbox_controller.dart | 4 +- .../mailbox/presentation/mailbox_view.dart | 6 +- .../presentation/mailbox_view_web.dart | 6 +- .../mailbox_dashboard_controller.dart | 4 +- .../mailbox_dashboard_view_web.dart | 5 + .../navigation_bar/navigation_bar_widget.dart | 7 +- .../contact_support_capability_extension.dart | 11 ++ model/lib/model.dart | 1 + .../session/session_extensions_test.dart | 100 ++++++++++++++++++ 10 files changed, 176 insertions(+), 6 deletions(-) create mode 100644 lib/features/base/mixin/contact_support_mixin.dart create mode 100644 model/lib/extensions/contact_support_capability_extension.dart diff --git a/lib/features/base/mixin/contact_support_mixin.dart b/lib/features/base/mixin/contact_support_mixin.dart new file mode 100644 index 000000000..535984d45 --- /dev/null +++ b/lib/features/base/mixin/contact_support_mixin.dart @@ -0,0 +1,38 @@ + +import 'package:core/utils/app_logger.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/utils/app_utils.dart'; + +typedef OnTapContactSupportAction = Function(ContactSupportCapability contactSupport); + +mixin ContactSupportMixin { + + void onGetHelpOrReportBug( + ContactSupportCapability contactSupport, + MailboxDashBoardController mailboxDashBoardController, + ) { + log('ContactSupportMixin::onGetHelpOrReportBug:contactSupport = $contactSupport'); + if (contactSupport.isMailAddressSupported) { + _handleMailAddress(contactSupport.supportMailAddress!, mailboxDashBoardController); + } else if (contactSupport.isHttpLinkSupported) { + _handleHttpLink(contactSupport.httpLink!); + } + } + + void _handleMailAddress( + String mailAddress, + MailboxDashBoardController mailboxDashBoardController, + ) { + mailboxDashBoardController.goToComposer( + ComposerArguments.fromEmailAddress(EmailAddress(null, mailAddress)), + ); + } + + void _handleHttpLink(String httpLink) { + AppUtils.launchLink(httpLink); + } +} \ No newline at end of file diff --git a/lib/features/mailbox/presentation/mailbox_controller.dart b/lib/features/mailbox/presentation/mailbox_controller.dart index 8308ccf59..524f7d1a0 100644 --- a/lib/features/mailbox/presentation/mailbox_controller.dart +++ b/lib/features/mailbox/presentation/mailbox_controller.dart @@ -17,6 +17,7 @@ import 'package:model/model.dart'; import 'package:pointer_interceptor/pointer_interceptor.dart'; import 'package:rxdart/transformers.dart'; import 'package:tmail_ui_user/features/base/base_mailbox_controller.dart'; +import 'package:tmail_ui_user/features/base/mixin/contact_support_mixin.dart'; import 'package:tmail_ui_user/features/base/mixin/mailbox_action_handler_mixin.dart'; import 'package:tmail_ui_user/features/email/domain/model/move_action.dart'; import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart'; @@ -77,7 +78,8 @@ 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/ios_sharing_manager.dart'; -class MailboxController extends BaseMailboxController with MailboxActionHandlerMixin { +class MailboxController extends BaseMailboxController + with MailboxActionHandlerMixin, ContactSupportMixin { final mailboxDashBoardController = Get.find(); final isMailboxListScrollable = false.obs; diff --git a/lib/features/mailbox/presentation/mailbox_view.dart b/lib/features/mailbox/presentation/mailbox_view.dart index 545604983..6117a92ac 100644 --- a/lib/features/mailbox/presentation/mailbox_view.dart +++ b/lib/features/mailbox/presentation/mailbox_view.dart @@ -118,7 +118,11 @@ class MailboxView extends BaseMailboxView { fontWeight: FontWeight.w500, color: AppColor.primaryColor, ), - onTapActionCallback: () {}, + onTapActionCallback: () => + controller.onGetHelpOrReportBug( + controller.contactSupportCapability!, + controller.mailboxDashBoardController, + ), ), ), ], diff --git a/lib/features/mailbox/presentation/mailbox_view_web.dart b/lib/features/mailbox/presentation/mailbox_view_web.dart index c3b36186b..0be90fdbf 100644 --- a/lib/features/mailbox/presentation/mailbox_view_web.dart +++ b/lib/features/mailbox/presentation/mailbox_view_web.dart @@ -101,7 +101,11 @@ class MailboxView extends BaseMailboxView { fontWeight: FontWeight.w500, color: AppColor.primaryColor, ), - onTapActionCallback: () {}, + onTapActionCallback: () => + controller.onGetHelpOrReportBug( + controller.contactSupportCapability!, + controller.mailboxDashBoardController, + ), ), ), ], diff --git a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart index 4af181a92..7966608a7 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart @@ -28,6 +28,7 @@ import 'package:pointer_interceptor/pointer_interceptor.dart'; import 'package:receive_sharing_intent/receive_sharing_intent.dart'; import 'package:rxdart/transformers.dart'; import 'package:tmail_ui_user/features/base/action/ui_action.dart'; +import 'package:tmail_ui_user/features/base/mixin/contact_support_mixin.dart'; import 'package:tmail_ui_user/features/base/reloadable/reloadable_controller.dart'; import 'package:tmail_ui_user/features/composer/domain/exceptions/set_method_exception.dart'; import 'package:tmail_ui_user/features/composer/domain/extensions/email_request_extension.dart'; @@ -166,7 +167,8 @@ import 'package:tmail_ui_user/main/utils/email_receive_manager.dart'; import 'package:tmail_ui_user/main/utils/ios_notification_manager.dart'; import 'package:uuid/uuid.dart'; -class MailboxDashBoardController extends ReloadableController with UserSettingPopupMenuMixin { +class MailboxDashBoardController extends ReloadableController + with UserSettingPopupMenuMixin, ContactSupportMixin { final RemoveEmailDraftsInteractor _removeEmailDraftsInteractor = Get.find(); final EmailReceiveManager _emailReceiveManager = Get.find(); diff --git a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart index c214085f2..bef9b16a6 100644 --- a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart +++ b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart @@ -75,6 +75,11 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { onShowAppDashboardAction: controller.showAppDashboardAction, onTapApplicationLogoAction: controller.redirectToInboxAction, onTapAvatarAction: (position) => controller.handleClickAvatarAction(context, position), + onTapContactSupportAction: (contactSupport) => + controller.onGetHelpOrReportBug( + contactSupport, + controller, + ), ); } }), diff --git a/lib/features/mailbox_dashboard/presentation/widgets/navigation_bar/navigation_bar_widget.dart b/lib/features/mailbox_dashboard/presentation/widgets/navigation_bar/navigation_bar_widget.dart index 2c0207d60..1061d3e8c 100644 --- a/lib/features/mailbox_dashboard/presentation/widgets/navigation_bar/navigation_bar_widget.dart +++ b/lib/features/mailbox_dashboard/presentation/widgets/navigation_bar/navigation_bar_widget.dart @@ -5,6 +5,7 @@ import 'package:core/presentation/views/button/tmail_button_widget.dart'; import 'package:core/presentation/views/image/avatar_builder.dart'; import 'package:flutter/material.dart'; import 'package:model/support/contact_support_capability.dart'; +import 'package:tmail_ui_user/features/base/mixin/contact_support_mixin.dart'; import 'package:tmail_ui_user/features/base/widget/application_logo_with_text_widget.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/app_grid_dashboard_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/styles/navigation_bar_style.dart'; @@ -22,6 +23,7 @@ class NavigationBarWidget extends StatelessWidget { final VoidCallback? onTapApplicationLogoAction; final VoidCallback? onShowAppDashboardAction; final OnTapAvatarActionWithPositionClick? onTapAvatarAction; + final OnTapContactSupportAction? onTapContactSupportAction; const NavigationBarWidget({ super.key, @@ -33,6 +35,7 @@ class NavigationBarWidget extends StatelessWidget { this.onShowAppDashboardAction, this.onTapApplicationLogoAction, this.onTapAvatarAction, + this.onTapContactSupportAction, }); @override @@ -69,7 +72,7 @@ class NavigationBarWidget extends StatelessWidget { backgroundColor: Colors.transparent, margin: const EdgeInsetsDirectional.only(end: 8), tooltipMessage: AppLocalizations.of(context).getHelpOrReportABug, - onTapActionCallback: () {}, + onTapActionCallback: () => onTapContactSupportAction?.call(contactSupportCapability!), ), if (AppConfig.appGridDashboardAvailable && appGridController != null) Padding( @@ -109,7 +112,7 @@ class NavigationBarWidget extends StatelessWidget { backgroundColor: Colors.transparent, margin: const EdgeInsetsDirectional.only(end: 8), tooltipMessage: AppLocalizations.of(context).getHelpOrReportABug, - onTapActionCallback: () {}, + onTapActionCallback: () => onTapContactSupportAction?.call(contactSupportCapability!), ), if (AppConfig.appGridDashboardAvailable && appGridController != null) Padding( diff --git a/model/lib/extensions/contact_support_capability_extension.dart b/model/lib/extensions/contact_support_capability_extension.dart new file mode 100644 index 000000000..54fec1ba9 --- /dev/null +++ b/model/lib/extensions/contact_support_capability_extension.dart @@ -0,0 +1,11 @@ + +import 'package:model/support/contact_support_capability.dart'; + +extension ContactSupportCapabilityExtension on ContactSupportCapability { + + bool get isMailAddressSupported => + supportMailAddress?.trim().isNotEmpty == true; + + bool get isHttpLinkSupported => + httpLink?.trim().isNotEmpty == true; +} \ No newline at end of file diff --git a/model/lib/model.dart b/model/lib/model.dart index 1cfbf702b..29e3c9733 100644 --- a/model/lib/model.dart +++ b/model/lib/model.dart @@ -59,6 +59,7 @@ export 'extensions/properties_extension.dart'; export 'extensions/session_extension.dart'; export 'extensions/username_extension.dart'; export 'extensions/utc_date_extension.dart'; +export 'extensions/contact_support_capability_extension.dart'; // Identity export 'identity/identity_request_dto.dart'; export 'mailbox/expand_mode.dart'; diff --git a/test/features/session/session_extensions_test.dart b/test/features/session/session_extensions_test.dart index 221914a42..abacfc00c 100644 --- a/test/features/session/session_extensions_test.dart +++ b/test/features/session/session_extensions_test.dart @@ -6,6 +6,7 @@ import 'package:jmap_dart_client/jmap/core/session/session.dart'; import 'package:jmap_dart_client/jmap/core/state.dart'; import 'package:jmap_dart_client/jmap/core/unsigned_int.dart'; import 'package:jmap_dart_client/jmap/core/user_name.dart'; +import 'package:model/support/contact_support_capability.dart'; import 'package:tmail_ui_user/features/home/domain/extensions/session_extensions.dart'; import '../../fixtures/account_fixtures.dart'; @@ -102,4 +103,103 @@ void main() { expect(result, isNull); }); }); + + group('getContactSupportCapability::test', () { + test('SHOULD return ContactSupportCapability WHEN ContactSupportCapability is available', () { + // Arrange + final contactSupportCapability = ContactSupportCapability( + supportMailAddress: 'contact.support@example.com', + httpLink: 'https://contact.support', + ); + final session = Session( + { + SessionExtensions.linagoraContactSupportCapability: contactSupportCapability + }, + { + AccountFixtures.aliceAccountId: Account( + AccountName('Alice'), + true, + false, + { + SessionExtensions.linagoraContactSupportCapability: contactSupportCapability + }, + ) + }, + {}, + UserName(''), + Uri(), + Uri(), + Uri(), + Uri(), + State(''), + ); + + // Act + final result = session.getContactSupportCapability(AccountFixtures.aliceAccountId); + + // Assert + expect(result?.supportMailAddress, equals(contactSupportCapability.supportMailAddress)); + expect(result?.httpLink, equals(contactSupportCapability.httpLink)); + }); + + test('SHOULD return null WHEN ContactSupportCapability is not available', () { + // Arrange + final session = Session( + { + SessionExtensions.linagoraContactSupportCapability: EmptyCapability() + }, + { + AccountFixtures.aliceAccountId: Account( + AccountName('Alice'), + true, + false, + { + SessionExtensions.linagoraContactSupportCapability: EmptyCapability() + }, + ) + }, + {}, + UserName(''), + Uri(), + Uri(), + Uri(), + Uri(), + State(''), + ); + + // Act + final result = session.getContactSupportCapability(AccountFixtures.aliceAccountId); + + // Assert + expect(result, isNull); + }); + + test('SHOULD return null WHEN ContactSupportCapability is not supported', () { + // Arrange + final session = Session( + {}, + { + AccountFixtures.aliceAccountId: Account( + AccountName('Alice'), + true, + false, + {}, + ) + }, + {}, + UserName(''), + Uri(), + Uri(), + Uri(), + Uri(), + State(''), + ); + + // Act + final result = session.getContactSupportCapability(AccountFixtures.aliceAccountId); + + // Assert + expect(result, isNull); + }); + }); }