TF-3715 Thread Detail create resuable actions

TF-3715 Thread Detail refactor actions for expanded email view

TF-3715 Thread Detail apply actions for collapsed email view

TF-3715 Thread Detail fix unit tests

TF-3715 Thread Detail add await for _getEmailContent in composer

TF-3715 Thread Detail remove unused emailLoaded in ThreadDetailAppBar

TF-3715 Thread Detail hide print action when isMobile

TF-3715 Thread Detail allow mark as read in EmailActionReactor

TF-3715 Thread Detail fix loadMoreThreadDetailEmails unit test

TF-3715 Thread Detail fix action small tap region

TF-3715 Thread Detail fix cannot permanent delete email

TF-3715 Thread Detail prevent close when move email

TF-3715 Thread Detail fix refresh when mark star selected collapsed email

TF-3715 Thread Detail update print action display logic

TF-3715 Thread Detail fix duplicate mark star in app bar

TF-3715 Thread Detail create new transformer for reply forward empty content email

TF-3715 Thread Detail fix email not load after open multiple times

TF-3715 Thread Detail fix close when move expanded email

TF-3715 Thread Detail fix duplicate and missing actions

TF-3715 Thread Detail restore editAsNewEmail action to _getEmailContent in setupEmailContent

TF-3715 Thread Detail update print action name

TF-3715 Thread Detail handle move and delete email with 1 item in thread detail

TF-3715 Thread Detail fix tap outside to close context menu

TF-3715 Thread Detail fix create rule and compose from recipient info

TF-3715 Thread Detail handle move and delete email with 1 item in thread detail

TF-3715 Thread Detail Fix cannot create email rule

TF-3715 Thread Detail Fix crash composer

TF-3715 Thread Detail Fix cannot unsubscribe

TF-3715 Thread Detail Fix duplicate actions on single email

TF-3715 Thread Detail Fix refresh view when reply/forward

TF-3715 Thread Detail Revert old logic to _getEmailContent

TF-3715 Thread Detail Update specific cases for UpdatedEmailKeywordsAction

TF-3715 Thread Detail Fix concurrent modification during iteration

TF-3715 Thread Detail Fix unsubscribe for all thread detail emails

TF-3715 Thread Detail Remove unnecessary Future in reactor

TF-3715 Thread Detail Remove dependency from SingleEmailController

TF-3715 Thread Detail Apply individual list post and unsubscribe header

TF-3715 Thread Detail Fix unsubscribe collapsed email

