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

@@ -1,4 +1,5 @@
namespace Wino.Core.Domain.Enums;
namespace Wino.Core.Domain.Enums;
public enum MailListDisplayMode
{

View File

@@ -0,0 +1,6 @@
namespace Wino.Core.Domain.Enums;
public enum SearchMode
{
Local,
Online
}

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using MailKit;
using MailKit.Net.Imap;
using Wino.Core.Domain.Entities.Mail;
@@ -17,5 +18,15 @@ public interface IImapSynchronizerStrategy
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>List of new downloaded message ids that don't exist locally.</returns>
Task<List<string>> HandleSynchronizationAsync(IImapClient client, MailItemFolder folder, IImapSynchronizer synchronizer, CancellationToken cancellationToken = default);
/// <summary>
/// Downloads given set of messages from the folder.
/// Folder is expected to be opened and synchronizer is connected.
/// </summary>
/// <param name="synchronizer">Synchronizer that performs the action.</param>
/// <param name="folder">Remote folder to download messages from.</param>
/// <param name="uniqueIdSet">Set of message uniqueids.</param>
/// <param name="cancellationToken">Cancellation token.</param>
Task DownloadMessagesAsync(IImapSynchronizer synchronizer, IMailFolder folder, UniqueIdSet uniqueIdSet, CancellationToken cancellationToken = default);
}

View File

@@ -13,6 +13,14 @@ public interface IMailService
{
Task<MailCopy> GetSingleMailItemAsync(string mailCopyId, string remoteFolderId);
Task<MailCopy> GetSingleMailItemAsync(Guid uniqueMailId);
/// <summary>
/// Returns the single mail item with the given mail copy id.
/// Caution: This method is not safe. Use other overrides.
/// </summary>
/// <param name="mailCopyId"></param>
/// <returns></returns>
Task<MailCopy> GetSingleMailItemAsync(string mailCopyId);
Task<List<IMailItem>> FetchMailsAsync(MailListInitializationOptions options, CancellationToken cancellationToken = default);
/// <summary>
@@ -117,4 +125,14 @@ public interface IMailService
/// <param name="uniqueIds"></param>
/// <returns></returns>
Task<List<MailCopy>> GetExistingMailsAsync(Guid folderId, IEnumerable<UniqueId> uniqueIds);
/// <summary>
/// Creates a new mail from a package without doing any existence check.
/// Use it with caution.
/// </summary>
/// <param name="account">Account that mail belongs to.</param>
/// <param name="mailItemFolder">Assigned folder.</param>
/// <param name="package">Mail creation package.</param>
/// <returns></returns>
Task CreateMailRawAsync(MailAccount account, MailItemFolder mailItemFolder, NewMailItemPackage package);
}

View File

@@ -39,6 +39,17 @@ public interface IPreferencesService
/// </summary>
bool Prefer24HourTimeFormat { get; set; }
/// <summary>
/// Diagnostic ID for the application.
/// Changes per-install.
/// </summary>
string DiagnosticId { get; set; }
/// <summary>
/// Setting: Defines the user's preference of default search mode in mail list.
/// Local search will still offer online search at the end of local search results.
/// </summary>
SearchMode DefaultSearchMode { get; set; }
#endregion
#region Mail
@@ -187,7 +198,7 @@ public interface IPreferencesService
DayOfWeek WorkingDayStart { get; set; }
DayOfWeek WorkingDayEnd { get; set; }
double HourHeight { get; set; }
string DiagnosticId { get; set; }
CalendarSettings GetCurrentCalendarSettings();

View File

@@ -1,6 +1,9 @@
using System.Threading;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using MailKit;
using Wino.Core.Domain.Entities.Mail;
using Wino.Core.Domain.Models.Folders;
using Wino.Core.Domain.Models.MailItem;
using Wino.Core.Domain.Models.Synchronization;
@@ -35,4 +38,13 @@ public interface IWinoSynchronizerBase : IBaseSynchronizer
/// 3. Dispose all resources.
/// </summary>
Task KillSynchronizerAsync();
/// <summary>
/// Perform online search on the server.
/// </summary>
/// <param name="queryText">Search query.</param>
/// <param name="folders">Folders to include in search. All folders if null.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>Search results after downloading missing mail copies from server.</returns>
Task<List<MailCopy>> OnlineSearchAsync(string queryText, List<IMailItemFolder> folders, CancellationToken cancellationToken = default);
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Wino.Core.Domain.Entities.Mail;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.Folders;
@@ -11,4 +12,5 @@ public record MailListInitializationOptions(IEnumerable<IMailItemFolder> Folders
bool CreateThreads,
bool? IsFocusedOnly,
string SearchQuery,
IEnumerable<Guid> ExistingUniqueIds);
IEnumerable<Guid> ExistingUniqueIds,
List<MailCopy> PreFetchMailCopies = null);

View File

@@ -0,0 +1,6 @@
using System.Collections.Generic;
using Wino.Core.Domain.Entities.Mail;
namespace Wino.Core.Domain.Models.Synchronization;
public record OnlineSearchResult(List<MailCopy> SearchResult);

View File

@@ -393,6 +393,9 @@
"Notifications_WinoUpdatedMessage": "Checkout new version {0}",
"Notifications_WinoUpdatedTitle": "Wino Mail has been updated.",
"Other": "Other",
"OnlineSearchFailed_Message": "Failed to perform search\n{0}\n\nListing offline mails.",
"OnlineSearchTry_Line1": "Can't find what you are looking for?",
"OnlineSearchTry_Line2": "Try online search.",
"PaneLengthOption_Default": "Default",
"PaneLengthOption_ExtraLarge": "Extra Large",
"PaneLengthOption_Large": "Large",
@@ -520,6 +523,10 @@
"SettingsAppPreferences_StartupBehavior_FatalError": "Fatal error occurred while changing the startup mode for Wino Mail.",
"SettingsAppPreferences_StartupBehavior_Enable": "Enable",
"SettingsAppPreferences_StartupBehavior_Disable": "Disable",
"SettingsAppPreferences_SearchMode_Title": "Default search mode",
"SettingsAppPreferences_SearchMode_Description": "Set whether Wino should check fetched mails first while doing a search or ask your mail server online. Local search is always faster and you can always do an online search if your mail is not in the results.",
"SettingsAppPreferences_SearchMode_Local": "Local",
"SettingsAppPreferences_SearchMode_Online": "Online",
"SettingsReorderAccounts_Title": "Reorder Accounts",
"SettingsReorderAccounts_Description": "Change the order of accounts in the account list.",
"SettingsManageLink_Description": "Move items to add new link or remove existing link.",
@@ -650,3 +657,4 @@
"QuickEventDialog_IsAllDay": "All day"
}