Online Search (#576)

* Very basic online search for gmail.

* Server side of handling offline search and listing part in listing page.

* Default search mode implementation and search UI improvements.

* Online search for Outlook.

* Very basic online search for gmail.

* Server side of handling offline search and listing part in listing page.

* Default search mode implementation and search UI improvements.

* Online search for Outlook.

* Online search for imap without downloading the messages yet. TODO

* Completing imap search.
This commit is contained in:
Burak Kaan Köse
2025-02-22 00:22:00 +01:00
committed by GitHub
parent 42b695854b
commit f61bcb621b
30 changed files with 900 additions and 209 deletions

View File

@@ -23,6 +23,7 @@ public class ServerMessageHandlerFactory : IServerMessageHandlerFactory
nameof(TerminateServerRequested) => App.Current.Services.GetService<TerminateServerRequestHandler>(),
nameof(ImapConnectivityTestRequested) => App.Current.Services.GetService<ImapConnectivityTestHandler>(),
nameof(KillAccountSynchronizerRequested) => App.Current.Services.GetService<KillAccountSynchronizerHandler>(),
nameof(OnlineSearchRequested) => App.Current.Services.GetService<OnlineSearchRequestHandler>(),
_ => throw new Exception($"Server handler for {typeName} is not registered."),
};
}
@@ -41,5 +42,6 @@ public class ServerMessageHandlerFactory : IServerMessageHandlerFactory
serviceCollection.AddTransient<TerminateServerRequestHandler>();
serviceCollection.AddTransient<ImapConnectivityTestHandler>();
serviceCollection.AddTransient<KillAccountSynchronizerHandler>();
serviceCollection.AddTransient<OnlineSearchRequestHandler>();
}
}

View File

@@ -51,6 +51,14 @@ public class MailSynchronizationRequestHandler : ServerMessageHandler<NewMailSyn
try
{
// test
//if (synchronizer.Account.ProviderType == MailProviderType.Gmail)
//{
// await synchronizer.OnlineSearchAsync("label:unread", null, cancellationToken);
// return WinoServerResponse<MailSynchronizationResult>.CreateSuccessResponse(MailSynchronizationResult.Canceled);
//}
var synchronizationResult = await synchronizer.SynchronizeMailsAsync(message.Options, cancellationToken).ConfigureAwait(false);
if (synchronizationResult.DownloadedMessages?.Any() ?? false || !synchronizer.Account.Preferences.IsNotificationsEnabled)

View File

@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Server;
using Wino.Core.Domain.Models.Synchronization;
using Wino.Messaging.Server;
using Wino.Server.Core;
namespace Wino.Server.MessageHandlers;
public class OnlineSearchRequestHandler : ServerMessageHandler<OnlineSearchRequested, OnlineSearchResult>
{
private readonly ISynchronizerFactory _synchronizerFactory;
public OnlineSearchRequestHandler(ISynchronizerFactory synchronizerFactory)
{
_synchronizerFactory = synchronizerFactory;
}
public override WinoServerResponse<OnlineSearchResult> FailureDefaultResponse(Exception ex)
=> WinoServerResponse<OnlineSearchResult>.CreateErrorResponse(ex.Message);
protected override async Task<WinoServerResponse<OnlineSearchResult>> HandleAsync(OnlineSearchRequested message, CancellationToken cancellationToken = default)
{
List<IWinoSynchronizerBase> synchronizers = new();
foreach (var accountId in message.AccountIds)
{
var synchronizer = await _synchronizerFactory.GetAccountSynchronizerAsync(accountId);
synchronizers.Add(synchronizer);
}
var tasks = synchronizers.Select(s => s.OnlineSearchAsync(message.QueryText, message.Folders, cancellationToken)).ToList();
var results = await Task.WhenAll(tasks);
// Flatten the results from all synchronizers into a single list
var allResults = results.SelectMany(x => x).ToList();
return WinoServerResponse<OnlineSearchResult>.CreateSuccessResponse(new OnlineSearchResult(allResults));
}
}

View File

@@ -43,7 +43,8 @@ public class ServerContext :
IRecipient<AccountSynchronizationProgressUpdatedMessage>,
IRecipient<AccountFolderConfigurationUpdated>,
IRecipient<CopyAuthURLRequested>,
IRecipient<NewMailSynchronizationRequested>
IRecipient<NewMailSynchronizationRequested>,
IRecipient<OnlineSearchRequested>
{
private readonly System.Timers.Timer _timer;
private static object connectionLock = new object();
@@ -141,8 +142,11 @@ public class ServerContext :
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);
public async void Receive(OnlineSearchRequested message) => await SendMessageAsync(MessageType.UIMessage, message);
#endregion
private string GetAppPackagFamilyName()
@@ -326,6 +330,9 @@ public class ServerContext :
case nameof(KillAccountSynchronizerRequested):
await ExecuteServerMessageSafeAsync(args, JsonSerializer.Deserialize<KillAccountSynchronizerRequested>(messageJson, _jsonSerializerOptions));
break;
case nameof(OnlineSearchRequested):
await ExecuteServerMessageSafeAsync(args, JsonSerializer.Deserialize<OnlineSearchRequested>(messageJson, _jsonSerializerOptions));
break;
default:
Debug.WriteLine($"Missing handler for {typeName} in the server. Check ServerContext.cs - HandleServerMessageAsync.");
break;