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:
@@ -8,6 +8,7 @@ using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using MailKit;
|
||||
using MailKit.Net.Imap;
|
||||
using MailKit.Search;
|
||||
using MoreLinq;
|
||||
using Serilog;
|
||||
using Wino.Core.Domain.Entities.Mail;
|
||||
@@ -16,6 +17,7 @@ using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Exceptions;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Connectivity;
|
||||
using Wino.Core.Domain.Models.Folders;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
using Wino.Core.Domain.Models.Synchronization;
|
||||
using Wino.Core.Extensions;
|
||||
@@ -628,6 +630,80 @@ public class ImapSynchronizer : WinoSynchronizer<ImapRequest, ImapMessageCreatio
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<List<MailCopy>> OnlineSearchAsync(string queryText, List<IMailItemFolder> folders, CancellationToken cancellationToken = default)
|
||||
{
|
||||
IImapClient client = null;
|
||||
IMailFolder activeFolder = null;
|
||||
|
||||
try
|
||||
{
|
||||
client = await _clientPool.GetClientAsync().ConfigureAwait(false);
|
||||
|
||||
var searchResults = new List<MailCopy>();
|
||||
List<string> searchResultFolderMailUids = new();
|
||||
|
||||
foreach (var folder in folders)
|
||||
{
|
||||
var remoteFolder = await client.GetFolderAsync(folder.RemoteFolderId).ConfigureAwait(false);
|
||||
await remoteFolder.OpenAsync(FolderAccess.ReadOnly, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Look for subject and body.
|
||||
var query = SearchQuery.BodyContains(queryText).Or(SearchQuery.SubjectContains(queryText));
|
||||
|
||||
var searchResultsInFolder = await remoteFolder.SearchAsync(query, cancellationToken).ConfigureAwait(false);
|
||||
var nonExisttingUniqueIds = new List<UniqueId>();
|
||||
|
||||
foreach (var searchResultId in searchResultsInFolder)
|
||||
{
|
||||
var folderMailUid = MailkitClientExtensions.CreateUid(folder.Id, searchResultId.Id);
|
||||
searchResultFolderMailUids.Add(folderMailUid);
|
||||
|
||||
bool exists = await _imapChangeProcessor.IsMailExistsAsync(folderMailUid);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
nonExisttingUniqueIds.Add(searchResultId);
|
||||
}
|
||||
}
|
||||
|
||||
if (nonExisttingUniqueIds.Any())
|
||||
{
|
||||
var syncStrategy = _imapSynchronizationStrategyProvider.GetSynchronizationStrategy(client);
|
||||
await syncStrategy.DownloadMessagesAsync(this, remoteFolder, new UniqueIdSet(nonExisttingUniqueIds, SortOrder.Ascending), cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await remoteFolder.CloseAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
foreach (var messageId in searchResultFolderMailUids)
|
||||
{
|
||||
var copy = await _imapChangeProcessor.GetMailCopyAsync(messageId).ConfigureAwait(false);
|
||||
|
||||
if (copy == null) continue;
|
||||
|
||||
searchResults.Add(copy);
|
||||
}
|
||||
|
||||
return searchResults;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Failed to perform online imap search.");
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (activeFolder?.IsOpen ?? false)
|
||||
{
|
||||
await activeFolder.CloseAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
_clientPool.Release(client);
|
||||
}
|
||||
|
||||
return new List<MailCopy>();
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<string>> SynchronizeFolderInternalAsync(MailItemFolder folder, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (!folder.IsSynchronizationEnabled) return default;
|
||||
|
||||
Reference in New Issue
Block a user