Default theme is back. Container selection functionality etc.

This commit is contained in:
Burak Kaan Köse
2025-10-18 22:16:28 +02:00
parent ad135c5e32
commit ecff97419b
18 changed files with 205 additions and 655 deletions
+1 -1
View File
@@ -17,7 +17,7 @@
<ResourceDictionary Source="Styles/WebViewEditorControl.xaml" />
<styles:WinoExpanderStyle />
<ResourceDictionary Source="/Wino.Core.WinUI/AppThemes/Mica.xaml" />
<ResourceDictionary Source="/Wino.Core.WinUI/AppThemes/Default.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</uwp:WinoApplication.Resources>
@@ -2,6 +2,7 @@
using System.Windows.Input;
using CommunityToolkit.WinUI;
using Microsoft.UI.Xaml.Controls;
using Wino.Mail.ViewModels.Data;
namespace Wino.Mail.WinUI.Controls.Advanced;
@@ -43,4 +44,44 @@ public partial class WinoItemsView : ItemsView
// Trigger when scrolled past 90% of total height
if (progress >= 0.9) LoadMoreCommand?.Execute(null);
}
public bool SelectMailItemContainer(MailItemViewModel mailItemViewModel)
{
return true;
}
/// <summary>
/// Recursively clears all selections except the given mail.
/// </summary>
/// <param name="exceptViewModel">Exceptional mail item to be not unselected.</param>
/// <param name="preserveThreadExpanding">Whether expansion states of thread containers should stay as it is or not.</param>
public void ClearSelections(MailItemViewModel? exceptViewModel = null, bool preserveThreadExpanding = false)
{
if (CastedItemsSource == null) return;
foreach (var item in CastedItemsSource)
{
if (item is MailItemViewModel mailItemViewModel)
{
if (mailItemViewModel != exceptViewModel)
{
mailItemViewModel.IsSelected = false;
}
}
else if (item is ThreadMailItemViewModel threadMailItemViewModel)
{
threadMailItemViewModel.IsSelected = false;
if (!preserveThreadExpanding) threadMailItemViewModel.IsThreadExpanded = false;
foreach (var childMail in threadMailItemViewModel.ThreadEmails)
{
if (childMail != exceptViewModel)
{
childMail.IsSelected = false;
}
}
}
}
}
}
+3 -2
View File
@@ -12,16 +12,17 @@
<!-- SystemBackdrop will be set by NewThemeService -->
<Grid Background="{ThemeResource WinoApplicationBackgroundColor}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.RowSpan="2" Background="{ThemeResource WinoApplicationBackgroundColor}" />
<TitleBar
x:Name="ShellTitleBar"
Title="{x:Bind StatePersistanceService.CoreWindowTitle, Mode=OneWay}"
Margin="-3,-3,0,0"
MinHeight="48"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
BackRequested="BackButtonClicked"
+2 -4
View File
@@ -127,10 +127,7 @@
</DataTemplate>
<DataTemplate x:Key="DateGroupHeaderTemplate" x:DataType="data:DateGroupHeader">
<ItemContainer
CanUserSelect="UserCannotSelect"
IsEnabled="False"
IsHitTestVisible="False">
<ItemContainer CanUserSelect="UserCannotSelect" IsHitTestVisible="False">
<Grid Padding="12,8" Background="{ThemeResource CardBackgroundFillColorDefaultBrush}">
<TextBlock
FontSize="14"
@@ -197,6 +194,7 @@
<AutoSuggestBox
x:Name="SearchBar"
Width="400"
Margin="2,0,-2,0"
VerticalAlignment="Center"
BorderBrush="Transparent"
+65 -43
View File
@@ -98,10 +98,7 @@ public sealed partial class MailListPage : MailListPageAbstract,
SelectAllCheckbox.Unchecked += SelectAllCheckboxUnchecked;
}
private void SelectionModeToggleChecked(object sender, RoutedEventArgs e)
{
ChangeSelectionMode(ListViewSelectionMode.Multiple);
}
private void SelectionModeToggleChecked(object sender, RoutedEventArgs e) => ChangeSelectionMode(ItemsViewSelectionMode.Multiple);
private void FolderPivotChanged(object sender, SelectionChangedEventArgs e)
{
@@ -130,20 +127,19 @@ public sealed partial class MailListPage : MailListPageAbstract,
ViewModel.SelectedPivotChangedCommand.Execute(null);
}
private void ChangeSelectionMode(ListViewSelectionMode mode)
private void ChangeSelectionMode(ItemsViewSelectionMode mode)
{
// ItemsView doesn't have a ChangeSelectionMode method like ListView
// The selection mode is set in XAML and doesn't need to change dynamically for ItemsView
MailListView.SelectionMode = mode;
if (ViewModel?.PivotFolders != null)
{
ViewModel.PivotFolders.ForEach(a => a.IsExtendedMode = mode == ListViewSelectionMode.Extended);
ViewModel.PivotFolders.ForEach(a => a.IsExtendedMode = mode == ItemsViewSelectionMode.Extended);
}
}
private void SelectionModeToggleUnchecked(object sender, RoutedEventArgs e)
{
ChangeSelectionMode(ListViewSelectionMode.Extended);
ChangeSelectionMode(ItemsViewSelectionMode.Extended);
}
private void SelectAllCheckboxChecked(object sender, RoutedEventArgs e)
@@ -306,46 +302,54 @@ public sealed partial class MailListPage : MailListPageAbstract,
{
if (message.SelectedMailViewModel == null) return;
//await ViewModel.ExecuteUIThread(async () =>
//{
// MailListView.ClearSelections(message.SelectedMailViewModel, true);
await ViewModel.ExecuteUIThread(async () =>
{
MailListView.ClearSelections(message.SelectedMailViewModel, true);
// int retriedSelectionCount = 0;
//trySelection:
int retriedSelectionCount = 0;
trySelection:
// bool isSelected = MailListView.SelectMailItemContainer(message.SelectedMailViewModel);
bool isSelected = MailListView.SelectMailItemContainer(message.SelectedMailViewModel);
// if (!isSelected)
// {
// for (int i = retriedSelectionCount; i < 5;)
// {
// // Retry with delay until the container is realized. Max 1 second.
// await Task.Delay(200);
if (!isSelected)
{
for (int i = retriedSelectionCount; i < 5;)
{
// Retry with delay until the container is realized. Max 1 second.
await Task.Delay(200);
// retriedSelectionCount++;
retriedSelectionCount++;
// goto trySelection;
// }
// }
goto trySelection;
}
}
// // Automatically scroll to the selected item.
// // This is useful when creating draft.
// if (isSelected && message.ScrollToItem)
// {
// var collectionContainer = ViewModel.MailCollection.GetMailItemContainer(message.SelectedMailViewModel.UniqueId);
// Automatically scroll to the selected item.
// This is useful when creating draft.
// // Scroll to thread if available.
// if (collectionContainer.ThreadViewModel != null)
// {
// MailListView.StartBringItemIntoView(collectionContainer.ThreadViewModel, new BringIntoViewOptions());
// }
// else if (collectionContainer.ItemViewModel != null)
// {
// MailListView.StartBringItemIntoView(collectionContainer.ItemViewModel, new BringIntoViewOptions());
// }
if (isSelected && message.ScrollToItem)
{
var collectionContainer = ViewModel.MailCollection.GetMailItemContainer(message.SelectedMailViewModel.MailCopy.UniqueId);
// }
//});
// Scroll to thread if available.
// Find the item index on the UI. This is different than ListView.
int scrollIndex = -1;
if (collectionContainer.ThreadViewModel != null)
{
scrollIndex = ViewModel.MailCollection.IndexOf(collectionContainer.ThreadViewModel);
}
else if (collectionContainer.ItemViewModel != null)
{
scrollIndex = ViewModel.MailCollection.IndexOf(collectionContainer.ItemViewModel);
}
if (scrollIndex >= 0)
{
MailListView.StartBringItemIntoView(scrollIndex, new BringIntoViewOptions() { AnimationDesired = true });
}
}
});
}
private void SearchBoxFocused(object sender, RoutedEventArgs e)
@@ -501,8 +505,6 @@ public sealed partial class MailListPage : MailListPageAbstract,
private void DeleteAllInvoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args)
=> ViewModel.ExecuteMailOperationCommand.Execute(MailOperation.SoftDelete);
/// <summary>
/// Animates the rotation using high-performance Composition APIs
/// </summary>
@@ -539,6 +541,26 @@ public sealed partial class MailListPage : MailListPageAbstract,
{
UpdateSelectAllButtonStatus();
UpdateAdaptiveness();
SynchronizeSelectedItems();
}
private static object _selectedItemsLock = new object();
private void SynchronizeSelectedItems()
{
lock (_selectedItemsLock)
{
ViewModel.SelectedItems.Clear();
foreach (var item in MailListView.SelectedItems)
{
if (item is MailItemViewModel mailItem)
{
if (!mailItem.IsSelected) mailItem.IsSelected = true;
if (!ViewModel.SelectedItems.Contains(mailItem)) ViewModel.SelectedItems.Add(mailItem);
}
}
}
}
private void ThreadContainerRightTapped(object sender, RightTappedRoutedEventArgs e)
@@ -151,8 +151,8 @@
<!-- Backdrop Selection -->
<controls:SettingsCard
Description="Choose the backdrop effect for your app window"
Header="Window Backdrop"
Description="{x:Bind domain:Translator.SettingsWindowBackdrop_Description}"
Header="{x:Bind domain:Translator.SettingsWindowBackdrop_Title}"
IsEnabled="{x:Bind ViewModel.CanSelectElementTheme, Mode=OneWay}">
<controls:SettingsCard.HeaderIcon>
<PathIcon Data="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6h-2zm0 8h2v2h-2z" />
@@ -172,6 +172,13 @@
</controls:SettingsCard.Content>
</controls:SettingsCard>
<TextBlock
x:Name="WindowBackdropSelectionDisabledTextBlock"
Margin="4,0,0,0"
x:Load="{x:Bind ViewModel.CanSelectElementTheme, Mode=OneWay, Converter={StaticResource ReverseBooleanConverter}}"
Foreground="{ThemeResource InfoBarWarningSeverityIconBackground}"
Text="{x:Bind domain:Translator.SettingsWindowBackdrop_Disabled}" />
<!-- Mail spacing. -->
<controls:SettingsExpander Description="{x:Bind domain:Translator.SettingsMailSpacing_Description}" Header="{x:Bind domain:Translator.SettingsMailSpacing_Title}">
<controls:SettingsExpander.HeaderIcon>
+1
View File
@@ -112,6 +112,7 @@
<PackageReference Include="Sentry.Serilog" />
<PackageReference Include="sqlite-net-pcl" />
<PackageReference Include="EmailValidation" />
<PackageReference Include="System.Drawing.Common" />
<PackageReference Include="WinUIEx" />
<PackageReference Include="H.NotifyIcon.WinUI" />
</ItemGroup>