TF-1718 Implement unsubscribeMail on Jmap server

Signed-off-by: dab246 <tdvu@linagora.com>
(cherry picked from commit 0f61a97aab513cda75c65e3c92ebcf8f6290b6ec)
This commit is contained in:
dab246
2023-11-16 12:48:38 +07:00
committed by Dat Vu
parent 4d8c7dc52e
commit a6ecaf321d
18 changed files with 169 additions and 36 deletions
@@ -32,6 +32,7 @@ import 'package:tmail_ui_user/features/email/domain/model/detailed_email.dart';
import 'package:tmail_ui_user/features/email/domain/model/event_action.dart';
import 'package:tmail_ui_user/features/email/domain/model/mark_read_action.dart';
import 'package:tmail_ui_user/features/email/domain/state/parse_calendar_event_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/unsubscribe_email_state.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/parse_calendar_event_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/store_opened_email_interactor.dart';
import 'package:tmail_ui_user/features/email/presentation/action/email_ui_action.dart';
@@ -231,6 +232,14 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
mailboxDashBoardController.clearEmailUIAction();
}
});
ever(mailboxDashBoardController.viewState, (viewState) {
viewState.map((success) {
if (success is UnsubscribeEmailSuccess) {
emailUnsubscribe.value = null;
}
});
});
}
bool isListEmailContainSelectedEmail(PresentationEmail selectedEmail) {
@@ -441,7 +450,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
_handleReadReceipt();
}
if (success.emailCurrent?.hasListUnsubscribe == true) {
if (currentEmail?.isSubscribed == false && success.emailCurrent?.hasListUnsubscribe == true) {
_handleUnsubscribe(success.emailCurrent!.listUnsubscribe);
} else {
emailUnsubscribe.value = null;
@@ -501,7 +510,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
_handleReadReceipt();
}
if (success.emailCurrent?.hasListUnsubscribe == true) {
if (currentEmail?.isSubscribed == false && success.emailCurrent?.hasListUnsubscribe == true) {
_handleUnsubscribe(success.emailCurrent!.listUnsubscribe);
} else {
emailUnsubscribe.value = null;
@@ -951,11 +960,9 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
}
}
void _markAsEmailStarSuccess(Success success) {
if (success is MarkAsStarEmailSuccess) {
final selectedEmail = mailboxDashBoardController.selectedEmail.value;
mailboxDashBoardController.setSelectedEmail(selectedEmail?.updateKeywords(success.updatedEmail.keywords));
}
void _markAsEmailStarSuccess(MarkAsStarEmailSuccess success) {
final selectedEmail = mailboxDashBoardController.selectedEmail.value;
mailboxDashBoardController.setSelectedEmail(selectedEmail?.updateKeywords(success.updatedEmail.keywords));
mailboxDashBoardController.dispatchState(Right(success));
}
@@ -1406,9 +1413,17 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
AppLocalizations.of(context).unsubscribe,
onConfirmAction: () {
if (emailUnsubscribe.value?.httpLinks.isNotEmpty == true) {
_handleUnsubscribeMailByHttpsLink(context, emailUnsubscribe.value!.httpLinks);
_handleUnsubscribeMailByHttpsLink(
context: context,
emailId: presentationEmail.id!,
httpLinks: emailUnsubscribe.value!.httpLinks
);
} else if (emailUnsubscribe.value?.mailtoLinks.isNotEmpty == true) {
_handleUnsubscribeMailByMailtoLink(context, emailUnsubscribe.value!.mailtoLinks);
_handleUnsubscribeMailByMailtoLink(
context: context,
emailId: presentationEmail.id!,
mailtoLinks: emailUnsubscribe.value!.mailtoLinks
);
}
},
showAsBottomSheet: true,
@@ -1434,24 +1449,29 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
);
}
void _handleUnsubscribeMailByHttpsLink(BuildContext context, List<String> httpLinks) async {
void _handleUnsubscribeMailByHttpsLink({
required BuildContext context,
required EmailId emailId,
required List<String> httpLinks
}) {
log('SingleEmailController::_handleUnsubscribeMailByHttpsLink:httpLinks: $httpLinks');
final result = await AppUtils.launchLink(httpLinks.first);
if (result && context.mounted) {
_appToast.showToastSuccessMessage(
context,
AppLocalizations.of(context).unsubscribedFromThisMailingList);
}
mailboxDashBoardController.unsubscribeMail(emailId);
AppUtils.launchLink(httpLinks.first);
}
void _handleUnsubscribeMailByMailtoLink(BuildContext context, List<String> mailtoLinks) {
void _handleUnsubscribeMailByMailtoLink({
required BuildContext context,
required EmailId emailId,
required 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
body: navigationRouter.body,
previousEmailId: emailId,
)
);
}
@@ -33,6 +33,7 @@ import 'package:tmail_ui_user/features/email/presentation/widgets/email_subject_
import 'package:tmail_ui_user/features/email/presentation/widgets/email_view_empty_widget.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/email_view_loading_bar_widget.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/information_sender_and_receiver_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/mail_unsubscribed_banner.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
@@ -307,6 +308,10 @@ class EmailView extends GetWidget<SingleEmailController> {
openEmailAddressDetailAction: controller.openEmailAddressDialog,
onEmailActionClick: (presentationEmail, actionType) => controller.handleEmailAction(context, presentationEmail, actionType),
)),
Obx(() => MailUnsubscribedBanner(
presentationEmail: controller.currentEmail,
emailUnsubscribe: controller.emailUnsubscribe.value
)),
Obx(() {
final attachments = controller.attachments.listAttachmentsDisplayedOutSide;
if (attachments.isNotEmpty) {
@@ -432,7 +437,7 @@ class EmailView extends GetWidget<SingleEmailController> {
EmailActionType.moveToSpam,
if (presentationEmail.from?.isNotEmpty == true)
EmailActionType.createRule,
if (controller.emailUnsubscribe.value != null)
if (!presentationEmail.isSubscribed && controller.emailUnsubscribe.value != null)
EmailActionType.unsubscribe
];
@@ -21,6 +21,7 @@ class ComposerArguments extends RouterArguments {
final String? body;
final MessageIdsHeaderValue? messageId;
final MessageIdsHeaderValue? references;
final EmailId? previousEmailId;
ComposerArguments({
this.emailActionType = EmailActionType.compose,
@@ -35,6 +36,7 @@ class ComposerArguments extends RouterArguments {
this.body,
this.messageId,
this.references,
this.previousEmailId,
});
factory ComposerArguments.fromSendingEmail(SendingEmail sendingEmail) =>
@@ -139,12 +141,18 @@ class ComposerArguments extends RouterArguments {
? SendingEmailActionType.edit
: SendingEmailActionType.create;
factory ComposerArguments.fromUnsubscribeMailtoLink({EmailAddress? emailAddress, String? subject, String? body}) =>
factory ComposerArguments.fromUnsubscribeMailtoLink({
EmailAddress? emailAddress,
String? subject,
String? body,
EmailId? previousEmailId
}) =>
ComposerArguments(
emailActionType: EmailActionType.composeFromUnsubscribeMailtoLink,
emailAddress: emailAddress,
subject: subject,
body: body,
previousEmailId: previousEmailId,
);
@@ -63,7 +63,7 @@ class InformationSenderAndReceiverBuilder extends StatelessWidget {
openEmailAddressDetailAction: openEmailAddressDetailAction,
)
)),
if (emailUnsubscribe != null && !responsiveUtils.isPortraitMobile(context))
if (!emailSelected.isSubscribed && emailUnsubscribe != null && !responsiveUtils.isPortraitMobile(context))
TMailButtonWidget.fromText(
text: AppLocalizations.of(context).unsubscribe,
textStyle: const TextStyle(
@@ -0,0 +1,36 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:flutter/material.dart';
import 'package:model/email/presentation_email.dart';
import 'package:tmail_ui_user/features/email/presentation/model/email_unsubscribe.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class MailUnsubscribedBanner extends StatelessWidget {
final PresentationEmail? presentationEmail;
final EmailUnsubscribe? emailUnsubscribe;
const MailUnsubscribedBanner({
super.key,
required this.presentationEmail,
this.emailUnsubscribe
});
@override
Widget build(BuildContext context) {
if (presentationEmail?.isSubscribed == true && emailUnsubscribe == null) {
return Padding(
padding: const EdgeInsetsDirectional.only(bottom: 16, start: 20, end: 20),
child: Text(
AppLocalizations.of(context).mailUnsubscribedMessage(presentationEmail?.firstEmailAddressInFrom ?? ''),
style: const TextStyle(
fontWeight: FontWeight.normal,
fontSize: 15,
color: AppColor.labelColor
),
),
);
} else {
return const SizedBox.shrink();
}
}
}