IDLE implementation, imap synchronization strategies basics and condstore synchronization.
This commit is contained in:
@@ -5,7 +5,6 @@ using MimeKit;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Services.Extensions;
|
||||
|
||||
namespace Wino.Services.Extensions
|
||||
{
|
||||
@@ -22,6 +21,9 @@ namespace Wino.Services.Extensions
|
||||
throw new ArgumentOutOfRangeException(nameof(mailCopyId), mailCopyId, "Invalid mailCopyId format.");
|
||||
}
|
||||
|
||||
public static UniqueId ResolveUidStruct(string mailCopyId)
|
||||
=> new UniqueId(ResolveUid(mailCopyId));
|
||||
|
||||
public static string CreateUid(Guid folderId, uint messageUid)
|
||||
=> $"{folderId}{MailCopyUidSeparator}{messageUid}";
|
||||
|
||||
|
||||
@@ -367,16 +367,14 @@ namespace Wino.Services
|
||||
|
||||
public async Task<IList<uint>> GetKnownUidsForFolderAsync(Guid folderId)
|
||||
{
|
||||
var folder = await GetFolderAsync(folderId);
|
||||
|
||||
if (folder == null) return default;
|
||||
|
||||
var mailCopyIds = await GetMailCopyIdsByFolderIdAsync(folderId);
|
||||
|
||||
// Make sure we don't include Ids that doesn't have uid separator.
|
||||
// Local drafts might not have it for example.
|
||||
|
||||
return new List<uint>(mailCopyIds.Where(a => a.Contains(MailkitClientExtensions.MailCopyUidSeparator)).Select(a => MailkitClientExtensions.ResolveUid(a)));
|
||||
return new List<uint>(mailCopyIds
|
||||
.Where(a => a.Contains(MailkitClientExtensions.MailCopyUidSeparator))
|
||||
.Select(a => MailkitClientExtensions.ResolveUid(a)));
|
||||
}
|
||||
|
||||
public async Task<MailAccount> UpdateSystemFolderConfigurationAsync(Guid accountId, SystemFolderConfiguration configuration)
|
||||
@@ -546,7 +544,19 @@ namespace Wino.Services
|
||||
{
|
||||
var folders = new List<MailItemFolder>();
|
||||
|
||||
if (options.Type == MailSynchronizationType.FullFolders)
|
||||
if (options.Type == MailSynchronizationType.IMAPIdle)
|
||||
{
|
||||
// Type Inbox will include Sent, Drafts and Deleted folders as well.
|
||||
// For IMAP idle sync, we must include only Inbox folder.
|
||||
|
||||
var inboxFolder = await GetSpecialFolderByAccountIdAsync(options.AccountId, SpecialFolderType.Inbox);
|
||||
|
||||
if (inboxFolder != null)
|
||||
{
|
||||
folders.Add(inboxFolder);
|
||||
}
|
||||
}
|
||||
else if (options.Type == MailSynchronizationType.FullFolders)
|
||||
{
|
||||
// Only get sync enabled folders.
|
||||
|
||||
@@ -570,12 +580,19 @@ namespace Wino.Services
|
||||
}
|
||||
else if (options.Type == MailSynchronizationType.CustomFolders)
|
||||
{
|
||||
// Only get the specified and enabled folders.
|
||||
// Only get the specified folders.
|
||||
|
||||
var synchronizationFolders = await Connection.Table<MailItemFolder>()
|
||||
.Where(a => a.MailAccountId == options.AccountId && options.SynchronizationFolderIds.Contains(a.Id))
|
||||
.Where(a =>
|
||||
a.MailAccountId == options.AccountId &&
|
||||
options.SynchronizationFolderIds.Contains(a.Id))
|
||||
.ToListAsync();
|
||||
|
||||
if (options.ExcludeMustHaveFolders)
|
||||
{
|
||||
return synchronizationFolders;
|
||||
}
|
||||
|
||||
// Order is important for moving.
|
||||
// By implementation, removing mail folders must be synchronized first. Requests are made in that order for custom sync.
|
||||
// eg. Moving item from Folder A to Folder B. If we start syncing Folder B first, we might miss adding assignment for Folder A.
|
||||
|
||||
@@ -984,6 +984,17 @@ namespace Wino.Services
|
||||
public Task<bool> IsMailExistsAsync(string mailCopyId)
|
||||
=> Connection.ExecuteScalarAsync<bool>("SELECT EXISTS(SELECT 1 FROM MailCopy WHERE Id = ?)", mailCopyId);
|
||||
|
||||
public async Task<List<MailCopy>> GetExistingMailsAsync(Guid folderId, IEnumerable<MailKit.UniqueId> uniqueIds)
|
||||
{
|
||||
var localMailIds = uniqueIds.Where(a => a != null).Select(a => MailkitClientExtensions.CreateUid(folderId, a.Id)).ToArray();
|
||||
|
||||
var query = new Query(nameof(MailCopy))
|
||||
.WhereIn("Id", localMailIds)
|
||||
.GetRawQuery();
|
||||
|
||||
return await Connection.QueryAsync<MailCopy>(query);
|
||||
}
|
||||
|
||||
public Task<bool> IsMailExistsAsync(string mailCopyId, Guid folderId)
|
||||
=> Connection.ExecuteScalarAsync<bool>("SELECT EXISTS(SELECT 1 FROM MailCopy WHERE Id = ? AND FolderId = ?)", mailCopyId, folderId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user