Some threading stuff.

This commit is contained in:
Burak Kaan Köse
2025-11-01 21:46:23 +01:00
parent ae9e35e091
commit 5f9b51e4db
4 changed files with 49 additions and 9 deletions
@@ -69,7 +69,7 @@ public static class OutlookIntegratorExtensions
return mailCopy;
}
public static Message AsOutlookMessage(this MimeMessage mime, bool includeInternetHeaders)
public static Message AsOutlookMessage(this MimeMessage mime, bool includeInternetHeaders, string conversationId = null)
{
var fromAddress = GetRecipients(mime.From).ElementAt(0);
var toAddresses = GetRecipients(mime.To).ToList();
@@ -93,6 +93,12 @@ public static class OutlookIntegratorExtensions
Attachments = []
};
// Set ConversationId if provided to maintain threading
if (!string.IsNullOrEmpty(conversationId))
{
message.ConversationId = conversationId;
}
// Headers are only included when creating the draft.
// When sending, they are not included. Graph will throw an error.
@@ -1231,7 +1231,9 @@ public class OutlookSynchronizer : WinoSynchronizer<RequestInformation, Message,
// Alias support is lacking with direct MIMEs.
// Therefore we convert the MIME message to Outlook message and use proper APIs.
var outlookMessage = mimeMessage.AsOutlookMessage(false);
// Pass the ConversationId (ThreadId) to maintain threading for replies/forwards
var conversationId = sendDraftPreparationRequest.MailItem.ThreadId;
var outlookMessage = mimeMessage.AsOutlookMessage(false, conversationId);
// Create attachment requests.
// TODO: We need to support large file attachments with sessioned upload at some point.
@@ -405,12 +405,12 @@ public class WinoMailCollection : ObservableRecipient, IRecipient<SelectedItemsC
private async Task UpdateExistingItemAsync(MailItemViewModel existingItem, MailCopy updatedItem)
{
UpdateUniqueIdHashes(existingItem, false);
await ExecuteUIThread(() =>
{
await ExecuteUIThread(() =>
{
existingItem.MailCopy = updatedItem;
});
UpdateUniqueIdHashes(existingItem, true);
}
@@ -702,10 +702,10 @@ public class WinoMailCollection : ObservableRecipient, IRecipient<SelectedItemsC
if (itemContainer.ItemViewModel != null)
{
UpdateUniqueIdHashes(itemContainer.ItemViewModel, false);
// Update the MailCopy - this will automatically notify all dependent properties
itemContainer.ItemViewModel.MailCopy = updatedMailCopy;
UpdateUniqueIdHashes(itemContainer.ItemViewModel, true);
}
@@ -962,6 +962,7 @@ public class WinoMailCollection : ObservableRecipient, IRecipient<SelectedItemsC
}
finally
{
Messenger.Unregister<SelectedItemsChangedMessage>(this);
Messenger.Register<SelectedItemsChangedMessage>(this);
Messenger.Send(new SelectedItemsChangedMessage());
+32 -1
View File
@@ -936,12 +936,43 @@ public class MailService : BaseDatabaseService, IMailService
}
// Manage "ThreadId-ConversationId"
// CRITICAL: In-Reply-To and References headers are essential for threading
// They must reference the original message's Message-ID from the MIME headers
if (!string.IsNullOrEmpty(referenceMessage.MessageId))
{
message.InReplyTo = referenceMessage.MessageId;
message.References.AddRange(referenceMessage.References);
// Add all previous References first
if (referenceMessage.References != null && referenceMessage.References.Count > 0)
{
message.References.AddRange(referenceMessage.References);
}
// Then add the message we're replying to
message.References.Add(referenceMessage.MessageId);
}
else
{
// WARNING: Reference message has no Message-ID!
// This will break threading. Try to use the MessageId from MailCopy if available.
var referenceMailCopy = draftCreationOptions.ReferencedMessage.MailCopy;
if (referenceMailCopy != null && !string.IsNullOrEmpty(referenceMailCopy.MessageId))
{
message.InReplyTo = referenceMailCopy.MessageId;
if (!string.IsNullOrEmpty(referenceMailCopy.References))
{
// Parse the References string and add them
var references = referenceMailCopy.References.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var reference in references)
{
message.References.Add(reference.Trim());
}
}
message.References.Add(referenceMailCopy.MessageId);
}
}
message.Headers.Add("Thread-Topic", referenceMessage.Subject);
}