Files
Wino-Mail/Wino.Core/Synchronizers/ImapSynchronizer.cs

818 lines
35 KiB
C#
Raw Normal View History

2024-04-18 01:44:37 +02:00
using System;
using System.Collections.Generic;
2025-02-15 12:53:32 +01:00
using System.Diagnostics;
using System.IO;
2024-04-18 01:44:37 +02:00
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Messaging;
2024-04-18 01:44:37 +02:00
using MailKit;
using MailKit.Net.Imap;
using MoreLinq;
using Serilog;
using Wino.Core.Domain.Entities.Mail;
using Wino.Core.Domain.Entities.Shared;
2024-04-18 01:44:37 +02:00
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Exceptions;
using Wino.Core.Domain.Interfaces;
2024-09-29 21:21:51 +02:00
using Wino.Core.Domain.Models.Connectivity;
2024-04-18 01:44:37 +02:00
using Wino.Core.Domain.Models.MailItem;
using Wino.Core.Domain.Models.Synchronization;
using Wino.Core.Extensions;
using Wino.Core.Integration;
using Wino.Core.Integration.Processors;
using Wino.Core.Requests.Bundles;
2024-11-26 20:03:10 +01:00
using Wino.Core.Requests.Folder;
using Wino.Core.Requests.Mail;
2025-02-15 12:53:32 +01:00
using Wino.Messaging.Server;
using Wino.Messaging.UI;
using Wino.Services.Extensions;
2024-04-18 01:44:37 +02:00
namespace Wino.Core.Synchronizers.Mail
2024-04-18 01:44:37 +02:00
{
2025-02-15 12:53:32 +01:00
public class ImapSynchronizer : WinoSynchronizer<ImapRequest, ImapMessageCreationPackage, object>, IImapSynchronizer
2024-04-18 01:44:37 +02:00
{
2025-02-15 12:53:32 +01:00
[Obsolete("N/A")]
public override uint BatchModificationSize => 1000;
public override uint InitialMessageDownloadCountPerFolder => 500;
#region Idle Implementation
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
private CancellationTokenSource idleCancellationTokenSource;
private CancellationTokenSource idleDoneTokenSource;
#endregion
2024-04-18 01:44:37 +02:00
private readonly ILogger _logger = Log.ForContext<ImapSynchronizer>();
private readonly ImapClientPool _clientPool;
2024-06-02 21:35:03 +02:00
private readonly IImapChangeProcessor _imapChangeProcessor;
2025-02-15 12:53:32 +01:00
private readonly IImapSynchronizationStrategyProvider _imapSynchronizationStrategyProvider;
private readonly IApplicationConfiguration _applicationConfiguration;
2024-04-18 01:44:37 +02:00
public ImapSynchronizer(MailAccount account,
IImapChangeProcessor imapChangeProcessor,
2025-02-15 12:53:32 +01:00
IImapSynchronizationStrategyProvider imapSynchronizationStrategyProvider,
IApplicationConfiguration applicationConfiguration) : base(account)
2024-04-18 01:44:37 +02:00
{
// Create client pool with account protocol log.
_imapChangeProcessor = imapChangeProcessor;
2025-02-15 12:53:32 +01:00
_imapSynchronizationStrategyProvider = imapSynchronizationStrategyProvider;
_applicationConfiguration = applicationConfiguration;
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
var protocolLogStream = CreateAccountProtocolLogFileStream();
var poolOptions = ImapClientPoolOptions.CreateDefault(Account.ServerInformation, protocolLogStream);
2024-09-29 21:21:51 +02:00
_clientPool = new ImapClientPool(poolOptions);
2024-04-18 01:44:37 +02:00
}
private Stream CreateAccountProtocolLogFileStream()
{
if (Account == null) throw new ArgumentNullException(nameof(Account));
2025-02-15 12:53:32 +01:00
var logFile = Path.Combine(_applicationConfiguration.ApplicationDataFolderPath, $"Protocol_{Account.Address}_{Account.Id}.log");
// Each session should start a new log.
if (File.Exists(logFile)) File.Delete(logFile);
return new FileStream(logFile, FileMode.CreateNew);
}
2024-11-26 20:03:10 +01:00
/// <summary>
/// Returns UniqueId for the given mail copy id.
/// </summary>
2025-02-15 12:53:32 +01:00
private UniqueId GetUniqueId(string mailCopyId) => new(MailkitClientExtensions.ResolveUid(mailCopyId));
2024-11-26 20:03:10 +01:00
2024-04-18 01:44:37 +02:00
#region Mail Integrations
// Items are grouped before being passed to this method.
// Meaning that all items will come from and to the same folder.
// It's fine to assume that here.
2024-11-26 20:03:10 +01:00
public override List<IRequestBundle<ImapRequest>> Move(BatchMoveRequest requests)
2024-04-18 01:44:37 +02:00
{
2024-11-26 20:03:10 +01:00
return CreateTaskBundle(async (client, item) =>
2024-04-18 01:44:37 +02:00
{
2024-11-26 20:03:10 +01:00
var sourceFolder = await client.GetFolderAsync(item.FromFolder.RemoteFolderId);
var destinationFolder = await client.GetFolderAsync(item.ToFolder.RemoteFolderId);
2024-04-18 01:44:37 +02:00
// Only opening source folder is enough.
await sourceFolder.OpenAsync(FolderAccess.ReadWrite).ConfigureAwait(false);
2024-11-26 20:03:10 +01:00
await sourceFolder.MoveToAsync(GetUniqueId(item.Item.Id), destinationFolder).ConfigureAwait(false);
2024-04-18 01:44:37 +02:00
await sourceFolder.CloseAsync().ConfigureAwait(false);
2024-11-26 20:03:10 +01:00
}, requests);
2024-04-18 01:44:37 +02:00
}
2024-11-26 20:03:10 +01:00
public override List<IRequestBundle<ImapRequest>> ChangeFlag(BatchChangeFlagRequest requests)
2024-04-18 01:44:37 +02:00
{
2024-11-26 20:03:10 +01:00
return CreateTaskBundle(async (client, item) =>
2024-04-18 01:44:37 +02:00
{
2024-11-26 20:03:10 +01:00
var folder = item.Item.AssignedFolder;
2024-04-18 01:44:37 +02:00
var remoteFolder = await client.GetFolderAsync(folder.RemoteFolderId);
await remoteFolder.OpenAsync(FolderAccess.ReadWrite).ConfigureAwait(false);
2024-11-26 20:03:10 +01:00
await remoteFolder.StoreAsync(GetUniqueId(item.Item.Id), new StoreFlagsRequest(item.Item.IsFlagged ? StoreAction.Add : StoreAction.Remove, MessageFlags.Flagged) { Silent = true }).ConfigureAwait(false);
2024-04-18 01:44:37 +02:00
await remoteFolder.CloseAsync().ConfigureAwait(false);
2024-11-26 20:03:10 +01:00
}, requests);
2024-04-18 01:44:37 +02:00
}
2024-11-26 20:03:10 +01:00
public override List<IRequestBundle<ImapRequest>> Delete(BatchDeleteRequest requests)
2024-04-18 01:44:37 +02:00
{
2024-11-26 20:03:10 +01:00
return CreateTaskBundle(async (client, request) =>
2024-04-18 01:44:37 +02:00
{
2024-11-26 20:03:10 +01:00
var folder = request.Item.AssignedFolder;
2024-04-18 01:44:37 +02:00
var remoteFolder = await client.GetFolderAsync(folder.RemoteFolderId).ConfigureAwait(false);
await remoteFolder.OpenAsync(FolderAccess.ReadWrite).ConfigureAwait(false);
2024-11-26 20:03:10 +01:00
await remoteFolder.StoreAsync(GetUniqueId(request.Item.Id), new StoreFlagsRequest(StoreAction.Add, MessageFlags.Deleted) { Silent = true }).ConfigureAwait(false);
2024-04-18 01:44:37 +02:00
await remoteFolder.ExpungeAsync().ConfigureAwait(false);
await remoteFolder.CloseAsync().ConfigureAwait(false);
2024-11-26 20:03:10 +01:00
}, requests);
2024-04-18 01:44:37 +02:00
}
2024-11-26 20:03:10 +01:00
public override List<IRequestBundle<ImapRequest>> MarkRead(BatchMarkReadRequest requests)
2024-04-18 01:44:37 +02:00
{
2024-11-26 20:03:10 +01:00
return CreateTaskBundle(async (client, request) =>
2024-04-18 01:44:37 +02:00
{
2024-11-26 20:03:10 +01:00
var folder = request.Item.AssignedFolder;
2024-04-18 01:44:37 +02:00
var remoteFolder = await client.GetFolderAsync(folder.RemoteFolderId);
await remoteFolder.OpenAsync(FolderAccess.ReadWrite).ConfigureAwait(false);
2024-11-26 20:03:10 +01:00
await remoteFolder.StoreAsync(GetUniqueId(request.Item.Id), new StoreFlagsRequest(request.IsRead ? StoreAction.Add : StoreAction.Remove, MessageFlags.Seen) { Silent = true }).ConfigureAwait(false);
2024-04-18 01:44:37 +02:00
await remoteFolder.CloseAsync().ConfigureAwait(false);
2024-11-26 20:03:10 +01:00
}, requests);
2024-04-18 01:44:37 +02:00
}
2024-11-26 20:03:10 +01:00
public override List<IRequestBundle<ImapRequest>> CreateDraft(CreateDraftRequest request)
2024-04-18 01:44:37 +02:00
{
2024-11-27 02:51:07 +01:00
return CreateSingleTaskBundle(async (client, item) =>
2024-04-18 01:44:37 +02:00
{
var remoteDraftFolder = await client.GetFolderAsync(request.DraftPreperationRequest.CreatedLocalDraftCopy.AssignedFolder.RemoteFolderId).ConfigureAwait(false);
await remoteDraftFolder.OpenAsync(FolderAccess.ReadWrite).ConfigureAwait(false);
await remoteDraftFolder.AppendAsync(request.DraftPreperationRequest.CreatedLocalDraftMimeMessage, MessageFlags.Draft).ConfigureAwait(false);
await remoteDraftFolder.CloseAsync().ConfigureAwait(false);
2024-11-26 20:03:10 +01:00
}, request, request);
}
public override List<IRequestBundle<ImapRequest>> Archive(BatchArchiveRequest request)
{
var batchMoveRequest = new BatchMoveRequest(request.Select(item => new MoveRequest(item.Item, item.FromFolder, item.ToFolder)));
return Move(batchMoveRequest);
2024-04-18 01:44:37 +02:00
}
Folder operations, Gmail folder sync improvements and rework of menu items. (#273) * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * New rename folder dialog keys. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * Enable empty folder on base sync. * Move updates on event listeners. * Remove folder UI messages. * Reworked folder synchronization for gmail. * Loading folders on the fly as the selected account changed instead of relying on cached menu items. * Merged account folder items, re-navigating to existing rendering page. * - Reworked merged account menu system. - Reworked unread item count loadings. - Fixed back button visibility. - Instant rendering of mails if renderer is active. - Animation fixes. - Menu item re-load crash/hang fixes. * Handle folder renaming on the UI. * Empty folder for all synchronizers. * New execution delay mechanism and handling folder mark as read for all synchronizers. * Revert UI changes on failure for IMAP. * Remove duplicate translation keys. * Cleanup.
2024-07-09 01:05:16 +02:00
2024-11-26 20:03:10 +01:00
public override List<IRequestBundle<ImapRequest>> EmptyFolder(EmptyFolderRequest request)
Folder operations, Gmail folder sync improvements and rework of menu items. (#273) * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * New rename folder dialog keys. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * Enable empty folder on base sync. * Move updates on event listeners. * Remove folder UI messages. * Reworked folder synchronization for gmail. * Loading folders on the fly as the selected account changed instead of relying on cached menu items. * Merged account folder items, re-navigating to existing rendering page. * - Reworked merged account menu system. - Reworked unread item count loadings. - Fixed back button visibility. - Instant rendering of mails if renderer is active. - Animation fixes. - Menu item re-load crash/hang fixes. * Handle folder renaming on the UI. * Empty folder for all synchronizers. * New execution delay mechanism and handling folder mark as read for all synchronizers. * Revert UI changes on failure for IMAP. * Remove duplicate translation keys. * Cleanup.
2024-07-09 01:05:16 +02:00
=> Delete(new BatchDeleteRequest(request.MailsToDelete.Select(a => new DeleteRequest(a))));
2024-11-26 20:03:10 +01:00
public override List<IRequestBundle<ImapRequest>> MarkFolderAsRead(MarkFolderAsReadRequest request)
=> MarkRead(new BatchMarkReadRequest(request.MailsToMarkRead.Select(a => new MarkReadRequest(a, true))));
2024-11-26 20:03:10 +01:00
public override List<IRequestBundle<ImapRequest>> SendDraft(SendDraftRequest request)
2024-04-18 01:44:37 +02:00
{
2024-11-27 02:51:07 +01:00
return CreateSingleTaskBundle(async (client, item) =>
2024-04-18 01:44:37 +02:00
{
// Batch sending is not supported. It will always be a single request therefore no need for a loop here.
var singleRequest = request.Request;
using var smtpClient = new MailKit.Net.Smtp.SmtpClient();
if (smtpClient.IsConnected && client.IsAuthenticated) return;
if (!smtpClient.IsConnected)
await smtpClient.ConnectAsync(Account.ServerInformation.OutgoingServer, int.Parse(Account.ServerInformation.OutgoingServerPort), MailKit.Security.SecureSocketOptions.Auto);
if (!smtpClient.IsAuthenticated)
await smtpClient.AuthenticateAsync(Account.ServerInformation.OutgoingServerUsername, Account.ServerInformation.OutgoingServerPassword);
// TODO: Transfer progress implementation as popup in the UI.
await smtpClient.SendAsync(singleRequest.Mime, default);
await smtpClient.DisconnectAsync(true);
// SMTP sent the message, but we need to remove it from the Draft folder.
var draftFolder = singleRequest.MailItem.AssignedFolder;
var folder = await client.GetFolderAsync(draftFolder.RemoteFolderId);
await folder.OpenAsync(FolderAccess.ReadWrite);
var notUpdatedIds = await folder.StoreAsync(new UniqueId(MailkitClientExtensions.ResolveUid(singleRequest.MailItem.Id)), new StoreFlagsRequest(StoreAction.Add, MessageFlags.Deleted) { Silent = true });
await folder.ExpungeAsync();
await folder.CloseAsync();
// Check whether we need to create a copy of the message to Sent folder.
// This comes from the account preferences.
if (singleRequest.AccountPreferences.ShouldAppendMessagesToSentFolder && singleRequest.SentFolder != null)
{
var sentFolder = await client.GetFolderAsync(singleRequest.SentFolder.RemoteFolderId);
await sentFolder.OpenAsync(FolderAccess.ReadWrite);
// Delete local Wino draft header. Otherwise mapping will be applied on re-sync.
singleRequest.Mime.Headers.Remove(Domain.Constants.WinoLocalDraftHeader);
await sentFolder.AppendAsync(singleRequest.Mime, MessageFlags.Seen);
await sentFolder.CloseAsync();
}
2024-11-26 20:03:10 +01:00
}, request, request);
2024-04-18 01:44:37 +02:00
}
public override async Task DownloadMissingMimeMessageAsync(IMailItem mailItem,
ITransferProgress transferProgress = null,
CancellationToken cancellationToken = default)
{
var folder = mailItem.AssignedFolder;
var remoteFolderId = folder.RemoteFolderId;
var client = await _clientPool.GetClientAsync().ConfigureAwait(false);
var remoteFolder = await client.GetFolderAsync(remoteFolderId, cancellationToken).ConfigureAwait(false);
var uniqueId = new UniqueId(MailkitClientExtensions.ResolveUid(mailItem.Id));
await remoteFolder.OpenAsync(FolderAccess.ReadOnly, cancellationToken).ConfigureAwait(false);
var message = await remoteFolder.GetMessageAsync(uniqueId, cancellationToken, transferProgress).ConfigureAwait(false);
await _imapChangeProcessor.SaveMimeFileAsync(mailItem.FileId, message, Account.Id).ConfigureAwait(false);
await remoteFolder.CloseAsync(false, cancellationToken).ConfigureAwait(false);
_clientPool.Release(client);
}
2024-11-26 20:03:10 +01:00
public override List<IRequestBundle<ImapRequest>> RenameFolder(RenameFolderRequest request)
Folder operations, Gmail folder sync improvements and rework of menu items. (#273) * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * New rename folder dialog keys. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * Enable empty folder on base sync. * Move updates on event listeners. * Remove folder UI messages. * Reworked folder synchronization for gmail. * Loading folders on the fly as the selected account changed instead of relying on cached menu items. * Merged account folder items, re-navigating to existing rendering page. * - Reworked merged account menu system. - Reworked unread item count loadings. - Fixed back button visibility. - Instant rendering of mails if renderer is active. - Animation fixes. - Menu item re-load crash/hang fixes. * Handle folder renaming on the UI. * Empty folder for all synchronizers. * New execution delay mechanism and handling folder mark as read for all synchronizers. * Revert UI changes on failure for IMAP. * Remove duplicate translation keys. * Cleanup.
2024-07-09 01:05:16 +02:00
{
2024-11-27 02:51:07 +01:00
return CreateSingleTaskBundle(async (client, item) =>
Folder operations, Gmail folder sync improvements and rework of menu items. (#273) * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * New rename folder dialog keys. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * Enable empty folder on base sync. * Move updates on event listeners. * Remove folder UI messages. * Reworked folder synchronization for gmail. * Loading folders on the fly as the selected account changed instead of relying on cached menu items. * Merged account folder items, re-navigating to existing rendering page. * - Reworked merged account menu system. - Reworked unread item count loadings. - Fixed back button visibility. - Instant rendering of mails if renderer is active. - Animation fixes. - Menu item re-load crash/hang fixes. * Handle folder renaming on the UI. * Empty folder for all synchronizers. * New execution delay mechanism and handling folder mark as read for all synchronizers. * Revert UI changes on failure for IMAP. * Remove duplicate translation keys. * Cleanup.
2024-07-09 01:05:16 +02:00
{
var folder = await client.GetFolderAsync(request.Folder.RemoteFolderId).ConfigureAwait(false);
await folder.RenameAsync(folder.ParentFolder, request.NewFolderName).ConfigureAwait(false);
2024-11-26 20:03:10 +01:00
}, request, request);
Folder operations, Gmail folder sync improvements and rework of menu items. (#273) * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * New rename folder dialog keys. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * Enable empty folder on base sync. * Move updates on event listeners. * Remove folder UI messages. * Reworked folder synchronization for gmail. * Loading folders on the fly as the selected account changed instead of relying on cached menu items. * Merged account folder items, re-navigating to existing rendering page. * - Reworked merged account menu system. - Reworked unread item count loadings. - Fixed back button visibility. - Instant rendering of mails if renderer is active. - Animation fixes. - Menu item re-load crash/hang fixes. * Handle folder renaming on the UI. * Empty folder for all synchronizers. * New execution delay mechanism and handling folder mark as read for all synchronizers. * Revert UI changes on failure for IMAP. * Remove duplicate translation keys. * Cleanup.
2024-07-09 01:05:16 +02:00
}
2024-04-18 01:44:37 +02:00
#endregion
public override async Task<List<NewMailItemPackage>> CreateNewMailPackagesAsync(ImapMessageCreationPackage message, MailItemFolder assignedFolder, CancellationToken cancellationToken = default)
{
2025-02-15 12:53:32 +01:00
var mailCopy = message.MessageSummary.GetMailDetails(assignedFolder, message.MimeMessage);
2024-04-18 01:44:37 +02:00
// Draft folder message updates must be updated as IsDraft.
2025-02-15 12:53:32 +01:00
// I couldn't find it in MimeMesssage...
2024-04-18 01:44:37 +02:00
mailCopy.IsDraft = assignedFolder.SpecialFolderType == SpecialFolderType.Draft;
// Check draft mapping.
// This is the same implementation as in the OutlookSynchronizer.
2025-02-15 12:53:32 +01:00
if (message.MimeMessage != null &&
message.MimeMessage.Headers.Contains(Domain.Constants.WinoLocalDraftHeader) &&
Guid.TryParse(message.MimeMessage.Headers[Domain.Constants.WinoLocalDraftHeader], out Guid localDraftCopyUniqueId))
2024-04-18 01:44:37 +02:00
{
// 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 _imapChangeProcessor.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.
}
2025-02-15 12:53:32 +01:00
var package = new NewMailItemPackage(mailCopy, message.MimeMessage, assignedFolder.RemoteFolderId);
2024-04-18 01:44:37 +02:00
return
[
package
];
}
2024-12-24 18:30:25 +01:00
protected override async Task<MailSynchronizationResult> SynchronizeMailsInternalAsync(MailSynchronizationOptions options, CancellationToken cancellationToken = default)
2024-04-18 01:44:37 +02:00
{
var downloadedMessageIds = new List<string>();
_logger.Information("Internal synchronization started for {Name}", Account.Name);
_logger.Information("Options: {Options}", options);
Full trust Wino Server implementation. (#295) * Separation of messages. Introducing Wino.Messages library. * Wino.Server and Wino.Packaging projects. Enabling full trust for UWP and app service connection manager basics. * Remove debug code. * Enable generating assembly info to deal with unsupported os platform warnings. * Fix server-client connection. * UIMessage communication. Single instancing for server and re-connection mechanism on suspension. * Removed IWinoSynchronizerFactory from UWP project. * Removal of background task service from core. * Delegating changes to UI and triggering new background synchronization. * Fix build error. * Moved core lib messages to Messaging project. * Better client-server communication. Handling of requests in the server. New synchronizer factory in the server. * WAM broker and MSAL token caching for OutlookAuthenticator. Handling account creation for Outlook. * WinoServerResponse basics. * Delegating protocol activation for Gmail authenticator. * Adding margin to searchbox to match action bar width. * Move libraries into lib folder. * Storing base64 encoded mime on draft creation instead of MimeMessage object. Fixes serialization/deserialization issue with S.T.Json * Scrollbar adjustments * WınoExpander for thread expander layout ıssue. * Handling synchronizer state changes. * Double init on background activation. * FIxing packaging issues and new Wino Mail launcher protocol for activation from full thrust process. * Remove debug deserialization. * Remove debug code. * Making sure the server connection is established when the app is launched. * Thrust -> Trust string replacement... * Rename package to Wino Mail * Enable translated values in the server. * Fixed an issue where toast activation can't find the clicked mail after the folder is initialized. * Revert debug code. * Change server background sync to every 3 minute and Inbox only synchronization. * Revert google auth changes. * App preferences page. * Changing tray icon visibility on preference change. * Start the server with invisible tray icon if set to invisible. * Reconnect button on the title bar. * Handling of toast actions. * Enable x86 build for server during packaging. * Get rid of old background tasks and v180 migration. * Terminate client when Exit clicked in server. * Introducing SynchronizationSource to prevent notifying UI after server tick synchronization. * Remove confirmAppClose restricted capability and unused debug code in manifest. * Closing the reconnect info popup when reconnect is clicked. * Custom RetryHandler for OutlookSynchronizer and separating client/server logs. * Running server on Windows startup. * Fix startup exe. * Fix for expander list view item paddings. * Force full sync on app launch instead of Inbox. * Fix draft creation. * Fix an issue with custom folder sync logic. * Reporting back account sync progress from server. * Fix sending drafts and missing notifications for imap. * Changing imap folder sync requirements. * Retain file count is set to 3. * Disabled swipe gestures temporarily due to native crash with SwipeControl * Save all attachments implementation. * Localization for save all attachments button. * Fix logging dates for logs. * Fixing ARM64 build. * Add ARM64 build config to packaging project. * Comment out OutOfProcPDB for ARM64. * Hnadling GONE response for Outlook folder synchronization.
2024-08-05 00:36:26 +02:00
PublishSynchronizationProgress(1);
2024-04-18 01:44:37 +02:00
2024-12-24 18:30:25 +01:00
bool shouldDoFolderSync = options.Type == MailSynchronizationType.FullFolders || options.Type == MailSynchronizationType.FoldersOnly;
2024-04-18 01:44:37 +02:00
Full trust Wino Server implementation. (#295) * Separation of messages. Introducing Wino.Messages library. * Wino.Server and Wino.Packaging projects. Enabling full trust for UWP and app service connection manager basics. * Remove debug code. * Enable generating assembly info to deal with unsupported os platform warnings. * Fix server-client connection. * UIMessage communication. Single instancing for server and re-connection mechanism on suspension. * Removed IWinoSynchronizerFactory from UWP project. * Removal of background task service from core. * Delegating changes to UI and triggering new background synchronization. * Fix build error. * Moved core lib messages to Messaging project. * Better client-server communication. Handling of requests in the server. New synchronizer factory in the server. * WAM broker and MSAL token caching for OutlookAuthenticator. Handling account creation for Outlook. * WinoServerResponse basics. * Delegating protocol activation for Gmail authenticator. * Adding margin to searchbox to match action bar width. * Move libraries into lib folder. * Storing base64 encoded mime on draft creation instead of MimeMessage object. Fixes serialization/deserialization issue with S.T.Json * Scrollbar adjustments * WınoExpander for thread expander layout ıssue. * Handling synchronizer state changes. * Double init on background activation. * FIxing packaging issues and new Wino Mail launcher protocol for activation from full thrust process. * Remove debug deserialization. * Remove debug code. * Making sure the server connection is established when the app is launched. * Thrust -> Trust string replacement... * Rename package to Wino Mail * Enable translated values in the server. * Fixed an issue where toast activation can't find the clicked mail after the folder is initialized. * Revert debug code. * Change server background sync to every 3 minute and Inbox only synchronization. * Revert google auth changes. * App preferences page. * Changing tray icon visibility on preference change. * Start the server with invisible tray icon if set to invisible. * Reconnect button on the title bar. * Handling of toast actions. * Enable x86 build for server during packaging. * Get rid of old background tasks and v180 migration. * Terminate client when Exit clicked in server. * Introducing SynchronizationSource to prevent notifying UI after server tick synchronization. * Remove confirmAppClose restricted capability and unused debug code in manifest. * Closing the reconnect info popup when reconnect is clicked. * Custom RetryHandler for OutlookSynchronizer and separating client/server logs. * Running server on Windows startup. * Fix startup exe. * Fix for expander list view item paddings. * Force full sync on app launch instead of Inbox. * Fix draft creation. * Fix an issue with custom folder sync logic. * Reporting back account sync progress from server. * Fix sending drafts and missing notifications for imap. * Changing imap folder sync requirements. * Retain file count is set to 3. * Disabled swipe gestures temporarily due to native crash with SwipeControl * Save all attachments implementation. * Localization for save all attachments button. * Fix logging dates for logs. * Fixing ARM64 build. * Add ARM64 build config to packaging project. * Comment out OutOfProcPDB for ARM64. * Hnadling GONE response for Outlook folder synchronization.
2024-08-05 00:36:26 +02:00
if (shouldDoFolderSync)
{
await SynchronizeFoldersAsync(cancellationToken).ConfigureAwait(false);
}
2024-04-18 01:44:37 +02:00
2024-12-24 18:30:25 +01:00
if (options.Type != MailSynchronizationType.FoldersOnly)
2024-04-18 01:44:37 +02:00
{
var synchronizationFolders = await _imapChangeProcessor.GetSynchronizationFoldersAsync(options).ConfigureAwait(false);
for (int i = 0; i < synchronizationFolders.Count; i++)
{
var folder = synchronizationFolders[i];
var progress = (int)Math.Round((double)(i + 1) / synchronizationFolders.Count * 100);
Full trust Wino Server implementation. (#295) * Separation of messages. Introducing Wino.Messages library. * Wino.Server and Wino.Packaging projects. Enabling full trust for UWP and app service connection manager basics. * Remove debug code. * Enable generating assembly info to deal with unsupported os platform warnings. * Fix server-client connection. * UIMessage communication. Single instancing for server and re-connection mechanism on suspension. * Removed IWinoSynchronizerFactory from UWP project. * Removal of background task service from core. * Delegating changes to UI and triggering new background synchronization. * Fix build error. * Moved core lib messages to Messaging project. * Better client-server communication. Handling of requests in the server. New synchronizer factory in the server. * WAM broker and MSAL token caching for OutlookAuthenticator. Handling account creation for Outlook. * WinoServerResponse basics. * Delegating protocol activation for Gmail authenticator. * Adding margin to searchbox to match action bar width. * Move libraries into lib folder. * Storing base64 encoded mime on draft creation instead of MimeMessage object. Fixes serialization/deserialization issue with S.T.Json * Scrollbar adjustments * WınoExpander for thread expander layout ıssue. * Handling synchronizer state changes. * Double init on background activation. * FIxing packaging issues and new Wino Mail launcher protocol for activation from full thrust process. * Remove debug deserialization. * Remove debug code. * Making sure the server connection is established when the app is launched. * Thrust -> Trust string replacement... * Rename package to Wino Mail * Enable translated values in the server. * Fixed an issue where toast activation can't find the clicked mail after the folder is initialized. * Revert debug code. * Change server background sync to every 3 minute and Inbox only synchronization. * Revert google auth changes. * App preferences page. * Changing tray icon visibility on preference change. * Start the server with invisible tray icon if set to invisible. * Reconnect button on the title bar. * Handling of toast actions. * Enable x86 build for server during packaging. * Get rid of old background tasks and v180 migration. * Terminate client when Exit clicked in server. * Introducing SynchronizationSource to prevent notifying UI after server tick synchronization. * Remove confirmAppClose restricted capability and unused debug code in manifest. * Closing the reconnect info popup when reconnect is clicked. * Custom RetryHandler for OutlookSynchronizer and separating client/server logs. * Running server on Windows startup. * Fix startup exe. * Fix for expander list view item paddings. * Force full sync on app launch instead of Inbox. * Fix draft creation. * Fix an issue with custom folder sync logic. * Reporting back account sync progress from server. * Fix sending drafts and missing notifications for imap. * Changing imap folder sync requirements. * Retain file count is set to 3. * Disabled swipe gestures temporarily due to native crash with SwipeControl * Save all attachments implementation. * Localization for save all attachments button. * Fix logging dates for logs. * Fixing ARM64 build. * Add ARM64 build config to packaging project. * Comment out OutOfProcPDB for ARM64. * Hnadling GONE response for Outlook folder synchronization.
2024-08-05 00:36:26 +02:00
PublishSynchronizationProgress(progress);
2024-04-18 01:44:37 +02:00
var folderDownloadedMessageIds = await SynchronizeFolderInternalAsync(folder, cancellationToken).ConfigureAwait(false);
2025-02-15 12:53:32 +01:00
if (cancellationToken.IsCancellationRequested) return MailSynchronizationResult.Canceled;
if (folderDownloadedMessageIds != null)
{
downloadedMessageIds.AddRange(folderDownloadedMessageIds);
}
2024-04-18 01:44:37 +02:00
}
}
Full trust Wino Server implementation. (#295) * Separation of messages. Introducing Wino.Messages library. * Wino.Server and Wino.Packaging projects. Enabling full trust for UWP and app service connection manager basics. * Remove debug code. * Enable generating assembly info to deal with unsupported os platform warnings. * Fix server-client connection. * UIMessage communication. Single instancing for server and re-connection mechanism on suspension. * Removed IWinoSynchronizerFactory from UWP project. * Removal of background task service from core. * Delegating changes to UI and triggering new background synchronization. * Fix build error. * Moved core lib messages to Messaging project. * Better client-server communication. Handling of requests in the server. New synchronizer factory in the server. * WAM broker and MSAL token caching for OutlookAuthenticator. Handling account creation for Outlook. * WinoServerResponse basics. * Delegating protocol activation for Gmail authenticator. * Adding margin to searchbox to match action bar width. * Move libraries into lib folder. * Storing base64 encoded mime on draft creation instead of MimeMessage object. Fixes serialization/deserialization issue with S.T.Json * Scrollbar adjustments * WınoExpander for thread expander layout ıssue. * Handling synchronizer state changes. * Double init on background activation. * FIxing packaging issues and new Wino Mail launcher protocol for activation from full thrust process. * Remove debug deserialization. * Remove debug code. * Making sure the server connection is established when the app is launched. * Thrust -> Trust string replacement... * Rename package to Wino Mail * Enable translated values in the server. * Fixed an issue where toast activation can't find the clicked mail after the folder is initialized. * Revert debug code. * Change server background sync to every 3 minute and Inbox only synchronization. * Revert google auth changes. * App preferences page. * Changing tray icon visibility on preference change. * Start the server with invisible tray icon if set to invisible. * Reconnect button on the title bar. * Handling of toast actions. * Enable x86 build for server during packaging. * Get rid of old background tasks and v180 migration. * Terminate client when Exit clicked in server. * Introducing SynchronizationSource to prevent notifying UI after server tick synchronization. * Remove confirmAppClose restricted capability and unused debug code in manifest. * Closing the reconnect info popup when reconnect is clicked. * Custom RetryHandler for OutlookSynchronizer and separating client/server logs. * Running server on Windows startup. * Fix startup exe. * Fix for expander list view item paddings. * Force full sync on app launch instead of Inbox. * Fix draft creation. * Fix an issue with custom folder sync logic. * Reporting back account sync progress from server. * Fix sending drafts and missing notifications for imap. * Changing imap folder sync requirements. * Retain file count is set to 3. * Disabled swipe gestures temporarily due to native crash with SwipeControl * Save all attachments implementation. * Localization for save all attachments button. * Fix logging dates for logs. * Fixing ARM64 build. * Add ARM64 build config to packaging project. * Comment out OutOfProcPDB for ARM64. * Hnadling GONE response for Outlook folder synchronization.
2024-08-05 00:36:26 +02:00
PublishSynchronizationProgress(100);
2024-04-18 01:44:37 +02:00
// Get all unread new downloaded items and return in the result.
// This is primarily used in notifications.
var unreadNewItems = await _imapChangeProcessor.GetDownloadedUnreadMailsAsync(Account.Id, downloadedMessageIds).ConfigureAwait(false);
2024-12-24 18:30:25 +01:00
return MailSynchronizationResult.Completed(unreadNewItems);
2024-04-18 01:44:37 +02:00
}
2024-11-26 20:03:10 +01:00
public override async Task ExecuteNativeRequestsAsync(List<IRequestBundle<ImapRequest>> batchedRequests, CancellationToken cancellationToken = default)
2024-04-18 01:44:37 +02:00
{
// First apply the UI changes for each bundle.
// This is important to reflect changes to the UI before the network call is done.
foreach (var item in batchedRequests)
{
item.Request.ApplyUIChanges();
}
// All task bundles will execute on the same client.
// Tasks themselves don't pull the client from the pool
// because exception handling is easier this way.
// Also we might parallelize these bundles later on for additional performance.
foreach (var item in batchedRequests)
{
// At this point this client is ready to execute async commands.
// Each task bundle will await and execution will continue in case of error.
2025-02-15 12:53:32 +01:00
IImapClient executorClient = null;
2024-04-18 01:44:37 +02:00
bool isCrashed = false;
2024-04-18 01:44:37 +02:00
try
{
executorClient = await _clientPool.GetClientAsync();
}
catch (ImapClientPoolException)
{
// Client pool failed to get a client.
// Requests may not be executed at this point.
item.Request.RevertUIChanges();
isCrashed = true;
2024-04-18 01:44:37 +02:00
throw;
}
finally
{
// Make sure that the client is released from the pool for next usages if error occurs.
if (isCrashed && executorClient != null)
2024-04-18 01:44:37 +02:00
{
_clientPool.Release(executorClient);
}
}
// TODO: Retry pattern.
// TODO: Error handling.
try
{
2024-11-26 20:03:10 +01:00
await item.NativeRequest.IntegratorTask(executorClient, item.Request).ConfigureAwait(false);
2024-04-18 01:44:37 +02:00
}
catch (Exception)
{
Folder operations, Gmail folder sync improvements and rework of menu items. (#273) * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * New rename folder dialog keys. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * Enable empty folder on base sync. * Move updates on event listeners. * Remove folder UI messages. * Reworked folder synchronization for gmail. * Loading folders on the fly as the selected account changed instead of relying on cached menu items. * Merged account folder items, re-navigating to existing rendering page. * - Reworked merged account menu system. - Reworked unread item count loadings. - Fixed back button visibility. - Instant rendering of mails if renderer is active. - Animation fixes. - Menu item re-load crash/hang fixes. * Handle folder renaming on the UI. * Empty folder for all synchronizers. * New execution delay mechanism and handling folder mark as read for all synchronizers. * Revert UI changes on failure for IMAP. * Remove duplicate translation keys. * Cleanup.
2024-07-09 01:05:16 +02:00
item.Request.RevertUIChanges();
2024-04-18 01:44:37 +02:00
throw;
}
finally
{
_clientPool.Release(executorClient);
}
}
}
/// <summary>
/// Assigns special folder type for the given local folder.
/// If server doesn't support special folders, we can't determine the type. MailKit will throw for GetFolder.
/// Default type is Other.
/// </summary>
/// <param name="executorClient">ImapClient from the pool</param>
/// <param name="remoteFolder">Assigning remote folder.</param>
/// <param name="localFolder">Assigning local folder.</param>
2025-02-15 12:53:32 +01:00
private void AssignSpecialFolderType(IImapClient executorClient, IMailFolder remoteFolder, MailItemFolder localFolder)
2024-04-18 01:44:37 +02:00
{
// Inbox is awlawys available. Don't miss it for assignment even though XList or SpecialUser is not supported.
if (executorClient.Inbox == remoteFolder)
{
localFolder.SpecialFolderType = SpecialFolderType.Inbox;
return;
2024-04-18 01:44:37 +02:00
}
bool isSpecialFoldersSupported = executorClient.Capabilities.HasFlag(ImapCapabilities.SpecialUse) || executorClient.Capabilities.HasFlag(ImapCapabilities.XList);
2024-04-18 01:44:37 +02:00
if (!isSpecialFoldersSupported)
{
localFolder.SpecialFolderType = SpecialFolderType.Other;
return;
}
if (remoteFolder == executorClient.Inbox)
localFolder.SpecialFolderType = SpecialFolderType.Inbox;
else if (remoteFolder == executorClient.GetFolder(SpecialFolder.Drafts))
localFolder.SpecialFolderType = SpecialFolderType.Draft;
else if (remoteFolder == executorClient.GetFolder(SpecialFolder.Junk))
localFolder.SpecialFolderType = SpecialFolderType.Junk;
else if (remoteFolder == executorClient.GetFolder(SpecialFolder.Trash))
localFolder.SpecialFolderType = SpecialFolderType.Deleted;
else if (remoteFolder == executorClient.GetFolder(SpecialFolder.Sent))
localFolder.SpecialFolderType = SpecialFolderType.Sent;
else if (remoteFolder == executorClient.GetFolder(SpecialFolder.Archive))
localFolder.SpecialFolderType = SpecialFolderType.Archive;
else if (remoteFolder == executorClient.GetFolder(SpecialFolder.Important))
localFolder.SpecialFolderType = SpecialFolderType.Important;
else if (remoteFolder == executorClient.GetFolder(SpecialFolder.Flagged))
localFolder.SpecialFolderType = SpecialFolderType.Starred;
}
2024-04-18 01:44:37 +02:00
private async Task SynchronizeFoldersAsync(CancellationToken cancellationToken = default)
{
// https://www.rfc-editor.org/rfc/rfc4549#section-1.1
2024-04-18 01:44:37 +02:00
Folder operations, Gmail folder sync improvements and rework of menu items. (#273) * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * New rename folder dialog keys. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * Enable empty folder on base sync. * Move updates on event listeners. * Remove folder UI messages. * Reworked folder synchronization for gmail. * Loading folders on the fly as the selected account changed instead of relying on cached menu items. * Merged account folder items, re-navigating to existing rendering page. * - Reworked merged account menu system. - Reworked unread item count loadings. - Fixed back button visibility. - Instant rendering of mails if renderer is active. - Animation fixes. - Menu item re-load crash/hang fixes. * Handle folder renaming on the UI. * Empty folder for all synchronizers. * New execution delay mechanism and handling folder mark as read for all synchronizers. * Revert UI changes on failure for IMAP. * Remove duplicate translation keys. * Cleanup.
2024-07-09 01:05:16 +02:00
var localFolders = await _imapChangeProcessor.GetLocalFoldersAsync(Account.Id).ConfigureAwait(false);
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
IImapClient executorClient = null;
2024-04-18 01:44:37 +02:00
try
2024-04-18 01:44:37 +02:00
{
Folder operations, Gmail folder sync improvements and rework of menu items. (#273) * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * New rename folder dialog keys. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * Enable empty folder on base sync. * Move updates on event listeners. * Remove folder UI messages. * Reworked folder synchronization for gmail. * Loading folders on the fly as the selected account changed instead of relying on cached menu items. * Merged account folder items, re-navigating to existing rendering page. * - Reworked merged account menu system. - Reworked unread item count loadings. - Fixed back button visibility. - Instant rendering of mails if renderer is active. - Animation fixes. - Menu item re-load crash/hang fixes. * Handle folder renaming on the UI. * Empty folder for all synchronizers. * New execution delay mechanism and handling folder mark as read for all synchronizers. * Revert UI changes on failure for IMAP. * Remove duplicate translation keys. * Cleanup.
2024-07-09 01:05:16 +02:00
List<MailItemFolder> insertedFolders = new();
List<MailItemFolder> updatedFolders = new();
List<MailItemFolder> deletedFolders = new();
executorClient = await _clientPool.GetClientAsync().ConfigureAwait(false);
2024-04-18 01:44:37 +02:00
var remoteFolders = (await executorClient.GetFoldersAsync(executorClient.PersonalNamespaces[0], cancellationToken: cancellationToken)).ToList();
2024-04-18 01:44:37 +02:00
// 1. First check deleted folders.
2024-04-18 01:44:37 +02:00
// 1.a If local folder doesn't exists remotely, delete it.
// 1.b If local folder exists remotely, check if it is still a valid folder. If UidValidity is changed, delete it.
2024-04-18 01:44:37 +02:00
foreach (var localFolder in localFolders)
2024-04-18 01:44:37 +02:00
{
IMailFolder remoteFolder = null;
2024-04-18 01:44:37 +02:00
try
2024-04-18 01:44:37 +02:00
{
remoteFolder = remoteFolders.FirstOrDefault(a => a.FullName == localFolder.RemoteFolderId);
bool shouldDeleteLocalFolder = false;
// Check UidValidity of the remote folder if exists.
if (remoteFolder != null)
{
// UidValidity won't be available until it's opened.
await remoteFolder.OpenAsync(FolderAccess.ReadOnly, cancellationToken).ConfigureAwait(false);
shouldDeleteLocalFolder = remoteFolder.UidValidity != localFolder.UidValidity;
}
else
{
// Remote folder doesn't exist. Delete it.
shouldDeleteLocalFolder = true;
}
if (shouldDeleteLocalFolder)
{
await _imapChangeProcessor.DeleteFolderAsync(Account.Id, localFolder.RemoteFolderId).ConfigureAwait(false);
2024-04-18 01:44:37 +02:00
deletedFolders.Add(localFolder);
}
}
catch (Exception)
2024-04-18 01:44:37 +02:00
{
throw;
2024-04-18 01:44:37 +02:00
}
finally
2024-04-18 01:44:37 +02:00
{
if (remoteFolder != null)
{
await remoteFolder.CloseAsync().ConfigureAwait(false);
}
2024-04-18 01:44:37 +02:00
}
}
2024-04-18 01:44:37 +02:00
deletedFolders.ForEach(a => localFolders.Remove(a));
2024-04-18 01:44:37 +02:00
// 2. Get all remote folders and insert/update each of them.
2024-04-18 01:44:37 +02:00
var nameSpace = executorClient.PersonalNamespaces[0];
2024-04-18 01:44:37 +02:00
IMailFolder inbox = executorClient.Inbox;
2024-04-18 01:44:37 +02:00
// Sometimes Inbox is the root namespace. We need to check for that.
if (inbox != null && !remoteFolders.Contains(inbox))
remoteFolders.Add(inbox);
2024-04-18 01:44:37 +02:00
foreach (var remoteFolder in remoteFolders)
{
// Namespaces are not needed as folders.
// Non-existed folders don't need to be synchronized.
2024-04-18 01:44:37 +02:00
if (remoteFolder.IsNamespace && !remoteFolder.Attributes.HasFlag(FolderAttributes.Inbox) || !remoteFolder.Exists)
continue;
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
// Check for NoSelect folders. These are not selectable folders.
// TODO: With new MailKit version 'CanOpen' will be implemented for ease of use. Use that one.
if (remoteFolder.Attributes.HasFlag(FolderAttributes.NoSelect))
continue;
var existingLocalFolder = localFolders.FirstOrDefault(a => a.RemoteFolderId == remoteFolder.FullName);
if (existingLocalFolder == null)
{
// Folder doesn't exist locally. Insert it.
var localFolder = remoteFolder.GetLocalFolder();
// Check whether this is a special folder.
AssignSpecialFolderType(executorClient, remoteFolder, localFolder);
bool isSystemFolder = localFolder.SpecialFolderType != SpecialFolderType.Other;
localFolder.IsSynchronizationEnabled = isSystemFolder;
localFolder.IsSticky = isSystemFolder;
// By default, all special folders update unread count in the UI except Trash.
localFolder.ShowUnreadCount = localFolder.SpecialFolderType != SpecialFolderType.Deleted || localFolder.SpecialFolderType != SpecialFolderType.Other;
localFolder.MailAccountId = Account.Id;
// Sometimes sub folders are parented under Inbox.
// Even though this makes sense in server level, in the client it sucks.
// That will make sub folders to be parented under Inbox in the client.
// Instead, we will mark them as non-parented folders.
// This is better. Model allows personalized folder structure anyways
// even though we don't have the page/control to adjust it.
if (remoteFolder.ParentFolder == executorClient.Inbox)
localFolder.ParentRemoteFolderId = string.Empty;
// Set UidValidity for cache expiration.
// Folder must be opened for this.
await remoteFolder.OpenAsync(FolderAccess.ReadOnly, cancellationToken);
localFolder.UidValidity = remoteFolder.UidValidity;
await remoteFolder.CloseAsync(cancellationToken: cancellationToken);
Folder operations, Gmail folder sync improvements and rework of menu items. (#273) * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * New rename folder dialog keys. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * Enable empty folder on base sync. * Move updates on event listeners. * Remove folder UI messages. * Reworked folder synchronization for gmail. * Loading folders on the fly as the selected account changed instead of relying on cached menu items. * Merged account folder items, re-navigating to existing rendering page. * - Reworked merged account menu system. - Reworked unread item count loadings. - Fixed back button visibility. - Instant rendering of mails if renderer is active. - Animation fixes. - Menu item re-load crash/hang fixes. * Handle folder renaming on the UI. * Empty folder for all synchronizers. * New execution delay mechanism and handling folder mark as read for all synchronizers. * Revert UI changes on failure for IMAP. * Remove duplicate translation keys. * Cleanup.
2024-07-09 01:05:16 +02:00
insertedFolders.Add(localFolder);
}
else
{
// Update existing folder. Right now we only update the name.
Folder operations, Gmail folder sync improvements and rework of menu items. (#273) * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * New rename folder dialog keys. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * Enable empty folder on base sync. * Move updates on event listeners. * Remove folder UI messages. * Reworked folder synchronization for gmail. * Loading folders on the fly as the selected account changed instead of relying on cached menu items. * Merged account folder items, re-navigating to existing rendering page. * - Reworked merged account menu system. - Reworked unread item count loadings. - Fixed back button visibility. - Instant rendering of mails if renderer is active. - Animation fixes. - Menu item re-load crash/hang fixes. * Handle folder renaming on the UI. * Empty folder for all synchronizers. * New execution delay mechanism and handling folder mark as read for all synchronizers. * Revert UI changes on failure for IMAP. * Remove duplicate translation keys. * Cleanup.
2024-07-09 01:05:16 +02:00
// TODO: Moving folders around different parents. This is not supported right now.
// We will need more comphrensive folder update mechanism to support this.
if (ShouldUpdateFolder(remoteFolder, existingLocalFolder))
{
existingLocalFolder.FolderName = remoteFolder.Name;
Folder operations, Gmail folder sync improvements and rework of menu items. (#273) * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * New rename folder dialog keys. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * Enable empty folder on base sync. * Move updates on event listeners. * Remove folder UI messages. * Reworked folder synchronization for gmail. * Loading folders on the fly as the selected account changed instead of relying on cached menu items. * Merged account folder items, re-navigating to existing rendering page. * - Reworked merged account menu system. - Reworked unread item count loadings. - Fixed back button visibility. - Instant rendering of mails if renderer is active. - Animation fixes. - Menu item re-load crash/hang fixes. * Handle folder renaming on the UI. * Empty folder for all synchronizers. * New execution delay mechanism and handling folder mark as read for all synchronizers. * Revert UI changes on failure for IMAP. * Remove duplicate translation keys. * Cleanup.
2024-07-09 01:05:16 +02:00
updatedFolders.Add(existingLocalFolder);
}
else
{
// Remove it from the local folder list to skip additional folder updates.
localFolders.Remove(existingLocalFolder);
}
}
}
Folder operations, Gmail folder sync improvements and rework of menu items. (#273) * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * New rename folder dialog keys. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * Enable empty folder on base sync. * Move updates on event listeners. * Remove folder UI messages. * Reworked folder synchronization for gmail. * Loading folders on the fly as the selected account changed instead of relying on cached menu items. * Merged account folder items, re-navigating to existing rendering page. * - Reworked merged account menu system. - Reworked unread item count loadings. - Fixed back button visibility. - Instant rendering of mails if renderer is active. - Animation fixes. - Menu item re-load crash/hang fixes. * Handle folder renaming on the UI. * Empty folder for all synchronizers. * New execution delay mechanism and handling folder mark as read for all synchronizers. * Revert UI changes on failure for IMAP. * Remove duplicate translation keys. * Cleanup.
2024-07-09 01:05:16 +02:00
// Process changes in order-> Insert, Update. Deleted ones are already processed.
foreach (var folder in insertedFolders)
{
Folder operations, Gmail folder sync improvements and rework of menu items. (#273) * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * New rename folder dialog keys. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * Enable empty folder on base sync. * Move updates on event listeners. * Remove folder UI messages. * Reworked folder synchronization for gmail. * Loading folders on the fly as the selected account changed instead of relying on cached menu items. * Merged account folder items, re-navigating to existing rendering page. * - Reworked merged account menu system. - Reworked unread item count loadings. - Fixed back button visibility. - Instant rendering of mails if renderer is active. - Animation fixes. - Menu item re-load crash/hang fixes. * Handle folder renaming on the UI. * Empty folder for all synchronizers. * New execution delay mechanism and handling folder mark as read for all synchronizers. * Revert UI changes on failure for IMAP. * Remove duplicate translation keys. * Cleanup.
2024-07-09 01:05:16 +02:00
await _imapChangeProcessor.InsertFolderAsync(folder).ConfigureAwait(false);
2024-04-18 01:44:37 +02:00
}
Folder operations, Gmail folder sync improvements and rework of menu items. (#273) * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * New rename folder dialog keys. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * Enable empty folder on base sync. * Move updates on event listeners. * Remove folder UI messages. * Reworked folder synchronization for gmail. * Loading folders on the fly as the selected account changed instead of relying on cached menu items. * Merged account folder items, re-navigating to existing rendering page. * - Reworked merged account menu system. - Reworked unread item count loadings. - Fixed back button visibility. - Instant rendering of mails if renderer is active. - Animation fixes. - Menu item re-load crash/hang fixes. * Handle folder renaming on the UI. * Empty folder for all synchronizers. * New execution delay mechanism and handling folder mark as read for all synchronizers. * Revert UI changes on failure for IMAP. * Remove duplicate translation keys. * Cleanup.
2024-07-09 01:05:16 +02:00
foreach (var folder in updatedFolders)
2024-04-18 01:44:37 +02:00
{
Folder operations, Gmail folder sync improvements and rework of menu items. (#273) * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * New rename folder dialog keys. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * Enable empty folder on base sync. * Move updates on event listeners. * Remove folder UI messages. * Reworked folder synchronization for gmail. * Loading folders on the fly as the selected account changed instead of relying on cached menu items. * Merged account folder items, re-navigating to existing rendering page. * - Reworked merged account menu system. - Reworked unread item count loadings. - Fixed back button visibility. - Instant rendering of mails if renderer is active. - Animation fixes. - Menu item re-load crash/hang fixes. * Handle folder renaming on the UI. * Empty folder for all synchronizers. * New execution delay mechanism and handling folder mark as read for all synchronizers. * Revert UI changes on failure for IMAP. * Remove duplicate translation keys. * Cleanup.
2024-07-09 01:05:16 +02:00
await _imapChangeProcessor.UpdateFolderAsync(folder).ConfigureAwait(false);
2024-04-18 01:44:37 +02:00
}
if (insertedFolders.Any() || deletedFolders.Any() || updatedFolders.Any())
{
WeakReferenceMessenger.Default.Send(new AccountFolderConfigurationUpdated(Account.Id));
}
2024-04-18 01:44:37 +02:00
}
catch (Exception ex)
{
_logger.Error(ex, "Synchronizing IMAP folders failed.");
2024-04-18 01:44:37 +02:00
throw;
}
finally
{
if (executorClient != null)
{
_clientPool.Release(executorClient);
}
}
2024-04-18 01:44:37 +02:00
}
private async Task<IEnumerable<string>> SynchronizeFolderInternalAsync(MailItemFolder folder, CancellationToken cancellationToken = default)
{
if (!folder.IsSynchronizationEnabled) return default;
2025-02-15 12:53:32 +01:00
IImapClient availableClient = null;
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
retry:
try
{
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
availableClient = await _clientPool.GetClientAsync().ConfigureAwait(false);
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
var strategy = _imapSynchronizationStrategyProvider.GetSynchronizationStrategy(availableClient);
return await strategy.HandleSynchronizationAsync(availableClient, folder, this, cancellationToken).ConfigureAwait(false);
}
catch (IOException)
2024-04-18 01:44:37 +02:00
{
2025-02-15 12:53:32 +01:00
_clientPool.Release(availableClient, false);
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
goto retry;
}
catch (OperationCanceledException)
{
// Ignore cancellations.
}
catch (Exception)
{
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
}
finally
2024-04-18 01:44:37 +02:00
{
2025-02-15 12:53:32 +01:00
_clientPool.Release(availableClient, false);
}
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
return new List<string>();
}
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
/// <summary>
/// Whether the local folder should be updated with the remote folder.
/// IMAP only compares folder name for now.
/// </summary>
/// <param name="remoteFolder">Remote folder</param>
/// <param name="localFolder">Local folder.</param>
public bool ShouldUpdateFolder(IMailFolder remoteFolder, MailItemFolder localFolder)
=> !localFolder.FolderName.Equals(remoteFolder.Name, StringComparison.OrdinalIgnoreCase);
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
protected override Task<CalendarSynchronizationResult> SynchronizeCalendarEventsInternalAsync(CalendarSynchronizationOptions options, CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
public async Task StartIdleClientAsync()
{
IImapClient idleClient = null;
IMailFolder inboxFolder = null;
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
bool? reconnect = null;
2024-04-18 01:44:37 +02:00
try
{
2025-02-15 12:53:32 +01:00
var client = await _clientPool.GetClientAsync().ConfigureAwait(false);
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
if (!client.Capabilities.HasFlag(ImapCapabilities.Idle))
2024-04-18 01:44:37 +02:00
{
2025-02-15 12:53:32 +01:00
Log.Debug($"{Account.Name} does not support Idle command. Ignored.");
return;
2024-04-18 01:44:37 +02:00
}
2025-02-15 12:53:32 +01:00
if (client.Inbox == null)
{
Log.Warning($"{Account.Name} does not have an Inbox folder for idle client to track. Ignored.");
return;
}
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
// Setup idle client.
idleClient = client;
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
idleDoneTokenSource ??= new CancellationTokenSource();
idleCancellationTokenSource ??= new CancellationTokenSource();
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
inboxFolder = client.Inbox;
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
await inboxFolder.OpenAsync(FolderAccess.ReadOnly, idleCancellationTokenSource.Token);
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
inboxFolder.CountChanged += IdleNotificationTriggered;
inboxFolder.MessageFlagsChanged += IdleNotificationTriggered;
inboxFolder.MessageExpunged += IdleNotificationTriggered;
inboxFolder.MessagesVanished += IdleNotificationTriggered;
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
Log.Debug("Starting an idle client for {Name}", Account.Name);
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
await client.IdleAsync(idleDoneTokenSource.Token, idleCancellationTokenSource.Token);
}
catch (ImapProtocolException protocolException)
{
Log.Warning(protocolException, "Idle client received protocol exception.");
reconnect = true;
}
catch (IOException ioException)
{
Log.Warning(ioException, "Idle client received IO exception.");
reconnect = true;
}
catch (OperationCanceledException)
{
reconnect = !IsDisposing;
}
catch (Exception ex)
{
Log.Warning(ex, "Idle client failed to start.");
reconnect = false;
}
finally
{
if (inboxFolder != null)
{
inboxFolder.CountChanged -= IdleNotificationTriggered;
inboxFolder.MessageFlagsChanged -= IdleNotificationTriggered;
inboxFolder.MessageExpunged -= IdleNotificationTriggered;
inboxFolder.MessagesVanished -= IdleNotificationTriggered;
2024-04-18 01:44:37 +02:00
}
2025-02-15 12:53:32 +01:00
if (idleDoneTokenSource != null)
{
2025-02-15 12:53:32 +01:00
idleDoneTokenSource.Dispose();
idleDoneTokenSource = null;
}
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
if (idleClient != null)
2024-04-18 01:44:37 +02:00
{
2025-02-15 12:53:32 +01:00
// Killing the client is not necessary. We can re-use it later.
_clientPool.Release(idleClient, destroyClient: false);
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
idleClient = null;
2024-04-18 01:44:37 +02:00
}
2025-02-15 12:53:32 +01:00
if (reconnect == true)
2024-04-18 01:44:37 +02:00
{
2025-02-15 12:53:32 +01:00
Log.Information("Idle client is reconnecting.");
2025-02-15 12:53:32 +01:00
_ = StartIdleClientAsync();
2024-04-18 01:44:37 +02:00
}
2025-02-15 12:53:32 +01:00
else if (reconnect == false)
{
Log.Information("Finalized idle client.");
}
}
}
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
private void RequestIdleChangeSynchronization()
{
Debug.WriteLine("Detected idle change.");
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
// We don't really need to act on the count change in detail.
// Our synchronization should be enough to handle the changes with on-demand sync.
// We can just trigger a sync here IMAPIdle type.
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
var options = new MailSynchronizationOptions()
2024-04-18 01:44:37 +02:00
{
2025-02-15 12:53:32 +01:00
AccountId = Account.Id,
Type = MailSynchronizationType.IMAPIdle
};
2024-04-18 01:44:37 +02:00
2025-02-15 12:53:32 +01:00
WeakReferenceMessenger.Default.Send(new NewMailSynchronizationRequested(options, SynchronizationSource.Client));
2024-04-18 01:44:37 +02:00
}
Folder operations, Gmail folder sync improvements and rework of menu items. (#273) * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * New rename folder dialog keys. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * Enable empty folder on base sync. * Move updates on event listeners. * Remove folder UI messages. * Reworked folder synchronization for gmail. * Loading folders on the fly as the selected account changed instead of relying on cached menu items. * Merged account folder items, re-navigating to existing rendering page. * - Reworked merged account menu system. - Reworked unread item count loadings. - Fixed back button visibility. - Instant rendering of mails if renderer is active. - Animation fixes. - Menu item re-load crash/hang fixes. * Handle folder renaming on the UI. * Empty folder for all synchronizers. * New execution delay mechanism and handling folder mark as read for all synchronizers. * Revert UI changes on failure for IMAP. * Remove duplicate translation keys. * Cleanup.
2024-07-09 01:05:16 +02:00
2025-02-15 12:53:32 +01:00
private void IdleNotificationTriggered(object sender, EventArgs e)
=> RequestIdleChangeSynchronization();
Folder operations, Gmail folder sync improvements and rework of menu items. (#273) * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Disable vertical scroll for composing page editor items. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * New rename folder dialog keys. * Insfra work for folder operations and rename folder code. * RenameFolder for Gmail. * Fixed input dialog to take custom take for primary button. * Missing rename for DS call. * Outlook to throw exception in case of error. * Implemented rename folder functionality for Outlook. * Remove default primary text from input dialog. * Fixed an issue where outlook folder rename does not work. * Fixing some issues with imap folder sync. * fix copy pasta * TODO folder update/removed overrides for shell. * New rename folder dialog keys. * New rename folder dialog keys. * New rename folder dialog keys. * Fixed an issue where redundant older updates causing pivots to be re-created. * New empty folder request * Enable empty folder on base sync. * Move updates on event listeners. * Remove folder UI messages. * Reworked folder synchronization for gmail. * Loading folders on the fly as the selected account changed instead of relying on cached menu items. * Merged account folder items, re-navigating to existing rendering page. * - Reworked merged account menu system. - Reworked unread item count loadings. - Fixed back button visibility. - Instant rendering of mails if renderer is active. - Animation fixes. - Menu item re-load crash/hang fixes. * Handle folder renaming on the UI. * Empty folder for all synchronizers. * New execution delay mechanism and handling folder mark as read for all synchronizers. * Revert UI changes on failure for IMAP. * Remove duplicate translation keys. * Cleanup.
2024-07-09 01:05:16 +02:00
2025-02-15 12:53:32 +01:00
public Task StopIdleClientAsync()
{
idleDoneTokenSource?.Cancel();
idleCancellationTokenSource?.Cancel();
2024-12-24 18:30:25 +01:00
2025-02-15 12:53:32 +01:00
return Task.CompletedTask;
}
public override async Task KillSynchronizerAsync()
2024-12-24 18:30:25 +01:00
{
2025-02-15 12:53:32 +01:00
await base.KillSynchronizerAsync();
await StopIdleClientAsync();
// Make sure the client pool safely disconnects all ImapClients.
_clientPool.Dispose();
2024-12-24 18:30:25 +01:00
}
2024-04-18 01:44:37 +02:00
}
}