TF-2596 Support mail to with several recipients

Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
dab246
2024-02-16 18:23:28 +07:00
committed by Dat PHAM HOANG
parent b60d071d9a
commit 5c7d2fd5d9
8 changed files with 51 additions and 32 deletions
@@ -456,7 +456,7 @@ class ComposerController extends BaseController {
_addAttachmentFromFileShare(arguments.listSharedMediaFile!); _addAttachmentFromFileShare(arguments.listSharedMediaFile!);
break; break;
case EmailActionType.composeFromEmailAddress: case EmailActionType.composeFromEmailAddress:
listToEmailAddress.add(arguments.emailAddress!); listToEmailAddress.addAll(arguments.listEmailAddress ?? []);
isInitialRecipient.value = true; isInitialRecipient.value = true;
toAddressExpandMode.value = ExpandMode.COLLAPSE; toAddressExpandMode.value = ExpandMode.COLLAPSE;
_updateStatusEmailSendButton(); _updateStatusEmailSendButton();
@@ -466,8 +466,8 @@ class ComposerController extends BaseController {
setSubjectEmail(arguments.subject!); setSubjectEmail(arguments.subject!);
subjectEmailInputController.text = arguments.subject!; subjectEmailInputController.text = arguments.subject!;
} }
if (arguments.emailAddress != null) { if (arguments.listEmailAddress?.isNotEmpty == true) {
listToEmailAddress.add(arguments.emailAddress!); listToEmailAddress.addAll(arguments.listEmailAddress!);
isInitialRecipient.value = true; isInitialRecipient.value = true;
toAddressExpandMode.value = ExpandMode.COLLAPSE; toAddressExpandMode.value = ExpandMode.COLLAPSE;
} }
@@ -512,8 +512,8 @@ class ComposerController extends BaseController {
setSubjectEmail(arguments.subject!); setSubjectEmail(arguments.subject!);
subjectEmailInputController.text = arguments.subject!; subjectEmailInputController.text = arguments.subject!;
} }
if (arguments.emailAddress != null) { if (arguments.listEmailAddress?.isNotEmpty == true) {
listToEmailAddress.add(arguments.emailAddress!); listToEmailAddress.addAll(arguments.listEmailAddress!);
isInitialRecipient.value = true; isInitialRecipient.value = true;
toAddressExpandMode.value = ExpandMode.COLLAPSE; toAddressExpandMode.value = ExpandMode.COLLAPSE;
} }
@@ -1476,7 +1476,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
final navigationRouter = RouteUtils.generateNavigationRouterFromMailtoLink(mailtoLinks.first); final navigationRouter = RouteUtils.generateNavigationRouterFromMailtoLink(mailtoLinks.first);
mailboxDashBoardController.goToComposer( mailboxDashBoardController.goToComposer(
ComposerArguments.fromUnsubscribeMailtoLink( ComposerArguments.fromUnsubscribeMailtoLink(
emailAddress: navigationRouter.emailAddress, listEmailAddress: navigationRouter.listEmailAddress,
subject: navigationRouter.subject, subject: navigationRouter.subject,
body: navigationRouter.body, body: navigationRouter.body,
previousEmailId: emailId, previousEmailId: emailId,
@@ -13,7 +13,7 @@ class ComposerArguments extends RouterArguments {
final PresentationEmail? presentationEmail; final PresentationEmail? presentationEmail;
final String? emailContents; final String? emailContents;
final List<SharedMediaFile>? listSharedMediaFile; final List<SharedMediaFile>? listSharedMediaFile;
final EmailAddress? emailAddress; final List<EmailAddress>? listEmailAddress;
final List<Attachment>? attachments; final List<Attachment>? attachments;
final Role? mailboxRole; final Role? mailboxRole;
final SendingEmail? sendingEmail; final SendingEmail? sendingEmail;
@@ -29,7 +29,7 @@ class ComposerArguments extends RouterArguments {
this.emailContents, this.emailContents,
this.attachments, this.attachments,
this.mailboxRole, this.mailboxRole,
this.emailAddress, this.listEmailAddress,
this.listSharedMediaFile, this.listSharedMediaFile,
this.sendingEmail, this.sendingEmail,
this.subject, this.subject,
@@ -60,13 +60,13 @@ class ComposerArguments extends RouterArguments {
factory ComposerArguments.fromEmailAddress(EmailAddress emailAddress) => factory ComposerArguments.fromEmailAddress(EmailAddress emailAddress) =>
ComposerArguments( ComposerArguments(
emailActionType: EmailActionType.composeFromEmailAddress, emailActionType: EmailActionType.composeFromEmailAddress,
emailAddress: emailAddress listEmailAddress: [emailAddress]
); );
factory ComposerArguments.fromMailtoUri({EmailAddress? emailAddress, String? subject, String? body}) => factory ComposerArguments.fromMailtoUri({List<EmailAddress>? listEmailAddress, String? subject, String? body}) =>
ComposerArguments( ComposerArguments(
emailActionType: EmailActionType.composeFromMailtoUri, emailActionType: EmailActionType.composeFromMailtoUri,
emailAddress: emailAddress, listEmailAddress: listEmailAddress,
subject: subject, subject: subject,
body: body, body: body,
); );
@@ -142,14 +142,14 @@ class ComposerArguments extends RouterArguments {
: SendingEmailActionType.create; : SendingEmailActionType.create;
factory ComposerArguments.fromUnsubscribeMailtoLink({ factory ComposerArguments.fromUnsubscribeMailtoLink({
EmailAddress? emailAddress, List<EmailAddress>? listEmailAddress,
String? subject, String? subject,
String? body, String? body,
EmailId? previousEmailId EmailId? previousEmailId
}) => }) =>
ComposerArguments( ComposerArguments(
emailActionType: EmailActionType.composeFromUnsubscribeMailtoLink, emailActionType: EmailActionType.composeFromUnsubscribeMailtoLink,
emailAddress: emailAddress, listEmailAddress: listEmailAddress,
subject: subject, subject: subject,
body: body, body: body,
previousEmailId: previousEmailId, previousEmailId: previousEmailId,
@@ -163,7 +163,7 @@ class ComposerArguments extends RouterArguments {
emailContents, emailContents,
attachments, attachments,
mailboxRole, mailboxRole,
emailAddress, listEmailAddress,
listSharedMediaFile, listSharedMediaFile,
sendingEmail, sendingEmail,
subject, subject,
@@ -225,7 +225,7 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM
} }
}); });
ever<Map<String, String?>?>( ever<Map<String, dynamic>?>(
mailboxDashBoardController.routerParameters, mailboxDashBoardController.routerParameters,
_handleNavigationRouteParameters _handleNavigationRouteParameters
); );
@@ -436,7 +436,7 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM
if (_navigationRouter?.routeName == AppRoutes.mailtoURL) { if (_navigationRouter?.routeName == AppRoutes.mailtoURL) {
mailboxDashBoardController.goToComposer( mailboxDashBoardController.goToComposer(
ComposerArguments.fromMailtoUri( ComposerArguments.fromMailtoUri(
emailAddress: _navigationRouter?.emailAddress, listEmailAddress: _navigationRouter?.listEmailAddress,
subject: _navigationRouter?.subject, subject: _navigationRouter?.subject,
body: _navigationRouter?.body body: _navigationRouter?.body
) )
@@ -967,7 +967,7 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM
curve: Curves.easeInToLinear); curve: Curves.easeInToLinear);
} }
void _handleNavigationRouteParameters(Map<String, String?>? parameters) { void _handleNavigationRouteParameters(Map<String, dynamic>? parameters) {
log('MailboxController::_handleNavigationRouteParameters(): parameters: $parameters'); log('MailboxController::_handleNavigationRouteParameters(): parameters: $parameters');
if (parameters != null) { if (parameters != null) {
final navigationRouter = RouteUtils.parsingRouteParametersToNavigationRouter(parameters); final navigationRouter = RouteUtils.parsingRouteParametersToNavigationRouter(parameters);
@@ -211,7 +211,7 @@ class MailboxDashBoardController extends ReloadableController {
final composerOverlayState = ComposerOverlayState.inActive.obs; final composerOverlayState = ComposerOverlayState.inActive.obs;
final viewStateMarkAsReadMailbox = Rx<Either<Failure, Success>>(Right(UIState.idle)); final viewStateMarkAsReadMailbox = Rx<Either<Failure, Success>>(Right(UIState.idle));
final vacationResponse = Rxn<VacationResponse>(); final vacationResponse = Rxn<VacationResponse>();
final routerParameters = Rxn<Map<String, String?>>(); final routerParameters = Rxn<Map<String, dynamic>>();
final _isDraggingMailbox = RxBool(false); final _isDraggingMailbox = RxBool(false);
final searchMailboxActivated = RxBool(false); final searchMailboxActivated = RxBool(false);
final listSendingEmails = RxList<SendingEmail>(); final listSendingEmails = RxList<SendingEmail>();
@@ -10,7 +10,7 @@ class MailtoArguments extends RouterArguments {
MailtoArguments({required this.session, this.mailtoUri}); MailtoArguments({required this.session, this.mailtoUri});
Map<String, String?> toMapRouter() => RouteUtils.parseMapMailtoFromUri(mailtoUri); Map<String, dynamic> toMapRouter() => RouteUtils.parseMapMailtoFromUri(mailtoUri);
@override @override
List<Object?> get props => [session, mailtoUri]; List<Object?> get props => [session, mailtoUri];
+3 -3
View File
@@ -17,7 +17,7 @@ class NavigationRouter with EquatableMixin {
final DashboardType dashboardType; final DashboardType dashboardType;
final SearchQuery? searchQuery; final SearchQuery? searchQuery;
final String? routeName; final String? routeName;
final EmailAddress? emailAddress; final List<EmailAddress>? listEmailAddress;
final String? subject; final String? subject;
final String? body; final String? body;
final AccountMenuItem accountMenuItem; final AccountMenuItem accountMenuItem;
@@ -28,7 +28,7 @@ class NavigationRouter with EquatableMixin {
this.searchQuery, this.searchQuery,
this.dashboardType = DashboardType.normal, this.dashboardType = DashboardType.normal,
this.routeName, this.routeName,
this.emailAddress, this.listEmailAddress,
this.subject, this.subject,
this.body, this.body,
this.accountMenuItem = AccountMenuItem.none, this.accountMenuItem = AccountMenuItem.none,
@@ -43,7 +43,7 @@ class NavigationRouter with EquatableMixin {
searchQuery, searchQuery,
dashboardType, dashboardType,
routeName, routeName,
emailAddress, listEmailAddress,
subject, subject,
body, body,
accountMenuItem, accountMenuItem,
+29 -10
View File
@@ -27,7 +27,7 @@ abstract class RouteUtils {
static const String paramBody = 'body'; static const String paramBody = 'body';
static const String mailtoPrefix = 'mailto:'; static const String mailtoPrefix = 'mailto:';
static const String ADDRESS_SEPARATOR = ',';
static const String INVALID_VALUE = 'invalid'; static const String INVALID_VALUE = 'invalid';
static String get baseOriginUrl => Uri.base.origin; static String get baseOriginUrl => Uri.base.origin;
@@ -100,7 +100,7 @@ abstract class RouteUtils {
} }
} }
static NavigationRouter parsingRouteParametersToNavigationRouter(Map<String, String?> parameters) { static NavigationRouter parsingRouteParametersToNavigationRouter(Map<String, dynamic> parameters) {
final idParam = parameters[paramID]; final idParam = parameters[paramID];
final typeParam = parameters[paramType]; final typeParam = parameters[paramType];
final contextPram = parameters[paramContext]; final contextPram = parameters[paramContext];
@@ -115,17 +115,27 @@ abstract class RouteUtils {
final searchQuery = queryParam != null ? SearchQuery(queryParam) : null; final searchQuery = queryParam != null ? SearchQuery(queryParam) : null;
final dashboardType = DashboardType.values.firstWhereOrNull((type) => type.name == typeParam) ?? DashboardType.normal; final dashboardType = DashboardType.values.firstWhereOrNull((type) => type.name == typeParam) ?? DashboardType.normal;
final settingType = AccountMenuItem.values.firstWhereOrNull((type) => type.getAliasBrowser() == typeParam) ?? AccountMenuItem.none; final settingType = AccountMenuItem.values.firstWhereOrNull((type) => type.getAliasBrowser() == typeParam) ?? AccountMenuItem.none;
final emailAddress = mailtoAddress != null && GetUtils.isEmail(mailtoAddress) List<EmailAddress>? listEmailAddress;
? EmailAddress(null, mailtoAddress) if (mailtoAddress is List<String>) {
: EmailAddress(null, INVALID_VALUE); 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( return NavigationRouter(
emailId: emailId, emailId: emailId,
mailboxId: mailboxId, mailboxId: mailboxId,
searchQuery: searchQuery, searchQuery: searchQuery,
dashboardType: dashboardType, dashboardType: dashboardType,
routeName: routeName, routeName: routeName,
emailAddress: emailAddress, listEmailAddress: listEmailAddress,
subject: subject, subject: subject,
body: body, body: body,
accountMenuItem: settingType, accountMenuItem: settingType,
@@ -137,20 +147,28 @@ abstract class RouteUtils {
html.window.history.replaceState(null, title, url.toString()); html.window.history.replaceState(null, title, url.toString());
} }
static Map<String, String?> parseMapMailtoFromUri(String? mailtoUri) { static Map<String, dynamic> parseMapMailtoFromUri(String? mailtoUri) {
log('RouteUtils::parseMapMailtoFromUri:mailtoUri: $mailtoUri'); log('RouteUtils::parseMapMailtoFromUri:mailtoUri: $mailtoUri');
final mapMailto = <String, String?>{ final mapMailto = <String, dynamic>{
RouteUtils.paramRouteName: AppRoutes.mailtoURL, RouteUtils.paramRouteName: AppRoutes.mailtoURL,
}; };
if (mailtoUri?.startsWith(mailtoPrefix) == true) { if (mailtoUri?.startsWith(mailtoPrefix) == true) {
final mailtoUrlDecoded = Uri.decodeFull(mailtoUri!); final mailtoUrlDecoded = Uri.decodeFull(mailtoUri!);
log('RouteUtils::parseMapMailtoFromUri:mailtoUrlDecoded = $mailtoUrlDecoded');
final uri = Uri.tryParse(mailtoUrlDecoded); final uri = Uri.tryParse(mailtoUrlDecoded);
if (uri == null) return mapMailto; if (uri == null) return mapMailto;
final mailtoAddress = uri.path; final mailtoAddress = uri.path;
final mapQueryParam = uri.queryParameters; 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)) { if (mapQueryParam.containsKey(paramSubject)) {
mapMailto[paramSubject] = mapQueryParam[paramSubject]; mapMailto[paramSubject] = mapQueryParam[paramSubject];
} }
@@ -159,6 +177,7 @@ abstract class RouteUtils {
} }
} else if (mailtoUri != null) { } else if (mailtoUri != null) {
final mailtoUrlDecoded = Uri.decodeFull(mailtoUri); final mailtoUrlDecoded = Uri.decodeFull(mailtoUri);
log('RouteUtils::parseMapMailtoFromUri:mailtoUrlDecoded = $mailtoUrlDecoded');
mapMailto[paramMailtoAddress] = mailtoUrlDecoded; mapMailto[paramMailtoAddress] = mailtoUrlDecoded;
} else { } else {
mapMailto[paramMailtoAddress] = mailtoUri; mapMailto[paramMailtoAddress] = mailtoUri;