Optimize mail list selection and draft pruning

This commit is contained in:
Burak Kaan Köse
2026-04-11 10:54:14 +02:00
parent fdb340549d
commit 40318ef99c
5 changed files with 305 additions and 187 deletions
@@ -44,6 +44,8 @@ public class WinoMailCollection : ObservableRecipient, IRecipient<SelectedItemsC
private readonly ObservableGroupedCollection<object, IMailListItem> _mailItemSource = new ObservableGroupedCollection<object, IMailListItem>();
private readonly SemaphoreSlim _mutationGate = new(1, 1);
private int _selectionNotificationSuppressionCount;
private bool _selectionNotificationPending;
public ReadOnlyObservableGroupedCollection<object, IMailListItem> MailItems { get; }
@@ -305,6 +307,36 @@ public class WinoMailCollection : ObservableRecipient, IRecipient<SelectedItemsC
return null;
}
public ThreadMailItemViewModel GetThreadByMailUniqueId(Guid uniqueId)
{
if (_uniqueIdToThreadMap.TryGetValue(uniqueId, out var threadViewModel))
{
return threadViewModel;
}
_ = Find(uniqueId);
return _uniqueIdToThreadMap.TryGetValue(uniqueId, out threadViewModel) ? threadViewModel : null;
}
public List<ThreadMailItemViewModel> GetThreadItems()
{
var threads = new List<ThreadMailItemViewModel>();
foreach (var group in _mailItemSource)
{
foreach (var item in group)
{
if (item is ThreadMailItemViewModel threadItem)
{
threads.Add(threadItem);
}
}
}
return threads;
}
private async Task InsertItemInternalAsync(object groupKey, IMailListItem mailItem)
{
UpdateUniqueIdHashes(mailItem, true);
@@ -1049,44 +1081,52 @@ public class WinoMailCollection : ObservableRecipient, IRecipient<SelectedItemsC
public bool IsAllItemsSelected => AllItems.Any() && AllItems.All(a => a.IsSelected);
public bool HasSingleItemSelected => SelectedItemsCount == 1;
public async Task ExecuteWithoutRaiseSelectionChangedAsync(Action<IMailListItem> action, bool includeThreads)
public async Task ExecuteSelectionBatchAsync(Action action, bool notifySelectionChanged = true)
{
try
{
// Do not listen to individual selection changes while we are doing bulk selection.
Messenger.Unregister<SelectedItemsChangedMessage>(this);
await ExecuteUIThread(() =>
{
if (includeThreads)
{
foreach (var item in AllItemsIncludingThreads)
{
action(item);
}
}
else
{
foreach (var item in AllItems)
{
action(item);
}
}
});
_selectionNotificationSuppressionCount++;
await ExecuteUIThread(action);
}
catch (Exception)
{
}
finally
{
Messenger.Unregister<SelectedItemsChangedMessage>(this);
Messenger.Register<SelectedItemsChangedMessage>(this);
Messenger.Send(new SelectedItemsChangedMessage());
_selectionNotificationSuppressionCount = Math.Max(0, _selectionNotificationSuppressionCount - 1);
await NotifySelectionChangesAsync();
if (_selectionNotificationSuppressionCount == 0)
{
var shouldNotify = notifySelectionChanged || _selectionNotificationPending;
_selectionNotificationPending = false;
if (shouldNotify)
{
await NotifySelectionChangesAsync();
}
}
}
}
public Task ExecuteWithoutRaiseSelectionChangedAsync(Action<IMailListItem> action, bool includeThreads)
=> ExecuteSelectionBatchAsync(() =>
{
if (includeThreads)
{
foreach (var item in AllItemsIncludingThreads)
{
action(item);
}
}
else
{
foreach (var item in AllItems)
{
action(item);
}
}
});
public Task ToggleSelectAllAsync()
{
if (IsAllItemsSelected)
@@ -1144,7 +1184,16 @@ public class WinoMailCollection : ObservableRecipient, IRecipient<SelectedItemsC
}
}
public void Receive(SelectedItemsChangedMessage message) => _ = NotifySelectionChangesAsync();
public void Receive(SelectedItemsChangedMessage message)
{
if (_selectionNotificationSuppressionCount > 0)
{
_selectionNotificationPending = true;
return;
}
_ = NotifySelectionChangesAsync();
}
private async Task NotifySelectionChangesAsync()
{