TF-3941 Thread Detail Thread level mark read/star, archive and spam

This commit is contained in:
DatDang
2025-08-05 14:15:03 +07:00
committed by Dat H. Pham
parent f44118af48
commit b7cd3f7179
35 changed files with 902 additions and 552 deletions
@@ -0,0 +1,49 @@
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/thread_detail_controller.dart';
extension GetThreadDetailActionStatus on ThreadDetailController {
bool get threadDetailIsStarred {
return emailsInThreadDetailInfo.every(
(email) {
return email.keywords?.containsKey(KeyWordIdentifier.emailFlagged) ==
true;
},
);
}
bool get threadDetailIsRead {
return emailsInThreadDetailInfo.every(
(email) {
return email.keywords?.containsKey(KeyWordIdentifier.emailSeen) == true;
},
);
}
MailboxId? getMailboxIdByRole(Role role) {
return mailboxDashBoardController.mapDefaultMailboxIdByRole[role];
}
bool get threadDetailIsArchived {
final archiveMailboxId = getMailboxIdByRole(
PresentationMailbox.roleArchive,
);
return emailsInThreadDetailInfo.every(
(email) {
return email.mailboxIds?[archiveMailboxId] == true;
},
);
}
bool get threadDetailIsSpam {
final spamMailboxId =
getMailboxIdByRole(PresentationMailbox.roleJunk) ??
getMailboxIdByRole(PresentationMailbox.roleSpam);
return emailsInThreadDetailInfo.every(
(email) {
return email.mailboxIds?[spamMailboxId] == true;
},
);
}
}
@@ -1,10 +1,7 @@
import 'package:flutter/material.dart';
import 'package:model/email/email_action_type.dart';
import 'package:model/extensions/presentation_email_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/email_view.dart';
import 'package:model/email/email_in_thread_status.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_open_context_menu_extension.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/get_thread_detail_email_mailbox_contains.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/load_more_thread_detail_emails.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/thread_detail_on_email_action_click.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/thread_detail_open_email_address_detail_action.dart';
@@ -14,7 +11,6 @@ import 'package:tmail_ui_user/features/thread_detail/presentation/extension/togg
import 'package:tmail_ui_user/features/thread_detail/presentation/thread_detail_controller.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/widgets/thread_detail_collapsed_email.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/widgets/thread_detail_load_more_circle.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
extension GetThreadDetailEmailViews on ThreadDetailController {
List<Widget> getThreadDetailEmailViews() {
@@ -65,33 +61,6 @@ extension GetThreadDetailEmailViews on ThreadDetailController {
),
emailLoaded: null,
onEmailActionClick: threadDetailOnEmailActionClick,
onMoreActionClick: (presentationEmail, position) => emailActionReactor.handleMoreEmailAction(
mailboxContain: getThreadDetailEmailMailboxContains(presentationEmail),
presentationEmail: presentationEmail,
position: position,
responsiveUtils: responsiveUtils,
imagePaths: imagePaths,
username: session?.username,
handleEmailAction: threadDetailOnEmailActionClick,
additionalActions: [
EmailActionType.forward,
EmailActionType.replyAll,
EmailActionType.replyToList,
EmailActionType.printAll,
if (currentContext != null &&
responsiveUtils.isMobile(currentContext!))
EmailActionType.moveToMailbox,
if (!responsiveUtils.isDesktop(currentContext!)) ...[
EmailActionType.markAsStarred,
EmailActionType.unMarkAsStarred,
EmailActionType.moveToTrash,
EmailActionType.deletePermanently,
],
],
emailIsRead: presentationEmail.hasRead,
openBottomSheetContextMenu: mailboxDashBoardController.openBottomSheetContextMenu,
openPopupMenu: mailboxDashBoardController.openPopupMenu,
),
openEmailAddressDetailAction: (_, emailAddress) {
openEmailAddressDetailAction(emailAddress);
},
@@ -11,15 +11,22 @@ extension HandleGetEmailIdsByThreadIdSuccess on ThreadDetailController {
}
final allEmailIds = success.emailIds;
final allEmailsInThreadDetailInfo = success.emailsInThreadDetailInfo;
if (success.updateCurrentThreadDetail) {
final newEmailIds = allEmailIds.where(
(emailId) => !emailIdsPresentation.keys.contains(emailId),
);
final newEmailsInThreadDetailInfo = allEmailsInThreadDetailInfo.where(
(email) => !emailsInThreadDetailInfo.contains(email),
);
emailIdsPresentation
..removeWhere((key, _) => !allEmailIds.contains(key))
..addEntries(
newEmailIds.map((emailId) => MapEntry(emailId, null)),
);
emailsInThreadDetailInfo
..removeWhere((e) => !allEmailsInThreadDetailInfo.contains(e))
..addAll(newEmailsInThreadDetailInfo);
return;
}
@@ -31,5 +38,9 @@ extension HandleGetEmailIdsByThreadIdSuccess on ThreadDetailController {
? emailIdsPresentation[id] ?? selectedEmail
: null,
};
if ((isThreadDetailEnabled && success is! PreloadEmailIdsInThreadSuccess) ||
(!isThreadDetailEnabled && success is PreloadEmailIdsInThreadSuccess)) {
emailsInThreadDetailInfo.value = allEmailsInThreadDetailInfo;
}
}
}
@@ -0,0 +1,32 @@
import 'package:core/presentation/state/success.dart';
import 'package:dartz/dartz.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:model/email/read_actions.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/close_thread_detail_action.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/toggle_thread_detail_collape_expand.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/thread_detail_controller.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
extension HandleMarkMultipleEmailsReadSuccess on ThreadDetailController {
void handleMarkMultipleEmailsReadSuccess(
UIState success,
ReadActions readActions,
List<EmailId> emailIds,
) {
mailboxDashBoardController.consumeState(Stream.value(Right(success)));
if (readActions == ReadActions.markAsRead) return;
if (emailsInThreadDetailInfo.length == 1) {
closeThreadDetailAction(currentContext);
return;
}
final expandedEmailId = currentExpandedEmailId.value;
if (expandedEmailId == null) return;
final expandedEmail = emailIdsPresentation[expandedEmailId];
if (emailIds.contains(expandedEmailId) && expandedEmail != null) {
toggleThreadDetailCollapeExpand(expandedEmail);
}
}
}
@@ -7,6 +7,7 @@ import 'package:model/extensions/keyword_identifier_extension.dart';
import 'package:model/extensions/list_email_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/action/email_ui_action.dart';
import 'package:tmail_ui_user/features/email/presentation/extensions/email_extension.dart';
import 'package:tmail_ui_user/features/thread/data/extensions/list_email_extension.dart';
import 'package:tmail_ui_user/features/thread_detail/domain/state/get_emails_by_ids_state.dart';
import 'package:tmail_ui_user/features/thread_detail/domain/state/get_thread_by_id_state.dart';
import 'package:tmail_ui_user/features/thread_detail/domain/usecases/get_thread_by_id_interactor.dart';
@@ -34,6 +35,10 @@ extension HandleRefreshThreadDetailAction on ThreadDetailController {
[currentEmailId],
updateCurrentThreadDetail: true,
threadId: mailboxDashBoardController.selectedEmail.value?.threadId,
emailsInThreadDetailInfo: action.emailChangeResponse.updated?.toEmailsInThreadDetailInfo(
sentMailboxId: sentMailboxId,
ownEmailAddress: ownEmailAddress,
) ?? [],
))));
}
@@ -71,6 +76,14 @@ extension HandleRefreshThreadDetailAction on ThreadDetailController {
updated: emailsUpdated,
destroyed: emailIdsDestroyed.toList(),
);
final afterRefreshedThreadDetailInfo = ThreadDetailPresentationUtils.refreshThreadDetailInfo(
original: emailsInThreadDetailInfo,
created: emailsCreated,
updated: emailsUpdated,
destroyed: emailIdsDestroyed.toList(),
sentMailboxId: sentMailboxId,
ownEmailAddress: ownEmailAddress,
);
if (afterRefreshedEmailIds.isEmpty) {
closeThreadDetailAction(currentContext);
@@ -81,6 +94,7 @@ extension HandleRefreshThreadDetailAction on ThreadDetailController {
afterRefreshedEmailIds,
threadId: currentThreadId,
updateCurrentThreadDetail: true,
emailsInThreadDetailInfo: afterRefreshedThreadDetailInfo,
))));
consumeState(Stream.value(Right(GetEmailsByIdsSuccess(
afterRefreshedEmails,
@@ -0,0 +1,160 @@
import 'package:dartz/dartz.dart';
import 'package:flutter/material.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/email/email_action_type.dart';
import 'package:model/email/mark_star_action.dart';
import 'package:model/email/read_actions.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/base/widget/popup_menu/popup_menu_item_action_widget.dart';
import 'package:tmail_ui_user/features/email/presentation/model/context_item_email_action.dart';
import 'package:tmail_ui_user/features/email/presentation/model/popup_menu_item_email_action.dart';
import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_open_context_menu_extension.dart';
import 'package:tmail_ui_user/features/thread/domain/state/mark_as_multiple_email_read_state.dart';
import 'package:tmail_ui_user/features/thread/domain/state/mark_as_star_multiple_email_state.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/close_thread_detail_action.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/get_thread_detail_action_status.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/thread_detail_controller.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
extension OnThreadDetailActionClick on ThreadDetailController {
void onThreadDetailActionClick(EmailActionType threadDetailActionType) {
switch (threadDetailActionType) {
case EmailActionType.markAsRead:
case EmailActionType.markAsUnread:
if (session == null || accountId == null) {
consumeState(Stream.value(Left(MarkAsMultipleEmailReadFailure(
threadDetailActionType == EmailActionType.markAsRead
? ReadActions.markAsRead
: ReadActions.markAsUnread,
NotFoundSessionException(),
))));
return;
}
consumeState(markAsMultipleEmailReadInteractor.execute(
session!,
accountId!,
emailsInThreadDetailInfo.map((e) => e.emailId).toList(),
threadDetailActionType == EmailActionType.markAsRead
? ReadActions.markAsRead
: ReadActions.markAsUnread,
{},
));
break;
case EmailActionType.markAsStarred:
case EmailActionType.unMarkAsStarred:
if (session == null || accountId == null) {
consumeState(Stream.value(Left(MarkAsStarMultipleEmailFailure(
threadDetailActionType == EmailActionType.markAsStarred
? MarkStarAction.markStar
: MarkStarAction.unMarkStar,
NotFoundSessionException(),
))));
return;
}
consumeState(markAsStarMultipleEmailInteractor.execute(
session!,
accountId!,
emailsInThreadDetailInfo.map((e) => e.emailId).toList(),
threadDetailActionType == EmailActionType.markAsStarred
? MarkStarAction.markStar
: MarkStarAction.unMarkStar,
));
break;
case EmailActionType.archiveMessage:
final mailboxId = mailboxDashBoardController.getMailboxIdByRole(
PresentationMailbox.roleArchive,
);
if (mailboxId == null) return;
_moveToMailbox(mailboxId, threadDetailActionType);
break;
case EmailActionType.moveToSpam:
final mailboxId = mailboxDashBoardController.getMailboxIdByRole(
PresentationMailbox.roleJunk,
) ?? mailboxDashBoardController.getMailboxIdByRole(
PresentationMailbox.roleSpam,
);
if (mailboxId == null) return;
_moveToMailbox(mailboxId, threadDetailActionType);
break;
case EmailActionType.unSpam:
final mailboxId = mailboxDashBoardController.getMailboxIdByRole(
PresentationMailbox.roleInbox,
);
if (mailboxId == null) return;
_moveToMailbox(mailboxId, threadDetailActionType);
break;
default:
break;
}
}
void onThreadDetailMoreActionClick(RelativeRect? position) {
if (currentContext == null) return;
final moreActions = [
threadDetailIsRead
? EmailActionType.markAsUnread
: EmailActionType.markAsRead,
threadDetailIsStarred
? EmailActionType.unMarkAsStarred
: EmailActionType.markAsStarred,
if (!threadDetailIsArchived) EmailActionType.archiveMessage,
threadDetailIsSpam ? EmailActionType.unSpam : EmailActionType.moveToSpam,
];
if (position == null) {
mailboxDashBoardController.openBottomSheetContextMenu(
context: currentContext!,
itemActions: moreActions
.map(
(action) => ContextItemEmailAction(
action,
AppLocalizations.of(currentContext!),
imagePaths,
),
)
.toList(),
onContextMenuActionClick: (action) {
popBack();
onThreadDetailActionClick(action.action);
},
);
} else {
mailboxDashBoardController.openPopupMenu(
currentContext!,
position,
moreActions.map((action) {
return PopupMenuItem(
key: Key('${action.name}_action'),
padding: EdgeInsets.zero,
child: PopupMenuItemActionWidget(
menuAction: PopupMenuItemEmailAction(
action,
AppLocalizations.of(currentContext!),
imagePaths,
),
menuActionClick: (_) {
popBack();
onThreadDetailActionClick(action);
},
),
);
}).toList(),
);
}
}
void _moveToMailbox(MailboxId mailboxId, EmailActionType emailActionType) {
closeThreadDetailAction(currentContext);
mailboxDashBoardController.moveMultipleEmailInThreadDetail(
emailsInThreadDetailInfo,
destinationMailboxId: mailboxId,
emailActionType: emailActionType,
);
}
}
@@ -1,18 +1,10 @@
import 'dart:async';
import 'package:core/presentation/utils/html_transformer/transform_configuration.dart';
import 'package:model/email/email_action_type.dart';
import 'package:model/email/mark_star_action.dart';
import 'package:model/email/presentation_email.dart';
import 'package:model/email/read_actions.dart';
import 'package:model/extensions/presentation_email_extension.dart';
import 'package:model/extensions/session_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/open_and_close_composer_extension.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/close_thread_detail_action.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/thread_detail_controller.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
extension ThreadDetailOnEmailActionClick on ThreadDetailController {
void threadDetailOnEmailActionClick(
@@ -23,60 +15,9 @@ extension ThreadDetailOnEmailActionClick on ThreadDetailController {
case EmailActionType.markAsRead:
_markRead(presentationEmail);
break;
case EmailActionType.markAsUnread:
_unRead(presentationEmail);
break;
case EmailActionType.markAsStarred:
_markStar(presentationEmail, MarkStarAction.markStar);
break;
case EmailActionType.unMarkAsStarred:
_markStar(presentationEmail, MarkStarAction.unMarkStar);
break;
case EmailActionType.moveToMailbox:
_moveEmail(presentationEmail);
break;
case EmailActionType.moveToTrash:
_trashEmail(presentationEmail);
break;
case EmailActionType.deletePermanently:
_deleteEmailPermanently(presentationEmail);
break;
case EmailActionType.moveToSpam:
_markEmailSpam(presentationEmail);
break;
case EmailActionType.unSpam:
_unSpamEmail(presentationEmail);
break;
case EmailActionType.createRule:
_quickCreateRule(presentationEmail);
break;
case EmailActionType.unsubscribe:
_unsubscribeEmail(presentationEmail);
break;
case EmailActionType.archiveMessage:
_archiveMessage(presentationEmail);
break;
case EmailActionType.printAll:
_printEmail(presentationEmail);
break;
case EmailActionType.downloadMessageAsEML:
_downloadMessageAsEML(presentationEmail);
break;
case EmailActionType.editAsNewEmail:
_editAsNewEmail(presentationEmail);
break;
case EmailActionType.reply:
_replyEmail(presentationEmail);
break;
case EmailActionType.replyAll:
_replyAll(presentationEmail);
break;
case EmailActionType.replyToList:
_replyToList(presentationEmail);
break;
case EmailActionType.forward:
_forward(presentationEmail);
break;
default:
break;
}
@@ -93,212 +34,6 @@ extension ThreadDetailOnEmailActionClick on ThreadDetailController {
));
}
void _unRead(PresentationEmail presentationEmail) {
if (session == null || accountId == null || !presentationEmail.hasRead) return;
consumeState(emailActionReactor.markAsEmailRead(
session!,
accountId!,
presentationEmail,
readAction: ReadActions.markAsUnread,
));
}
void _markStar(
PresentationEmail presentationEmail,
MarkStarAction markStarAction,
) {
if (session == null ||
accountId == null ||
(presentationEmail.hasStarred && markStarAction == MarkStarAction.markStar) ||
(!presentationEmail.hasStarred && markStarAction == MarkStarAction.unMarkStar)) {
return;
}
consumeState(emailActionReactor.markAsStarEmail(
session!,
accountId!,
presentationEmail,
markStarAction: markStarAction,
));
}
Future<void> _moveEmail(PresentationEmail presentationEmail) async {
if (session == null || accountId == null) return;
final moveActionRequest = await emailActionReactor.moveToMailbox(
session!,
accountId!,
presentationEmail,
mapMailbox: mailboxDashBoardController.mapMailboxById,
selectedMailbox: presentationEmail.findMailboxContain(
mailboxDashBoardController.mapMailboxById,
),
isSearchEmailRunning: mailboxDashBoardController.searchController.isSearchEmailRunning,
);
if (moveActionRequest == null) return;
mailboxDashBoardController.moveToMailbox(
session!,
accountId!,
moveActionRequest.moveRequest,
moveActionRequest.emailIdsWithReadStatus,
);
if (emailIdsPresentation.length == 1) closeThreadDetailAction(currentContext);
}
void _trashEmail(PresentationEmail presentationEmail) {
if (session == null || accountId == null) return;
final moveActionRequest = emailActionReactor.moveToTrash(
presentationEmail,
mapMailbox: mailboxDashBoardController.mapMailboxById,
selectedMailbox: mailboxDashBoardController.selectedMailbox.value,
isSearchEmailRunning: mailboxDashBoardController.searchController.isSearchEmailRunning,
mapDefaultMailboxIdByRole: mailboxDashBoardController.mapDefaultMailboxIdByRole,
);
if (moveActionRequest == null) return;
mailboxDashBoardController.moveToMailbox(
session!,
accountId!,
moveActionRequest.moveRequest,
moveActionRequest.emailIdsWithReadStatus,
);
if (emailIdsPresentation.length == 1) closeThreadDetailAction(currentContext);
}
void _markEmailSpam(PresentationEmail presentationEmail) {
if (session == null || accountId == null) return;
final moveActionRequest = emailActionReactor.moveToSpam(
presentationEmail,
mapMailbox: mailboxDashBoardController.mapMailboxById,
selectedMailbox: mailboxDashBoardController.selectedMailbox.value,
isSearchEmailRunning: mailboxDashBoardController.searchController.isSearchEmailRunning,
mapDefaultMailboxIdByRole: mailboxDashBoardController.mapDefaultMailboxIdByRole,
);
if (moveActionRequest == null) return;
mailboxDashBoardController.moveToMailbox(
session!,
accountId!,
moveActionRequest.moveRequest,
moveActionRequest.emailIdsWithReadStatus,
);
if (emailIdsPresentation.length == 1) closeThreadDetailAction(currentContext);
}
void _unSpamEmail(PresentationEmail presentationEmail) {
if (session == null || accountId == null) return;
final moveActionRequest = emailActionReactor.unSpam(
presentationEmail,
mapMailbox: mailboxDashBoardController.mapMailboxById,
selectedMailbox: mailboxDashBoardController.selectedMailbox.value,
isSearchEmailRunning: mailboxDashBoardController.searchController.isSearchEmailRunning,
mapDefaultMailboxIdByRole: mailboxDashBoardController.mapDefaultMailboxIdByRole,
);
if (moveActionRequest == null) return;
mailboxDashBoardController.moveToMailbox(
session!,
accountId!,
moveActionRequest.moveRequest,
moveActionRequest.emailIdsWithReadStatus,
);
if (emailIdsPresentation.length == 1) closeThreadDetailAction(currentContext);
}
void _deleteEmailPermanently(PresentationEmail email) {
emailActionReactor.deleteEmailPermanently(
email,
onDeleteEmailRequest: (email) {
popBack();
mailboxDashBoardController.deleteEmailPermanently(email);
},
responsiveUtils: responsiveUtils,
imagePaths: imagePaths,
);
if (emailIdsPresentation.length == 1) closeThreadDetailAction(currentContext);
}
void _quickCreateRule(PresentationEmail presentationEmail) {
final emailAddress = presentationEmail.from?.first;
if (session == null || accountId == null || emailAddress == null) return;
consumeState(emailActionReactor.quickCreateRule(
session!,
accountId!,
emailAddress: emailAddress,
));
}
void _unsubscribeEmail(PresentationEmail presentationEmail) {
emailActionReactor.unsubscribeEmail(
presentationEmail,
emailUnsubscribe: EmailUtils.parsingUnsubscribe(
presentationEmail.listUnsubscribe ?? '',
),
onUnsubscribeByHttpsLink: mailboxDashBoardController.unsubscribeMail,
onUnsubscribeByMailtoLink: (emailId, navigationRouter) {
mailboxDashBoardController.openComposer(
ComposerArguments.fromUnsubscribeMailtoLink(
listEmailAddress: navigationRouter.listEmailAddress,
subject: navigationRouter.subject,
body: navigationRouter.body,
previousEmailId: emailId,
)
);
},
);
}
void _archiveMessage(PresentationEmail presentationEmail) {
if (currentContext == null) return;
emailActionReactor.archiveMessage(
presentationEmail,
onArchiveEmailRequest: (presentationEmail) {
mailboxDashBoardController.archiveMessage(currentContext!, presentationEmail);
},
);
}
void _printEmail(PresentationEmail presentationEmail) {
consumeState(emailActionReactor.printEmail(
presentationEmail,
ownEmailAddress: mailboxDashBoardController.ownEmailAddress.value,
emailLoaded: null,
session: session,
accountId: accountId,
baseDownloadUrl: session?.getDownloadUrl(jmapUrl: dynamicUrlInterceptors.jmapUrl),
transformConfiguration: TransformConfiguration.forPreviewEmailOnWeb(),
));
}
void _downloadMessageAsEML(PresentationEmail presentationEmail) {
if (accountId == null || session == null) return;
consumeState(emailActionReactor.downloadMessageAsEML(
session!,
accountId!,
presentationEmail,
downloadProgressStateController: downloadProgressState,
));
}
void _editAsNewEmail(PresentationEmail presentationEmail) {
if (accountId == null || session == null) return;
emailActionReactor.editAsNewEmail(
presentationEmail,
onEditAsEmailRequest: (presentationEmail) {
mailboxDashBoardController.openComposer(
ComposerArguments.editAsNewEmail(presentationEmail),
);
},
);
}
void _replyEmail(PresentationEmail presentationEmail) {
emailActionReactor.replyEmail(
presentationEmail,
@@ -318,61 +53,4 @@ extension ThreadDetailOnEmailActionClick on ThreadDetailController {
emailLoaded: null,
);
}
void _replyAll(PresentationEmail presentationEmail) {
emailActionReactor.replyAll(
presentationEmail,
onReplyAllRequest: (presentationEmail, emailLoaded) {
mailboxDashBoardController.openComposer(
ComposerArguments.replyAllEmail(
presentationEmail: presentationEmail,
content: emailLoaded?.htmlContent,
inlineImages: emailLoaded?.inlineImages,
mailboxRole: presentationEmail.mailboxContain?.role,
messageId: presentationEmail.messageId,
references: presentationEmail.references,
listPost: presentationEmail.listPost,
)
);
},
emailLoaded: null,
);
}
void _replyToList(PresentationEmail presentationEmail) {
emailActionReactor.replyToList(
presentationEmail,
onReplyToListRequest: (presentationEmail, emailLoaded) {
mailboxDashBoardController.openComposer(
ComposerArguments.replyToListEmail(
presentationEmail: presentationEmail,
content: emailLoaded?.htmlContent,
inlineImages: emailLoaded?.inlineImages,
mailboxRole: presentationEmail.mailboxContain?.role,
messageId: presentationEmail.messageId,
references: presentationEmail.references,
listPost: presentationEmail.listPost,
)
);
},
emailLoaded: null,
);
}
void _forward(PresentationEmail presentationEmail) {
emailActionReactor.forward(
presentationEmail,
onForwardRequest: (presentationEmail, emailLoaded) {
mailboxDashBoardController.openComposer(
ComposerArguments.forwardEmail(
presentationEmail: presentationEmail,
content: emailLoaded?.htmlContent,
attachments: emailLoaded?.attachments,
inlineImages: emailLoaded?.inlineImages,
messageId: presentationEmail.messageId,
references: presentationEmail.references,
)
);
},
emailLoaded: null,
);
}
}
@@ -2,6 +2,7 @@ import 'package:dartz/dartz.dart';
import 'package:flutter/widgets.dart';
import 'package:model/email/presentation_email.dart';
import 'package:tmail_ui_user/features/email/presentation/action/email_ui_action.dart';
import 'package:tmail_ui_user/features/thread/presentation/extensions/list_presentation_email_extensions.dart';
import 'package:tmail_ui_user/features/thread_detail/domain/state/get_emails_by_ids_state.dart';
import 'package:tmail_ui_user/features/thread_detail/domain/state/get_thread_by_id_state.dart';
import 'package:tmail_ui_user/features/thread_detail/domain/usecases/get_thread_by_id_interactor.dart';
@@ -56,6 +57,10 @@ extension ThreadDetailOnSelectedEmailUpdated on ThreadDetailController {
Right(PreloadEmailIdsInThreadSuccess(
[selectedEmail.id!],
threadId: selectedEmail.threadId,
emailsInThreadDetailInfo: [selectedEmail].toEmailsInThreadDetailInfo(
sentMailboxId: sentMailboxId,
ownEmailAddress: ownEmailAddress,
),
)),
Right(PreloadEmailsByIdsSuccess([selectedEmail])),
]));