More abstraction for mail/calendar.
This commit is contained in:
@@ -119,13 +119,13 @@ namespace Wino.Calendar.ViewModels
|
||||
// Start profile information synchronization.
|
||||
// It's only available for Outlook and Gmail synchronizers.
|
||||
|
||||
var profileSyncOptions = new SynchronizationOptions()
|
||||
var profileSyncOptions = new MailSynchronizationOptions()
|
||||
{
|
||||
AccountId = createdAccount.Id,
|
||||
Type = SynchronizationType.UpdateProfile
|
||||
Type = MailSynchronizationType.UpdateProfile
|
||||
};
|
||||
|
||||
var profileSynchronizationResponse = await WinoServerConnectionManager.GetResponseAsync<SynchronizationResult, NewSynchronizationRequested>(new NewSynchronizationRequested(profileSyncOptions, SynchronizationSource.Client));
|
||||
var profileSynchronizationResponse = await WinoServerConnectionManager.GetResponseAsync<MailSynchronizationResult, NewSynchronizationRequested>(new NewSynchronizationRequested(profileSyncOptions, SynchronizationSource.Client));
|
||||
|
||||
var profileSynchronizationResult = profileSynchronizationResponse.Data;
|
||||
|
||||
@@ -141,10 +141,10 @@ namespace Wino.Calendar.ViewModels
|
||||
accountCreationDialog.State = AccountCreationDialogState.FetchingEvents;
|
||||
|
||||
// Start synchronizing events.
|
||||
var eventsSyncOptions = new SynchronizationOptions()
|
||||
var eventsSyncOptions = new MailSynchronizationOptions()
|
||||
{
|
||||
AccountId = createdAccount.Id,
|
||||
Type = SynchronizationType.Events
|
||||
Type = MailSynchronizationType.Events
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
9
Wino.Core.Domain/Enums/CalendarSynchronizationType.cs
Normal file
9
Wino.Core.Domain/Enums/CalendarSynchronizationType.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
public enum CalendarSynchronizationType
|
||||
{
|
||||
AllCalendars, // Sync all calendars.
|
||||
SingleCalendar, // Sync only one calendar.
|
||||
UpdateProfile // Update profile information only.
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,14 @@
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
public enum SynchronizationType
|
||||
public enum MailSynchronizationType
|
||||
{
|
||||
// Shared
|
||||
UpdateProfile, // Only update profile information
|
||||
ExecuteRequests, // Run the queued requests, and then synchronize if needed.
|
||||
// Wino Mail
|
||||
FoldersOnly, // Only synchronize folder metadata.
|
||||
InboxOnly, // Only Inbox, Sent and Draft folders.
|
||||
CustomFolders, // Only sync folders that are specified in the options.
|
||||
FullFolders, // Synchronize all folders. This won't update profile or alias information.
|
||||
Alias, // Only update alias information
|
||||
// Calendar
|
||||
Events
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
public interface IBaseCalendarSynchronizer : IBaseSynchronizer
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ namespace Wino.Core.Domain.Interfaces
|
||||
Task ChangeFolderSynchronizationStateAsync(Guid folderId, bool isSynchronizationEnabled);
|
||||
Task ChangeFolderShowUnreadCountStateAsync(Guid folderId, bool showUnreadCount);
|
||||
|
||||
Task<List<MailItemFolder>> GetSynchronizationFoldersAsync(SynchronizationOptions options);
|
||||
Task<List<MailItemFolder>> GetSynchronizationFoldersAsync(MailSynchronizationOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the folder - mail mapping for the given mail copy ids.
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
public interface ISynchronizerFactory
|
||||
{
|
||||
Task<IBaseMailSynchronizer> GetAccountSynchronizerAsync(Guid accountId);
|
||||
Task<IWinoSynchronizerBase> GetAccountSynchronizerAsync(Guid accountId);
|
||||
Task InitializeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ using Wino.Core.Domain.Models.Synchronization;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
public interface IBaseMailSynchronizer : IBaseSynchronizer
|
||||
public interface IWinoSynchronizerBase : IBaseSynchronizer
|
||||
{
|
||||
/// <summary>
|
||||
/// Performs a full synchronization with the server with given options.
|
||||
@@ -17,7 +17,7 @@ namespace Wino.Core.Domain.Interfaces
|
||||
/// <param name="options">Options for synchronization.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>Result summary of synchronization.</returns>
|
||||
Task<SynchronizationResult> SynchronizeAsync(SynchronizationOptions options, CancellationToken cancellationToken = default);
|
||||
Task<MailSynchronizationResult> SynchronizeMailsAsync(MailSynchronizationOptions options, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Downloads a single MIME message from the server and saves it to disk.
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
namespace Wino.Core.Domain.Models.Synchronization
|
||||
{
|
||||
public class CalendarSynchronizationOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique id of synchronization.
|
||||
/// </summary>
|
||||
public Guid Id { get; } = Guid.NewGuid();
|
||||
|
||||
/// <summary>
|
||||
/// Account to execute synchronization for.
|
||||
/// </summary>
|
||||
public Guid AccountId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Type of the synchronization to be performed.
|
||||
/// </summary>
|
||||
public CalendarSynchronizationType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Calendar ids to synchronize.
|
||||
/// </summary>
|
||||
public List<Guid> SynchronizationCalendarIds { get; set; }
|
||||
|
||||
public override string ToString() => $"Type: {Type}, Calendars: {(SynchronizationCalendarIds == null ? "All" : string.Join(",", SynchronizationCalendarIds))}";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Accounts;
|
||||
|
||||
namespace Wino.Core.Domain.Models.Synchronization
|
||||
{
|
||||
public class CalendarSynchronizationResult
|
||||
{
|
||||
public CalendarSynchronizationResult() { }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the new downloaded events from synchronization.
|
||||
/// Server will create notifications for these event.
|
||||
/// It's ignored in serialization. Client should not react to this.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public IEnumerable<ICalendarItem> DownloadedEvents { get; set; } = [];
|
||||
|
||||
public ProfileInformation ProfileInformation { get; set; }
|
||||
|
||||
public SynchronizationCompletedState CompletedState { get; set; }
|
||||
|
||||
public static CalendarSynchronizationResult Empty => new() { CompletedState = SynchronizationCompletedState.Success };
|
||||
|
||||
// Mail synchronization
|
||||
public static CalendarSynchronizationResult Completed(IEnumerable<ICalendarItem> downloadedEvent)
|
||||
=> new()
|
||||
{
|
||||
DownloadedEvents = downloadedEvent,
|
||||
CompletedState = SynchronizationCompletedState.Success
|
||||
};
|
||||
|
||||
// Profile synchronization
|
||||
public static CalendarSynchronizationResult Completed(ProfileInformation profileInformation)
|
||||
=> new()
|
||||
{
|
||||
ProfileInformation = profileInformation,
|
||||
CompletedState = SynchronizationCompletedState.Success
|
||||
};
|
||||
|
||||
public static CalendarSynchronizationResult Canceled => new() { CompletedState = SynchronizationCompletedState.Canceled };
|
||||
public static CalendarSynchronizationResult Failed => new() { CompletedState = SynchronizationCompletedState.Failed };
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ using Wino.Core.Domain.Enums;
|
||||
|
||||
namespace Wino.Core.Domain.Models.Synchronization
|
||||
{
|
||||
public class SynchronizationOptions
|
||||
public class MailSynchronizationOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique id of synchronization.
|
||||
@@ -19,7 +19,7 @@ namespace Wino.Core.Domain.Models.Synchronization
|
||||
/// <summary>
|
||||
/// Type of the synchronization to be performed.
|
||||
/// </summary>
|
||||
public SynchronizationType Type { get; set; }
|
||||
public MailSynchronizationType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Collection of FolderId to perform SynchronizationType.Custom type sync.
|
||||
@@ -33,6 +33,6 @@ namespace Wino.Core.Domain.Models.Synchronization
|
||||
/// </summary>
|
||||
public Guid? GroupedSynchronizationTrackingId { get; set; }
|
||||
|
||||
public override string ToString() => $"Type: {Type}, Folders: {(SynchronizationFolderIds == null ? "None" : string.Join(",", SynchronizationFolderIds))}";
|
||||
public override string ToString() => $"Type: {Type}, Folders: {(SynchronizationFolderIds == null ? "All" : string.Join(",", SynchronizationFolderIds))}";
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Accounts;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
|
||||
namespace Wino.Core.Domain.Models.Synchronization
|
||||
{
|
||||
public class SynchronizationResult
|
||||
public class MailSynchronizationResult
|
||||
{
|
||||
public SynchronizationResult() { }
|
||||
public MailSynchronizationResult() { }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the new downloaded messages from synchronization.
|
||||
@@ -19,22 +18,14 @@ namespace Wino.Core.Domain.Models.Synchronization
|
||||
[JsonIgnore]
|
||||
public IEnumerable<IMailItem> DownloadedMessages { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the new downloaded events from synchronization.
|
||||
/// Server will create notifications for these events.
|
||||
/// It's ignored in serialization. Client should not react to this.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public IEnumerable<ICalendarItem> DownloadedEvents { get; set; } = [];
|
||||
|
||||
public ProfileInformation ProfileInformation { get; set; }
|
||||
|
||||
public SynchronizationCompletedState CompletedState { get; set; }
|
||||
|
||||
public static SynchronizationResult Empty => new() { CompletedState = SynchronizationCompletedState.Success };
|
||||
public static MailSynchronizationResult Empty => new() { CompletedState = SynchronizationCompletedState.Success };
|
||||
|
||||
// Mail synchronization
|
||||
public static SynchronizationResult Completed(IEnumerable<IMailItem> downloadedMessages)
|
||||
public static MailSynchronizationResult Completed(IEnumerable<IMailItem> downloadedMessages)
|
||||
=> new()
|
||||
{
|
||||
DownloadedMessages = downloadedMessages,
|
||||
@@ -42,14 +33,14 @@ namespace Wino.Core.Domain.Models.Synchronization
|
||||
};
|
||||
|
||||
// Profile synchronization
|
||||
public static SynchronizationResult Completed(ProfileInformation profileInformation)
|
||||
public static MailSynchronizationResult Completed(ProfileInformation profileInformation)
|
||||
=> new()
|
||||
{
|
||||
ProfileInformation = profileInformation,
|
||||
CompletedState = SynchronizationCompletedState.Success
|
||||
};
|
||||
|
||||
public static SynchronizationResult Canceled => new() { CompletedState = SynchronizationCompletedState.Canceled };
|
||||
public static SynchronizationResult Failed => new() { CompletedState = SynchronizationCompletedState.Failed };
|
||||
public static MailSynchronizationResult Canceled => new() { CompletedState = SynchronizationCompletedState.Canceled };
|
||||
public static MailSynchronizationResult Failed => new() { CompletedState = SynchronizationCompletedState.Failed };
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ namespace Wino.Core.Integration.Processors
|
||||
Task<List<MailItemFolder>> GetLocalFoldersAsync(Guid accountId);
|
||||
|
||||
|
||||
Task<List<MailItemFolder>> GetSynchronizationFoldersAsync(SynchronizationOptions options);
|
||||
Task<List<MailItemFolder>> GetSynchronizationFoldersAsync(MailSynchronizationOptions options);
|
||||
|
||||
Task<bool> MapLocalDraftAsync(Guid accountId, Guid localDraftCopyUniqueId, string newMailCopyId, string newDraftId, string newThreadId);
|
||||
Task UpdateFolderLastSyncDateAsync(Guid folderId);
|
||||
@@ -153,7 +153,7 @@ namespace Wino.Core.Integration.Processors
|
||||
public Task<List<MailItemFolder>> GetLocalFoldersAsync(Guid accountId)
|
||||
=> FolderService.GetFoldersAsync(accountId);
|
||||
|
||||
public Task<List<MailItemFolder>> GetSynchronizationFoldersAsync(SynchronizationOptions options)
|
||||
public Task<List<MailItemFolder>> GetSynchronizationFoldersAsync(MailSynchronizationOptions options)
|
||||
=> FolderService.GetSynchronizationFoldersAsync(options);
|
||||
|
||||
public Task DeleteFolderAsync(Guid accountId, string remoteFolderId)
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Wino.Core.Services
|
||||
private readonly IOutlookAuthenticator _outlookAuthenticator;
|
||||
private readonly IGmailAuthenticator _gmailAuthenticator;
|
||||
|
||||
private readonly List<IBaseMailSynchronizer> synchronizerCache = new();
|
||||
private readonly List<IWinoSynchronizerBase> synchronizerCache = new();
|
||||
|
||||
public SynchronizerFactory(IOutlookChangeProcessor outlookChangeProcessor,
|
||||
IGmailChangeProcessor gmailChangeProcessor,
|
||||
@@ -39,7 +39,7 @@ namespace Wino.Core.Services
|
||||
_applicationConfiguration = applicationConfiguration;
|
||||
}
|
||||
|
||||
public async Task<IBaseMailSynchronizer> GetAccountSynchronizerAsync(Guid accountId)
|
||||
public async Task<IWinoSynchronizerBase> GetAccountSynchronizerAsync(Guid accountId)
|
||||
{
|
||||
var synchronizer = synchronizerCache.Find(a => a.Account.Id == accountId);
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace Wino.Core.Services
|
||||
return synchronizer;
|
||||
}
|
||||
|
||||
private IBaseMailSynchronizer CreateIntegratorWithDefaultProcessor(MailAccount mailAccount)
|
||||
private IWinoSynchronizerBase CreateIntegratorWithDefaultProcessor(MailAccount mailAccount)
|
||||
{
|
||||
var providerType = mailAccount.ProviderType;
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace Wino.Core.Services
|
||||
return null;
|
||||
}
|
||||
|
||||
public IBaseMailSynchronizer CreateNewSynchronizer(MailAccount account)
|
||||
public IWinoSynchronizerBase CreateNewSynchronizer(MailAccount account)
|
||||
{
|
||||
var synchronizer = CreateIntegratorWithDefaultProcessor(account);
|
||||
|
||||
|
||||
@@ -143,10 +143,10 @@ namespace Wino.Core.Services
|
||||
{
|
||||
await EnsureServerConnectedAsync();
|
||||
|
||||
var options = new SynchronizationOptions()
|
||||
var options = new MailSynchronizationOptions()
|
||||
{
|
||||
AccountId = accountId,
|
||||
Type = SynchronizationType.ExecuteRequests
|
||||
Type = MailSynchronizationType.ExecuteRequests
|
||||
};
|
||||
|
||||
WeakReferenceMessenger.Default.Send(new NewSynchronizationRequested(options, SynchronizationSource.Client));
|
||||
|
||||
@@ -104,9 +104,9 @@ namespace Wino.Core.Synchronizers.Mail
|
||||
await _gmailChangeProcessor.UpdateRemoteAliasInformationAsync(Account, remoteAliases).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
protected override async Task<SynchronizationResult> SynchronizeInternalAsync(SynchronizationOptions options, CancellationToken cancellationToken = default)
|
||||
protected override async Task<MailSynchronizationResult> SynchronizeMailsInternalAsync(MailSynchronizationOptions options, CancellationToken cancellationToken = default)
|
||||
{
|
||||
_logger.Information("Internal synchronization started for {Name}", Account.Name);
|
||||
_logger.Information("Internal mail synchronization started for {Name}", Account.Name);
|
||||
|
||||
// Gmail must always synchronize folders before because it doesn't have a per-folder sync.
|
||||
bool shouldSynchronizeFolders = true;
|
||||
@@ -124,7 +124,7 @@ namespace Wino.Core.Synchronizers.Mail
|
||||
// Therefore we need to stop the synchronization at this point
|
||||
// if type is only folder metadata sync.
|
||||
|
||||
if (options.Type == SynchronizationType.FoldersOnly) return SynchronizationResult.Empty;
|
||||
if (options.Type == MailSynchronizationType.FoldersOnly) return MailSynchronizationResult.Empty;
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
@@ -281,7 +281,14 @@ namespace Wino.Core.Synchronizers.Mail
|
||||
|
||||
var unreadNewItems = await _gmailChangeProcessor.GetDownloadedUnreadMailsAsync(Account.Id, missingMessageIds).ConfigureAwait(false);
|
||||
|
||||
return SynchronizationResult.Completed(unreadNewItems);
|
||||
return MailSynchronizationResult.Completed(unreadNewItems);
|
||||
}
|
||||
|
||||
protected override Task<CalendarSynchronizationResult> SynchronizeCalendarEventsInternalAsync(CalendarSynchronizationOptions options, CancellationToken cancellationToken = default)
|
||||
{
|
||||
_logger.Information("Internal calendar synchronization started for {Name}", Account.Name);
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
private async Task SynchronizeFoldersAsync(CancellationToken cancellationToken = default)
|
||||
@@ -944,17 +951,16 @@ namespace Wino.Core.Synchronizers.Mail
|
||||
|
||||
await _gmailChangeProcessor.MapLocalDraftAsync(Account.Id, localDraftCopy.UniqueId, messageDraft.Message.Id, messageDraft.Id, messageDraft.Message.ThreadId);
|
||||
|
||||
var options = new SynchronizationOptions()
|
||||
var options = new MailSynchronizationOptions()
|
||||
{
|
||||
AccountId = Account.Id,
|
||||
Type = SynchronizationType.FullFolders
|
||||
Type = MailSynchronizationType.FullFolders
|
||||
};
|
||||
|
||||
await SynchronizeInternalAsync(options, cancellationToken);
|
||||
await SynchronizeMailsInternalAsync(options, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Maps existing Gmail Draft resources to local mail copies.
|
||||
/// This uses indexed search, therefore it's quite fast.
|
||||
|
||||
@@ -435,7 +435,7 @@ namespace Wino.Core.Synchronizers.Mail
|
||||
];
|
||||
}
|
||||
|
||||
protected override async Task<SynchronizationResult> SynchronizeInternalAsync(SynchronizationOptions options, CancellationToken cancellationToken = default)
|
||||
protected override async Task<MailSynchronizationResult> SynchronizeMailsInternalAsync(MailSynchronizationOptions options, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var downloadedMessageIds = new List<string>();
|
||||
|
||||
@@ -444,14 +444,14 @@ namespace Wino.Core.Synchronizers.Mail
|
||||
|
||||
PublishSynchronizationProgress(1);
|
||||
|
||||
bool shouldDoFolderSync = options.Type == SynchronizationType.FullFolders || options.Type == SynchronizationType.FoldersOnly;
|
||||
bool shouldDoFolderSync = options.Type == MailSynchronizationType.FullFolders || options.Type == MailSynchronizationType.FoldersOnly;
|
||||
|
||||
if (shouldDoFolderSync)
|
||||
{
|
||||
await SynchronizeFoldersAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (options.Type != SynchronizationType.FoldersOnly)
|
||||
if (options.Type != MailSynchronizationType.FoldersOnly)
|
||||
{
|
||||
var synchronizationFolders = await _imapChangeProcessor.GetSynchronizationFoldersAsync(options).ConfigureAwait(false);
|
||||
|
||||
@@ -474,7 +474,7 @@ namespace Wino.Core.Synchronizers.Mail
|
||||
|
||||
var unreadNewItems = await _imapChangeProcessor.GetDownloadedUnreadMailsAsync(Account.Id, downloadedMessageIds).ConfigureAwait(false);
|
||||
|
||||
return SynchronizationResult.Completed(unreadNewItems);
|
||||
return MailSynchronizationResult.Completed(unreadNewItems);
|
||||
}
|
||||
|
||||
public override async Task ExecuteNativeRequestsAsync(List<IRequestBundle<ImapRequest>> batchedRequests, CancellationToken cancellationToken = default)
|
||||
@@ -1035,5 +1035,10 @@ namespace Wino.Core.Synchronizers.Mail
|
||||
/// <param name="localFolder">Local folder.</param>
|
||||
public bool ShouldUpdateFolder(IMailFolder remoteFolder, MailItemFolder localFolder)
|
||||
=> !localFolder.FolderName.Equals(remoteFolder.Name, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
protected override Task<CalendarSynchronizationResult> SynchronizeCalendarEventsInternalAsync(CalendarSynchronizationOptions options, CancellationToken cancellationToken = default)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ namespace Wino.Core.Synchronizers.Mail
|
||||
#endregion
|
||||
|
||||
|
||||
protected override async Task<SynchronizationResult> SynchronizeInternalAsync(SynchronizationOptions options, CancellationToken cancellationToken = default)
|
||||
protected override async Task<MailSynchronizationResult> SynchronizeMailsInternalAsync(MailSynchronizationOptions options, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var downloadedMessageIds = new List<string>();
|
||||
|
||||
@@ -146,7 +146,7 @@ namespace Wino.Core.Synchronizers.Mail
|
||||
|
||||
await SynchronizeFoldersAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (options.Type != SynchronizationType.FoldersOnly)
|
||||
if (options.Type != MailSynchronizationType.FoldersOnly)
|
||||
{
|
||||
var synchronizationFolders = await _outlookChangeProcessor.GetSynchronizationFoldersAsync(options).ConfigureAwait(false);
|
||||
|
||||
@@ -181,7 +181,7 @@ namespace Wino.Core.Synchronizers.Mail
|
||||
|
||||
var unreadNewItems = await _outlookChangeProcessor.GetDownloadedUnreadMailsAsync(Account.Id, downloadedMessageIds).ConfigureAwait(false);
|
||||
|
||||
return SynchronizationResult.Completed(unreadNewItems);
|
||||
return MailSynchronizationResult.Completed(unreadNewItems);
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<string>> SynchronizeFolderAsync(MailItemFolder folder, CancellationToken cancellationToken = default)
|
||||
@@ -956,5 +956,10 @@ namespace Wino.Core.Synchronizers.Mail
|
||||
|
||||
return [package];
|
||||
}
|
||||
|
||||
protected override Task<CalendarSynchronizationResult> SynchronizeCalendarEventsInternalAsync(CalendarSynchronizationOptions options, CancellationToken cancellationToken = default)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ using Wino.Messaging.UI;
|
||||
|
||||
namespace Wino.Core.Synchronizers
|
||||
{
|
||||
public abstract class WinoSynchronizer<TBaseRequest, TMessageType, TCalendarEventType> : BaseSynchronizer<TBaseRequest>, IBaseMailSynchronizer
|
||||
public abstract class WinoSynchronizer<TBaseRequest, TMessageType, TCalendarEventType> : BaseSynchronizer<TBaseRequest>, IWinoSynchronizerBase
|
||||
{
|
||||
protected ILogger Logger = Log.ForContext<WinoSynchronizer<TBaseRequest, TMessageType, TCalendarEventType>>();
|
||||
|
||||
@@ -55,18 +55,23 @@ namespace Wino.Core.Synchronizers
|
||||
/// </summary>
|
||||
protected virtual Task SynchronizeAliasesAsync() => Task.CompletedTask;
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Internally synchronizes the account with the given options.
|
||||
/// Internally synchronizes the account's mails with the given options.
|
||||
/// Not exposed and overriden for each synchronizer.
|
||||
/// </summary>
|
||||
/// <param name="options">Synchronization options.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>Synchronization result that contains summary of the sync.</returns>
|
||||
protected abstract Task<SynchronizationResult> SynchronizeInternalAsync(SynchronizationOptions options, CancellationToken cancellationToken = default);
|
||||
|
||||
protected abstract Task<MailSynchronizationResult> SynchronizeMailsInternalAsync(MailSynchronizationOptions options, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Internally synchronizes the events of the account with given options.
|
||||
/// Not exposed and overriden for each synchronizer.
|
||||
/// </summary>
|
||||
/// <param name="options">Synchronization options.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>Synchronization result that contains summary of the sync.</returns>
|
||||
protected abstract Task<CalendarSynchronizationResult> SynchronizeCalendarEventsInternalAsync(CalendarSynchronizationOptions options, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Batches network requests, executes them, and does the needed synchronization after the batch request execution.
|
||||
@@ -74,7 +79,7 @@ namespace Wino.Core.Synchronizers
|
||||
/// <param name="options">Synchronization options.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>Synchronization result that contains summary of the sync.</returns>
|
||||
public async Task<SynchronizationResult> SynchronizeAsync(SynchronizationOptions options, CancellationToken cancellationToken = default)
|
||||
public async Task<MailSynchronizationResult> SynchronizeMailsAsync(MailSynchronizationOptions options, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -159,7 +164,7 @@ namespace Wino.Core.Synchronizers
|
||||
// Execute request sync options should be re-calculated after execution.
|
||||
// This is the part we decide which individual folders must be synchronized
|
||||
// after the batch request execution.
|
||||
if (options.Type == SynchronizationType.ExecuteRequests)
|
||||
if (options.Type == MailSynchronizationType.ExecuteRequests)
|
||||
options = GetSynchronizationOptionsAfterRequestExecution(requestCopies);
|
||||
|
||||
State = AccountSynchronizerState.Synchronizing;
|
||||
@@ -169,9 +174,9 @@ namespace Wino.Core.Synchronizers
|
||||
// Handle special synchronization types.
|
||||
|
||||
// Profile information sync.
|
||||
if (options.Type == SynchronizationType.UpdateProfile)
|
||||
if (options.Type == MailSynchronizationType.UpdateProfile)
|
||||
{
|
||||
if (!Account.IsProfileInfoSyncSupported) return SynchronizationResult.Empty;
|
||||
if (!Account.IsProfileInfoSyncSupported) return MailSynchronizationResult.Empty;
|
||||
|
||||
ProfileInformation newProfileInformation = null;
|
||||
|
||||
@@ -183,28 +188,28 @@ namespace Wino.Core.Synchronizers
|
||||
{
|
||||
Log.Error(ex, "Failed to update profile information for {Name}", Account.Name);
|
||||
|
||||
return SynchronizationResult.Failed;
|
||||
return MailSynchronizationResult.Failed;
|
||||
}
|
||||
|
||||
return SynchronizationResult.Completed(newProfileInformation);
|
||||
return MailSynchronizationResult.Completed(newProfileInformation);
|
||||
}
|
||||
|
||||
// Alias sync.
|
||||
if (options.Type == SynchronizationType.Alias)
|
||||
if (options.Type == MailSynchronizationType.Alias)
|
||||
{
|
||||
if (!Account.IsAliasSyncSupported) return SynchronizationResult.Empty;
|
||||
if (!Account.IsAliasSyncSupported) return MailSynchronizationResult.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
await SynchronizeAliasesAsync();
|
||||
|
||||
return SynchronizationResult.Empty;
|
||||
return MailSynchronizationResult.Empty;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Failed to update aliases for {Name}", Account.Name);
|
||||
|
||||
return SynchronizationResult.Failed;
|
||||
return MailSynchronizationResult.Failed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,7 +229,7 @@ namespace Wino.Core.Synchronizers
|
||||
}
|
||||
|
||||
// Start the internal synchronization.
|
||||
var synchronizationResult = await SynchronizeInternalAsync(options, activeSynchronizationCancellationToken).ConfigureAwait(false);
|
||||
var synchronizationResult = await SynchronizeMailsInternalAsync(options, activeSynchronizationCancellationToken).ConfigureAwait(false);
|
||||
|
||||
PublishUnreadItemChanges();
|
||||
|
||||
@@ -234,7 +239,7 @@ namespace Wino.Core.Synchronizers
|
||||
{
|
||||
Logger.Warning("Synchronization canceled.");
|
||||
|
||||
return SynchronizationResult.Canceled;
|
||||
return MailSynchronizationResult.Canceled;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -271,7 +276,7 @@ namespace Wino.Core.Synchronizers
|
||||
/// </summary>
|
||||
/// <param name="batches">Batch requests to run in synchronization.</param>
|
||||
/// <returns>New synchronization options with minimal HTTP effort.</returns>
|
||||
private SynchronizationOptions GetSynchronizationOptionsAfterRequestExecution(List<IRequestBase> requests)
|
||||
private MailSynchronizationOptions GetSynchronizationOptionsAfterRequestExecution(List<IRequestBase> requests)
|
||||
{
|
||||
List<Guid> synchronizationFolderIds = requests
|
||||
.Where(a => a is ICustomFolderSynchronizationRequest)
|
||||
@@ -279,7 +284,7 @@ namespace Wino.Core.Synchronizers
|
||||
.SelectMany(a => a.SynchronizationFolderIds)
|
||||
.ToList();
|
||||
|
||||
var options = new SynchronizationOptions()
|
||||
var options = new MailSynchronizationOptions()
|
||||
{
|
||||
AccountId = Account.Id,
|
||||
};
|
||||
@@ -288,13 +293,13 @@ namespace Wino.Core.Synchronizers
|
||||
{
|
||||
// Gather FolderIds to synchronize.
|
||||
|
||||
options.Type = SynchronizationType.CustomFolders;
|
||||
options.Type = MailSynchronizationType.CustomFolders;
|
||||
options.SynchronizationFolderIds = synchronizationFolderIds;
|
||||
}
|
||||
else
|
||||
{
|
||||
// At this point it's a mix of everything. Do full sync.
|
||||
options.Type = SynchronizationType.FullFolders;
|
||||
options.Type = MailSynchronizationType.FullFolders;
|
||||
}
|
||||
|
||||
return options;
|
||||
|
||||
@@ -159,13 +159,13 @@ namespace Wino.Mail.ViewModels
|
||||
// Start profile information synchronization.
|
||||
// It's only available for Outlook and Gmail synchronizers.
|
||||
|
||||
var profileSyncOptions = new SynchronizationOptions()
|
||||
var profileSyncOptions = new MailSynchronizationOptions()
|
||||
{
|
||||
AccountId = createdAccount.Id,
|
||||
Type = SynchronizationType.UpdateProfile
|
||||
Type = MailSynchronizationType.UpdateProfile
|
||||
};
|
||||
|
||||
var profileSynchronizationResponse = await WinoServerConnectionManager.GetResponseAsync<SynchronizationResult, NewSynchronizationRequested>(new NewSynchronizationRequested(profileSyncOptions, SynchronizationSource.Client));
|
||||
var profileSynchronizationResponse = await WinoServerConnectionManager.GetResponseAsync<MailSynchronizationResult, NewSynchronizationRequested>(new NewSynchronizationRequested(profileSyncOptions, SynchronizationSource.Client));
|
||||
|
||||
var profileSynchronizationResult = profileSynchronizationResponse.Data;
|
||||
|
||||
@@ -189,13 +189,13 @@ namespace Wino.Mail.ViewModels
|
||||
creationDialog.State = AccountCreationDialogState.PreparingFolders;
|
||||
|
||||
// Start synchronizing folders.
|
||||
var folderSyncOptions = new SynchronizationOptions()
|
||||
var folderSyncOptions = new MailSynchronizationOptions()
|
||||
{
|
||||
AccountId = createdAccount.Id,
|
||||
Type = SynchronizationType.FoldersOnly
|
||||
Type = MailSynchronizationType.FoldersOnly
|
||||
};
|
||||
|
||||
var folderSynchronizationResponse = await WinoServerConnectionManager.GetResponseAsync<SynchronizationResult, NewSynchronizationRequested>(new NewSynchronizationRequested(folderSyncOptions, SynchronizationSource.Client));
|
||||
var folderSynchronizationResponse = await WinoServerConnectionManager.GetResponseAsync<MailSynchronizationResult, NewSynchronizationRequested>(new NewSynchronizationRequested(folderSyncOptions, SynchronizationSource.Client));
|
||||
|
||||
var folderSynchronizationResult = folderSynchronizationResponse.Data;
|
||||
|
||||
@@ -207,13 +207,13 @@ namespace Wino.Mail.ViewModels
|
||||
{
|
||||
// Try to synchronize aliases for the account.
|
||||
|
||||
var aliasSyncOptions = new SynchronizationOptions()
|
||||
var aliasSyncOptions = new MailSynchronizationOptions()
|
||||
{
|
||||
AccountId = createdAccount.Id,
|
||||
Type = SynchronizationType.Alias
|
||||
Type = MailSynchronizationType.Alias
|
||||
};
|
||||
|
||||
var aliasSyncResponse = await WinoServerConnectionManager.GetResponseAsync<SynchronizationResult, NewSynchronizationRequested>(new NewSynchronizationRequested(aliasSyncOptions, SynchronizationSource.Client));
|
||||
var aliasSyncResponse = await WinoServerConnectionManager.GetResponseAsync<MailSynchronizationResult, NewSynchronizationRequested>(new NewSynchronizationRequested(aliasSyncOptions, SynchronizationSource.Client));
|
||||
var aliasSynchronizationResult = folderSynchronizationResponse.Data;
|
||||
|
||||
if (aliasSynchronizationResult.CompletedState != SynchronizationCompletedState.Success)
|
||||
|
||||
@@ -76,13 +76,13 @@ namespace Wino.Mail.ViewModels
|
||||
{
|
||||
if (!CanSynchronizeAliases) return;
|
||||
|
||||
var aliasSyncOptions = new SynchronizationOptions()
|
||||
var aliasSyncOptions = new MailSynchronizationOptions()
|
||||
{
|
||||
AccountId = Account.Id,
|
||||
Type = SynchronizationType.Alias
|
||||
Type = MailSynchronizationType.Alias
|
||||
};
|
||||
|
||||
var aliasSyncResponse = await _winoServerConnectionManager.GetResponseAsync<SynchronizationResult, NewSynchronizationRequested>(new NewSynchronizationRequested(aliasSyncOptions, SynchronizationSource.Client));
|
||||
var aliasSyncResponse = await _winoServerConnectionManager.GetResponseAsync<MailSynchronizationResult, NewSynchronizationRequested>(new NewSynchronizationRequested(aliasSyncOptions, SynchronizationSource.Client));
|
||||
|
||||
if (aliasSyncResponse.IsSuccess)
|
||||
await LoadAliasesAsync();
|
||||
|
||||
@@ -312,10 +312,10 @@ namespace Wino.Mail.ViewModels
|
||||
|
||||
foreach (var account in accounts)
|
||||
{
|
||||
var options = new SynchronizationOptions()
|
||||
var options = new MailSynchronizationOptions()
|
||||
{
|
||||
AccountId = account.Id,
|
||||
Type = SynchronizationType.FullFolders
|
||||
Type = MailSynchronizationType.FullFolders
|
||||
};
|
||||
|
||||
Messenger.Send(new NewSynchronizationRequested(options, SynchronizationSource.Client));
|
||||
@@ -885,10 +885,10 @@ namespace Wino.Mail.ViewModels
|
||||
await ChangeLoadedAccountAsync(createdMenuItem);
|
||||
|
||||
// Each created account should start a new synchronization automatically.
|
||||
var options = new SynchronizationOptions()
|
||||
var options = new MailSynchronizationOptions()
|
||||
{
|
||||
AccountId = createdAccount.Id,
|
||||
Type = SynchronizationType.FullFolders,
|
||||
Type = MailSynchronizationType.FullFolders,
|
||||
};
|
||||
|
||||
Messenger.Send(new NewSynchronizationRequested(options, SynchronizationSource.Client));
|
||||
|
||||
@@ -471,10 +471,10 @@ namespace Wino.Mail.ViewModels
|
||||
|
||||
foreach (var folder in ActiveFolder.HandlingFolders)
|
||||
{
|
||||
var options = new SynchronizationOptions()
|
||||
var options = new MailSynchronizationOptions()
|
||||
{
|
||||
AccountId = folder.MailAccountId,
|
||||
Type = SynchronizationType.CustomFolders,
|
||||
Type = MailSynchronizationType.CustomFolders,
|
||||
SynchronizationFolderIds = [folder.Id],
|
||||
GroupedSynchronizationTrackingId = trackingSynchronizationId
|
||||
};
|
||||
@@ -516,7 +516,7 @@ namespace Wino.Mail.ViewModels
|
||||
{
|
||||
if (string.IsNullOrEmpty(SearchQuery) && IsInSearchMode)
|
||||
{
|
||||
UpdateFolderPivotsAsync();
|
||||
await UpdateFolderPivotsAsync();
|
||||
IsInSearchMode = false;
|
||||
await InitializeFolderAsync();
|
||||
}
|
||||
@@ -892,7 +892,7 @@ namespace Wino.Mail.ViewModels
|
||||
OnPropertyChanged(nameof(IsArchiveSpecialFolder));
|
||||
|
||||
// Prepare Focused - Other or folder name tabs.
|
||||
UpdateFolderPivotsAsync();
|
||||
await UpdateFolderPivotsAsync();
|
||||
|
||||
// Reset filters and sorting options.
|
||||
ResetFilters();
|
||||
|
||||
@@ -228,7 +228,7 @@ namespace Wino
|
||||
{
|
||||
try
|
||||
{
|
||||
var synchronizationResultResponse = await AppServiceConnectionManager.GetResponseAsync<SynchronizationResult, NewSynchronizationRequested>(message);
|
||||
var synchronizationResultResponse = await AppServiceConnectionManager.GetResponseAsync<MailSynchronizationResult, NewSynchronizationRequested>(message);
|
||||
synchronizationResultResponse.ThrowIfFailed();
|
||||
}
|
||||
catch (WinoServerException serverException)
|
||||
|
||||
@@ -91,10 +91,10 @@ namespace Wino.Services
|
||||
|
||||
WeakReferenceMessenger.Default.Send(new AccountFolderConfigurationUpdated(accountId));
|
||||
|
||||
var options = new SynchronizationOptions()
|
||||
var options = new MailSynchronizationOptions()
|
||||
{
|
||||
AccountId = accountId,
|
||||
Type = SynchronizationType.FullFolders,
|
||||
Type = MailSynchronizationType.FullFolders,
|
||||
};
|
||||
|
||||
WeakReferenceMessenger.Default.Send(new NewSynchronizationRequested(options, SynchronizationSource.Client));
|
||||
|
||||
@@ -8,5 +8,5 @@ namespace Wino.Messaging.Server
|
||||
/// Triggers a new synchronization if possible.
|
||||
/// </summary>
|
||||
/// <param name="Options">Options for synchronization.</param>
|
||||
public record NewSynchronizationRequested(SynchronizationOptions Options, SynchronizationSource Source) : IClientMessage;
|
||||
public record NewSynchronizationRequested(MailSynchronizationOptions Options, SynchronizationSource Source) : IClientMessage;
|
||||
}
|
||||
|
||||
@@ -16,10 +16,10 @@ namespace Wino.Server.MessageHandlers
|
||||
/// <summary>
|
||||
/// Handler for NewSynchronizationRequested from the client.
|
||||
/// </summary>
|
||||
public class SynchronizationRequestHandler : ServerMessageHandler<NewSynchronizationRequested, SynchronizationResult>
|
||||
public class SynchronizationRequestHandler : ServerMessageHandler<NewSynchronizationRequested, MailSynchronizationResult>
|
||||
{
|
||||
public override WinoServerResponse<SynchronizationResult> FailureDefaultResponse(Exception ex)
|
||||
=> WinoServerResponse<SynchronizationResult>.CreateErrorResponse(ex.Message);
|
||||
public override WinoServerResponse<MailSynchronizationResult> FailureDefaultResponse(Exception ex)
|
||||
=> WinoServerResponse<MailSynchronizationResult>.CreateErrorResponse(ex.Message);
|
||||
|
||||
private readonly ISynchronizerFactory _synchronizerFactory;
|
||||
private readonly INotificationBuilder _notificationBuilder;
|
||||
@@ -34,7 +34,7 @@ namespace Wino.Server.MessageHandlers
|
||||
_folderService = folderService;
|
||||
}
|
||||
|
||||
protected override async Task<WinoServerResponse<SynchronizationResult>> HandleAsync(NewSynchronizationRequested message, CancellationToken cancellationToken = default)
|
||||
protected override async Task<WinoServerResponse<MailSynchronizationResult>> HandleAsync(NewSynchronizationRequested message, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var synchronizer = await _synchronizerFactory.GetAccountSynchronizerAsync(message.Options.AccountId);
|
||||
|
||||
@@ -45,12 +45,12 @@ namespace Wino.Server.MessageHandlers
|
||||
// It happens very common and there is no need to send a message for each synchronization.
|
||||
|
||||
bool shouldReportSynchronizationResult =
|
||||
message.Options.Type != SynchronizationType.ExecuteRequests &&
|
||||
message.Options.Type != MailSynchronizationType.ExecuteRequests &&
|
||||
message.Source == SynchronizationSource.Client;
|
||||
|
||||
try
|
||||
{
|
||||
var synchronizationResult = await synchronizer.SynchronizeAsync(message.Options, cancellationToken).ConfigureAwait(false);
|
||||
var synchronizationResult = await synchronizer.SynchronizeMailsAsync(message.Options, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (synchronizationResult.DownloadedMessages?.Any() ?? false || !synchronizer.Account.Preferences.IsNotificationsEnabled)
|
||||
{
|
||||
@@ -79,7 +79,7 @@ namespace Wino.Server.MessageHandlers
|
||||
WeakReferenceMessenger.Default.Send(completedMessage);
|
||||
}
|
||||
|
||||
return WinoServerResponse<SynchronizationResult>.CreateSuccessResponse(synchronizationResult);
|
||||
return WinoServerResponse<MailSynchronizationResult>.CreateSuccessResponse(synchronizationResult);
|
||||
}
|
||||
// TODO: Following cases might always be thrown from server. Handle them properly.
|
||||
|
||||
|
||||
@@ -90,10 +90,10 @@ namespace Wino.Server
|
||||
|
||||
foreach (var account in accounts)
|
||||
{
|
||||
var options = new SynchronizationOptions
|
||||
var options = new MailSynchronizationOptions
|
||||
{
|
||||
AccountId = account.Id,
|
||||
Type = SynchronizationType.InboxOnly,
|
||||
Type = MailSynchronizationType.InboxOnly,
|
||||
};
|
||||
|
||||
var request = new NewSynchronizationRequested(options, SynchronizationSource.Server);
|
||||
|
||||
@@ -542,11 +542,11 @@ namespace Wino.Services
|
||||
public Task<List<MailFolderPairMetadata>> GetMailFolderPairMetadatasAsync(string mailCopyId)
|
||||
=> GetMailFolderPairMetadatasAsync(new List<string>() { mailCopyId });
|
||||
|
||||
public async Task<List<MailItemFolder>> GetSynchronizationFoldersAsync(SynchronizationOptions options)
|
||||
public async Task<List<MailItemFolder>> GetSynchronizationFoldersAsync(MailSynchronizationOptions options)
|
||||
{
|
||||
var folders = new List<MailItemFolder>();
|
||||
|
||||
if (options.Type == SynchronizationType.FullFolders)
|
||||
if (options.Type == MailSynchronizationType.FullFolders)
|
||||
{
|
||||
// Only get sync enabled folders.
|
||||
|
||||
@@ -564,11 +564,11 @@ namespace Wino.Services
|
||||
|
||||
var mustHaveFolders = await GetInboxSynchronizationFoldersAsync(options.AccountId);
|
||||
|
||||
if (options.Type == SynchronizationType.InboxOnly)
|
||||
if (options.Type == MailSynchronizationType.InboxOnly)
|
||||
{
|
||||
return mustHaveFolders;
|
||||
}
|
||||
else if (options.Type == SynchronizationType.CustomFolders)
|
||||
else if (options.Type == MailSynchronizationType.CustomFolders)
|
||||
{
|
||||
// Only get the specified and enabled folders.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user