TF-1718 Handle unsubscribe mail by mailto links

Signed-off-by: dab246 <tdvu@linagora.com>
(cherry picked from commit f96273c52456ecd758d8bbbafc4d2c7af6ec7921)
This commit is contained in:
dab246
2023-11-16 10:40:58 +07:00
committed by Dat Vu
parent 67f0b702ab
commit 41eb95257d
10 changed files with 95 additions and 3 deletions
@@ -1,6 +1,11 @@
class ServicePath { import 'package:equatable/equatable.dart';
class ServicePath with EquatableMixin {
final String path; final String path;
ServicePath(this.path); ServicePath(this.path);
@override
List<Object?> get props => [path];
} }
@@ -489,6 +489,9 @@ class ComposerController extends BaseController {
isInitialRecipient.value = true; isInitialRecipient.value = true;
toAddressExpandMode.value = ExpandMode.COLLAPSE; toAddressExpandMode.value = ExpandMode.COLLAPSE;
} }
if (arguments.body?.isNotEmpty == true) {
_getEmailContentFromMailtoUri(arguments.body!);
}
_updateStatusEmailSendButton(); _updateStatusEmailSendButton();
break; break;
case EmailActionType.reply: case EmailActionType.reply:
@@ -524,6 +527,21 @@ class ComposerController extends BaseController {
_initAttachments(arguments.attachments ?? []); _initAttachments(arguments.attachments ?? []);
_getEmailContentFromSessionStorageBrowser(arguments.emailContents!); _getEmailContentFromSessionStorageBrowser(arguments.emailContents!);
break; break;
case EmailActionType.composeFromUnsubscribeMailtoLink:
if (arguments.subject != null) {
setSubjectEmail(arguments.subject!);
subjectEmailInputController.text = arguments.subject!;
}
if (arguments.emailAddress != null) {
listToEmailAddress.add(arguments.emailAddress!);
isInitialRecipient.value = true;
toAddressExpandMode.value = ExpandMode.COLLAPSE;
}
if (arguments.body?.isNotEmpty == true) {
_getEmailContentFromUnsubscribeMailtoLink(arguments.body!);
}
_updateStatusEmailSendButton();
break;
default: default:
break; break;
} }
@@ -1422,6 +1440,26 @@ class ComposerController extends BaseController {
)); ));
} }
void _getEmailContentFromMailtoUri(String content) {
log('ComposerController::_getEmailContentFromMailtoUri:content: $content');
consumeState(Stream.value(
Right(GetEmailContentSuccess(
htmlEmailContent: content,
attachments: [],
))
));
}
void _getEmailContentFromUnsubscribeMailtoLink(String content) {
log('ComposerController::_getEmailContentFromUnsubscribeMailtoLink:content: $content');
consumeState(Stream.value(
Right(GetEmailContentSuccess(
htmlEmailContent: content,
attachments: [],
))
));
}
void _getEmailContentFromEmailId({required EmailId emailId, bool isDraftEmail = false}) { void _getEmailContentFromEmailId({required EmailId emailId, bool isDraftEmail = false}) {
final session = mailboxDashBoardController.sessionCurrent; final session = mailboxDashBoardController.sessionCurrent;
final accountId = mailboxDashBoardController.accountId.value; final accountId = mailboxDashBoardController.accountId.value;
@@ -47,6 +47,8 @@ class MobileEditorView extends StatelessWidget with EditorViewMixin {
case EmailActionType.editSendingEmail: case EmailActionType.editSendingEmail:
case EmailActionType.composeFromContentShared: case EmailActionType.composeFromContentShared:
case EmailActionType.reopenComposerBrowser: case EmailActionType.reopenComposerBrowser:
case EmailActionType.composeFromMailtoUri:
case EmailActionType.composeFromUnsubscribeMailtoLink:
if (contentViewState == null) { if (contentViewState == null) {
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
@@ -81,6 +81,8 @@ class WebEditorView extends StatelessWidget with EditorViewMixin {
case EmailActionType.editSendingEmail: case EmailActionType.editSendingEmail:
case EmailActionType.composeFromContentShared: case EmailActionType.composeFromContentShared:
case EmailActionType.reopenComposerBrowser: case EmailActionType.reopenComposerBrowser:
case EmailActionType.composeFromUnsubscribeMailtoLink:
case EmailActionType.composeFromMailtoUri:
if (contentViewState == null) { if (contentViewState == null) {
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
@@ -1407,6 +1407,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
onConfirmAction: () { onConfirmAction: () {
if (emailUnsubscribe.value?.httpLinks.isNotEmpty == true) { if (emailUnsubscribe.value?.httpLinks.isNotEmpty == true) {
_handleUnsubscribeMailByHttpsLink(context, emailUnsubscribe.value!.httpLinks); _handleUnsubscribeMailByHttpsLink(context, emailUnsubscribe.value!.httpLinks);
} else if (emailUnsubscribe.value?.mailtoLinks.isNotEmpty == true) {
_handleUnsubscribeMailByMailtoLink(context, emailUnsubscribe.value!.mailtoLinks);
} }
}, },
showAsBottomSheet: true, showAsBottomSheet: true,
@@ -1441,4 +1443,16 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
AppLocalizations.of(context).unsubscribedFromThisMailingList); AppLocalizations.of(context).unsubscribedFromThisMailingList);
} }
} }
void _handleUnsubscribeMailByMailtoLink(BuildContext context, List<String> mailtoLinks) {
log('SingleEmailController::_handleUnsubscribeMailByMailtoLink:mailtoLinks: $mailtoLinks');
final navigationRouter = RouteUtils.generateNavigationRouterFromMailtoLink(mailtoLinks.first);
mailboxDashBoardController.goToComposer(
ComposerArguments.fromUnsubscribeMailtoLink(
emailAddress: navigationRouter.emailAddress,
subject: navigationRouter.subject,
body: navigationRouter.body
)
);
}
} }
@@ -18,6 +18,7 @@ class ComposerArguments extends RouterArguments {
final Role? mailboxRole; final Role? mailboxRole;
final SendingEmail? sendingEmail; final SendingEmail? sendingEmail;
final String? subject; final String? subject;
final String? body;
final MessageIdsHeaderValue? messageId; final MessageIdsHeaderValue? messageId;
final MessageIdsHeaderValue? references; final MessageIdsHeaderValue? references;
@@ -31,6 +32,7 @@ class ComposerArguments extends RouterArguments {
this.listSharedMediaFile, this.listSharedMediaFile,
this.sendingEmail, this.sendingEmail,
this.subject, this.subject,
this.body,
this.messageId, this.messageId,
this.references, this.references,
}); });
@@ -59,11 +61,12 @@ class ComposerArguments extends RouterArguments {
emailAddress: emailAddress emailAddress: emailAddress
); );
factory ComposerArguments.fromMailtoUri({EmailAddress? emailAddress, String? subject}) => factory ComposerArguments.fromMailtoUri({EmailAddress? emailAddress, String? subject, String? body}) =>
ComposerArguments( ComposerArguments(
emailActionType: EmailActionType.composeFromMailtoUri, emailActionType: EmailActionType.composeFromMailtoUri,
emailAddress: emailAddress, emailAddress: emailAddress,
subject: subject, subject: subject,
body: body,
); );
factory ComposerArguments.editDraftEmail(PresentationEmail presentationEmail) => factory ComposerArguments.editDraftEmail(PresentationEmail presentationEmail) =>
@@ -136,6 +139,15 @@ class ComposerArguments extends RouterArguments {
? SendingEmailActionType.edit ? SendingEmailActionType.edit
: SendingEmailActionType.create; : SendingEmailActionType.create;
factory ComposerArguments.fromUnsubscribeMailtoLink({EmailAddress? emailAddress, String? subject, String? body}) =>
ComposerArguments(
emailActionType: EmailActionType.composeFromUnsubscribeMailtoLink,
emailAddress: emailAddress,
subject: subject,
body: body,
);
@override @override
List<Object?> get props => [ List<Object?> get props => [
emailActionType, emailActionType,
@@ -147,6 +159,7 @@ class ComposerArguments extends RouterArguments {
listSharedMediaFile, listSharedMediaFile,
sendingEmail, sendingEmail,
subject, subject,
body,
messageId, messageId,
references, references,
]; ];
@@ -425,7 +425,8 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM
mailboxDashBoardController.goToComposer( mailboxDashBoardController.goToComposer(
ComposerArguments.fromMailtoUri( ComposerArguments.fromMailtoUri(
emailAddress: navigationRouter?.emailAddress, emailAddress: navigationRouter?.emailAddress,
subject: navigationRouter?.subject subject: navigationRouter?.subject,
body: navigationRouter?.body
) )
); );
} }
+3
View File
@@ -18,6 +18,7 @@ class NavigationRouter with EquatableMixin {
final String? routeName; final String? routeName;
final EmailAddress? emailAddress; final EmailAddress? emailAddress;
final String? subject; final String? subject;
final String? body;
NavigationRouter({ NavigationRouter({
this.emailId, this.emailId,
@@ -27,6 +28,7 @@ class NavigationRouter with EquatableMixin {
this.routeName, this.routeName,
this.emailAddress, this.emailAddress,
this.subject, this.subject,
this.body,
}); });
factory NavigationRouter.initial() => NavigationRouter(); factory NavigationRouter.initial() => NavigationRouter();
@@ -40,5 +42,6 @@ class NavigationRouter with EquatableMixin {
routeName, routeName,
emailAddress, emailAddress,
subject, subject,
body,
]; ];
} }
+13
View File
@@ -23,6 +23,7 @@ abstract class RouteUtils {
static const String paramRouteName = 'routeName'; static const String paramRouteName = 'routeName';
static const String paramMailtoAddress = 'mailtoAddress'; static const String paramMailtoAddress = 'mailtoAddress';
static const String paramSubject = 'subject'; static const String paramSubject = 'subject';
static const String paramBody = 'body';
static const String mailtoPrefix = 'mailto:'; static const String mailtoPrefix = 'mailto:';
@@ -76,6 +77,7 @@ abstract class RouteUtils {
final routeName = parameters[paramRouteName]; final routeName = parameters[paramRouteName];
final mailtoAddress = parameters[paramMailtoAddress]; final mailtoAddress = parameters[paramMailtoAddress];
final subject = parameters[paramSubject]; final subject = parameters[paramSubject];
final body = parameters[paramBody];
final emailId = idParam != null ? EmailId(Id(idParam)) : null; final emailId = idParam != null ? EmailId(Id(idParam)) : null;
final mailboxId = contextPram != null ? MailboxId(Id(contextPram)) : null; final mailboxId = contextPram != null ? MailboxId(Id(contextPram)) : null;
@@ -95,6 +97,7 @@ abstract class RouteUtils {
routeName: routeName, routeName: routeName,
emailAddress: emailAddress, emailAddress: emailAddress,
subject: subject, subject: subject,
body: body,
); );
} }
@@ -121,6 +124,9 @@ abstract class RouteUtils {
if (mapQueryParam.containsKey(paramSubject)) { if (mapQueryParam.containsKey(paramSubject)) {
mapMailto[paramSubject] = mapQueryParam[paramSubject]; mapMailto[paramSubject] = mapQueryParam[paramSubject];
} }
if (mapQueryParam.containsKey(paramBody)) {
mapMailto[paramBody] = mapQueryParam[paramBody];
}
} else if (mailtoUri != null) { } else if (mailtoUri != null) {
final mailtoUrlDecoded = Uri.decodeFull(mailtoUri); final mailtoUrlDecoded = Uri.decodeFull(mailtoUri);
mapMailto[paramMailtoAddress] = mailtoUrlDecoded; mapMailto[paramMailtoAddress] = mailtoUrlDecoded;
@@ -130,4 +136,11 @@ abstract class RouteUtils {
log('RouteUtils::parseMapMailtoFromUri:mapMailto: $mapMailto'); log('RouteUtils::parseMapMailtoFromUri:mapMailto: $mapMailto');
return mapMailto; return mapMailto;
} }
static NavigationRouter generateNavigationRouterFromMailtoLink(String mailtoLink) {
final mailtoMap = parseMapMailtoFromUri(mailtoLink);
final navigationRouter = parsingRouteParametersToNavigationRouter(mailtoMap);
log('RouteUtils::generateNavigationRouterFromMailtoLink:navigationRouter: $navigationRouter');
return navigationRouter;
}
} }
+1
View File
@@ -25,4 +25,5 @@ enum EmailActionType {
openInNewTab, openInNewTab,
createRule, createRule,
unsubscribe, unsubscribe,
composeFromUnsubscribeMailtoLink,
} }