IMAP Improvements (#558)
* Fixing an issue where scrollviewer overrides a part of template in mail list. Adjusted zoomed out header grid's corner radius. * IDLE implementation, imap synchronization strategies basics and condstore synchronization. * Adding iCloud and Yahoo as special IMAP handling scenario. * iCloud special imap handling. * Support for killing synchronizers. * Update privacy policy url. * Batching condstore downloads into 50, using SORT extension for searches if supported. * Bumping some nugets. More on the imap synchronizers. * Delegating idle synchronizations to server to post-sync operations. * Update mailkit to resolve qresync bug with iCloud. * Fixing remote highest mode seq checks for qresync and condstore synchronizers. * Yahoo custom settings. * Bump google sdk package. * Fixing the build issue.... * NRE on canceled token accounts during setup. * Server crash handlers. * Remove ARM32. Upgrade server to .NET 9. * Fix icons for yahoo and apple. * Fixed an issue where disabled folders causing an exception on forced sync. * Remove smtp encoding constraint. * Remove commented code. * Fixing merge conflict * Addressing double registrations for mailkit remote folder events in synchronizers. * Making sure idle canceled result is not reported. * Fixing custom imap server dialog opening. * Fixing the issue with account creation making the previously selected account as selected as well. * Fixing app close behavior and logging app close.
This commit is contained in:
@@ -8,6 +8,7 @@ using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using H.NotifyIcon;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Serilog;
|
||||
using Windows.Storage;
|
||||
using Wino.Calendar.Services;
|
||||
using Wino.Core;
|
||||
@@ -188,6 +189,9 @@ namespace Wino.Server
|
||||
|
||||
if (isCreatedNew)
|
||||
{
|
||||
AppDomain.CurrentDomain.UnhandledException += ServerCrashed;
|
||||
Application.Current.DispatcherUnhandledException += UIThreadCrash;
|
||||
TaskScheduler.UnobservedTaskException += TaskCrashed;
|
||||
// Ensure proper encodings are available for MimeKit
|
||||
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
|
||||
|
||||
@@ -237,6 +241,12 @@ namespace Wino.Server
|
||||
}
|
||||
}
|
||||
|
||||
private void TaskCrashed(object sender, UnobservedTaskExceptionEventArgs e) => Log.Error(e.Exception, "Task crashed.");
|
||||
|
||||
private void UIThreadCrash(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) => Log.Error(e.Exception, "UI thread crashed.");
|
||||
|
||||
private void ServerCrashed(object sender, UnhandledExceptionEventArgs e) => Log.Error((Exception)e.ExceptionObject, "Server crashed.");
|
||||
|
||||
protected override void OnExit(ExitEventArgs e)
|
||||
{
|
||||
notifyIcon?.Dispose();
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace Wino.Server.Core
|
||||
nameof(ServerTerminationModeChanged) => App.Current.Services.GetService<ServerTerminationModeHandler>(),
|
||||
nameof(TerminateServerRequested) => App.Current.Services.GetService<TerminateServerRequestHandler>(),
|
||||
nameof(ImapConnectivityTestRequested) => App.Current.Services.GetService<ImapConnectivityTestHandler>(),
|
||||
nameof(KillAccountSynchronizerRequested) => App.Current.Services.GetService<KillAccountSynchronizerHandler>(),
|
||||
_ => throw new Exception($"Server handler for {typeName} is not registered."),
|
||||
};
|
||||
}
|
||||
@@ -39,6 +40,7 @@ namespace Wino.Server.Core
|
||||
serviceCollection.AddTransient<ServerTerminationModeHandler>();
|
||||
serviceCollection.AddTransient<TerminateServerRequestHandler>();
|
||||
serviceCollection.AddTransient<ImapConnectivityTestHandler>();
|
||||
serviceCollection.AddTransient<KillAccountSynchronizerHandler>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Server;
|
||||
using Wino.Messaging.Server;
|
||||
using Wino.Server.Core;
|
||||
|
||||
namespace Wino.Server.MessageHandlers
|
||||
{
|
||||
public class KillAccountSynchronizerHandler : ServerMessageHandler<KillAccountSynchronizerRequested, bool>
|
||||
{
|
||||
private readonly ISynchronizerFactory _synchronizerFactory;
|
||||
|
||||
public override WinoServerResponse<bool> FailureDefaultResponse(Exception ex)
|
||||
=> WinoServerResponse<bool>.CreateErrorResponse(ex.Message);
|
||||
|
||||
public KillAccountSynchronizerHandler(ISynchronizerFactory synchronizerFactory)
|
||||
{
|
||||
_synchronizerFactory = synchronizerFactory;
|
||||
}
|
||||
|
||||
protected override async Task<WinoServerResponse<bool>> HandleAsync(KillAccountSynchronizerRequested message, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await _synchronizerFactory.DeleteSynchronizerAsync(message.AccountId);
|
||||
|
||||
return WinoServerResponse<bool>.CreateSuccessResponse(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,7 @@ namespace Wino.Server.MessageHandlers
|
||||
|
||||
bool shouldReportSynchronizationResult =
|
||||
message.Options.Type != MailSynchronizationType.ExecuteRequests &&
|
||||
message.Options.Type != MailSynchronizationType.IMAPIdle &&
|
||||
message.Source == SynchronizationSource.Client;
|
||||
|
||||
try
|
||||
@@ -64,6 +65,12 @@ namespace Wino.Server.MessageHandlers
|
||||
|
||||
var isSynchronizationSucceeded = synchronizationResult.CompletedState == SynchronizationCompletedState.Success;
|
||||
|
||||
// IDLE requests might be canceled successfully.
|
||||
if (message.Options.Type == MailSynchronizationType.IMAPIdle && synchronizationResult.CompletedState == SynchronizationCompletedState.Canceled)
|
||||
{
|
||||
isSynchronizationSucceeded = true;
|
||||
}
|
||||
|
||||
// Update badge count of the notification task.
|
||||
if (isSynchronizationSucceeded)
|
||||
{
|
||||
|
||||
@@ -42,7 +42,8 @@ namespace Wino.Server
|
||||
IRecipient<ServerTerminationModeChanged>,
|
||||
IRecipient<AccountSynchronizationProgressUpdatedMessage>,
|
||||
IRecipient<AccountFolderConfigurationUpdated>,
|
||||
IRecipient<CopyAuthURLRequested>
|
||||
IRecipient<CopyAuthURLRequested>,
|
||||
IRecipient<NewMailSynchronizationRequested>
|
||||
{
|
||||
private readonly System.Timers.Timer _timer;
|
||||
private static object connectionLock = new object();
|
||||
@@ -140,6 +141,7 @@ namespace Wino.Server
|
||||
public async void Receive(AccountFolderConfigurationUpdated message) => await SendMessageAsync(MessageType.UIMessage, message);
|
||||
|
||||
public async void Receive(CopyAuthURLRequested message) => await SendMessageAsync(MessageType.UIMessage, message);
|
||||
public async void Receive(NewMailSynchronizationRequested message) => await SendMessageAsync(MessageType.UIMessage, message);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -321,6 +323,9 @@ namespace Wino.Server
|
||||
|
||||
KillServer();
|
||||
break;
|
||||
case nameof(KillAccountSynchronizerRequested):
|
||||
await ExecuteServerMessageSafeAsync(args, JsonSerializer.Deserialize<KillAccountSynchronizerRequested>(messageJson, _jsonSerializerOptions));
|
||||
break;
|
||||
default:
|
||||
Debug.WriteLine($"Missing handler for {typeName} in the server. Check ServerContext.cs - HandleServerMessageAsync.");
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user