draft header
This commit is contained in:
@@ -323,10 +323,24 @@ public static class OutlookIntegratorExtensions
|
|||||||
|
|
||||||
var headers = new List<InternetMessageHeader>();
|
var headers = new List<InternetMessageHeader>();
|
||||||
|
|
||||||
|
// PRIORITY: Always include WinoLocalDraftHeader first if it exists
|
||||||
|
// This is critical for draft mapping functionality
|
||||||
|
var winoDraftHeader = mime.Headers.FirstOrDefault(h => h.Field == Domain.Constants.WinoLocalDraftHeader);
|
||||||
int includedHeaderCount = 0;
|
int includedHeaderCount = 0;
|
||||||
|
|
||||||
|
if (winoDraftHeader != null)
|
||||||
|
{
|
||||||
|
var headerValue = winoDraftHeader.Value.Length >= 995 ? winoDraftHeader.Value.Substring(0, 995) : winoDraftHeader.Value;
|
||||||
|
headers.Add(new InternetMessageHeader() { Name = winoDraftHeader.Field, Value = headerValue });
|
||||||
|
includedHeaderCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Include other headers up to the limit (excluding the already added WinoLocalDraftHeader)
|
||||||
foreach (var header in mime.Headers)
|
foreach (var header in mime.Headers)
|
||||||
{
|
{
|
||||||
|
if (header.Field == Domain.Constants.WinoLocalDraftHeader)
|
||||||
|
continue; // Already processed above
|
||||||
|
|
||||||
if (!headersToIgnore.Contains(header.Field))
|
if (!headersToIgnore.Contains(header.Field))
|
||||||
{
|
{
|
||||||
var headerName = headersToModify.Contains(header.Field) ? $"X-{header.Field}" : header.Field;
|
var headerName = headersToModify.Contains(header.Field) ? $"X-{header.Field}" : header.Field;
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ public class OutlookSynchronizer : WinoSynchronizer<RequestInformation, Message,
|
|||||||
"Subject",
|
"Subject",
|
||||||
"ParentFolderId",
|
"ParentFolderId",
|
||||||
"InternetMessageId",
|
"InternetMessageId",
|
||||||
|
"InternetMessageHeaders",
|
||||||
];
|
];
|
||||||
|
|
||||||
private readonly SemaphoreSlim _handleItemRetrievalSemaphore = new(1);
|
private readonly SemaphoreSlim _handleItemRetrievalSemaphore = new(1);
|
||||||
@@ -575,7 +576,7 @@ public class OutlookSynchronizer : WinoSynchronizer<RequestInformation, Message,
|
|||||||
if (message != null)
|
if (message != null)
|
||||||
{
|
{
|
||||||
// Create MailCopy from metadata only
|
// Create MailCopy from metadata only
|
||||||
var mailCopy = CreateMailCopyFromMessage(message, folder);
|
var mailCopy = await CreateMailCopyFromMessageAsync(message, folder).ConfigureAwait(false);
|
||||||
|
|
||||||
if (mailCopy != null)
|
if (mailCopy != null)
|
||||||
{
|
{
|
||||||
@@ -666,7 +667,7 @@ public class OutlookSynchronizer : WinoSynchronizer<RequestInformation, Message,
|
|||||||
/// Creates a MailCopy from an Outlook Message with metadata only (centralized method).
|
/// Creates a MailCopy from an Outlook Message with metadata only (centralized method).
|
||||||
/// This replaces the scattered CreateMinimalMailCopyAsync and AsMailCopy calls.
|
/// This replaces the scattered CreateMinimalMailCopyAsync and AsMailCopy calls.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private MailCopy CreateMailCopyFromMessage(Message message, MailItemFolder assignedFolder)
|
private async Task<MailCopy> CreateMailCopyFromMessageAsync(Message message, MailItemFolder assignedFolder)
|
||||||
{
|
{
|
||||||
if (message == null) return null;
|
if (message == null) return null;
|
||||||
|
|
||||||
@@ -675,6 +676,37 @@ public class OutlookSynchronizer : WinoSynchronizer<RequestInformation, Message,
|
|||||||
mailCopy.UniqueId = Guid.NewGuid();
|
mailCopy.UniqueId = Guid.NewGuid();
|
||||||
mailCopy.FileId = Guid.NewGuid();
|
mailCopy.FileId = Guid.NewGuid();
|
||||||
|
|
||||||
|
// Check for draft mapping if this is a draft with WinoLocalDraftHeader
|
||||||
|
if (message.IsDraft.GetValueOrDefault() && message.InternetMessageHeaders != null)
|
||||||
|
{
|
||||||
|
var winoDraftHeader = message.InternetMessageHeaders
|
||||||
|
.FirstOrDefault(h => string.Equals(h.Name, Domain.Constants.WinoLocalDraftHeader, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
|
if (winoDraftHeader != null && Guid.TryParse(winoDraftHeader.Value, out Guid localDraftCopyUniqueId))
|
||||||
|
{
|
||||||
|
// This message belongs to existing local draft copy.
|
||||||
|
// We don't need to create a new mail copy for this message, just update the existing one.
|
||||||
|
|
||||||
|
bool isMappingSuccessful = await _outlookChangeProcessor.MapLocalDraftAsync(
|
||||||
|
Account.Id,
|
||||||
|
localDraftCopyUniqueId,
|
||||||
|
mailCopy.Id,
|
||||||
|
mailCopy.DraftId,
|
||||||
|
mailCopy.ThreadId);
|
||||||
|
|
||||||
|
if (isMappingSuccessful)
|
||||||
|
{
|
||||||
|
_logger.Debug("Successfully mapped remote draft {RemoteId} to local draft {LocalId}",
|
||||||
|
mailCopy.Id, localDraftCopyUniqueId);
|
||||||
|
return null; // Don't create new mail copy, existing one was updated
|
||||||
|
}
|
||||||
|
|
||||||
|
// Local copy doesn't exist. Continue execution to insert mail copy.
|
||||||
|
_logger.Debug("Local draft copy {LocalId} not found, creating new mail copy for {RemoteId}",
|
||||||
|
localDraftCopyUniqueId, mailCopy.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return mailCopy;
|
return mailCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -687,10 +719,10 @@ public class OutlookSynchronizer : WinoSynchronizer<RequestInformation, Message,
|
|||||||
await QueueMailIdsForFolderAsync(folder, cancellationToken).ConfigureAwait(false);
|
await QueueMailIdsForFolderAsync(folder, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Task<MailCopy> CreateMinimalMailCopyAsync(Message message, MailItemFolder assignedFolder, CancellationToken cancellationToken = default)
|
protected override async Task<MailCopy> CreateMinimalMailCopyAsync(Message message, MailItemFolder assignedFolder, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
// Use centralized method
|
// Use centralized method
|
||||||
return Task.FromResult(CreateMailCopyFromMessage(message, assignedFolder));
|
return await CreateMailCopyFromMessageAsync(message, assignedFolder).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Message> GetMessageByIdAsync(string messageId, CancellationToken cancellationToken = default)
|
private async Task<Message> GetMessageByIdAsync(string messageId, CancellationToken cancellationToken = default)
|
||||||
@@ -1760,23 +1792,12 @@ public class OutlookSynchronizer : WinoSynchronizer<RequestInformation, Message,
|
|||||||
public override async Task<List<NewMailItemPackage>> CreateNewMailPackagesAsync(Message message, MailItemFolder assignedFolder, CancellationToken cancellationToken = default)
|
public override async Task<List<NewMailItemPackage>> CreateNewMailPackagesAsync(Message message, MailItemFolder assignedFolder, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
// Download MIME message for specific scenarios (e.g., search results, draft handling)
|
// Download MIME message for specific scenarios (e.g., search results, draft handling)
|
||||||
// During normal sync, this method should not be called - use CreateMailCopyFromMessage instead
|
// During normal sync, this method should not be called - use CreateMailCopyFromMessageAsync instead
|
||||||
var mimeMessage = await DownloadMimeMessageAsync(message.Id, cancellationToken).ConfigureAwait(false);
|
var mimeMessage = await DownloadMimeMessageAsync(message.Id, cancellationToken).ConfigureAwait(false);
|
||||||
var mailCopy = CreateMailCopyFromMessage(message, assignedFolder);
|
var mailCopy = await CreateMailCopyFromMessageAsync(message, assignedFolder).ConfigureAwait(false);
|
||||||
|
|
||||||
if (message.IsDraft.GetValueOrDefault()
|
// If draft mapping was successful, mailCopy will be null
|
||||||
&& mimeMessage.Headers.Contains(Domain.Constants.WinoLocalDraftHeader)
|
if (mailCopy == null) return null;
|
||||||
&& Guid.TryParse(mimeMessage.Headers[Domain.Constants.WinoLocalDraftHeader], out Guid localDraftCopyUniqueId))
|
|
||||||
{
|
|
||||||
// This message belongs to existing local draft copy.
|
|
||||||
// We don't need to create a new mail copy for this message, just update the existing one.
|
|
||||||
|
|
||||||
bool isMappingSuccessful = await _outlookChangeProcessor.MapLocalDraftAsync(Account.Id, localDraftCopyUniqueId, mailCopy.Id, mailCopy.DraftId, mailCopy.ThreadId);
|
|
||||||
|
|
||||||
if (isMappingSuccessful) return null;
|
|
||||||
|
|
||||||
// Local copy doesn't exists. Continue execution to insert mail copy.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Outlook messages can only be assigned to 1 folder at a time.
|
// Outlook messages can only be assigned to 1 folder at a time.
|
||||||
// Therefore we don't need to create multiple copies of the same message for different folders.
|
// Therefore we don't need to create multiple copies of the same message for different folders.
|
||||||
|
|||||||
Reference in New Issue
Block a user