diff --git a/Wino.Core.Domain/Interfaces/IPreferencesService.cs b/Wino.Core.Domain/Interfaces/IPreferencesService.cs
index 505b309c..c5c377ea 100644
--- a/Wino.Core.Domain/Interfaces/IPreferencesService.cs
+++ b/Wino.Core.Domain/Interfaces/IPreferencesService.cs
@@ -155,5 +155,10 @@ namespace Wino.Core.Domain.Interfaces
/// Setting: Gets or sets what should happen to server app when the client is terminated.
///
ServerBackgroundMode ServerTerminationBehavior { get; set; }
+
+ ///
+ /// Setting: Whether the mail list action bar is enabled or not.
+ ///
+ bool IsMailListActionBarEnabled { get; set; }
}
}
diff --git a/Wino.Core.Domain/Translations/en_US/resources.json b/Wino.Core.Domain/Translations/en_US/resources.json
index c0739152..807d8b08 100644
--- a/Wino.Core.Domain/Translations/en_US/resources.json
+++ b/Wino.Core.Domain/Translations/en_US/resources.json
@@ -519,7 +519,7 @@
"SettingsRenameMergeAccount_Title": "Rename",
"SettingsSemanticZoom_Description": "This will allow you to click on the headers in messages list and go to specific date",
"SettingsSemanticZoom_Title": "Semantic Zoom for Date Headers",
- "SettingsShowPreviewText_Description": "Hide/show thepreview text.",
+ "SettingsShowPreviewText_Description": "Hide/show the preview text.",
"SettingsShowPreviewText_Title": "Show Preview Text",
"SettingsShowSenderPictures_Description": "Hide/show the thumbnail sender pictures.",
"SettingsShowSenderPictures_Title": "Show Sender Avatars",
@@ -533,7 +533,9 @@
"SettingsStore_Title": "Rate in Store",
"SettingsThreads_Description": "Organize messages into conversation threads.",
"SettingsThreads_Title": "Conversation Threading",
- "SettingsUnlinkAccounts_Description": "Remove the link between accounts. This will not delete your accounts.",
+ "SettingsMailListActionBar_Description": "Hide/show action bar at top of message list.",
+ "SettingsMailListActionBar_Title": "Show mail list actions",
+ "SettingsUnlinkAccounts_Description": "Remove the link between accounts. his will not delete your accounts.",
"SettingsUnlinkAccounts_Title": "Unlink Accounts",
"SortingOption_Date": "by date",
"SortingOption_Name": "by name",
diff --git a/Wino.Core.Domain/Translator.Designer.cs b/Wino.Core.Domain/Translator.Designer.cs
index 4f086782..ca031f72 100644
--- a/Wino.Core.Domain/Translator.Designer.cs
+++ b/Wino.Core.Domain/Translator.Designer.cs
@@ -2619,7 +2619,7 @@ namespace Wino.Core.Domain
public static string SettingsSemanticZoom_Title => Resources.GetTranslatedString(@"SettingsSemanticZoom_Title");
///
- /// Hide/show thepreview text.
+ /// Hide/show the preview text.
///
public static string SettingsShowPreviewText_Description => Resources.GetTranslatedString(@"SettingsShowPreviewText_Description");
@@ -2689,7 +2689,17 @@ namespace Wino.Core.Domain
public static string SettingsThreads_Title => Resources.GetTranslatedString(@"SettingsThreads_Title");
///
- /// Remove the link between accounts. This will not delete your accounts.
+ /// Hide/show action bar at top of message list.
+ ///
+ public static string SettingsMailListActionBar_Description => Resources.GetTranslatedString(@"SettingsMailListActionBar_Description");
+
+ ///
+ /// Show mail list actions
+ ///
+ public static string SettingsMailListActionBar_Title => Resources.GetTranslatedString(@"SettingsMailListActionBar_Title");
+
+ ///
+ /// Remove the link between accounts. his will not delete your accounts.
///
public static string SettingsUnlinkAccounts_Description => Resources.GetTranslatedString(@"SettingsUnlinkAccounts_Description");
diff --git a/Wino.Core.UWP/Services/PreferencesService.cs b/Wino.Core.UWP/Services/PreferencesService.cs
index 7d77aef5..d7826f0e 100644
--- a/Wino.Core.UWP/Services/PreferencesService.cs
+++ b/Wino.Core.UWP/Services/PreferencesService.cs
@@ -64,6 +64,12 @@ namespace Wino.Core.UWP.Services
set => SetPropertyAndSave(nameof(IsThreadingEnabled), value);
}
+ public bool IsMailListActionBarEnabled
+ {
+ get => _configurationService.Get(nameof(IsMailListActionBarEnabled), false);
+ set => SetPropertyAndSave(nameof(IsMailListActionBarEnabled), value);
+ }
+
public bool IsShowSenderPicturesEnabled
{
get => _configurationService.Get(nameof(IsShowSenderPicturesEnabled), true);
diff --git a/Wino.Core/Services/ContextMenuItemService.cs b/Wino.Core/Services/ContextMenuItemService.cs
index 3c1040fe..e6238e8f 100644
--- a/Wino.Core/Services/ContextMenuItemService.cs
+++ b/Wino.Core/Services/ContextMenuItemService.cs
@@ -80,27 +80,26 @@ namespace Wino.Core.Services
}
else
{
- bool isAllFlagged = selectedMailItems.All(a => a.IsFlagged);
bool isAllRead = selectedMailItems.All(a => a.IsRead);
bool isAllUnread = selectedMailItems.All(a => !a.IsRead);
+ bool isAllFlagged = selectedMailItems.All(a => a.IsFlagged);
+ bool isAllNotFlagged = selectedMailItems.All(a => !a.IsFlagged);
- if (isAllRead)
- operationList.Add(MailOperationMenuItem.Create(MailOperation.MarkAsUnread));
- else
+ List readOperations = (isAllRead, isAllUnread) switch
{
- if (!isAllUnread)
- operationList.Add(MailOperationMenuItem.Create(MailOperation.MarkAsUnread));
+ (true, false) => [MailOperationMenuItem.Create(MailOperation.MarkAsUnread)],
+ (false, true) => [MailOperationMenuItem.Create(MailOperation.MarkAsRead)],
+ _ => [MailOperationMenuItem.Create(MailOperation.MarkAsRead), MailOperationMenuItem.Create(MailOperation.MarkAsUnread)]
+ };
+ operationList.AddRange(readOperations);
- operationList.Add(MailOperationMenuItem.Create(MailOperation.MarkAsRead));
- }
-
- if (isAllFlagged)
- operationList.Add(MailOperationMenuItem.Create(MailOperation.ClearFlag));
- else
+ List flagsOperations = (isAllFlagged, isAllNotFlagged) switch
{
- operationList.Add(MailOperationMenuItem.Create(MailOperation.ClearFlag));
- operationList.Add(MailOperationMenuItem.Create(MailOperation.SetFlag));
- }
+ (true, false) => [MailOperationMenuItem.Create(MailOperation.ClearFlag)],
+ (false, true) => [MailOperationMenuItem.Create(MailOperation.SetFlag)],
+ _ => [MailOperationMenuItem.Create(MailOperation.SetFlag), MailOperationMenuItem.Create(MailOperation.ClearFlag)]
+ };
+ operationList.AddRange(flagsOperations);
}
// Ignore
diff --git a/Wino.Mail.ViewModels/MailListPageViewModel.cs b/Wino.Mail.ViewModels/MailListPageViewModel.cs
index a09c3d67..47dedbd2 100644
--- a/Wino.Mail.ViewModels/MailListPageViewModel.cs
+++ b/Wino.Mail.ViewModels/MailListPageViewModel.cs
@@ -41,8 +41,7 @@ namespace Wino.Mail.ViewModels
IRecipient,
IRecipient,
IRecipient,
- IRecipient,
- IRecipient
+ IRecipient
{
private bool isChangingFolder = false;
@@ -63,6 +62,7 @@ namespace Wino.Mail.ViewModels
public ObservableCollection SelectedItems { get; set; } = [];
public ObservableCollection PivotFolders { get; set; } = [];
+ public ObservableCollection ActionItems { get; set; } = [];
private readonly SemaphoreSlim listManipulationSemepahore = new SemaphoreSlim(1);
private CancellationTokenSource listManipulationCancellationTokenSource = new CancellationTokenSource();
@@ -200,6 +200,13 @@ namespace Wino.Mail.ViewModels
};
}
+ private void SetupTopBarActions()
+ {
+ ActionItems.Clear();
+ var actions = GetAvailableMailActions(SelectedItems);
+ actions.ForEach(a => ActionItems.Add(a));
+ }
+
#region Properties
///
@@ -365,7 +372,7 @@ namespace Wino.Mail.ViewModels
NotifyItemSelected();
- Messenger.Send(new SelectedMailItemsChanged(SelectedItems.Count));
+ SetupTopBarActions();
}
private void UpdateFolderPivots()
@@ -415,19 +422,31 @@ namespace Wino.Mail.ViewModels
[RelayCommand]
public Task ExecuteHoverAction(MailOperationPreperationRequest request) => ExecuteMailOperationAsync(request);
+ [RelayCommand]
+ private async Task ExecuteTopBarAction(MailOperationMenuItem menuItem)
+ {
+ if (menuItem == null || !SelectedItems.Any()) return;
+
+ await HandleMailOperation(menuItem.Operation, SelectedItems);
+ }
+
///
/// Executes the requested mail operation for currently selected items.
///
/// Action to execute for selected items.
[RelayCommand]
- private async Task MailOperationAsync(int mailOperationIndex)
+ private async Task ExecuteMailOperation(MailOperation mailOperation)
{
if (!SelectedItems.Any()) return;
- // Commands don't like enums. So it has to be int.
- var operation = (MailOperation)mailOperationIndex;
+ await HandleMailOperation(mailOperation, SelectedItems);
+ }
- var package = new MailOperationPreperationRequest(operation, SelectedItems.Select(a => a.MailCopy));
+ private async Task HandleMailOperation(MailOperation mailOperation, IEnumerable mailItems)
+ {
+ if (!mailItems.Any()) return;
+
+ var package = new MailOperationPreperationRequest(mailOperation, mailItems.Select(a => a.MailCopy));
await ExecuteMailOperationAsync(package);
}
@@ -649,6 +668,8 @@ namespace Wino.Mail.ViewModels
Debug.WriteLine($"Updating {updatedMail.Id}-> {updatedMail.UniqueId}");
await MailCollection.UpdateMailCopy(updatedMail);
+
+ await ExecuteUIThread(() => { SetupTopBarActions(); });
}
protected override async void OnMailRemoved(MailCopy removedMail)
@@ -1012,7 +1033,5 @@ namespace Wino.Mail.ViewModels
await ExecuteUIThread(() => { IsAccountSynchronizerInSynchronization = isAnyAccountSynchronizing; });
}
-
- public void Receive(SelectedMailItemsChanged message) => NotifyItemSelected();
}
}
diff --git a/Wino.Mail/App.xaml b/Wino.Mail/App.xaml
index bf1fe890..91b2d0b2 100644
--- a/Wino.Mail/App.xaml
+++ b/Wino.Mail/App.xaml
@@ -11,6 +11,8 @@
+
+
diff --git a/Wino.Mail/Controls/Advanced/WinoListView.cs b/Wino.Mail/Controls/Advanced/WinoListView.cs
index 10f215da..764084e2 100644
--- a/Wino.Mail/Controls/Advanced/WinoListView.cs
+++ b/Wino.Mail/Controls/Advanced/WinoListView.cs
@@ -120,7 +120,7 @@ namespace Wino.Controls.Advanced
{
args.Handled = true;
- ItemDeletedCommand?.Execute((int)MailOperation.SoftDelete);
+ ItemDeletedCommand?.Execute(MailOperation.SoftDelete);
}
}
diff --git a/Wino.Mail/Controls/WinoPivotControl.xaml b/Wino.Mail/Controls/WinoPivotControl.xaml
deleted file mode 100644
index a524e6d3..00000000
--- a/Wino.Mail/Controls/WinoPivotControl.xaml
+++ /dev/null
@@ -1,123 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Wino.Mail/Controls/WinoPivotControl.xaml.cs b/Wino.Mail/Controls/WinoPivotControl.xaml.cs
deleted file mode 100644
index 975871bc..00000000
--- a/Wino.Mail/Controls/WinoPivotControl.xaml.cs
+++ /dev/null
@@ -1,195 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Numerics;
-using System.Runtime.InteropServices.WindowsRuntime;
-using System.Threading.Tasks;
-using Windows.Foundation;
-using Windows.Foundation.Collections;
-using Windows.UI;
-using Windows.UI.Composition;
-using Windows.UI.Xaml;
-using Windows.UI.Xaml.Controls;
-using Windows.UI.Xaml.Controls.Primitives;
-using Windows.UI.Xaml.Data;
-using Windows.UI.Xaml.Input;
-using Windows.UI.Xaml.Media;
-using Windows.UI.Xaml.Navigation;
-using Wino.Extensions;
-
-namespace Wino.Controls
-{
- // TODO: Memory leak with FolderPivot bindings.
- public sealed partial class WinoPivotControl : UserControl
- {
- private Compositor _compositor;
- private ShapeVisual _shapeVisual;
- private CompositionSpriteShape _spriteShape;
- private CompositionRoundedRectangleGeometry _roundedRectangle;
-
- public event EventHandler SelectionChanged;
-
- public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register(nameof(SelectedItem), typeof(object), typeof(WinoPivotControl), new PropertyMetadata(null));
- public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(nameof(ItemsSource), typeof(object), typeof(WinoPivotControl), new PropertyMetadata(null));
- public static readonly DependencyProperty SelectorPipeColorProperty = DependencyProperty.Register(nameof(SelectorPipeColor), typeof(SolidColorBrush), typeof(WinoPivotControl), new PropertyMetadata(Colors.Transparent, OnSelectorPipeColorChanged));
- public static readonly DependencyProperty DataTemplateProperty = DependencyProperty.Register(nameof(DataTemplate), typeof(DataTemplate), typeof(WinoPivotControl), new PropertyMetadata(null));
-
- public DataTemplate DataTemplate
- {
- get { return (DataTemplate)GetValue(DataTemplateProperty); }
- set { SetValue(DataTemplateProperty, value); }
- }
-
- public SolidColorBrush SelectorPipeColor
- {
- get { return (SolidColorBrush)GetValue(SelectorPipeColorProperty); }
- set { SetValue(SelectorPipeColorProperty, value); }
- }
-
- public object SelectedItem
- {
- get { return (object)GetValue(SelectedItemProperty); }
- set { SetValue(SelectedItemProperty, value); }
- }
-
- public object ItemsSource
- {
- get { return (object)GetValue(ItemsSourceProperty); }
- set { SetValue(ItemsSourceProperty, value); }
- }
-
- private static void OnSelectorPipeColorChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
- {
- if (obj is WinoPivotControl control)
- {
- control.UpdateSelectorPipeColor();
- }
- }
-
- private void UpdateSelectorPipeColor()
- {
- if (_spriteShape != null && _compositor != null)
- {
- _spriteShape.FillBrush = _compositor.CreateColorBrush(SelectorPipeColor.Color);
- }
- }
-
- private void CreateSelectorVisuals()
- {
- _compositor = this.Visual().Compositor;
-
- _roundedRectangle = _compositor.CreateRoundedRectangleGeometry();
- _roundedRectangle.CornerRadius = new Vector2(3, 3);
-
- _spriteShape = _compositor.CreateSpriteShape(_roundedRectangle);
- _spriteShape.CenterPoint = new Vector2(100, 100);
-
- _shapeVisual = _compositor.CreateShapeVisual();
-
- _shapeVisual.Shapes.Clear();
- _shapeVisual.Shapes.Add(_spriteShape);
-
- SelectorPipe.SetChildVisual(_shapeVisual);
-
- _shapeVisual.EnableImplicitAnimation(VisualPropertyType.Size, 400);
- }
-
- public WinoPivotControl()
- {
- this.InitializeComponent();
-
- CreateSelectorVisuals();
- }
-
- private bool IsContainerPresent()
- {
- return SelectedItem != null && PivotHeaders.ContainerFromItem(SelectedItem) != null;
- }
-
- private void PivotHeaders_SelectionChanged(object sender, SelectionChangedEventArgs e)
- {
- UpdateVisuals();
-
- SelectionChanged?.Invoke(sender, e);
- }
-
- private void UpdateVisuals()
- {
- MoveSelector();
- }
-
- private void UpdateSelectorVisibility()
- {
- SelectorPipe.Visibility = IsContainerPresent() ? Visibility.Visible : Visibility.Collapsed;
- }
-
- private async void MoveSelector()
- {
- if (PivotHeaders.SelectedItem != null)
- {
- // Get selected item container position
- // TODO: It's bad...
- while(PivotHeaders.ContainerFromItem(PivotHeaders.SelectedItem) == null)
- {
- await Task.Delay(100);
- }
-
- UpdateSelectorVisibility();
-
- var container = PivotHeaders.ContainerFromItem(PivotHeaders.SelectedItem) as FrameworkElement;
-
- if (container != null)
- {
- var transformToVisual = container.TransformToVisual(this);
- Point screenCoords = transformToVisual.TransformPoint(new Point(0, 0));
-
- float actualWidth = 0, leftMargin = 0, translateX = 0;
-
- leftMargin = (float)(screenCoords.X);
-
- if (PivotHeaders.Items.Count > 1)
- {
- // Multiple items, pipe is centered.
-
- actualWidth = (float)(container.ActualWidth + 12) / 2;
- translateX = leftMargin - 10 + (actualWidth / 2);
- }
- else
- {
- actualWidth = (float)(container.ActualWidth) - 12;
- translateX = leftMargin + 4;
- }
-
- SelectorPipe.Width = actualWidth;
- SelectorPipe.Translation = new Vector3(translateX, 0, 0);
- }
- else
- {
- Debug.WriteLine("Container null");
- }
- }
- }
-
- private void SelectorPipeSizeChanged(object sender, SizeChangedEventArgs e)
- {
- _roundedRectangle.Size = e.NewSize.ToVector2();
- _shapeVisual.Size = e.NewSize.ToVector2();
- }
-
- private void ControlUnloaded(object sender, RoutedEventArgs e)
- {
- //PivotHeaders.SelectionChanged -= PivotHeaders_SelectionChanged;
- //PivotHeaders.SelectedItem = null;
-
- //SelectedItem = null;
- //ItemsSource = null;
- }
-
- private void ControlLoaded(object sender, RoutedEventArgs e)
- {
- // Bindings.Update();
- }
- }
-}
diff --git a/Wino.Mail/Extensions/EnumerableExtensions.cs b/Wino.Mail/Extensions/EnumerableExtensions.cs
deleted file mode 100644
index 4d94a9be..00000000
--- a/Wino.Mail/Extensions/EnumerableExtensions.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Collections;
-
-namespace Wino.Extensions
-{
- public static class EnumerableExtensions
- {
- public static IEnumerable OfType(this IEnumerable source)
- {
- foreach (object item in source)
- {
- if (item is T1 || item is T2)
- {
- yield return item;
- }
- }
- }
- }
-}
diff --git a/Wino.Mail/Views/MailListPage.xaml b/Wino.Mail/Views/MailListPage.xaml
index 61328647..e7ec8e49 100644
--- a/Wino.Mail/Views/MailListPage.xaml
+++ b/Wino.Mail/Views/MailListPage.xaml
@@ -5,7 +5,6 @@
xmlns:abstract="using:Wino.Views.Abstract"
xmlns:collections="using:CommunityToolkit.Mvvm.Collections"
xmlns:controls="using:Wino.Controls"
- xmlns:controls1="using:CommunityToolkit.WinUI.Controls"
xmlns:converters="using:Wino.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:domain="using:Wino.Core.Domain"
@@ -13,11 +12,14 @@
xmlns:helpers="using:Wino.Helpers"
xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
+ xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:listview="using:Wino.Controls.Advanced"
+ xmlns:local="using:Wino.Behaviors"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:menuflyouts="using:Wino.MenuFlyouts"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
xmlns:selectors="using:Wino.Selectors"
+ xmlns:toolkit="using:CommunityToolkit.WinUI.Controls"
xmlns:ui="using:Microsoft.Toolkit.Uwp.UI"
xmlns:viewModelData="using:Wino.Mail.ViewModels.Data"
xmlns:wino="using:Wino"
@@ -31,6 +33,28 @@
IsSourceGrouped="True"
Source="{x:Bind ViewModel.MailCollection.MailItems, Mode=OneWay}" />
+
+
0,0,0,0
0,0,12,0
0,0,0,0
@@ -45,23 +69,10 @@
-
-
-
-
-
-
-
-
-
@@ -208,28 +219,6 @@
Transparent
-
-
-
-
@@ -272,7 +261,7 @@
-
+
+ Visibility="{x:Bind ViewModel.PreferencesService.IsMailListActionBarEnabled}">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+ MinWidth="0"
+ Margin="8,0,0,0"
+ VerticalAlignment="Center"
+ Canvas.ZIndex="100"
+ Checked="SelectAllCheckboxChecked"
+ Unchecked="SelectAllCheckboxUnchecked"
+ Visibility="{x:Bind helpers:XamlHelpers.IsSelectionModeMultiple(MailListView.SelectionMode), Mode=OneWay}" />
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
@@ -502,20 +395,20 @@
SortingOptions="{x:Bind ViewModel.SortingOptions, Mode=OneTime}" />
+
-
-
-
-
-
-
+
+
+
+
+
@@ -574,7 +467,7 @@
ui:ListViewExtensions.ItemContainerStretchDirection="Horizontal"
ui:ScrollViewerExtensions.EnableMiddleClickScrolling="True"
ui:ScrollViewerExtensions.VerticalScrollBarMargin="0"
- ItemDeletedCommand="{x:Bind ViewModel.MailOperationCommand}"
+ ItemDeletedCommand="{x:Bind ViewModel.ExecuteMailOperationCommand}"
ItemTemplateSelector="{StaticResource MailItemDisplaySelector}"
ItemsSource="{x:Bind MailCollectionViewSource.View, Mode=OneWay}"
LoadMoreCommand="{x:Bind ViewModel.LoadMoreItemsCommand}"
@@ -615,10 +508,7 @@
-
+
-
+
+
+
+
+
+
+
diff --git a/Wino.Mail/Wino.Mail.csproj b/Wino.Mail/Wino.Mail.csproj
index ee8dbb55..6a741eff 100644
--- a/Wino.Mail/Wino.Mail.csproj
+++ b/Wino.Mail/Wino.Mail.csproj
@@ -141,6 +141,9 @@
8.1.240821
+
+ 8.1.240821
+
8.1.240821
@@ -265,9 +268,6 @@
-
- WinoPivotControl.xaml
-
AccountCreationDialog.xaml
@@ -276,7 +276,6 @@
-
@@ -456,10 +455,6 @@
Designer
MSBuild:Compile
-
- Designer
- MSBuild:Compile
-
Designer
MSBuild:Compile
diff --git a/Wino.Messages/Client/Mails/SelectedMailItemsChanged.cs b/Wino.Messages/Client/Mails/SelectedMailItemsChanged.cs
deleted file mode 100644
index 11ca361f..00000000
--- a/Wino.Messages/Client/Mails/SelectedMailItemsChanged.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Wino.Messaging.Client.Mails
-{
- ///
- /// When selected mail count is changed.
- ///
- /// New selected mail count.
- public record SelectedMailItemsChanged(int SelectedItemCount);
-}