TF-3413 Fix ReplyAll & Reply is buggy
This commit is contained in:
@@ -23,7 +23,6 @@ import 'package:jmap_dart_client/jmap/identities/identity.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/individual_header_identifier.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
||||
@@ -647,8 +646,6 @@ class ComposerController extends BaseController
|
||||
_initEmailAddress(
|
||||
presentationEmail: arguments.presentationEmail!,
|
||||
actionType: arguments.emailActionType,
|
||||
mailboxRole: arguments.presentationEmail!.mailboxContain?.role
|
||||
?? mailboxDashBoardController.selectedMailbox.value?.role,
|
||||
listPost: arguments.listPost,
|
||||
);
|
||||
_initSubjectEmail(
|
||||
@@ -802,32 +799,23 @@ class ComposerController extends BaseController
|
||||
void _initEmailAddress({
|
||||
required PresentationEmail presentationEmail,
|
||||
required EmailActionType actionType,
|
||||
Role? mailboxRole,
|
||||
String? listPost,
|
||||
}) {
|
||||
log('ComposerController::_initEmailAddress:listPost = $listPost');
|
||||
final userName = mailboxDashBoardController.sessionCurrent?.username.value;
|
||||
final isSender = presentationEmail.from
|
||||
.asList()
|
||||
.any((element) => element.emailAddress.isNotEmpty && element.emailAddress == userName);
|
||||
|
||||
final recipients = presentationEmail.generateRecipientsEmailAddressForComposer(
|
||||
emailActionType: actionType,
|
||||
mailboxRole: mailboxRole,
|
||||
isSender: isSender,
|
||||
userName: userName,
|
||||
listPost: listPost,
|
||||
);
|
||||
final userName = mailboxDashBoardController.sessionCurrent?.username;
|
||||
if (userName != null) {
|
||||
final isSender = presentationEmail.from.asList().every((element) => element.email == userName.value);
|
||||
if (isSender) {
|
||||
listToEmailAddress = List.from(recipients.value1.toSet());
|
||||
listCcEmailAddress = List.from(recipients.value2.toSet());
|
||||
listBccEmailAddress = List.from(recipients.value3.toSet());
|
||||
} else {
|
||||
listToEmailAddress = List.from(recipients.value1.toSet().filterEmailAddress(userName.value));
|
||||
listCcEmailAddress = List.from(recipients.value2.toSet().filterEmailAddress(userName.value));
|
||||
listBccEmailAddress = List.from(recipients.value3.toSet().filterEmailAddress(userName.value));
|
||||
}
|
||||
} else {
|
||||
listToEmailAddress = List.from(recipients.value1.toSet());
|
||||
listCcEmailAddress = List.from(recipients.value2.toSet());
|
||||
listBccEmailAddress = List.from(recipients.value3.toSet());
|
||||
}
|
||||
|
||||
listToEmailAddress = List.from(recipients.value1);
|
||||
listCcEmailAddress = List.from(recipients.value2);
|
||||
listBccEmailAddress = List.from(recipients.value3);
|
||||
|
||||
if (listToEmailAddress.isNotEmpty || listCcEmailAddress.isNotEmpty || listBccEmailAddress.isNotEmpty) {
|
||||
isInitialRecipient.value = true;
|
||||
|
||||
@@ -1422,6 +1422,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
mailboxRole: presentationEmail.mailboxContain?.role,
|
||||
messageId: currentEmailLoaded.value?.emailCurrent?.messageId,
|
||||
references: currentEmailLoaded.value?.emailCurrent?.references,
|
||||
listPost: currentEmailLoaded.value?.emailCurrent?.listPost,
|
||||
)
|
||||
);
|
||||
break;
|
||||
@@ -1448,6 +1449,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
mailboxRole: presentationEmail.mailboxContain?.role,
|
||||
messageId: currentEmailLoaded.value?.emailCurrent?.messageId,
|
||||
references: currentEmailLoaded.value?.emailCurrent?.references,
|
||||
listPost: currentEmailLoaded.value?.emailCurrent?.listPost,
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
@@ -1,49 +1,91 @@
|
||||
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||
import 'package:model/email/email_action_type.dart';
|
||||
import 'package:model/email/presentation_email.dart';
|
||||
import 'package:model/extensions/list_email_address_extension.dart';
|
||||
import 'package:model/mailbox/presentation_mailbox.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart';
|
||||
|
||||
extension PresentationEmailExtension on PresentationEmail {
|
||||
Tuple3<List<EmailAddress>, List<EmailAddress>, List<EmailAddress>> generateRecipientsEmailAddressForComposer({
|
||||
required EmailActionType emailActionType,
|
||||
Role? mailboxRole,
|
||||
bool isSender = false,
|
||||
String? userName,
|
||||
String? listPost,
|
||||
}) {
|
||||
final newFromAddress = from.removeDuplicateEmails();
|
||||
final newToAddress = to.removeDuplicateEmails();
|
||||
final newCcAddress = cc.removeDuplicateEmails();
|
||||
final newBccAddress = bcc.removeDuplicateEmails();
|
||||
final newReplyToAddress = replyTo.removeDuplicateEmails();
|
||||
|
||||
switch (emailActionType) {
|
||||
case EmailActionType.reply:
|
||||
if (mailboxRole == PresentationMailbox.roleSent) {
|
||||
return Tuple3(to.asList(), [], []);
|
||||
} else {
|
||||
final replyToAddress = replyTo.asList().isNotEmpty
|
||||
? replyTo.asList()
|
||||
: from.asList();
|
||||
return Tuple3(replyToAddress, [], []);
|
||||
}
|
||||
final listReplyAddress = isSender ? newToAddress : newFromAddress;
|
||||
final listReplyAddressWithoutUsername = listReplyAddress.withoutMe(userName);
|
||||
|
||||
return Tuple3(listReplyAddressWithoutUsername, [], []);
|
||||
case EmailActionType.replyToList:
|
||||
final listEmailAddress = EmailUtils.parsingListPost(listPost ?? '') ?? [];
|
||||
log('PresentationEmailExtension::generateRecipientsEmailAddressForComposer:listEmailAddress = $listEmailAddress');
|
||||
return Tuple3(listEmailAddress, [], []);
|
||||
final recipientRecord = EmailUtils.extractRecipientsFromListPost(listPost ?? '');
|
||||
|
||||
final listToAddressWithoutUsername = recipientRecord.toMailAddresses
|
||||
.toSet()
|
||||
.removeDuplicateEmails()
|
||||
.withoutMe(userName);
|
||||
|
||||
final listCcAddressWithoutUsername = recipientRecord.ccMailAddresses
|
||||
.toSet()
|
||||
.removeDuplicateEmails()
|
||||
.withoutMe(userName);
|
||||
|
||||
final listBccAddressWithoutUsername = recipientRecord.bccMailAddresses
|
||||
.toSet()
|
||||
.removeDuplicateEmails()
|
||||
.withoutMe(userName);
|
||||
|
||||
return Tuple3(
|
||||
listToAddressWithoutUsername,
|
||||
listCcAddressWithoutUsername,
|
||||
listBccAddressWithoutUsername,
|
||||
);
|
||||
case EmailActionType.replyAll:
|
||||
if (mailboxRole == PresentationMailbox.roleSent) {
|
||||
return Tuple3(to.asList(), cc.asList(), bcc.asList());
|
||||
} else {
|
||||
final senderReplyToAddress = replyTo.asList().isNotEmpty
|
||||
? replyTo.asList()
|
||||
: from.asList();
|
||||
return Tuple3(
|
||||
to.asList() + senderReplyToAddress,
|
||||
cc.asList(),
|
||||
bcc.asList(),
|
||||
);
|
||||
}
|
||||
final recipientRecord = EmailUtils.extractRecipientsFromListPost(listPost ?? '');
|
||||
|
||||
final listToAddress = recipientRecord.toMailAddresses
|
||||
+ newReplyToAddress
|
||||
+ newFromAddress
|
||||
+ newToAddress;
|
||||
final listCcAddress = recipientRecord.ccMailAddresses + newCcAddress;
|
||||
final listBccAddress = recipientRecord.bccMailAddresses + newBccAddress;
|
||||
|
||||
final listToAddressWithoutUsername = listToAddress
|
||||
.toSet()
|
||||
.removeDuplicateEmails()
|
||||
.withoutMe(userName);
|
||||
final listCcAddressWithoutUsername = listCcAddress
|
||||
.toSet()
|
||||
.removeDuplicateEmails()
|
||||
.withoutMe(userName);
|
||||
final listBccAddressWithoutUsername = listBccAddress
|
||||
.toSet()
|
||||
.removeDuplicateEmails()
|
||||
.withoutMe(userName);
|
||||
|
||||
return Tuple3(
|
||||
listToAddressWithoutUsername,
|
||||
listCcAddressWithoutUsername,
|
||||
listBccAddressWithoutUsername,
|
||||
);
|
||||
default:
|
||||
return Tuple3(to.asList(), cc.asList(), bcc.asList());
|
||||
final listToAddressWithoutUsername = newToAddress.withoutMe(userName);
|
||||
final listCcAddressWithoutUsername = newCcAddress.withoutMe(userName);
|
||||
final listBccAddressWithoutUsername = newBccAddress.withoutMe(userName);
|
||||
|
||||
return Tuple3(
|
||||
listToAddressWithoutUsername,
|
||||
listCcAddressWithoutUsername,
|
||||
listBccAddressWithoutUsername,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,6 +122,7 @@ class ComposerArguments extends RouterArguments {
|
||||
Role? mailboxRole,
|
||||
MessageIdsHeaderValue? messageId,
|
||||
MessageIdsHeaderValue? references,
|
||||
String? listPost,
|
||||
}) => ComposerArguments(
|
||||
emailActionType: EmailActionType.reply,
|
||||
presentationEmail: presentationEmail,
|
||||
@@ -130,6 +131,7 @@ class ComposerArguments extends RouterArguments {
|
||||
mailboxRole: mailboxRole,
|
||||
messageId: messageId,
|
||||
references: references,
|
||||
listPost: listPost,
|
||||
);
|
||||
|
||||
factory ComposerArguments.replyToListEmail({
|
||||
@@ -158,6 +160,7 @@ class ComposerArguments extends RouterArguments {
|
||||
Role? mailboxRole,
|
||||
MessageIdsHeaderValue? messageId,
|
||||
MessageIdsHeaderValue? references,
|
||||
String? listPost,
|
||||
}) => ComposerArguments(
|
||||
emailActionType: EmailActionType.replyAll,
|
||||
presentationEmail: presentationEmail,
|
||||
@@ -166,6 +169,7 @@ class ComposerArguments extends RouterArguments {
|
||||
mailboxRole: mailboxRole,
|
||||
messageId: messageId,
|
||||
references: references,
|
||||
listPost: listPost,
|
||||
);
|
||||
|
||||
factory ComposerArguments.forwardEmail({
|
||||
|
||||
@@ -86,37 +86,108 @@ class EmailUtils {
|
||||
}
|
||||
}
|
||||
|
||||
static List<EmailAddress>? parsingListPost(String listPost) {
|
||||
static List<String> extractMailtoLinksFromListPost(String listPost) {
|
||||
try {
|
||||
if (listPost.isEmpty) {
|
||||
return null;
|
||||
if (listPost.trim().isEmpty) return [];
|
||||
|
||||
final decodedInput = Uri.decodeComponent(listPost);
|
||||
|
||||
final mailtoRegex = RegExp(r'<(mailto:[^<>]+)>');
|
||||
|
||||
final matches = mailtoRegex.allMatches(decodedInput);
|
||||
|
||||
if (matches.isEmpty) {
|
||||
log('EmailUtils::extractMailtoLinksFromListPost: Not found mailto link');
|
||||
return [];
|
||||
}
|
||||
|
||||
final regExpMailtoLinks = RegExp(r'mailto:([^>,]*)');
|
||||
final allMatchesMailtoLinks = regExpMailtoLinks.allMatches(listPost);
|
||||
final listMailtoLinks = allMatchesMailtoLinks
|
||||
.map((match) => match.group(0))
|
||||
.whereNotNull()
|
||||
.toList();
|
||||
log('EmailUtils::parsingListPost:listMailtoLinks: $listMailtoLinks');
|
||||
|
||||
if (listMailtoLinks.isNotEmpty) {
|
||||
return listMailtoLinks
|
||||
.map((mailto) {
|
||||
final mapMailto = RouteUtils.parseMapMailtoFromUri(mailto);
|
||||
final emailAddress = mapMailto[RouteUtils.paramMailtoAddress];
|
||||
return emailAddress != null
|
||||
? EmailAddress(null, emailAddress)
|
||||
: null;
|
||||
})
|
||||
.whereNotNull()
|
||||
.toList();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return matches.map((match) => match.group(1)!).toList();
|
||||
} catch (e) {
|
||||
logError('EmailUtils::parsingListPost:Exception = $e');
|
||||
return null;
|
||||
logError('EmailUtils::extractMailtoLinksFromListPost:Exception = $e');
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
static ({
|
||||
List<EmailAddress> toMailAddresses,
|
||||
List<EmailAddress> ccMailAddresses,
|
||||
List<EmailAddress> bccMailAddresses,
|
||||
}) extractRecipientsFromListMailtoLink(List<String> mailtoLinks) {
|
||||
try {
|
||||
log('EmailUtils::extractRecipientsFromListMailtoLink: mailtoLinks: $mailtoLinks:');
|
||||
if (mailtoLinks.isEmpty) {
|
||||
return (
|
||||
toMailAddresses: [],
|
||||
ccMailAddresses: [],
|
||||
bccMailAddresses: [],
|
||||
);
|
||||
}
|
||||
|
||||
final toMailAddresses = <EmailAddress>[];
|
||||
final ccMailAddresses = <EmailAddress>[];
|
||||
final bccMailAddresses = <EmailAddress>[];
|
||||
|
||||
for (var mailtoLink in mailtoLinks) {
|
||||
final recipientRecord = extractRecipientsFromMailtoLink(mailtoLink);
|
||||
toMailAddresses.addAll(recipientRecord.toMailAddresses);
|
||||
ccMailAddresses.addAll(recipientRecord.ccMailAddresses);
|
||||
bccMailAddresses.addAll(recipientRecord.bccMailAddresses);
|
||||
}
|
||||
|
||||
return (
|
||||
toMailAddresses: toMailAddresses,
|
||||
ccMailAddresses: ccMailAddresses,
|
||||
bccMailAddresses: bccMailAddresses
|
||||
);
|
||||
} catch (e) {
|
||||
logError('EmailUtils::extractRecipientsFromListMailtoLink:Exception = $e');
|
||||
return (
|
||||
toMailAddresses: [],
|
||||
ccMailAddresses: [],
|
||||
bccMailAddresses: [],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static ({
|
||||
List<EmailAddress> toMailAddresses,
|
||||
List<EmailAddress> ccMailAddresses,
|
||||
List<EmailAddress> bccMailAddresses,
|
||||
}) extractRecipientsFromMailtoLink(String mailtoLink) {
|
||||
try {
|
||||
log('EmailUtils::extractRecipientsFromMailtoLink:mailtoLink: $mailtoLink:');
|
||||
if (mailtoLink.isEmpty) {
|
||||
return (
|
||||
toMailAddresses: [],
|
||||
ccMailAddresses: [],
|
||||
bccMailAddresses: [],
|
||||
);
|
||||
}
|
||||
|
||||
final navigationRouter =
|
||||
RouteUtils.generateNavigationRouterFromMailtoLink(mailtoLink);
|
||||
log('EmailUtils::extractRecipientsFromMailtoLink:navigationRouter = $navigationRouter');
|
||||
return (
|
||||
toMailAddresses: navigationRouter.listEmailAddress ?? [],
|
||||
ccMailAddresses: navigationRouter.cc ?? [],
|
||||
bccMailAddresses: navigationRouter.bcc ?? [],
|
||||
);
|
||||
} catch (e) {
|
||||
logError('EmailUtils::extractRecipientsFromMailtoLink:Exception = $e');
|
||||
return (
|
||||
toMailAddresses: [],
|
||||
ccMailAddresses: [],
|
||||
bccMailAddresses: [],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static ({
|
||||
List<EmailAddress> toMailAddresses,
|
||||
List<EmailAddress> ccMailAddresses,
|
||||
List<EmailAddress> bccMailAddresses,
|
||||
}) extractRecipientsFromListPost(String listPost) {
|
||||
final mailtoLinks = extractMailtoLinksFromListPost(listPost);
|
||||
return extractRecipientsFromListMailtoLink(mailtoLinks);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user