Bunch of changes for ItemsView and threads.
This commit is contained in:
@@ -39,6 +39,7 @@ public partial class GroupedEmailCollection : ObservableObject, IRecipient<Prope
|
||||
private readonly Dictionary<string, int> _groupHeaderIndexCache = [];
|
||||
private readonly Dictionary<string, List<object>> _groupItems = [];
|
||||
private readonly Dictionary<string, ThreadMailItemViewModel> _threadExpanders = [];
|
||||
private readonly HashSet<Guid> _mailCopyIdHashSet = [];
|
||||
private bool _disposed;
|
||||
private bool _isUpdating;
|
||||
|
||||
@@ -78,6 +79,11 @@ public partial class GroupedEmailCollection : ObservableObject, IRecipient<Prope
|
||||
/// </summary>
|
||||
public int TotalUnreadCount => _sourceItems.Count(e => e.MailCopy?.IsRead == false);
|
||||
|
||||
/// <summary>
|
||||
/// HashSet containing unique IDs of all mail copies in the collection for pagination tracking
|
||||
/// </summary>
|
||||
public HashSet<Guid> MailCopyIdHashSet => _mailCopyIdHashSet;
|
||||
|
||||
/// <summary>
|
||||
/// Gets all email items across all groups as a flat collection
|
||||
/// </summary>
|
||||
@@ -227,6 +233,9 @@ public partial class GroupedEmailCollection : ObservableObject, IRecipient<Prope
|
||||
if (email?.MailCopy == null)
|
||||
return;
|
||||
|
||||
// Add to unique ID tracking
|
||||
_mailCopyIdHashSet.Add(email.MailCopy.UniqueId);
|
||||
|
||||
_isUpdating = true;
|
||||
try
|
||||
{
|
||||
@@ -306,6 +315,9 @@ public partial class GroupedEmailCollection : ObservableObject, IRecipient<Prope
|
||||
if (email?.MailCopy == null)
|
||||
return;
|
||||
|
||||
// Remove from unique ID tracking
|
||||
_mailCopyIdHashSet.Remove(email.MailCopy.UniqueId);
|
||||
|
||||
_isUpdating = true;
|
||||
try
|
||||
{
|
||||
@@ -386,6 +398,12 @@ public partial class GroupedEmailCollection : ObservableObject, IRecipient<Prope
|
||||
_isUpdating = true;
|
||||
try
|
||||
{
|
||||
// Add to unique ID tracking
|
||||
foreach (var email in emailList)
|
||||
{
|
||||
_mailCopyIdHashSet.Add(email.MailCopy.UniqueId);
|
||||
}
|
||||
|
||||
// For bulk loading, add to source and refresh
|
||||
foreach (var email in emailList)
|
||||
{
|
||||
@@ -430,6 +448,7 @@ public partial class GroupedEmailCollection : ObservableObject, IRecipient<Prope
|
||||
_groupHeaderIndexCache.Clear();
|
||||
_groupItems.Clear();
|
||||
_threadExpanders.Clear();
|
||||
_mailCopyIdHashSet.Clear();
|
||||
|
||||
OnPropertyChanged(nameof(TotalCount));
|
||||
OnPropertyChanged(nameof(TotalUnreadCount));
|
||||
|
||||
@@ -13,14 +13,13 @@ using Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Exceptions;
|
||||
using Wino.Core.Services;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
using Wino.Core.Domain.Models.Navigation;
|
||||
using Wino.Core.Extensions;
|
||||
using Wino.Core.Services;
|
||||
using Wino.Mail.ViewModels.Data;
|
||||
using Wino.Messaging.Client.Mails;
|
||||
using Wino.Messaging.Server;
|
||||
|
||||
namespace Wino.Mail.ViewModels;
|
||||
|
||||
@@ -411,8 +410,8 @@ public partial class ComposePageViewModel : MailBaseViewModel
|
||||
|
||||
// Download missing MIME message using SynchronizationManager
|
||||
await SynchronizationManager.Instance.DownloadMimeMessageAsync(
|
||||
CurrentMailDraftItem.MailCopy,
|
||||
CurrentMailDraftItem.AssignedAccount.Id);
|
||||
CurrentMailDraftItem.MailCopy,
|
||||
CurrentMailDraftItem.MailCopy.AssignedAccount.Id);
|
||||
|
||||
goto retry;
|
||||
}
|
||||
|
||||
@@ -53,16 +53,13 @@ public partial class ThreadMailItemViewModel : ObservableRecipient, IDisposable
|
||||
/// </summary>
|
||||
public IReadOnlyList<MailItemViewModel> ThreadEmails => _threadEmails.AsReadOnly();
|
||||
|
||||
public MailItemViewModel LatestMailViewModel => _threadEmails.OrderByDescending(e => e.MailCopy?.CreationDate).FirstOrDefault()!;
|
||||
|
||||
public ThreadMailItemViewModel(string threadId)
|
||||
{
|
||||
_threadId = threadId;
|
||||
}
|
||||
|
||||
partial void OnIsSelectedChanged(bool value)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed)
|
||||
@@ -86,6 +83,8 @@ public partial class ThreadMailItemViewModel : ObservableRecipient, IDisposable
|
||||
{
|
||||
OnPropertyChanged(nameof(Subject));
|
||||
OnPropertyChanged(nameof(FromName));
|
||||
OnPropertyChanged(nameof(LatestEmailDate));
|
||||
OnPropertyChanged(nameof(LatestMailViewModel));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -60,14 +60,6 @@ public partial class MailListPageViewModel : MailBaseViewModel,
|
||||
private IObservable<System.Reactive.EventPattern<NotifyCollectionChangedEventArgs>> selectionChangedObservable = null;
|
||||
|
||||
public GroupedEmailCollection MailCollection { get; set; } = new GroupedEmailCollection();
|
||||
|
||||
//public IEnumerable<MailItemViewModel> SelectedItems
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
|
||||
// }
|
||||
//}
|
||||
public ObservableCollection<MailItemViewModel> SelectedItems { get; set; } = [];
|
||||
public ObservableCollection<FolderPivotViewModel> PivotFolders { get; set; } = [];
|
||||
public ObservableCollection<MailOperationMenuItem> ActionItems { get; set; } = [];
|
||||
@@ -246,11 +238,10 @@ public partial class MailListPageViewModel : MailBaseViewModel,
|
||||
{
|
||||
if (SetProperty(ref _selectedSortingOption, value))
|
||||
{
|
||||
// TODO: Update sorting in mail collection.
|
||||
//if (value != null && MailCollection != null)
|
||||
//{
|
||||
// MailCollection.SortingType = value.Type;
|
||||
//}
|
||||
if (value != null && MailCollection != null)
|
||||
{
|
||||
MailCollection.GroupingType = value.Type == SortingOptionType.ReceiveDate ? EmailGroupingType.ByDate : EmailGroupingType.ByFromName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -562,24 +553,24 @@ public partial class MailListPageViewModel : MailBaseViewModel,
|
||||
[RelayCommand]
|
||||
private async Task LoadMoreItemsAsync()
|
||||
{
|
||||
//if (IsInitializingFolder || IsOnlineSearchEnabled) return;
|
||||
if (IsInitializingFolder || IsOnlineSearchEnabled) return;
|
||||
|
||||
//await ExecuteUIThread(() => { IsInitializingFolder = true; });
|
||||
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 = new MailListInitializationOptions(ActiveFolder.HandlingFolders,
|
||||
SelectedFilterOption.Type,
|
||||
SelectedSortingOption.Type,
|
||||
PreferencesService.IsThreadingEnabled,
|
||||
SelectedFolderPivot.IsFocused,
|
||||
IsInSearchMode ? SearchQuery : string.Empty,
|
||||
MailCollection.MailCopyIdHashSet);
|
||||
|
||||
//var items = await _mailService.FetchMailsAsync(initializationOptions).ConfigureAwait(false);
|
||||
var items = await _mailService.FetchMailsAsync(initializationOptions).ConfigureAwait(false);
|
||||
|
||||
//var viewModels = PrepareMailViewModels(items);
|
||||
var viewModels = PrepareMailViewModels(items);
|
||||
|
||||
//await ExecuteUIThread(() => { MailCollection.AddRange(viewModels, clearIdCache: false); });
|
||||
//await ExecuteUIThread(() => { IsInitializingFolder = false; });
|
||||
await ExecuteUIThread(() => { MailCollection.AddEmails(viewModels); });
|
||||
await ExecuteUIThread(() => { IsInitializingFolder = false; });
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -589,7 +580,6 @@ public partial class MailListPageViewModel : MailBaseViewModel,
|
||||
public IEnumerable<MailOperationMenuItem> GetAvailableMailActions(IEnumerable<MailItemViewModel> contextMailItems)
|
||||
=> _contextMenuItemService.GetMailItemContextMenuActions(contextMailItems.Select(a => a.MailCopy));
|
||||
|
||||
|
||||
private bool ShouldPreventItemAdd(MailCopy mailItem)
|
||||
{
|
||||
bool condition = mailItem.IsRead
|
||||
@@ -733,13 +723,6 @@ public partial class MailListPageViewModel : MailBaseViewModel,
|
||||
private IEnumerable<MailItemViewModel> PrepareMailViewModels(IEnumerable<MailCopy> mailItems)
|
||||
{
|
||||
return mailItems.Select(a => new MailItemViewModel(a));
|
||||
//foreach (var item in mailItems)
|
||||
//{
|
||||
// if (item is MailCopy singleMailItem)
|
||||
// yield return new MailItemViewModel(singleMailItem);
|
||||
// else if (item is ThreadMailItem threadMailItem)
|
||||
// yield return new ThreadMailItemViewModel(threadMailItem);
|
||||
//}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
@@ -784,7 +767,6 @@ public partial class MailListPageViewModel : MailBaseViewModel,
|
||||
// Here items are sorted and filtered.
|
||||
|
||||
List<MailCopy> items = null;
|
||||
List<MailCopy> onlineSearchItems = null;
|
||||
|
||||
bool isDoingSearch = !string.IsNullOrEmpty(SearchQuery);
|
||||
bool isDoingOnlineSearch = false;
|
||||
@@ -851,8 +833,7 @@ public partial class MailListPageViewModel : MailBaseViewModel,
|
||||
PreferencesService.IsThreadingEnabled,
|
||||
SelectedFolderPivot.IsFocused,
|
||||
SearchQuery,
|
||||
default,
|
||||
onlineSearchItems);
|
||||
MailCollection.MailCopyIdHashSet);
|
||||
|
||||
items = await _mailService.FetchMailsAsync(initializationOptions, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ using Wino.Core.Services;
|
||||
using Wino.Mail.ViewModels.Data;
|
||||
using Wino.Mail.ViewModels.Messages;
|
||||
using Wino.Messaging.Client.Mails;
|
||||
using Wino.Messaging.Server;
|
||||
using Wino.Messaging.UI;
|
||||
using IMailService = Wino.Core.Domain.Interfaces.IMailService;
|
||||
|
||||
@@ -355,8 +354,8 @@ public partial class MailRenderingPageViewModel : MailBaseViewModel,
|
||||
|
||||
// Download missing MIME message using SynchronizationManager
|
||||
await SynchronizationManager.Instance.DownloadMimeMessageAsync(
|
||||
mailItemViewModel.MailCopy,
|
||||
mailItemViewModel.AssignedAccount.Id);
|
||||
mailItemViewModel.MailCopy,
|
||||
mailItemViewModel.MailCopy.AssignedAccount.Id);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user