diff --git a/Directory.Packages.props b/Directory.Packages.props
index 710751ef..388751b7 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -15,56 +15,56 @@
-
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
+
-
-
-
+
+
+
-
-
+
+
-
\ No newline at end of file
+
diff --git a/Wino.Core.Domain/Models/MailItem/MailListInitializationOptions.cs b/Wino.Core.Domain/Models/MailItem/MailListInitializationOptions.cs
index 033ec012..c938941f 100644
--- a/Wino.Core.Domain/Models/MailItem/MailListInitializationOptions.cs
+++ b/Wino.Core.Domain/Models/MailItem/MailListInitializationOptions.cs
@@ -12,5 +12,7 @@ public record MailListInitializationOptions(IEnumerable Folders
bool CreateThreads,
bool? IsFocusedOnly,
string SearchQuery,
- IEnumerable ExistingUniqueIds,
- List PreFetchMailCopies = null);
+ HashSet ExistingUniqueIds = null,
+ List PreFetchMailCopies = null,
+ int Skip = 0,
+ int Take = 0);
diff --git a/Wino.Core.Domain/Wino.Core.Domain.csproj b/Wino.Core.Domain/Wino.Core.Domain.csproj
index f34bd83b..35882868 100644
--- a/Wino.Core.Domain/Wino.Core.Domain.csproj
+++ b/Wino.Core.Domain/Wino.Core.Domain.csproj
@@ -1,6 +1,6 @@
- net9.0
+ net10.0
win-x86;win-x64;win-arm64
true
x86;x64;arm64
@@ -57,7 +57,6 @@
-
diff --git a/Wino.Core.WinUI/Helpers/XamlHelpers.cs b/Wino.Core.WinUI/Helpers/XamlHelpers.cs
index b2318e7d..3bb6f8d0 100644
--- a/Wino.Core.WinUI/Helpers/XamlHelpers.cs
+++ b/Wino.Core.WinUI/Helpers/XamlHelpers.cs
@@ -26,6 +26,7 @@ public static class XamlHelpers
#region Converters
+ public static Thickness GetMailItemControlMargin(bool isDisplayedInThread) => isDisplayedInThread ? new Thickness(40, 0, 6, 0) : new Thickness(6, 0, 6, 0);
public static bool IsMultiple(int count) => count > 1;
public static bool ReverseIsMultiple(int count) => count < 1;
public static PopupPlacementMode GetPlaccementModeForCalendarType(CalendarDisplayType type)
diff --git a/Wino.Mail.ViewModels/Collections/GroupedEmailCollection.cs b/Wino.Mail.ViewModels/Collections/GroupedEmailCollection.cs
index 72b5bb6e..96076530 100644
--- a/Wino.Mail.ViewModels/Collections/GroupedEmailCollection.cs
+++ b/Wino.Mail.ViewModels/Collections/GroupedEmailCollection.cs
@@ -39,6 +39,7 @@ public partial class GroupedEmailCollection : ObservableObject, IRecipient _groupHeaderIndexCache = [];
private readonly Dictionary> _groupItems = [];
private readonly Dictionary _threadExpanders = [];
+ private readonly HashSet _mailCopyIdHashSet = [];
private bool _disposed;
private bool _isUpdating;
@@ -78,6 +79,11 @@ public partial class GroupedEmailCollection : ObservableObject, IRecipient
public int TotalUnreadCount => _sourceItems.Count(e => e.MailCopy?.IsRead == false);
+ ///
+ /// HashSet containing unique IDs of all mail copies in the collection for pagination tracking
+ ///
+ public HashSet MailCopyIdHashSet => _mailCopyIdHashSet;
+
///
/// Gets all email items across all groups as a flat collection
///
@@ -227,6 +233,9 @@ public partial class GroupedEmailCollection : ObservableObject, IRecipient
public IReadOnlyList 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));
}
diff --git a/Wino.Mail.ViewModels/MailListPageViewModel.cs b/Wino.Mail.ViewModels/MailListPageViewModel.cs
index c2f8e386..7b2c7cf9 100644
--- a/Wino.Mail.ViewModels/MailListPageViewModel.cs
+++ b/Wino.Mail.ViewModels/MailListPageViewModel.cs
@@ -60,14 +60,6 @@ public partial class MailListPageViewModel : MailBaseViewModel,
private IObservable> selectionChangedObservable = null;
public GroupedEmailCollection MailCollection { get; set; } = new GroupedEmailCollection();
-
- //public IEnumerable SelectedItems
- //{
- // get
- // {
-
- // }
- //}
public ObservableCollection SelectedItems { get; set; } = [];
public ObservableCollection PivotFolders { get; set; } = [];
public ObservableCollection 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 GetAvailableMailActions(IEnumerable 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 PrepareMailViewModels(IEnumerable 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 items = null;
- List 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);
diff --git a/Wino.Mail.ViewModels/MailRenderingPageViewModel.cs b/Wino.Mail.ViewModels/MailRenderingPageViewModel.cs
index 2e230a18..f6bfbe12 100644
--- a/Wino.Mail.ViewModels/MailRenderingPageViewModel.cs
+++ b/Wino.Mail.ViewModels/MailRenderingPageViewModel.cs
@@ -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)
{
diff --git a/Wino.Mail.WinUI/AppShell.xaml b/Wino.Mail.WinUI/AppShell.xaml
index 13f7a210..03c810fb 100644
--- a/Wino.Mail.WinUI/AppShell.xaml
+++ b/Wino.Mail.WinUI/AppShell.xaml
@@ -3,7 +3,6 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:abstract="using:Wino.Views.Abstract"
- xmlns:advanced="using:Wino.Controls.Advanced"
xmlns:animatedvisuals="using:Microsoft.UI.Xaml.Controls.AnimatedVisuals"
xmlns:animations="using:CommunityToolkit.WinUI.Animations"
xmlns:controls="using:Wino.Controls"
@@ -356,7 +355,6 @@
diff --git a/Wino.Mail.WinUI/Controls/Advanced/WinoItemsView.cs b/Wino.Mail.WinUI/Controls/Advanced/WinoItemsView.cs
index 5b972551..8772925f 100644
--- a/Wino.Mail.WinUI/Controls/Advanced/WinoItemsView.cs
+++ b/Wino.Mail.WinUI/Controls/Advanced/WinoItemsView.cs
@@ -1,14 +1,46 @@
using System.Collections.Generic;
+using System.Windows.Input;
+using CommunityToolkit.WinUI;
using Microsoft.UI.Xaml.Controls;
namespace Wino.Mail.WinUI.Controls.Advanced;
public partial class WinoItemsView : ItemsView
{
+ private const string PART_ScrollView = nameof(PART_ScrollView);
+
+ private ScrollView? _internalScrollView;
+
+ [GeneratedDependencyProperty]
+ public partial ICommand LoadMoreCommand { get; set; }
+
public IEnumerable