Create sub folder, delete folder, storage settings, some ui adjustments on threads.

This commit is contained in:
Burak Kaan Köse
2026-02-07 19:47:21 +01:00
parent 2cd03d5fec
commit 5bfa61a218
30 changed files with 900 additions and 58 deletions
+65 -3
View File
@@ -21,6 +21,7 @@ using Wino.Mail.Services;
using Wino.Mail.ViewModels;
using Wino.Mail.WinUI.Interfaces;
using Wino.Mail.WinUI.Services;
using Wino.Messaging.UI;
using Wino.Messaging.Client.Accounts;
using Wino.Messaging.Server;
using Wino.Services;
@@ -92,7 +93,6 @@ public partial class App : WinoApplication,
services.AddTransient(typeof(AliasManagementPageViewModel));
services.AddTransient(typeof(ContactsPageViewModel));
services.AddTransient(typeof(SignatureAndEncryptionPageViewModel));
services.AddTransient(typeof(CalendarPageViewModel));
services.AddTransient(typeof(CalendarSettingsPageViewModel));
services.AddTransient(typeof(CalendarAccountSettingsPageViewModel));
@@ -362,8 +362,70 @@ public partial class App : WinoApplication,
WeakReferenceMessenger.Default.Register<NewCalendarSynchronizationRequested>(this);
}
public void Receive(NewMailSynchronizationRequested message) => _synchronizationManager?.SynchronizeMailAsync(message.Options);
public void Receive(NewCalendarSynchronizationRequested message) => _synchronizationManager?.SynchronizeCalendarAsync(message.Options);
public async void Receive(NewMailSynchronizationRequested message)
{
if (_synchronizationManager == null) return;
MailSynchronizationResult syncResult;
try
{
syncResult = await _synchronizationManager.SynchronizeMailAsync(message.Options);
}
catch (Exception ex)
{
// Defensive fallback to guarantee completion message emission.
syncResult = MailSynchronizationResult.Failed(ex);
}
WeakReferenceMessenger.Default.Send(new AccountSynchronizationCompleted(
message.Options.AccountId,
syncResult.CompletedState,
message.Options.GroupedSynchronizationTrackingId));
if (syncResult.CompletedState == SynchronizationCompletedState.Failed ||
syncResult.CompletedState == SynchronizationCompletedState.PartiallyCompleted)
{
var dialogService = Services.GetRequiredService<IMailDialogService>();
var errorMessage = GetSynchronizationFailureMessage(message.Options.Type, syncResult.Exception?.Message);
var severity = syncResult.CompletedState == SynchronizationCompletedState.PartiallyCompleted
? InfoBarMessageType.Warning
: InfoBarMessageType.Error;
dialogService.InfoBarMessage(Translator.Info_SyncFailedTitle, errorMessage, severity);
}
}
public async void Receive(NewCalendarSynchronizationRequested message)
{
if (_synchronizationManager == null) return;
var calendarSyncResult = await _synchronizationManager.SynchronizeCalendarAsync(message.Options);
if (calendarSyncResult.CompletedState == SynchronizationCompletedState.Failed)
{
var dialogService = Services.GetRequiredService<IMailDialogService>();
dialogService.InfoBarMessage(
Translator.Info_SyncFailedTitle,
Translator.Exception_FailedToSynchronizeFolders,
InfoBarMessageType.Error);
}
}
private static string GetSynchronizationFailureMessage(MailSynchronizationType synchronizationType, string? exceptionMessage)
{
if (!string.IsNullOrWhiteSpace(exceptionMessage))
{
return exceptionMessage;
}
return synchronizationType switch
{
MailSynchronizationType.Alias => Translator.Exception_FailedToSynchronizeAliases,
MailSynchronizationType.UpdateProfile => Translator.Exception_FailedToSynchronizeProfileInformation,
_ => Translator.Exception_FailedToSynchronizeFolders
};
}
/// <summary>
/// Handles activation redirected from another instance (single-instancing).
@@ -66,6 +66,7 @@ public class NavigationService : NavigationServiceBase, INavigationService
WinoPage.KeyboardShortcutsPage => typeof(KeyboardShortcutsPage),
WinoPage.ContactsPage => typeof(ContactsPage),
WinoPage.SignatureAndEncryptionPage => typeof(SignatureAndEncryptionPage),
WinoPage.StoragePage => typeof(StoragePage),
WinoPage.CalendarPage => typeof(CalendarPage),
WinoPage.EventDetailsPage => typeof(EventDetailsPage),
WinoPage.CalendarSettingsPage => typeof(CalendarSettingsPage),
@@ -15,14 +15,14 @@
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="F1 M 0 9.375 C 0 8.509115 0.110677 7.677409 0.332031 6.879883 C 0.553385 6.082357 0.867513 5.335287 1.274414 4.638672 C 1.681315 3.942059 2.169596 3.30892 2.739258 2.739258 C 3.308919 2.169598 3.942057 1.681316 4.638672 1.274414 C 5.335286 0.867514 6.082356 0.553387 6.879883 0.332031 C 7.677409 0.110678 8.509114 0 9.375 0 C 10.240885 0 11.072591 0.110678 11.870117 0.332031 C 12.667643 0.553387 13.414713 0.867514 14.111328 1.274414 C 14.807942 1.681316 15.44108 2.169598 16.010742 2.739258 C 16.580402 3.30892 17.068684 3.942059 17.475586 4.638672 C 17.882486 5.335287 18.196613 6.082357 18.417969 6.879883 C 18.639322 7.677409 18.75 8.509115 18.75 9.375 C 18.75 10.240886 18.637695 11.072592 18.413086 11.870117 C 18.188477 12.667644 17.872721 13.413086 17.46582 14.106445 C 17.058918 14.799805 16.570637 15.431315 16.000977 16.000977 C 15.431314 16.570639 14.799804 17.05892 14.106445 17.46582 C 13.413085 17.872721 12.666015 18.188477 11.865234 18.413086 C 11.064453 18.637695 10.234375 18.75 9.375 18.75 C 8.509114 18.75 7.675781 18.639322 6.875 18.417969 C 6.074219 18.196615 5.327148 17.882486 4.633789 17.475586 C 3.94043 17.068686 3.308919 16.580404 2.739258 16.010742 C 2.169596 15.441081 1.681315 14.80957 1.274414 14.116211 C 0.867513 13.422852 0.553385 12.675781 0.332031 11.875 C 0.110677 11.074219 0 10.240886 0 9.375 Z M 17.5 9.375 C 17.5 8.626303 17.403971 7.905273 17.211914 7.211914 C 17.019855 6.518556 16.746418 5.87077 16.391602 5.268555 C 16.036783 4.666342 15.613606 4.119467 15.12207 3.62793 C 14.630533 3.136395 14.083658 2.713217 13.481445 2.358398 C 12.879231 2.003582 12.231445 1.730145 11.538086 1.538086 C 10.844727 1.346029 10.123697 1.25 9.375 1.25 C 8.626302 1.25 7.905273 1.346029 7.211914 1.538086 C 6.518555 1.730145 5.870768 2.003582 5.268555 2.358398 C 4.666341 2.713217 4.119466 3.136395 3.62793 3.62793 C 3.136393 4.119467 2.713216 4.666342 2.358398 5.268555 C 2.003581 5.87077 1.730143 6.518556 1.538086 7.211914 C 1.346029 7.905273 1.25 8.626303 1.25 9.375 C 1.25 10.123698 1.346029 10.844727 1.538086 11.538086 C 1.730143 12.231445 2.001953 12.879232 2.353516 13.481445 C 2.705078 14.083659 3.128255 14.632162 3.623047 15.126953 C 4.117838 15.621745 4.666341 16.044922 5.268555 16.396484 C 5.870768 16.748047 6.518555 17.019857 7.211914 17.211914 C 7.905273 17.403971 8.626302 17.5 9.375 17.5 C 10.123697 17.5 10.844727 17.403971 11.538086 17.211914 C 12.231445 17.019857 12.879231 16.748047 13.481445 16.396484 C 14.083658 16.044922 14.63216 15.621745 15.126953 15.126953 C 15.621744 14.632162 16.044922 14.083659 16.396484 13.481445 C 16.748047 12.879232 17.019855 12.231445 17.211914 11.538086 C 17.403971 10.844727 17.5 10.123698 17.5 9.375 Z M 8.4375 5.625 C 8.4375 5.364584 8.528646 5.14323 8.710938 4.960938 C 8.893229 4.778646 9.114583 4.6875 9.375 4.6875 C 9.635416 4.6875 9.856771 4.778646 10.039062 4.960938 C 10.221354 5.14323 10.3125 5.364584 10.3125 5.625 C 10.3125 5.885417 10.221354 6.106771 10.039062 6.289062 C 9.856771 6.471354 9.635416 6.5625 9.375 6.5625 C 9.114583 6.5625 8.893229 6.471354 8.710938 6.289062 C 8.528646 6.106771 8.4375 5.885417 8.4375 5.625 Z M 8.75 13.125 L 8.75 8.125 C 8.75 7.95573 8.811849 7.809246 8.935547 7.685547 C 9.059244 7.56185 9.205729 7.5 9.375 7.5 C 9.544271 7.5 9.690755 7.56185 9.814453 7.685547 C 9.93815 7.809246 10 7.95573 10 8.125 L 10 13.125 C 10 13.294271 9.93815 13.440756 9.814453 13.564453 C 9.690755 13.688151 9.544271 13.75 9.375 13.75 C 9.205729 13.75 9.059244 13.688151 8.935547 13.564453 C 8.811849 13.440756 8.75 13.294271 8.75 13.125 Z "
Fill="#0f80d7" />
Fill="{ThemeResource SystemAccentColor}" />
</DataTemplate>
<DataTemplate x:Key="WinoCustomMessageDialogQuestionIconTemplate">
<Path
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8m8-6.5a6.5 6.5 0 1 0 0 13a6.5 6.5 0 0 0 0-13M6.92 6.085h.001a.749.749 0 1 1-1.342-.67c.169-.339.436-.701.849-.977C6.845 4.16 7.369 4 8 4a2.76 2.76 0 0 1 1.637.525c.503.377.863.965.863 1.725c0 .448-.115.83-.329 1.15c-.205.307-.47.513-.692.662c-.109.072-.22.138-.313.195l-.006.004a6 6 0 0 0-.26.16a1 1 0 0 0-.276.245a.75.75 0 0 1-1.248-.832c.184-.264.42-.489.692-.661q.154-.1.313-.195l.007-.004c.1-.061.182-.11.258-.161a1 1 0 0 0 .277-.245C8.96 6.514 9 6.427 9 6.25a.61.61 0 0 0-.262-.525A1.27 1.27 0 0 0 8 5.5c-.369 0-.595.09-.74.187a1 1 0 0 0-.34.398M9 11a1 1 0 1 1-2 0a1 1 0 0 1 2 0"
Fill="#0984e3" />
Fill="{ThemeResource SystemAccentColor}" />
</DataTemplate>
<DataTemplate x:Key="WinoCustomMessageDialogWarningIconTemplate">
<Path
@@ -59,8 +59,8 @@
</Grid.RowDefinitions>
<!-- Title -->
<StackPanel Orientation="Horizontal" Spacing="12">
<Viewbox Width="28" HorizontalAlignment="Left">
<StackPanel Orientation="Horizontal" Spacing="8">
<Viewbox Width="22" HorizontalAlignment="Left">
<ContentControl Content="{x:Bind Icon}" ContentTemplateSelector="{StaticResource CustomWinoMessageDialogIconSelector}" />
</Viewbox>
@@ -0,0 +1,6 @@
using Wino.Mail.ViewModels;
using Wino.Mail.WinUI;
namespace Wino.Views.Abstract;
public abstract class StoragePageAbstract : BasePage<StoragePageViewModel> { }
+3 -2
View File
@@ -210,14 +210,14 @@
<Border
x:Name="MailListContainer"
Grid.Column="0"
Margin="2"
Margin="6,2"
Padding="5,5,5,0"
HorizontalAlignment="Stretch"
Background="{ThemeResource WinoContentZoneBackgroud}"
BorderBrush="{StaticResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="{ThemeResource OverlayCornerRadius}"
Translation="0,0,50">
Translation="0,0,20">
<Border.Shadow>
<ThemeShadow />
</Border.Shadow>
@@ -421,6 +421,7 @@
HorizontalContentAlignment="Stretch"
toolkitExt:ListViewExtensions.ItemContainerStretchDirection="Horizontal"
toolkitExt:ScrollViewerExtensions.VerticalScrollBarMargin="0"
CanDragItems="True"
ChoosingItemContainer="WinoListViewChoosingItemContainer"
IsItemClickEnabled="True"
ItemClick="WinoListViewItemClicked"
@@ -409,6 +409,38 @@
Glyph="&#xE76C;" />
</Grid>
</Button>
<Button
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Background="Transparent"
BorderThickness="0"
Click="SettingOptionClicked"
CornerRadius="4"
Tag="{x:Bind enums:WinoPage.StoragePage}">
<Grid Padding="4,10" ColumnSpacing="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<FontIcon
VerticalAlignment="Center"
FontSize="16"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Glyph="&#xE81C;" />
<TextBlock
Grid.Column="1"
VerticalAlignment="Center"
Text="{x:Bind domain:Translator.SettingsStorage_Title}" />
<FontIcon
Grid.Column="2"
VerticalAlignment="Center"
FontSize="12"
Foreground="{ThemeResource TextFillColorTertiaryBrush}"
Glyph="&#xE76C;" />
</Grid>
</Button>
</StackPanel>
</Grid>
@@ -0,0 +1,113 @@
<abstract:StoragePageAbstract
x:Class="Wino.Views.Settings.StoragePage"
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:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:coreControls="using:Wino.Mail.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:domain="using:Wino.Core.Domain"
xmlns:helpers="using:Wino.Helpers"
xmlns:mailData="using:Wino.Mail.ViewModels.Data"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="root"
mc:Ignorable="d">
<ScrollViewer>
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<Grid
Padding="16"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="{ThemeResource OverlayCornerRadius}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Spacing="12">
<PathIcon>
<PathIcon.Data>
M5 7h14a3 3 0 0 1 2.995 2.824L22 10v4a3 3 0 0 1-2.824 2.995L19 17H5a3 3 0 0 1-2.995-2.824L2 14v-4a3 3 0 0 1 2.824-2.995L5 7h14H5Zm14 1.5H5A1.5 1.5 0 0 0 3.5 10v4A1.5 1.5 0 0 0 5 15.5h14a1.5 1.5 0 0 0 1.5-1.5v-4A1.5 1.5 0 0 0 19 8.5ZM18 10a1 1 0 1 1 0 2 1 1 0 0 1 0-2Zm-4 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2Z
</PathIcon.Data>
</PathIcon>
<StackPanel Spacing="2">
<TextBlock Style="{ThemeResource BodyStrongTextBlockStyle}" Text="{x:Bind domain:Translator.SettingsStorage_Title}" />
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="{x:Bind domain:Translator.SettingsStorage_Description}" TextWrapping="WrapWholeWords" />
</StackPanel>
</StackPanel>
<Grid
Grid.Row="1"
Margin="0,12,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock
VerticalAlignment="Center"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="{x:Bind ViewModel.SummaryText, Mode=OneWay}"
TextWrapping="WrapWholeWords" />
<Button
Grid.Column="1"
Margin="12,0,0,0"
Command="{x:Bind ViewModel.RefreshStorageCommand}"
Content="{x:Bind domain:Translator.SettingsStorage_ScanFolder}"
IsEnabled="{x:Bind ViewModel.IsBusy, Mode=OneWay, Converter={StaticResource ReverseBooleanConverter}}"
Style="{StaticResource AccentButtonStyle}" />
</Grid>
</Grid>
<ItemsControl ItemsSource="{x:Bind ViewModel.AccountStorageItems, Mode=OneWay}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="mailData:AccountStorageItemViewModel">
<controls:SettingsExpander Description="{x:Bind SizeDescription}" Header="{x:Bind AccountName}">
<controls:SettingsExpander.HeaderIcon>
<coreControls:WinoFontIcon FontSize="64" Icon="{x:Bind helpers:XamlHelpers.GetProviderIcon(Account)}" />
</controls:SettingsExpander.HeaderIcon>
<controls:SettingsExpander.Items>
<controls:SettingsCard Description="{x:Bind domain:Translator.SettingsStorage_DeleteAll_Description}" Header="{x:Bind domain:Translator.SettingsStorage_DeleteAll_Title}">
<Button
Command="{x:Bind DeleteAllCommand}"
CommandParameter="{x:Bind}"
Content="{x:Bind domain:Translator.SettingsStorage_DeleteAll_Button}"
IsEnabled="{x:Bind IsBusy, Mode=OneWay, Converter={StaticResource ReverseBooleanConverter}}" />
</controls:SettingsCard>
<controls:SettingsCard Description="{x:Bind domain:Translator.SettingsStorage_DeleteOld_Description}" Header="{x:Bind domain:Translator.SettingsStorage_DeleteOld_Title}">
<StackPanel Orientation="Horizontal" Spacing="8">
<Button
Command="{x:Bind DeleteOneMonthCommand}"
CommandParameter="{x:Bind}"
Content="{x:Bind domain:Translator.SettingsStorage_DeleteOld_1Month}"
IsEnabled="{x:Bind IsBusy, Mode=OneWay, Converter={StaticResource ReverseBooleanConverter}}" />
<Button
Command="{x:Bind DeleteThreeMonthsCommand}"
CommandParameter="{x:Bind}"
Content="{x:Bind domain:Translator.SettingsStorage_DeleteOld_3Months}"
IsEnabled="{x:Bind IsBusy, Mode=OneWay, Converter={StaticResource ReverseBooleanConverter}}" />
<Button
Command="{x:Bind DeleteSixMonthsCommand}"
CommandParameter="{x:Bind}"
Content="{x:Bind domain:Translator.SettingsStorage_DeleteOld_6Months}"
IsEnabled="{x:Bind IsBusy, Mode=OneWay, Converter={StaticResource ReverseBooleanConverter}}" />
<Button
Command="{x:Bind DeleteYearCommand}"
CommandParameter="{x:Bind}"
Content="{x:Bind domain:Translator.SettingsStorage_DeleteOld_1Year}"
IsEnabled="{x:Bind IsBusy, Mode=OneWay, Converter={StaticResource ReverseBooleanConverter}}" />
</StackPanel>
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
</abstract:StoragePageAbstract>
@@ -0,0 +1,11 @@
using Wino.Views.Abstract;
namespace Wino.Views.Settings;
public sealed partial class StoragePage : StoragePageAbstract
{
public StoragePage()
{
InitializeComponent();
}
}
@@ -47,6 +47,9 @@ public sealed partial class SettingsPage : SettingsPageAbstract,
case WinoPage.PersonalizationPage:
WeakReferenceMessenger.Default.Send(new BreadcrumbNavigationRequested(Translator.SettingsPersonalization_Title, WinoPage.PersonalizationPage));
break;
case WinoPage.StoragePage:
WeakReferenceMessenger.Default.Send(new BreadcrumbNavigationRequested(Translator.SettingsStorage_Title, WinoPage.StoragePage));
break;
}
}
}