TF-1767 Fix Reply/Forward original message should be marked, not the sent one
(cherry picked from commit 827c6537cbad268dac4860fb0c57714811ed44e1)
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||
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/mailbox/mailbox.dart';
|
||||
@@ -9,30 +8,33 @@ import 'package:model/email/email_action_type.dart';
|
||||
class EmailRequest with EquatableMixin {
|
||||
|
||||
final Email email;
|
||||
final Id submissionCreateId;
|
||||
final MailboxId? sentMailboxId;
|
||||
final EmailId? emailIdDestroyed;
|
||||
final EmailId? emailIdAnsweredOrForwarded;
|
||||
final Identity? identity;
|
||||
final EmailActionType? emailActionType;
|
||||
|
||||
EmailRequest(this.email, this.submissionCreateId, {
|
||||
EmailRequest(
|
||||
this.email, {
|
||||
this.sentMailboxId,
|
||||
this.identity,
|
||||
this.emailIdDestroyed,
|
||||
this.emailIdAnsweredOrForwarded,
|
||||
this.emailActionType
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
email,
|
||||
submissionCreateId,
|
||||
sentMailboxId,
|
||||
identity,
|
||||
emailIdDestroyed,
|
||||
emailIdAnsweredOrForwarded,
|
||||
emailActionType
|
||||
];
|
||||
|
||||
bool get isEmailAnswered => emailActionType == EmailActionType.reply || emailActionType == EmailActionType.replyAll;
|
||||
bool get isEmailAnswered => emailIdAnsweredOrForwarded != null &&
|
||||
(emailActionType == EmailActionType.reply || emailActionType == EmailActionType.replyAll);
|
||||
|
||||
bool get isEmailForwarded => emailActionType == EmailActionType.forward;
|
||||
bool get isEmailForwarded => emailIdAnsweredOrForwarded != null && emailActionType == EmailActionType.forward;
|
||||
}
|
||||
@@ -807,15 +807,14 @@ class ComposerController extends BaseController {
|
||||
|
||||
if (arguments != null && accountId != null && userProfile != null && session != null) {
|
||||
final email = await _generateEmail(context, userProfile, outboxMailboxId: outboxMailboxId);
|
||||
final submissionCreateId = Id(_uuid.v1());
|
||||
final emailRequest = EmailRequest(
|
||||
email,
|
||||
submissionCreateId,
|
||||
sentMailboxId: sentMailboxId,
|
||||
identity: identitySelected.value,
|
||||
emailIdDestroyed: arguments.emailActionType == EmailActionType.edit
|
||||
? arguments.presentationEmail?.id
|
||||
: null,
|
||||
emailIdAnsweredOrForwarded: arguments.presentationEmail?.id,
|
||||
emailActionType: arguments.emailActionType
|
||||
);
|
||||
final mailboxRequest = outboxMailboxId == null
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:core/core.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
@@ -13,10 +14,12 @@ import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart
|
||||
import 'package:jmap_dart_client/jmap/core/capability/core_capability.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/error/set_error.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/method/response/set_response.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/patch_object.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/reference_id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/reference_prefix.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/request/request_invocation.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
||||
import 'package:jmap_dart_client/jmap/jmap_request.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||
@@ -141,32 +144,48 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
final setEmailMethod = SetEmailMethod(accountId)
|
||||
..addCreate(idCreateMethod, emailNeedsToBeCreated);
|
||||
|
||||
final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
|
||||
final submissionCreateId = Id(_uuid.v1());
|
||||
final mailFrom = Address(emailNeedsToBeCreated.from?.first.email ?? '');
|
||||
final recipientsList = emailNeedsToBeCreated.getRecipientEmailAddressList()
|
||||
.map((emailAddress) => Address(emailAddress))
|
||||
.toSet();
|
||||
final emailSubmissionId = EmailSubmissionId(ReferenceId(ReferencePrefix.defaultPrefix, submissionCreateId));
|
||||
Map<EmailSubmissionId, PatchObject> mapEmailSubmissionUpdated = {
|
||||
emailSubmissionId: PatchObject({
|
||||
emailRequest.sentMailboxId!.generatePath() : true,
|
||||
outboxMailboxId!.generatePath() : null,
|
||||
KeyWordIdentifier.emailSeen.generatePath(): true,
|
||||
KeyWordIdentifier.emailDraft.generatePath(): null
|
||||
})
|
||||
};
|
||||
final emailSubmission = EmailSubmission(
|
||||
identityId: emailRequest.identity?.id?.id,
|
||||
emailId: EmailId(ReferenceId(ReferencePrefix.defaultPrefix, idCreateMethod)),
|
||||
envelope: Envelope(mailFrom, recipientsList));
|
||||
|
||||
final setEmailSubmissionMethod = SetEmailSubmissionMethod(accountId)
|
||||
..addCreate(
|
||||
emailRequest.submissionCreateId,
|
||||
EmailSubmission(
|
||||
identityId: emailRequest.identity?.id?.id,
|
||||
emailId: EmailId(ReferenceId(ReferencePrefix.defaultPrefix, idCreateMethod)),
|
||||
envelope: Envelope(
|
||||
Address(emailNeedsToBeCreated.from?.first.email ?? ''),
|
||||
emailNeedsToBeCreated.getRecipientEmailAddressList().map((emailAddress) => Address(emailAddress)).toSet()
|
||||
)
|
||||
))
|
||||
..addOnSuccessUpdateEmail({
|
||||
EmailSubmissionId(ReferenceId(ReferencePrefix.defaultPrefix, emailRequest.submissionCreateId)): PatchObject({
|
||||
emailRequest.sentMailboxId!.generatePath() : true,
|
||||
outboxMailboxId!.generatePath() : null,
|
||||
KeyWordIdentifier.emailSeen.generatePath(): true,
|
||||
KeyWordIdentifier.emailDraft.generatePath(): null,
|
||||
KeyWordIdentifier.emailAnswered.generatePath(): emailRequest.isEmailAnswered ? true : null,
|
||||
KeyWordIdentifier.emailForwarded.generatePath(): emailRequest.isEmailForwarded ? true : null
|
||||
})
|
||||
});
|
||||
..addCreate(submissionCreateId, emailSubmission)
|
||||
..addOnSuccessUpdateEmail(mapEmailSubmissionUpdated);
|
||||
|
||||
final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
|
||||
final setEmailSubmissionInvocation = requestBuilder.invocation(setEmailSubmissionMethod);
|
||||
|
||||
SetEmailMethod? markAsAnsweredOrForwardedSetMethod;
|
||||
RequestInvocation? markAsAnsweredOrForwardedInvocation;
|
||||
SetEmailResponse? markAsAnsweredOrForwardedSetResponse;
|
||||
|
||||
if (emailRequest.isEmailAnswered) {
|
||||
markAsAnsweredOrForwardedSetMethod = SetEmailMethod(accountId)
|
||||
..addUpdates([emailRequest.emailIdAnsweredOrForwarded!].generateMapUpdateObjectMarkAsAnswered());
|
||||
|
||||
markAsAnsweredOrForwardedInvocation = requestBuilder.invocation(markAsAnsweredOrForwardedSetMethod);
|
||||
} else if (emailRequest.isEmailForwarded) {
|
||||
markAsAnsweredOrForwardedSetMethod = SetEmailMethod(accountId)
|
||||
..addUpdates([emailRequest.emailIdAnsweredOrForwarded!].generateMapUpdateObjectMarkAsForwarded());
|
||||
|
||||
markAsAnsweredOrForwardedInvocation = requestBuilder.invocation(markAsAnsweredOrForwardedSetMethod);
|
||||
}
|
||||
|
||||
final capabilities = setEmailSubmissionMethod.requiredCapabilities
|
||||
.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
||||
|
||||
@@ -184,11 +203,18 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
SetEmailSubmissionResponse.deserialize,
|
||||
methodName: setEmailInvocation.methodName);
|
||||
|
||||
if (markAsAnsweredOrForwardedInvocation != null) {
|
||||
markAsAnsweredOrForwardedSetResponse = response.parse<SetEmailResponse>(
|
||||
markAsAnsweredOrForwardedInvocation.methodCallId,
|
||||
SetEmailResponse.deserialize);
|
||||
}
|
||||
|
||||
final emailCreated = setEmailResponse?.created?[idCreateMethod];
|
||||
final listEntriesErrors = _handleSetEmailResponse(
|
||||
response: setEmailResponse,
|
||||
submissionResponse: setEmailSubmissionResponse
|
||||
);
|
||||
final listEntriesErrors = _handleSetEmailResponse([
|
||||
setEmailResponse,
|
||||
setEmailSubmissionResponse,
|
||||
markAsAnsweredOrForwardedSetResponse
|
||||
]);
|
||||
final mapErrors = Map.fromEntries(listEntriesErrors);
|
||||
|
||||
if (emailCreated != null && mapErrors.isEmpty) {
|
||||
@@ -198,12 +224,14 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
}
|
||||
}
|
||||
|
||||
List<MapEntry<Id, SetError>> _handleSetEmailResponse({
|
||||
SetEmailResponse? response,
|
||||
SetEmailSubmissionResponse? submissionResponse
|
||||
}) {
|
||||
List<MapEntry<Id, SetError>> _handleSetEmailResponse(List<SetResponse?> listSetResponse) {
|
||||
final listSetResponseNotNull = listSetResponse.whereNotNull().toList();
|
||||
if (listSetResponseNotNull.isEmpty) {
|
||||
return [];
|
||||
}
|
||||
|
||||
final List<MapEntry<Id, SetError>> remainedErrors = [];
|
||||
if (response != null) {
|
||||
for (var response in listSetResponseNotNull) {
|
||||
handleSetErrors(
|
||||
notDestroyedError: response.notDestroyed,
|
||||
notUpdatedError: response.notUpdated,
|
||||
@@ -214,17 +242,6 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
}
|
||||
);
|
||||
}
|
||||
if (submissionResponse != null) {
|
||||
handleSetErrors(
|
||||
notDestroyedError: submissionResponse.notDestroyed,
|
||||
notUpdatedError: submissionResponse.notUpdated,
|
||||
notCreatedError: submissionResponse.notCreated,
|
||||
unCatchErrorHandler: (setErrorEntry) {
|
||||
remainedErrors.add(setErrorEntry);
|
||||
return false;
|
||||
}
|
||||
);
|
||||
}
|
||||
return remainedErrors;
|
||||
}
|
||||
|
||||
@@ -428,7 +445,6 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
return listEmailIdRequest.where((emailId) => listUpdated.expand((e) => e).toList().contains(emailId.id)).toList();
|
||||
}
|
||||
|
||||
|
||||
Future<List<Email>> markAsStar(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
@@ -490,7 +506,7 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
);
|
||||
|
||||
final emailCreated = setEmailResponse?.created?[idCreateMethod];
|
||||
final listEntriesErrors = _handleSetEmailResponse(response: setEmailResponse);
|
||||
final listEntriesErrors = _handleSetEmailResponse([setEmailResponse]);
|
||||
final mapErrors = Map.fromEntries(listEntriesErrors);
|
||||
|
||||
if (emailCreated != null && mapErrors.isEmpty) {
|
||||
@@ -554,7 +570,7 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
);
|
||||
|
||||
final emailUpdated = setEmailResponse?.created?[idCreateMethod];
|
||||
final listEntriesErrors = _handleSetEmailResponse(response: setEmailResponse);
|
||||
final listEntriesErrors = _handleSetEmailResponse([setEmailResponse]);
|
||||
final mapErrors = Map.fromEntries(listEntriesErrors);
|
||||
|
||||
if (emailUpdated != null && mapErrors.isEmpty) {
|
||||
|
||||
@@ -19,4 +19,16 @@ extension KeyWordIdentifierExtension on KeyWordIdentifier {
|
||||
generatePath(): markStarAction == MarkStarAction.markStar ? true : null
|
||||
});
|
||||
}
|
||||
|
||||
PatchObject generateAnsweredActionPath() {
|
||||
return PatchObject({
|
||||
generatePath(): true
|
||||
});
|
||||
}
|
||||
|
||||
PatchObject generateForwardedActionPath() {
|
||||
return PatchObject({
|
||||
generatePath(): true
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -10,34 +10,44 @@ extension ListEmailIdExtension on List<EmailId> {
|
||||
List<Id> toIds() => map((emailId) => emailId.id).toList();
|
||||
|
||||
Map<Id, PatchObject> generateMapUpdateObjectMarkAsRead(ReadActions readActions) {
|
||||
final Map<Id, PatchObject> maps = {};
|
||||
forEach((emailId) {
|
||||
maps[emailId.id] = KeyWordIdentifier.emailSeen.generateReadActionPath(readActions);
|
||||
});
|
||||
return maps;
|
||||
return {
|
||||
for (var emailId in this)
|
||||
emailId.id: KeyWordIdentifier.emailSeen.generateReadActionPath(readActions)
|
||||
};
|
||||
}
|
||||
|
||||
Map<Id, PatchObject> generateMapUpdateObjectMoveToMailbox(MailboxId currentMailboxId, MailboxId destinationMailboxId) {
|
||||
final Map<Id, PatchObject> maps = {};
|
||||
forEach((emailId) {
|
||||
maps[emailId.id] = currentMailboxId.generateMoveToMailboxActionPath(destinationMailboxId);
|
||||
});
|
||||
return maps;
|
||||
return {
|
||||
for (var emailId in this)
|
||||
emailId.id: currentMailboxId.generateMoveToMailboxActionPath(destinationMailboxId)
|
||||
};
|
||||
}
|
||||
|
||||
Map<Id, PatchObject> generateMapUpdateObjectMarkAsStar(MarkStarAction markStarAction) {
|
||||
final Map<Id, PatchObject> maps = {};
|
||||
forEach((emailId) {
|
||||
maps[emailId.id] = KeyWordIdentifier.emailFlagged.generateMarkStarActionPath(markStarAction);
|
||||
});
|
||||
return maps;
|
||||
return {
|
||||
for (var emailId in this)
|
||||
emailId.id: KeyWordIdentifier.emailFlagged.generateMarkStarActionPath(markStarAction)
|
||||
};
|
||||
}
|
||||
|
||||
Map<Id, PatchObject> generateMapUpdateObjectMarkAsSpam(MailboxId spamMailboxId) {
|
||||
final Map<Id, PatchObject> maps = {};
|
||||
forEach((emailId) {
|
||||
maps[emailId.id] = spamMailboxId.generateActionPath();
|
||||
});
|
||||
return maps;
|
||||
return {
|
||||
for (var emailId in this)
|
||||
emailId.id: spamMailboxId.generateActionPath()
|
||||
};
|
||||
}
|
||||
|
||||
Map<Id, PatchObject> generateMapUpdateObjectMarkAsAnswered() {
|
||||
return {
|
||||
for (var emailId in this)
|
||||
emailId.id: KeyWordIdentifier.emailAnswered.generateAnsweredActionPath()
|
||||
};
|
||||
}
|
||||
|
||||
Map<Id, PatchObject> generateMapUpdateObjectMarkAsForwarded() {
|
||||
return {
|
||||
for (var emailId in this)
|
||||
emailId.id: KeyWordIdentifier.emailForwarded.generateForwardedActionPath()
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user