Add mail categories support

This commit is contained in:
Burak Kaan Köse
2026-04-15 01:18:07 +02:00
parent feff929333
commit cf8fff8ef1
61 changed files with 2171 additions and 75 deletions
@@ -169,6 +169,10 @@ public partial class AccountDetailsPageViewModel : MailBaseViewModel
private void EditAliases()
=> Messenger.Send(new BreadcrumbNavigationRequested(Translator.SettingsManageAliases_Title, WinoPage.AliasManagementPage, Account.Id));
[RelayCommand]
private void EditCategories()
=> Messenger.Send(new BreadcrumbNavigationRequested(Translator.MailCategoryManagementPage_Title, WinoPage.MailCategoryManagementPage, Account.Id));
[RelayCommand]
private void EditImapCalDavSettings()
=> Messenger.Send(new BreadcrumbNavigationRequested(
@@ -81,6 +81,10 @@ public partial class AccountSetupProgressPageViewModel : MailBaseViewModel
Steps.Add(new AccountSetupStepModel { Title = Translator.AccountSetup_Step_FetchingProfile });
Steps.Add(new AccountSetupStepModel { Title = Translator.AccountSetup_Step_SavingAccount });
Steps.Add(new AccountSetupStepModel { Title = Translator.AccountSetup_Step_SyncingFolders });
if (WizardContext.SelectedProvider.Type == MailProviderType.Outlook)
{
Steps.Add(new AccountSetupStepModel { Title = Translator.AccountSetup_Step_SyncingCategories });
}
Steps.Add(new AccountSetupStepModel { Title = Translator.AccountSetup_Step_FetchingCalendarMetadata });
Steps.Add(new AccountSetupStepModel { Title = Translator.AccountSetup_Step_SyncingAliases });
Steps.Add(new AccountSetupStepModel { Title = Translator.AccountSetup_Step_Finalizing });
@@ -229,6 +233,16 @@ public partial class AccountSetupProgressPageViewModel : MailBaseViewModel
throw new Exception(Translator.Exception_FailedToSynchronizeFolders);
SetCurrentStepSucceeded();
// Step: Categories
if (_createdAccount.IsCategorySyncSupported)
{
SetStepInProgress(Translator.AccountSetup_Step_SyncingCategories);
var categoryResult = await SynchronizationManager.Instance.SynchronizeCategoriesAsync(_createdAccount.Id);
if (categoryResult.CompletedState != SynchronizationCompletedState.Success)
throw new Exception(Translator.Exception_FailedToSynchronizeCategories);
SetCurrentStepSucceeded();
}
// Step: Calendar metadata
SetStepInProgress(Translator.AccountSetup_Step_FetchingCalendarMetadata);
if (_createdAccount.IsCalendarAccessGranted)
+39 -3
View File
@@ -73,6 +73,7 @@ public partial class MailAppShellViewModel : MailBaseViewModel,
public IMenuItem CreatePrimaryMenuItem => CreateMailMenuItem;
private readonly IFolderService _folderService;
private readonly IMailCategoryService _mailCategoryService;
private readonly IConfigurationService _configurationService;
private readonly IStartupBehaviorService _startupBehaviorService;
private readonly IAccountService _accountService;
@@ -99,6 +100,7 @@ public partial class MailAppShellViewModel : MailBaseViewModel,
IMimeFileService mimeFileService,
INativeAppService nativeAppService,
IMailService mailService,
IMailCategoryService mailCategoryService,
IAccountService accountService,
IContextMenuItemService contextMenuItemService,
IStoreRatingService storeRatingService,
@@ -125,6 +127,7 @@ public partial class MailAppShellViewModel : MailBaseViewModel,
_mimeFileService = mimeFileService;
_nativeAppService = nativeAppService;
_mailService = mailService;
_mailCategoryService = mailCategoryService;
_folderService = folderService;
_accountService = accountService;
_contextMenuItemService = contextMenuItemService;
@@ -721,7 +724,8 @@ public partial class MailAppShellViewModel : MailBaseViewModel,
{
await HandleCreateNewMailAsync();
}
else if (clickedMenuItem is IBaseFolderMenuItem baseFolderMenuItem && baseFolderMenuItem.HandlingFolders.All(a => a.IsMoveTarget))
else if (clickedMenuItem is IBaseFolderMenuItem baseFolderMenuItem &&
(clickedMenuItem is IMailCategoryMenuItem or IMergedMailCategoryMenuItem || baseFolderMenuItem.HandlingFolders.All(a => a.IsMoveTarget)))
{
// Don't navigate to base folders that contain non-move target folders.
// Theory: This is a special folder like Categories or More. Don't navigate to it.
@@ -793,11 +797,20 @@ public partial class MailAppShellViewModel : MailBaseViewModel,
{
// Get visible account menu items, ordered by merged accounts at the last.
// We will update the unread counts for all single accounts and trigger UI refresh for merged menu items.
var accountMenuItems = MenuItems.GetAllAccountMenuItems().OrderBy(a => a.HoldingAccounts.Count());
List<IAccountMenuItem> accountMenuItems = null;
await ExecuteUIThread(() =>
{
accountMenuItems = MenuItems
.GetAllAccountMenuItems()
.OrderBy(a => a.HoldingAccounts.Count())
.ToList();
});
// Individually get all single accounts' unread counts.
var accountIds = accountMenuItems.OfType<AccountMenuItem>().Select(a => a.AccountId);
var accountIds = accountMenuItems.OfType<AccountMenuItem>().Select(a => a.AccountId).ToList();
var unreadCountResult = await _folderService.GetUnreadItemCountResultsAsync(accountIds).ConfigureAwait(false);
var unreadCategoryCountResult = await _mailCategoryService.GetUnreadCategoryCountResultsAsync(accountIds).ConfigureAwait(false);
// Recursively update all folders' unread counts to 0.
// Query above only returns unread counts that exists. We need to reset the rest to 0 first.
@@ -849,6 +862,29 @@ public partial class MailAppShellViewModel : MailBaseViewModel,
}
}
foreach (var unreadCategoryCount in unreadCategoryCountResult)
{
if (MenuItems.TryGetCategoryMenuItem(unreadCategoryCount.CategoryId, out var categoryMenuItem))
{
if (categoryMenuItem is IMergedMailCategoryMenuItem mergedCategoryMenuItem)
{
await ExecuteUIThread(() =>
{
categoryMenuItem.UnreadItemCount = unreadCategoryCountResult
.Where(a => mergedCategoryMenuItem.Categories.Any(b => b.Id == a.CategoryId))
.Sum(a => a.UnreadItemCount);
});
}
else
{
await ExecuteUIThread(() =>
{
categoryMenuItem.UnreadItemCount = unreadCategoryCount.UnreadItemCount;
});
}
}
}
// Update unread badge after all unread counts are updated.
await _notificationBuilder.UpdateTaskbarIconBadgeAsync();
}
@@ -0,0 +1,251 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Wino.Core.Domain;
using Wino.Core.Domain.Entities.Mail;
using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.MailItem;
using Wino.Core.Domain.Models.Navigation;
using Wino.Core.Domain.Models.Synchronization;
using Wino.Core.Requests.Category;
using Wino.Core.Services;
namespace Wino.Mail.ViewModels;
public partial class MailCategoryManagementPageViewModel : MailBaseViewModel
{
private readonly IMailCategoryService _mailCategoryService;
private readonly IAccountService _accountService;
private readonly IMailDialogService _dialogService;
private readonly IWinoRequestDelegator _winoRequestDelegator;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(CanRefresh))]
public partial MailAccount Account { get; set; }
public ObservableCollection<MailCategory> Categories { get; } = [];
public bool CanRefresh => Account?.ProviderType == MailProviderType.Outlook;
public bool HasCategories => Categories.Count > 0;
public MailCategoryManagementPageViewModel(
IMailCategoryService mailCategoryService,
IAccountService accountService,
IMailDialogService dialogService,
IWinoRequestDelegator winoRequestDelegator)
{
_mailCategoryService = mailCategoryService;
_accountService = accountService;
_dialogService = dialogService;
_winoRequestDelegator = winoRequestDelegator;
}
public override async void OnNavigatedTo(NavigationMode mode, object parameters)
{
base.OnNavigatedTo(mode, parameters);
if (parameters is not Guid accountId)
return;
Account = await _accountService.GetAccountAsync(accountId).ConfigureAwait(false);
if (Account != null)
{
await LoadCategoriesAsync().ConfigureAwait(false);
}
}
[RelayCommand]
private Task AddCategoryAsync()
=> CreateOrUpdateCategoryAsync();
[RelayCommand]
private async Task RefreshCategoriesAsync()
{
if (!CanRefresh)
return;
var shouldContinue = await _dialogService.ShowConfirmationDialogAsync(
Translator.MailCategoryManagementPage_RefreshConfirmationMessage,
Translator.Buttons_Refresh,
Translator.Buttons_Refresh).ConfigureAwait(false);
if (!shouldContinue)
return;
await _mailCategoryService.DeleteCategoriesAsync(Account.Id).ConfigureAwait(false);
await SynchronizationManager.Instance.SynchronizeCategoriesAsync(Account.Id).ConfigureAwait(false);
await LoadCategoriesAsync().ConfigureAwait(false);
}
public Task EditCategoryAsync(MailCategory category)
=> CreateOrUpdateCategoryAsync(category);
public async Task DeleteCategoryAsync(MailCategory category)
{
if (category == null)
return;
var shouldDelete = await _dialogService.ShowConfirmationDialogAsync(
string.Format(Translator.MailCategoryManagementPage_DeleteConfirmationMessage, category.Name),
Translator.MailCategoryManagementPage_DeleteConfirmationTitle,
Translator.Buttons_Delete).ConfigureAwait(false);
if (!shouldDelete)
return;
var deleteRequest = await BuildDeleteCategoryRequestAsync(category).ConfigureAwait(false);
await _mailCategoryService.DeleteCategoryAsync(category.Id).ConfigureAwait(false);
await QueueOutlookCategoryRequestsAsync(deleteRequest).ConfigureAwait(false);
await LoadCategoriesAsync().ConfigureAwait(false);
}
public async Task SetFavoriteAsync(MailCategory category, bool isFavorite)
{
if (category == null)
return;
await _mailCategoryService.ToggleFavoriteAsync(category.Id, isFavorite).ConfigureAwait(false);
await LoadCategoriesAsync().ConfigureAwait(false);
}
private async Task CreateOrUpdateCategoryAsync(MailCategory existingCategory = null)
{
var dialogResult = await _dialogService.ShowEditMailCategoryDialogAsync(existingCategory).ConfigureAwait(false);
if (dialogResult == null)
return;
if (string.IsNullOrWhiteSpace(dialogResult.Name))
{
await _dialogService.ShowMessageAsync(
Translator.MailCategoryDialog_InvalidNameMessage,
Translator.MailCategoryDialog_InvalidNameTitle,
WinoCustomMessageDialogIcon.Warning).ConfigureAwait(false);
return;
}
var normalizedName = dialogResult.Name.Trim();
var categoryIdToExclude = existingCategory?.Id;
var alreadyExists = await _mailCategoryService.CategoryNameExistsAsync(Account.Id, normalizedName, categoryIdToExclude).ConfigureAwait(false);
if (alreadyExists)
{
await _dialogService.ShowMessageAsync(
Translator.MailCategoryDialog_DuplicateMessage,
Translator.MailCategoryDialog_DuplicateTitle,
WinoCustomMessageDialogIcon.Warning).ConfigureAwait(false);
return;
}
if (existingCategory == null)
{
var newCategory = new MailCategory
{
Id = Guid.NewGuid(),
MailAccountId = Account.Id,
Name = normalizedName,
BackgroundColorHex = dialogResult.BackgroundColorHex,
TextColorHex = dialogResult.TextColorHex,
Source = Account.ProviderType == MailProviderType.Outlook ? MailCategorySource.Outlook : MailCategorySource.Local
};
await _mailCategoryService.CreateCategoryAsync(newCategory).ConfigureAwait(false);
if (Account.ProviderType == MailProviderType.Outlook)
{
await _winoRequestDelegator.ExecuteAsync(Account.Id, [new MailCategoryCreateRequest(newCategory)]).ConfigureAwait(false);
}
}
else
{
var previousName = existingCategory.Name;
var previousRemoteId = existingCategory.RemoteId;
existingCategory.Name = normalizedName;
existingCategory.BackgroundColorHex = dialogResult.BackgroundColorHex;
existingCategory.TextColorHex = dialogResult.TextColorHex;
await _mailCategoryService.UpdateCategoryAsync(existingCategory).ConfigureAwait(false);
if (Account.ProviderType == MailProviderType.Outlook)
{
if (string.IsNullOrWhiteSpace(previousRemoteId))
{
await _winoRequestDelegator.ExecuteAsync(Account.Id, [new MailCategoryCreateRequest(existingCategory)]).ConfigureAwait(false);
}
else
{
var affectedMessages = await BuildAffectedMessageTargetsAsync(existingCategory.Id).ConfigureAwait(false);
var updateRequest = new MailCategoryUpdateRequest(existingCategory, previousName, previousRemoteId, affectedMessages);
await _winoRequestDelegator.ExecuteAsync(Account.Id, [updateRequest]).ConfigureAwait(false);
}
}
}
await LoadCategoriesAsync().ConfigureAwait(false);
}
private async Task<MailCategoryDeleteRequest> BuildDeleteCategoryRequestAsync(MailCategory category)
{
if (category == null || Account?.ProviderType != MailProviderType.Outlook)
return null;
var mailCopies = await _mailCategoryService.GetMailCopiesForCategoryAsync(category.Id).ConfigureAwait(false);
var affectedMessages = new List<MailCategoryMessageUpdateTarget>();
foreach (var mailCopy in mailCopies.Where(a => !string.IsNullOrWhiteSpace(a.Id)))
{
var remainingNames = await _mailCategoryService.GetCategoryNamesForMailAsync(mailCopy.UniqueId).ConfigureAwait(false);
var categoryNames = remainingNames
.Where(a => !string.Equals(a, category.Name, StringComparison.OrdinalIgnoreCase))
.ToList();
affectedMessages.Add(new MailCategoryMessageUpdateTarget(mailCopy.Id, categoryNames));
}
return new MailCategoryDeleteRequest(category, category.RemoteId, affectedMessages);
}
private async Task<IReadOnlyList<MailCategoryMessageUpdateTarget>> BuildAffectedMessageTargetsAsync(Guid categoryId)
{
var mailCopies = await _mailCategoryService.GetMailCopiesForCategoryAsync(categoryId).ConfigureAwait(false);
var affectedMessages = new List<MailCategoryMessageUpdateTarget>();
foreach (var mailCopy in mailCopies.Where(a => !string.IsNullOrWhiteSpace(a.Id)))
{
var categoryNames = await _mailCategoryService.GetCategoryNamesForMailAsync(mailCopy.UniqueId).ConfigureAwait(false);
affectedMessages.Add(new MailCategoryMessageUpdateTarget(mailCopy.Id, categoryNames));
}
return affectedMessages;
}
private Task QueueOutlookCategoryRequestsAsync(params IRequestBase[] requests)
=> Account?.ProviderType == MailProviderType.Outlook && requests.Any(a => a != null)
? _winoRequestDelegator.ExecuteAsync(Account.Id, requests.Where(a => a != null))
: Task.CompletedTask;
private async Task LoadCategoriesAsync()
{
var categories = await _mailCategoryService.GetCategoriesAsync(Account.Id).ConfigureAwait(false);
await ExecuteUIThread(() =>
{
Categories.Clear();
foreach (var category in categories)
{
Categories.Add(category);
}
OnPropertyChanged(nameof(HasCategories));
});
}
}
+110 -21
View File
@@ -24,6 +24,7 @@ using Wino.Core.Domain.Models.Menus;
using Wino.Core.Domain.Models.Navigation;
using Wino.Core.Domain.Models.Reader;
using Wino.Core.Domain.Models.Synchronization;
using Wino.Core.Requests.Mail;
using Wino.Core.Services;
using Wino.Mail.ViewModels.Collections;
using Wino.Mail.ViewModels.Data;
@@ -77,6 +78,7 @@ public partial class MailListPageViewModel : MailBaseViewModel,
private readonly INotificationBuilder _notificationBuilder;
private readonly IFolderService _folderService;
private readonly IContextMenuItemService _contextMenuItemService;
private readonly IMailCategoryService _mailCategoryService;
private readonly IWinoRequestDelegator _winoRequestDelegator;
private readonly IKeyPressService _keyPressService;
private readonly IWinoLogger _winoLogger;
@@ -156,6 +158,8 @@ public partial class MailListPageViewModel : MailBaseViewModel,
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(CanSynchronize))]
[NotifyPropertyChangedFor(nameof(IsFolderSynchronizationEnabled))]
[NotifyPropertyChangedFor(nameof(IsCategoryView))]
[NotifyPropertyChangedFor(nameof(IsSyncButtonVisible))]
public partial IBaseFolderMenuItem ActiveFolder { get; set; }
[ObservableProperty]
@@ -172,6 +176,7 @@ public partial class MailListPageViewModel : MailBaseViewModel,
INotificationBuilder notificationBuilder,
IFolderService folderService,
IContextMenuItemService contextMenuItemService,
IMailCategoryService mailCategoryService,
IWinoRequestDelegator winoRequestDelegator,
IKeyPressService keyPressService,
IPreferencesService preferencesService,
@@ -185,6 +190,7 @@ public partial class MailListPageViewModel : MailBaseViewModel,
_mimeFileService = mimeFileService;
_folderService = folderService;
_contextMenuItemService = contextMenuItemService;
_mailCategoryService = mailCategoryService;
_winoRequestDelegator = winoRequestDelegator;
_keyPressService = keyPressService;
@@ -277,9 +283,11 @@ public partial class MailListPageViewModel : MailBaseViewModel,
}
}
public bool CanSynchronize => !IsAccountSynchronizerInSynchronization && IsFolderSynchronizationEnabled;
public bool CanSynchronize => !IsCategoryView && !IsAccountSynchronizerInSynchronization && IsFolderSynchronizationEnabled;
public bool IsFolderSynchronizationEnabled => ActiveFolder?.IsSynchronizationEnabled ?? false;
public bool IsArchiveSpecialFolder => ActiveFolder?.SpecialFolderType == SpecialFolderType.Archive;
public bool IsCategoryView => ActiveFolder is IMailCategoryMenuItem or IMergedMailCategoryMenuItem;
public bool IsSyncButtonVisible => !IsCategoryView;
public string SelectedMessageText => IsDragInProgress
? string.Format(Translator.MailsDragging, DraggingItemsCount)
@@ -396,9 +404,12 @@ public partial class MailListPageViewModel : MailBaseViewModel,
}
else
{
if (IsCategoryView)
{
PivotFolders.Add(new FolderPivotViewModel(ActiveFolder.FolderName, null));
}
// Merged folders don't support focused feature.
if (ActiveFolder is IMergedAccountFolderMenuItem)
else if (ActiveFolder is IMergedAccountFolderMenuItem)
{
PivotFolders.Add(new FolderPivotViewModel(ActiveFolder.FolderName, null));
}
@@ -545,7 +556,7 @@ public partial class MailListPageViewModel : MailBaseViewModel,
[RelayCommand]
private async Task EnableFolderSynchronizationAsync()
{
if (ActiveFolder == null) return;
if (ActiveFolder == null || IsCategoryView) return;
foreach (var folder in ActiveFolder.HandlingFolders)
{
@@ -561,13 +572,9 @@ public partial class MailListPageViewModel : MailBaseViewModel,
Debug.WriteLine("Loading more...");
await ExecuteUIThread(() => { IsInitializingFolder = true; });
var initializationOptions = new MailListInitializationOptions(ActiveFolder.HandlingFolders,
SelectedFilterOption.Type,
SelectedSortingOption.Type,
PreferencesService.IsThreadingEnabled,
SelectedFolderPivot.IsFocused,
IsInSearchMode ? SearchQuery : string.Empty,
MailCollection.MailCopyIdHashSet);
var initializationOptions = CreateInitializationOptions(
IsInSearchMode ? SearchQuery : string.Empty,
MailCollection.MailCopyIdHashSet);
var items = await _mailService.FetchMailsAsync(initializationOptions).ConfigureAwait(false);
@@ -674,6 +681,60 @@ public partial class MailListPageViewModel : MailBaseViewModel,
public IEnumerable<MailOperationMenuItem> GetAvailableMailActions(IEnumerable<MailItemViewModel> contextMailItems)
=> _contextMenuItemService.GetMailItemContextMenuActions(contextMailItems.Select(a => a.MailCopy));
public async Task<(IReadOnlyList<MailCategory> Categories, IReadOnlyCollection<Guid> AssignedCategoryIds)> GetAvailableCategoriesAsync(IEnumerable<MailItemViewModel> targetItems)
{
var targetList = targetItems?.Where(a => a?.MailCopy?.AssignedAccount != null).ToList() ?? [];
if (targetList.Count == 0)
return ([], []);
var accountIds = targetList.Select(a => a.MailCopy.AssignedAccount.Id).Distinct().ToList();
if (accountIds.Count != 1)
return ([], []);
var accountId = accountIds[0];
var uniqueIds = targetList.Select(a => a.MailCopy.UniqueId).Distinct().ToList();
var categories = await _mailCategoryService.GetCategoriesAsync(accountId).ConfigureAwait(false);
var assignedCategoryIds = await _mailCategoryService.GetAssignedCategoryIdsForAllAsync(uniqueIds).ConfigureAwait(false);
return (categories, assignedCategoryIds);
}
public async Task ToggleCategoryAssignmentAsync(MailCategory category, IEnumerable<MailItemViewModel> targetItems, bool isAssignedToAll)
{
var targetList = targetItems?.Where(a => a?.MailCopy?.AssignedAccount != null).ToList() ?? [];
if (category == null || targetList.Count == 0)
return;
var accountIds = targetList.Select(a => a.MailCopy.AssignedAccount.Id).Distinct().ToList();
if (accountIds.Count != 1)
return;
var accountId = accountIds[0];
var uniqueIds = targetList.Select(a => a.MailCopy.UniqueId).Distinct().ToList();
if (isAssignedToAll)
{
await _mailCategoryService.UnassignCategoryAsync(category.Id, uniqueIds).ConfigureAwait(false);
}
else
{
await _mailCategoryService.AssignCategoryAsync(category.Id, uniqueIds).ConfigureAwait(false);
}
if (targetList.First().MailCopy.AssignedAccount.ProviderType != MailProviderType.Outlook)
return;
var requests = new List<IRequestBase>();
foreach (var mailItem in targetList.Select(a => a.MailCopy).DistinctBy(a => a.UniqueId))
{
var categoryNames = await _mailCategoryService.GetCategoryNamesForMailAsync(mailItem.UniqueId).ConfigureAwait(false);
requests.Add(new MailCategoryAssignmentRequest(mailItem, category.Id, category.Name, categoryNames, !isAssignedToAll));
}
await _winoRequestDelegator.ExecuteAsync(accountId, requests).ConfigureAwait(false);
}
private bool ShouldPreventItemAdd(MailCopy mailItem)
{
bool condition = mailItem.IsRead
@@ -691,7 +752,7 @@ public partial class MailListPageViewModel : MailBaseViewModel,
=> ActiveFolder?.SpecialFolderType == SpecialFolderType.Draft;
private bool BelongsToActiveFolder(MailCopy mailItem)
=> mailItem?.AssignedFolder != null && ActiveFolder?.HandlingFolders?.Any(a => a.Id == mailItem.AssignedFolder.Id) == true;
=> !IsCategoryView && mailItem?.AssignedFolder != null && ActiveFolder?.HandlingFolders?.Any(a => a.Id == mailItem.AssignedFolder.Id) == true;
private bool ShouldIncludeByThread(MailCopy mailItem)
=> PreferencesService.IsThreadingEnabled
@@ -1069,6 +1130,38 @@ public partial class MailListPageViewModel : MailBaseViewModel,
}
}
private MailListInitializationOptions CreateInitializationOptions(
string searchQuery,
System.Collections.Concurrent.ConcurrentDictionary<Guid, bool> existingUniqueIds,
List<MailCopy> preFetchedMailCopies = null,
bool deduplicateByServerId = false)
{
var options = new MailListInitializationOptions(ActiveFolder.HandlingFolders,
SelectedFilterOption.Type,
SelectedSortingOption.Type,
PreferencesService.IsThreadingEnabled,
SelectedFolderPivot.IsFocused,
searchQuery,
existingUniqueIds,
preFetchedMailCopies,
DeduplicateByServerId: deduplicateByServerId);
if (!IsCategoryView)
return options;
var categoryIds = ActiveFolder switch
{
IMailCategoryMenuItem singleCategoryMenuItem => new List<Guid> { singleCategoryMenuItem.MailCategory.Id },
IMergedMailCategoryMenuItem mergedCategoryMenuItem => mergedCategoryMenuItem.Categories.Select(a => a.Id).ToList(),
_ => []
};
return options with
{
CategoryIds = categoryIds
};
}
[RelayCommand]
private async Task PerformOnlineSearchAsync()
{
@@ -1218,15 +1311,11 @@ public partial class MailListPageViewModel : MailBaseViewModel,
}
}
var initializationOptions = new MailListInitializationOptions(ActiveFolder.HandlingFolders,
SelectedFilterOption.Type,
SelectedSortingOption.Type,
PreferencesService.IsThreadingEnabled,
SelectedFolderPivot.IsFocused,
isDoingOnlineSearch ? string.Empty : SearchQuery,
MailCollection.MailCopyIdHashSet,
onlineSearchItems,
DeduplicateByServerId: isDoingOnlineSearch);
var initializationOptions = CreateInitializationOptions(
isDoingOnlineSearch ? string.Empty : SearchQuery,
MailCollection.MailCopyIdHashSet,
onlineSearchItems,
isDoingOnlineSearch);
items = await _mailService.FetchMailsAsync(initializationOptions, cancellationToken).ConfigureAwait(false);