From 5c7d2fd5d9591012aaced26ea33d8291c712ed01 Mon Sep 17 00:00:00 2001 From: dab246 Date: Fri, 16 Feb 2024 18:23:28 +0700 Subject: [PATCH] TF-2596 Support mail to with several recipients Signed-off-by: dab246 --- .../presentation/composer_controller.dart | 10 ++--- .../controller/single_email_controller.dart | 2 +- .../model/composer_arguments.dart | 16 ++++---- .../presentation/mailbox_controller.dart | 6 +-- .../mailbox_dashboard_controller.dart | 2 +- .../presentation/model/mailto_arguments.dart | 2 +- lib/main/routes/navigation_router.dart | 6 +-- lib/main/routes/route_utils.dart | 39 ++++++++++++++----- 8 files changed, 51 insertions(+), 32 deletions(-) diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart index a9a630482..34fe02abd 100644 --- a/lib/features/composer/presentation/composer_controller.dart +++ b/lib/features/composer/presentation/composer_controller.dart @@ -456,7 +456,7 @@ class ComposerController extends BaseController { _addAttachmentFromFileShare(arguments.listSharedMediaFile!); break; case EmailActionType.composeFromEmailAddress: - listToEmailAddress.add(arguments.emailAddress!); + listToEmailAddress.addAll(arguments.listEmailAddress ?? []); isInitialRecipient.value = true; toAddressExpandMode.value = ExpandMode.COLLAPSE; _updateStatusEmailSendButton(); @@ -466,8 +466,8 @@ class ComposerController extends BaseController { setSubjectEmail(arguments.subject!); subjectEmailInputController.text = arguments.subject!; } - if (arguments.emailAddress != null) { - listToEmailAddress.add(arguments.emailAddress!); + if (arguments.listEmailAddress?.isNotEmpty == true) { + listToEmailAddress.addAll(arguments.listEmailAddress!); isInitialRecipient.value = true; toAddressExpandMode.value = ExpandMode.COLLAPSE; } @@ -512,8 +512,8 @@ class ComposerController extends BaseController { setSubjectEmail(arguments.subject!); subjectEmailInputController.text = arguments.subject!; } - if (arguments.emailAddress != null) { - listToEmailAddress.add(arguments.emailAddress!); + if (arguments.listEmailAddress?.isNotEmpty == true) { + listToEmailAddress.addAll(arguments.listEmailAddress!); isInitialRecipient.value = true; toAddressExpandMode.value = ExpandMode.COLLAPSE; } diff --git a/lib/features/email/presentation/controller/single_email_controller.dart b/lib/features/email/presentation/controller/single_email_controller.dart index 85570a783..d692c43b6 100644 --- a/lib/features/email/presentation/controller/single_email_controller.dart +++ b/lib/features/email/presentation/controller/single_email_controller.dart @@ -1476,7 +1476,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin { final navigationRouter = RouteUtils.generateNavigationRouterFromMailtoLink(mailtoLinks.first); mailboxDashBoardController.goToComposer( ComposerArguments.fromUnsubscribeMailtoLink( - emailAddress: navigationRouter.emailAddress, + listEmailAddress: navigationRouter.listEmailAddress, subject: navigationRouter.subject, body: navigationRouter.body, previousEmailId: emailId, diff --git a/lib/features/email/presentation/model/composer_arguments.dart b/lib/features/email/presentation/model/composer_arguments.dart index 61afabf97..527ad67af 100644 --- a/lib/features/email/presentation/model/composer_arguments.dart +++ b/lib/features/email/presentation/model/composer_arguments.dart @@ -13,7 +13,7 @@ class ComposerArguments extends RouterArguments { final PresentationEmail? presentationEmail; final String? emailContents; final List? listSharedMediaFile; - final EmailAddress? emailAddress; + final List? listEmailAddress; final List? attachments; final Role? mailboxRole; final SendingEmail? sendingEmail; @@ -29,7 +29,7 @@ class ComposerArguments extends RouterArguments { this.emailContents, this.attachments, this.mailboxRole, - this.emailAddress, + this.listEmailAddress, this.listSharedMediaFile, this.sendingEmail, this.subject, @@ -60,13 +60,13 @@ class ComposerArguments extends RouterArguments { factory ComposerArguments.fromEmailAddress(EmailAddress emailAddress) => ComposerArguments( emailActionType: EmailActionType.composeFromEmailAddress, - emailAddress: emailAddress + listEmailAddress: [emailAddress] ); - factory ComposerArguments.fromMailtoUri({EmailAddress? emailAddress, String? subject, String? body}) => + factory ComposerArguments.fromMailtoUri({List? listEmailAddress, String? subject, String? body}) => ComposerArguments( emailActionType: EmailActionType.composeFromMailtoUri, - emailAddress: emailAddress, + listEmailAddress: listEmailAddress, subject: subject, body: body, ); @@ -142,14 +142,14 @@ class ComposerArguments extends RouterArguments { : SendingEmailActionType.create; factory ComposerArguments.fromUnsubscribeMailtoLink({ - EmailAddress? emailAddress, + List? listEmailAddress, String? subject, String? body, EmailId? previousEmailId }) => ComposerArguments( emailActionType: EmailActionType.composeFromUnsubscribeMailtoLink, - emailAddress: emailAddress, + listEmailAddress: listEmailAddress, subject: subject, body: body, previousEmailId: previousEmailId, @@ -163,7 +163,7 @@ class ComposerArguments extends RouterArguments { emailContents, attachments, mailboxRole, - emailAddress, + listEmailAddress, listSharedMediaFile, sendingEmail, subject, diff --git a/lib/features/mailbox/presentation/mailbox_controller.dart b/lib/features/mailbox/presentation/mailbox_controller.dart index 8452d40b0..45bdc7fa0 100644 --- a/lib/features/mailbox/presentation/mailbox_controller.dart +++ b/lib/features/mailbox/presentation/mailbox_controller.dart @@ -225,7 +225,7 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM } }); - ever?>( + ever?>( mailboxDashBoardController.routerParameters, _handleNavigationRouteParameters ); @@ -436,7 +436,7 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM if (_navigationRouter?.routeName == AppRoutes.mailtoURL) { mailboxDashBoardController.goToComposer( ComposerArguments.fromMailtoUri( - emailAddress: _navigationRouter?.emailAddress, + listEmailAddress: _navigationRouter?.listEmailAddress, subject: _navigationRouter?.subject, body: _navigationRouter?.body ) @@ -967,7 +967,7 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM curve: Curves.easeInToLinear); } - void _handleNavigationRouteParameters(Map? parameters) { + void _handleNavigationRouteParameters(Map? parameters) { log('MailboxController::_handleNavigationRouteParameters(): parameters: $parameters'); if (parameters != null) { final navigationRouter = RouteUtils.parsingRouteParametersToNavigationRouter(parameters); 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 db3b2b958..51dacdebb 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart @@ -211,7 +211,7 @@ class MailboxDashBoardController extends ReloadableController { final composerOverlayState = ComposerOverlayState.inActive.obs; final viewStateMarkAsReadMailbox = Rx>(Right(UIState.idle)); final vacationResponse = Rxn(); - final routerParameters = Rxn>(); + final routerParameters = Rxn>(); final _isDraggingMailbox = RxBool(false); final searchMailboxActivated = RxBool(false); final listSendingEmails = RxList(); diff --git a/lib/features/mailto/presentation/model/mailto_arguments.dart b/lib/features/mailto/presentation/model/mailto_arguments.dart index ec7d538e1..95db6f4a6 100644 --- a/lib/features/mailto/presentation/model/mailto_arguments.dart +++ b/lib/features/mailto/presentation/model/mailto_arguments.dart @@ -10,7 +10,7 @@ class MailtoArguments extends RouterArguments { MailtoArguments({required this.session, this.mailtoUri}); - Map toMapRouter() => RouteUtils.parseMapMailtoFromUri(mailtoUri); + Map toMapRouter() => RouteUtils.parseMapMailtoFromUri(mailtoUri); @override List get props => [session, mailtoUri]; diff --git a/lib/main/routes/navigation_router.dart b/lib/main/routes/navigation_router.dart index 9409e3240..50c120b6b 100644 --- a/lib/main/routes/navigation_router.dart +++ b/lib/main/routes/navigation_router.dart @@ -17,7 +17,7 @@ class NavigationRouter with EquatableMixin { final DashboardType dashboardType; final SearchQuery? searchQuery; final String? routeName; - final EmailAddress? emailAddress; + final List? listEmailAddress; final String? subject; final String? body; final AccountMenuItem accountMenuItem; @@ -28,7 +28,7 @@ class NavigationRouter with EquatableMixin { this.searchQuery, this.dashboardType = DashboardType.normal, this.routeName, - this.emailAddress, + this.listEmailAddress, this.subject, this.body, this.accountMenuItem = AccountMenuItem.none, @@ -43,7 +43,7 @@ class NavigationRouter with EquatableMixin { searchQuery, dashboardType, routeName, - emailAddress, + listEmailAddress, subject, body, accountMenuItem, diff --git a/lib/main/routes/route_utils.dart b/lib/main/routes/route_utils.dart index 842b62c54..3f4e03f1e 100644 --- a/lib/main/routes/route_utils.dart +++ b/lib/main/routes/route_utils.dart @@ -27,7 +27,7 @@ abstract class RouteUtils { static const String paramBody = 'body'; static const String mailtoPrefix = 'mailto:'; - + static const String ADDRESS_SEPARATOR = ','; static const String INVALID_VALUE = 'invalid'; static String get baseOriginUrl => Uri.base.origin; @@ -100,7 +100,7 @@ abstract class RouteUtils { } } - static NavigationRouter parsingRouteParametersToNavigationRouter(Map parameters) { + static NavigationRouter parsingRouteParametersToNavigationRouter(Map parameters) { final idParam = parameters[paramID]; final typeParam = parameters[paramType]; final contextPram = parameters[paramContext]; @@ -115,17 +115,27 @@ abstract class RouteUtils { final searchQuery = queryParam != null ? SearchQuery(queryParam) : null; final dashboardType = DashboardType.values.firstWhereOrNull((type) => type.name == typeParam) ?? DashboardType.normal; final settingType = AccountMenuItem.values.firstWhereOrNull((type) => type.getAliasBrowser() == typeParam) ?? AccountMenuItem.none; - final emailAddress = mailtoAddress != null && GetUtils.isEmail(mailtoAddress) - ? EmailAddress(null, mailtoAddress) - : EmailAddress(null, INVALID_VALUE); - + List? listEmailAddress; + if (mailtoAddress is List) { + listEmailAddress = mailtoAddress + .map((address) => EmailAddress( + null, + GetUtils.isEmail(address) ? address : INVALID_VALUE + )) + .toList(); + } else if (mailtoAddress is String) { + listEmailAddress = [ + EmailAddress(null, GetUtils.isEmail(mailtoAddress) ? mailtoAddress : INVALID_VALUE) + ]; + } + log('RouteUtils::parsingRouteParametersToNavigationRouter:listEmailAddress = $listEmailAddress'); return NavigationRouter( emailId: emailId, mailboxId: mailboxId, searchQuery: searchQuery, dashboardType: dashboardType, routeName: routeName, - emailAddress: emailAddress, + listEmailAddress: listEmailAddress, subject: subject, body: body, accountMenuItem: settingType, @@ -137,20 +147,28 @@ abstract class RouteUtils { html.window.history.replaceState(null, title, url.toString()); } - static Map parseMapMailtoFromUri(String? mailtoUri) { + static Map parseMapMailtoFromUri(String? mailtoUri) { log('RouteUtils::parseMapMailtoFromUri:mailtoUri: $mailtoUri'); - final mapMailto = { + final mapMailto = { RouteUtils.paramRouteName: AppRoutes.mailtoURL, }; if (mailtoUri?.startsWith(mailtoPrefix) == true) { final mailtoUrlDecoded = Uri.decodeFull(mailtoUri!); + log('RouteUtils::parseMapMailtoFromUri:mailtoUrlDecoded = $mailtoUrlDecoded'); final uri = Uri.tryParse(mailtoUrlDecoded); if (uri == null) return mapMailto; final mailtoAddress = uri.path; final mapQueryParam = uri.queryParameters; - mapMailto[paramMailtoAddress] = mailtoAddress; + if (mailtoAddress.contains(ADDRESS_SEPARATOR)) { + final listAddress = mailtoAddress.split(ADDRESS_SEPARATOR); + log('RouteUtils::parseMapMailtoFromUri:listAddress = $listAddress'); + mapMailto[paramMailtoAddress] = listAddress; + } else { + log('RouteUtils::parseMapMailtoFromUri:mailtoAddress = $mailtoAddress'); + mapMailto[paramMailtoAddress] = mailtoAddress; + } if (mapQueryParam.containsKey(paramSubject)) { mapMailto[paramSubject] = mapQueryParam[paramSubject]; } @@ -159,6 +177,7 @@ abstract class RouteUtils { } } else if (mailtoUri != null) { final mailtoUrlDecoded = Uri.decodeFull(mailtoUri); + log('RouteUtils::parseMapMailtoFromUri:mailtoUrlDecoded = $mailtoUrlDecoded'); mapMailto[paramMailtoAddress] = mailtoUrlDecoded; } else { mapMailto[paramMailtoAddress] = mailtoUri;