Contacts, thread animation and image preview control improvements.

This commit is contained in:
Burak Kaan Köse
2026-02-09 22:39:30 +01:00
parent e559a79506
commit 0999c71578
26 changed files with 1636 additions and 756 deletions
+89 -3
View File
@@ -289,6 +289,7 @@ public class GmailSynchronizer : WinoSynchronizer<IClientServiceRequest, Message
var folders = await _gmailChangeProcessor.GetLocalFoldersAsync(Account.Id).ConfigureAwait(false);
var syncableFolders = folders
.Where(f => f.IsSynchronizationEnabled && f.RemoteFolderId != ServiceConstants.ARCHIVE_LABEL_ID)
.OrderByDescending(f => f.SpecialFolderType == SpecialFolderType.Draft || f.RemoteFolderId == ServiceConstants.DRAFT_LABEL_ID)
.ToList();
var totalFolders = syncableFolders.Count;
@@ -328,8 +329,9 @@ public class GmailSynchronizer : WinoSynchronizer<IClientServiceRequest, Message
if (newMessageIds.Count > 0)
{
// Download metadata in batches (no raw MIME during initial sync)
await DownloadMessagesInBatchAsync(newMessageIds, downloadRawMime: false, cancellationToken).ConfigureAwait(false);
// Draft folder needs MIME during initial sync so compose can open immediately.
bool shouldDownloadRawMime = folder.SpecialFolderType == SpecialFolderType.Draft || folder.RemoteFolderId == ServiceConstants.DRAFT_LABEL_ID;
await DownloadMessagesInBatchAsync(newMessageIds, downloadRawMime: shouldDownloadRawMime, cancellationToken).ConfigureAwait(false);
foreach (var id in newMessageIds)
{
@@ -1848,6 +1850,88 @@ public class GmailSynchronizer : WinoSynchronizer<IClientServiceRequest, Message
return ("", emailOnly);
}
private static IReadOnlyList<AccountContact> ExtractContactsFromGmailMessage(Message message, MimeMessage mimeMessage)
{
var contacts = new Dictionary<string, AccountContact>(StringComparer.OrdinalIgnoreCase);
AddFromHeaders(message?.Payload?.Headers);
if (mimeMessage != null)
{
AddFromInternetAddressList(mimeMessage.From);
AddFromInternetAddressList(mimeMessage.To);
AddFromInternetAddressList(mimeMessage.Cc);
AddFromInternetAddressList(mimeMessage.Bcc);
AddFromInternetAddressList(mimeMessage.ReplyTo);
if (mimeMessage.Sender is MailboxAddress senderMailbox)
{
AddContact(senderMailbox.Address, senderMailbox.Name);
}
}
return contacts.Values.ToList();
void AddFromHeaders(IList<MessagePartHeader> headers)
{
if (headers == null || headers.Count == 0) return;
AddFromHeader("From");
AddFromHeader("Sender");
AddFromHeader("To");
AddFromHeader("Cc");
AddFromHeader("Bcc");
AddFromHeader("Reply-To");
void AddFromHeader(string headerName)
{
var headerValue = headers
.FirstOrDefault(h => h.Name.Equals(headerName, StringComparison.OrdinalIgnoreCase))
?.Value;
if (string.IsNullOrWhiteSpace(headerValue)) return;
try
{
var addresses = InternetAddressList.Parse(headerValue);
foreach (var mailbox in addresses.Mailboxes)
{
AddContact(mailbox.Address, mailbox.Name);
}
}
catch
{
var (name, email) = ExtractNameAndEmailFromHeader(headerValue);
AddContact(email, name);
}
}
}
void AddFromInternetAddressList(InternetAddressList addresses)
{
if (addresses == null) return;
foreach (var mailbox in addresses.Mailboxes)
{
AddContact(mailbox.Address, mailbox.Name);
}
}
void AddContact(string address, string name)
{
var trimmedAddress = address?.Trim();
if (string.IsNullOrWhiteSpace(trimmedAddress)) return;
var displayName = string.IsNullOrWhiteSpace(name) ? trimmedAddress : name.Trim();
contacts[trimmedAddress] = new AccountContact
{
Address = trimmedAddress,
Name = displayName
};
}
}
/// <summary>
/// Creates new mail packages for the given message.
/// AssignedFolder is null since the LabelId is parsed out of the Message.
@@ -1887,6 +1971,8 @@ public class GmailSynchronizer : WinoSynchronizer<IClientServiceRequest, Message
EnrichMailCopyFromMime(baseMailCopy, mimeMessage);
}
var extractedContacts = ExtractContactsFromGmailMessage(message, mimeMessage);
// Check for local draft mapping using X-Wino-Draft-Id header.
// For Metadata format we read from Payload.Headers.
// For Raw format (Payload is null), we read from parsed MIME headers.
@@ -1962,7 +2048,7 @@ public class GmailSynchronizer : WinoSynchronizer<IClientServiceRequest, Message
mailCopyForLabel.Id = sharedId;
mailCopyForLabel.FileId = sharedFileId;
packageList.Add(new NewMailItemPackage(mailCopyForLabel, mimeMessage, labelId));
packageList.Add(new NewMailItemPackage(mailCopyForLabel, mimeMessage, labelId, extractedContacts));
}
}