TF-3715 Thread Detail Conditionally inject rule filter interactor
This commit is contained in:
DatDang
2025-05-16 15:37:07 +07:00
committed by Dat H. Pham
parent 421fa321ba
commit 8a2ea62987
38 changed files with 2135 additions and 715 deletions
+17
View File
@@ -17,6 +17,7 @@ import 'package:model/email/email_in_thread_status.dart';
import 'package:model/email/mail_priority_header.dart';
import 'package:model/extensions/email_address_extension.dart';
import 'package:model/extensions/keyword_identifier_extension.dart';
import 'package:model/extensions/list_email_header_extension.dart';
import 'package:model/extensions/media_type_nullable_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:model/mailbox/select_mode.dart';
@@ -50,6 +51,8 @@ class PresentationEmail with EquatableMixin, SearchSnippetMixin {
final Map<IndividualHeaderIdentifier, String?>? xPriorityHeader;
final Map<IndividualHeaderIdentifier, String?>? importanceHeader;
final Map<IndividualHeaderIdentifier, String?>? priorityHeader;
final Map<IndividualHeaderIdentifier, String?>? listPostHeader;
final Map<IndividualHeaderIdentifier, String?>? listUnsubscribeHeader;
final EmailInThreadStatus? emailInThreadStatus;
PresentationEmail({
@@ -79,6 +82,8 @@ class PresentationEmail with EquatableMixin, SearchSnippetMixin {
this.xPriorityHeader,
this.importanceHeader,
this.priorityHeader,
this.listPostHeader,
this.listUnsubscribeHeader,
this.emailInThreadStatus,
});
@@ -141,6 +146,12 @@ class PresentationEmail with EquatableMixin, SearchSnippetMixin {
bool get hasCalendarEvent => headerCalendarEvent?[IndividualHeaderIdentifier.headerCalendarEvent]?.isNotEmpty == true;
String? get listPost => emailHeader?.toSet().listPost?.trim()
?? listPostHeader?[IndividualHeaderIdentifier.listPostHeader]?.trim();
String? get listUnsubscribe => emailHeader?.toSet().listUnsubscribe?.trim()
?? listUnsubscribeHeader?[IndividualHeaderIdentifier.listUnsubscribeHeader]?.trim();
bool get isMarkAsImportant {
final xPriority = xPriorityHeader?[IndividualHeaderIdentifier.xPriorityHeader]
?.trim()
@@ -201,6 +212,8 @@ class PresentationEmail with EquatableMixin, SearchSnippetMixin {
xPriorityHeader,
importanceHeader,
priorityHeader,
listPostHeader,
listUnsubscribeHeader,
emailInThreadStatus,
];
@@ -231,6 +244,8 @@ class PresentationEmail with EquatableMixin, SearchSnippetMixin {
Map<IndividualHeaderIdentifier, String?>? xPriorityHeader,
Map<IndividualHeaderIdentifier, String?>? importanceHeader,
Map<IndividualHeaderIdentifier, String?>? priorityHeader,
Map<IndividualHeaderIdentifier, String?>? listPostHeader,
Map<IndividualHeaderIdentifier, String?>? listUnsubscribeHeader,
EmailInThreadStatus? emailInThreadStatus,
}) {
return PresentationEmail(
@@ -260,6 +275,8 @@ class PresentationEmail with EquatableMixin, SearchSnippetMixin {
xPriorityHeader: xPriorityHeader ?? this.xPriorityHeader,
importanceHeader: importanceHeader ?? this.importanceHeader,
priorityHeader: priorityHeader ?? this.priorityHeader,
listPostHeader: listPostHeader ?? this.listPostHeader,
listUnsubscribeHeader: listUnsubscribeHeader ?? this.listUnsubscribeHeader,
emailInThreadStatus: emailInThreadStatus ?? this.emailInThreadStatus,
);
}
+18 -2
View File
@@ -33,7 +33,9 @@ extension EmailExtension on Email {
bool get withAttachments => hasAttachment == true;
String get listUnsubscribe => headers.listUnsubscribe;
String get listUnsubscribe => headers.listUnsubscribe
?? listUnsubscribeHeader?[IndividualHeaderIdentifier.listUnsubscribeHeader]
?? '';
bool get hasRequestReadReceipt => headers.readReceiptHasBeenRequested ||
headerMdn?.containsKey(IndividualHeaderIdentifier.headerMdn) == true;
@@ -42,7 +44,9 @@ extension EmailExtension on Email {
String get sMimeStatusHeaderParsed => sMimeStatusHeader?[IndividualHeaderIdentifier.sMimeStatusHeader]?.trim() ?? '';
String get listPost => headers.listPost.trim();
String get listPost => headers.listPost?.trim()
?? listPostHeader?[IndividualHeaderIdentifier.listPostHeader]?.trim()
?? '';
IdentityId? get identityIdFromHeader {
final rawIdentityId = identityHeader?[IndividualHeaderIdentifier.identityHeader];
@@ -125,6 +129,8 @@ extension EmailExtension on Email {
xPriorityHeader: xPriorityHeader,
importanceHeader: importanceHeader,
priorityHeader: priorityHeader,
listPostHeader: listPostHeader,
listUnsubscribeHeader: listUnsubscribeHeader,
)
..searchSnippetSubject = searchSnippetSubject
..searchSnippetPreview = searchSnippetPreview;
@@ -158,6 +164,12 @@ extension EmailExtension on Email {
priorityHeader: updatedProperties.contain(IndividualHeaderIdentifier.priorityHeader.value)
? newEmail.priorityHeader
: priorityHeader,
listPostHeader: updatedProperties.contain(IndividualHeaderIdentifier.listPostHeader.value)
? newEmail.listPostHeader
: listPostHeader,
listUnsubscribeHeader: updatedProperties.contain(IndividualHeaderIdentifier.listUnsubscribeHeader.value)
? newEmail.listUnsubscribeHeader
: listUnsubscribeHeader,
);
}
@@ -246,6 +258,8 @@ extension EmailExtension on Email {
Map<IndividualHeaderIdentifier, String?>? xPriorityHeader,
Map<IndividualHeaderIdentifier, String?>? importanceHeader,
Map<IndividualHeaderIdentifier, String?>? priorityHeader,
Map<IndividualHeaderIdentifier, String?>? listPostHeader,
Map<IndividualHeaderIdentifier, String?>? listUnsubscribeHeader,
}) {
return Email(
id: id ?? this.id,
@@ -283,6 +297,8 @@ extension EmailExtension on Email {
xPriorityHeader: xPriorityHeader ?? this.xPriorityHeader,
importanceHeader: importanceHeader ?? this.importanceHeader,
priorityHeader: priorityHeader ?? this.priorityHeader,
listPostHeader: listPostHeader ?? this.listPostHeader,
listUnsubscribeHeader: listUnsubscribeHeader ?? this.listUnsubscribeHeader,
);
}
}
@@ -14,9 +14,9 @@ extension ListEmailHeaderExtension on Set<EmailHeader>? {
}
}
String get listUnsubscribe {
String? get listUnsubscribe {
final listUnsubscribe = this?.firstWhereOrNull((header) => header.name == EmailProperty.headerUnsubscribeKey);
return listUnsubscribe?.value ?? '';
return listUnsubscribe?.value;
}
String get sMimeStatus {
@@ -25,8 +25,8 @@ extension ListEmailHeaderExtension on Set<EmailHeader>? {
return sMimeStatus?.value.trim() ?? '';
}
String get listPost {
String? get listPost {
final listPost = this?.firstWhereOrNull((header) => header.name == EmailProperty.headerListPostKey);
return listPost?.value ?? '';
return listPost?.value;
}
}
@@ -111,6 +111,9 @@ extension PresentationEmailExtension on PresentationEmail {
xPriorityHeader: xPriorityHeader,
importanceHeader: importanceHeader,
priorityHeader: priorityHeader,
listPostHeader: listPostHeader,
listUnsubscribeHeader: listUnsubscribeHeader,
threadId: threadId,
);
}