Initial WinUI switch.

This commit is contained in:
Burak Kaan Köse
2025-09-29 11:16:14 +02:00
parent f9c53ca2c9
commit e67b893ae4
345 changed files with 22458 additions and 746 deletions
@@ -0,0 +1,85 @@
<ContentDialog
x:Class="Wino.Dialogs.AccountReorderDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Wino.Controls"
xmlns:coreControls="using:Wino.Core.UWP.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:domain="using:Wino.Core.Domain"
xmlns:helpers="using:Wino.Helpers"
xmlns:interfaces="using:Wino.Core.Domain.Interfaces"
xmlns:local="using:Wino.Dialogs"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:selectors="using:Wino.Selectors"
Title="Reorder Accounnts"
Closed="DialogClosed"
DefaultButton="Secondary"
Opened="DialogOpened"
SecondaryButtonText="{x:Bind domain:Translator.Buttons_Cancel}"
Style="{StaticResource WinoDialogStyle}"
mc:Ignorable="d">
<ContentDialog.Resources>
<DataTemplate x:Key="RootAccountReorderTemplate" x:DataType="interfaces:IAccountProviderDetailViewModel">
<Grid Padding="12" ColumnSpacing="24">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<coreControls:WinoFontIcon
Grid.RowSpan="2"
VerticalAlignment="Center"
FontSize="24"
Icon="{x:Bind helpers:XamlHelpers.GetProviderIcon(ProviderDetail.Type, ProviderDetail.SpecialImapProvider)}" />
<TextBlock
Grid.Column="1"
FontWeight="SemiBold"
Text="{x:Bind StartupEntityTitle}" />
<TextBlock
Grid.Row="1"
Grid.Column="1"
Text="{x:Bind StartupEntityAddresses}" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="MergedAccountReorderTemplate" x:DataType="interfaces:IAccountProviderDetailViewModel">
<Grid Padding="12" ColumnSpacing="24">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<PathIcon
Grid.RowSpan="2"
VerticalAlignment="Center"
Data="F1 M 8.613281 17.5 C 8.75 17.942709 8.945312 18.359375 9.199219 18.75 L 4.921875 18.75 C 4.433594 18.75 3.966471 18.650717 3.520508 18.452148 C 3.074544 18.25358 2.683919 17.986654 2.348633 17.651367 C 2.013346 17.31608 1.746419 16.925455 1.547852 16.479492 C 1.349284 16.033529 1.25 15.566406 1.25 15.078125 L 1.25 4.921875 C 1.25 4.433594 1.349284 3.966473 1.547852 3.520508 C 1.746419 3.074545 2.013346 2.68392 2.348633 2.348633 C 2.683919 2.013348 3.074544 1.74642 3.520508 1.547852 C 3.966471 1.349285 4.433594 1.25 4.921875 1.25 L 15.078125 1.25 C 15.566406 1.25 16.033527 1.349285 16.479492 1.547852 C 16.925455 1.74642 17.31608 2.013348 17.651367 2.348633 C 17.986652 2.68392 18.25358 3.074545 18.452148 3.520508 C 18.650715 3.966473 18.75 4.433594 18.75 4.921875 L 18.75 6.572266 C 18.580729 6.344402 18.390299 6.132813 18.178711 5.9375 C 17.967121 5.742188 17.740885 5.566407 17.5 5.410156 L 17.5 4.951172 C 17.5 4.625651 17.433268 4.314779 17.299805 4.018555 C 17.16634 3.722332 16.987305 3.461914 16.762695 3.237305 C 16.538086 3.012695 16.277668 2.83366 15.981445 2.700195 C 15.685221 2.566732 15.374349 2.5 15.048828 2.5 L 4.951172 2.5 C 4.619141 2.5 4.303385 2.568359 4.003906 2.705078 C 3.704427 2.841797 3.44401 3.02409 3.222656 3.251953 C 3.001302 3.479818 2.825521 3.745117 2.695312 4.047852 C 2.565104 4.350587 2.5 4.66797 2.5 5 L 13.310547 5 C 12.60091 5.266928 11.998697 5.683594 11.503906 6.25 L 2.5 6.25 L 2.5 15.048828 C 2.5 15.38737 2.568359 15.704753 2.705078 16.000977 C 2.841797 16.297201 3.024088 16.55599 3.251953 16.777344 C 3.479818 16.998697 3.745117 17.174479 4.047852 17.304688 C 4.350586 17.434896 4.667969 17.5 5 17.5 Z M 18.125 9.443359 C 18.125 9.866537 18.040363 10.263672 17.871094 10.634766 C 17.701822 11.005859 17.473957 11.329753 17.1875 11.606445 C 16.901041 11.883139 16.56901 12.101237 16.191406 12.260742 C 15.813802 12.420248 15.416666 12.5 15 12.5 C 14.563802 12.5 14.1569 12.41862 13.779297 12.255859 C 13.401691 12.0931 13.071288 11.870117 12.788086 11.586914 C 12.504882 11.303711 12.2819 10.973308 12.119141 10.595703 C 11.95638 10.2181 11.875 9.811198 11.875 9.375 C 11.875 8.938803 11.95638 8.531901 12.119141 8.154297 C 12.2819 7.776693 12.504882 7.446289 12.788086 7.163086 C 13.071288 6.879883 13.401691 6.656901 13.779297 6.494141 C 14.1569 6.331381 14.563802 6.25 15 6.25 C 15.449218 6.25 15.864257 6.333008 16.245117 6.499023 C 16.625977 6.665039 16.956379 6.892904 17.236328 7.182617 C 17.516275 7.472331 17.734375 7.810873 17.890625 8.198242 C 18.046875 8.585612 18.125 9.000651 18.125 9.443359 Z M 20 16.25 C 20 16.666666 19.926758 17.049154 19.780273 17.397461 C 19.633789 17.745768 19.435221 18.058268 19.18457 18.334961 C 18.933918 18.611654 18.642578 18.854166 18.310547 19.0625 C 17.978516 19.270834 17.626953 19.444986 17.255859 19.584961 C 16.884766 19.724936 16.505533 19.829102 16.118164 19.897461 C 15.730794 19.96582 15.358072 20 15 20 C 14.654947 20 14.291992 19.96582 13.911133 19.897461 C 13.530273 19.829102 13.154297 19.726562 12.783203 19.589844 C 12.412109 19.453125 12.058919 19.282227 11.723633 19.077148 C 11.388346 18.87207 11.092122 18.632812 10.834961 18.359375 C 10.577799 18.085938 10.374349 17.779947 10.224609 17.441406 C 10.074869 17.102865 10 16.731771 10 16.328125 L 10 15.78125 C 10 15.501303 10.052083 15.237631 10.15625 14.990234 C 10.260416 14.742839 10.405273 14.526367 10.59082 14.34082 C 10.776367 14.155273 10.991211 14.010417 11.235352 13.90625 C 11.479492 13.802084 11.744791 13.75 12.03125 13.75 L 17.96875 13.75 C 18.248697 13.75 18.512369 13.803711 18.759766 13.911133 C 19.00716 14.018555 19.222004 14.163412 19.404297 14.345703 C 19.586588 14.527995 19.731445 14.742839 19.838867 14.990234 C 19.946289 15.237631 20 15.501303 20 15.78125 Z " />
<TextBlock
Grid.Column="1"
FontWeight="SemiBold"
Text="{x:Bind StartupEntityTitle}" />
<TextBlock
Grid.Row="1"
Grid.Column="1"
Text="{x:Bind StartupEntityAddresses}" />
</Grid>
</DataTemplate>
<selectors:AccountReorderTemplateSelector
x:Key="AccountReorderTemplateSelector"
MergedAccountReorderTemplate="{StaticResource MergedAccountReorderTemplate}"
RootAccountReorderTemplate="{StaticResource RootAccountReorderTemplate}" />
</ContentDialog.Resources>
<ListView
AllowDrop="True"
CanReorderItems="True"
ItemTemplateSelector="{StaticResource AccountReorderTemplateSelector}"
ItemsSource="{x:Bind Accounts}"
SelectionMode="None" />
</ContentDialog>
@@ -0,0 +1,52 @@
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.UI.Xaml.Controls;
using Wino.Core.Domain.Interfaces;
using Wino.Mail.WinUI;
namespace Wino.Dialogs;
public sealed partial class AccountReorderDialog : ContentDialog
{
public ObservableCollection<IAccountProviderDetailViewModel> Accounts { get; }
private int count;
private bool isOrdering = false;
private readonly IAccountService _accountService = App.Current.Services.GetService<IAccountService>();
public AccountReorderDialog(ObservableCollection<IAccountProviderDetailViewModel> accounts)
{
Accounts = accounts;
count = accounts.Count;
InitializeComponent();
}
private void DialogOpened(ContentDialog sender, ContentDialogOpenedEventArgs args)
{
Accounts.CollectionChanged -= AccountsChanged;
Accounts.CollectionChanged += AccountsChanged;
}
private void DialogClosed(ContentDialog sender, ContentDialogClosedEventArgs args) => Accounts.CollectionChanged -= AccountsChanged;
private async void AccountsChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (count - 1 == Accounts.Count)
isOrdering = true;
if (count == Accounts.Count && isOrdering)
{
// Order is completed. Apply changes.
var dict = Accounts.ToDictionary(a => a.StartupEntityId, a => Accounts.IndexOf(a));
await _accountService.UpdateAccountOrdersAsync(dict);
isOrdering = false;
}
}
}
@@ -0,0 +1,40 @@
<ContentDialog
x:Class="Wino.Dialogs.CreateAccountAliasDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:domain="using:Wino.Core.Domain"
xmlns:local="using:Wino.Dialogs"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="{x:Bind domain:Translator.CreateAccountAliasDialog_Title}"
DefaultButton="Primary"
PrimaryButtonClick="CreateClicked"
PrimaryButtonText="{x:Bind domain:Translator.Buttons_Create}"
SecondaryButtonText="{x:Bind domain:Translator.Buttons_Cancel}"
Style="{StaticResource WinoDialogStyle}"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="{x:Bind domain:Translator.CreateAccountAliasDialog_Description}" />
<StackPanel
Grid.Row="1"
Margin="0,20"
Spacing="8">
<TextBox
x:Name="AliasTextBox"
Header="{x:Bind domain:Translator.CreateAccountAliasDialog_AliasAddress}"
PlaceholderText="{x:Bind domain:Translator.CreateAccountAliasDialog_AliasAddressPlaceholder}" />
<TextBox
x:Name="ReplyToTextBox"
Header="{x:Bind domain:Translator.CreateAccountAliasDialog_ReplyToAddress}"
PlaceholderText="{x:Bind domain:Translator.CreateAccountAliasDialog_ReplyToAddressPlaceholder}" />
</StackPanel>
</Grid>
</ContentDialog>
@@ -0,0 +1,29 @@
using System;
using Microsoft.UI.Xaml.Controls;
using Wino.Core.Domain.Entities.Mail;
using Wino.Core.Domain.Interfaces;
namespace Wino.Dialogs;
public sealed partial class CreateAccountAliasDialog : ContentDialog, ICreateAccountAliasDialog
{
public MailAccountAlias CreatedAccountAlias { get; set; }
public CreateAccountAliasDialog()
{
InitializeComponent();
}
private void CreateClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
CreatedAccountAlias = new MailAccountAlias
{
AliasAddress = AliasTextBox.Text.Trim(),
ReplyToAddress = ReplyToTextBox.Text.Trim(),
Id = Guid.NewGuid(),
IsPrimary = false,
IsVerified = false
};
Hide();
}
}
@@ -0,0 +1,28 @@
<ContentDialog
x:Class="Wino.Mail.Dialogs.MessageSourceDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:domain="using:Wino.Core.Domain"
xmlns:local="using:Wino.Mail.Dialogs"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="{x:Bind domain:Translator.MessageSourceDialog_Title}"
DefaultButton="Primary"
PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
PrimaryButtonText="{x:Bind domain:Translator.Buttons_Copy}"
SecondaryButtonText="{x:Bind domain:Translator.Buttons_Close}"
Style="{StaticResource WinoDialogStyle}"
mc:Ignorable="d">
<ContentDialog.Resources>
<x:Double x:Key="ContentDialogMaxWidth">1200</x:Double>
</ContentDialog.Resources>
<ScrollViewer HorizontalScrollBarVisibility="Disabled" HorizontalScrollMode="Disabled">
<TextBlock
MaxWidth="1000"
IsTextSelectionEnabled="True"
Text="{x:Bind MessageSource, Mode=OneWay}"
TextWrapping="Wrap" />
</ScrollViewer>
</ContentDialog>
@@ -0,0 +1,24 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.UI.Xaml.Controls;
using Wino.Core.Domain.Interfaces;
using Wino.Mail.WinUI;
namespace Wino.Mail.Dialogs;
public sealed partial class MessageSourceDialog : ContentDialog
{
private readonly IClipboardService _clipboardService = App.Current.Services.GetService<IClipboardService>();
public string MessageSource { get; set; }
public bool Copied { get; set; }
public MessageSourceDialog()
{
this.InitializeComponent();
}
private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
_clipboardService.CopyClipboardAsync(MessageSource);
Copied = true;
}
}
@@ -0,0 +1,61 @@
<ContentDialog
x:Class="Wino.Dialogs.MoveMailDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Wino.Controls"
xmlns:coreControls="using:Wino.Core.UWP.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:domain="using:Wino.Core.Domain"
xmlns:folders="using:Wino.Core.Domain.Models.Folders"
xmlns:helpers="using:Wino.Helpers"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
Title="{x:Bind domain:Translator.MoveMailDialog_Title}"
DefaultButton="Primary"
PrimaryButtonClick="CancelClicked"
PrimaryButtonText="{x:Bind domain:Translator.Buttons_Cancel}"
Style="{StaticResource WinoDialogStyle}"
mc:Ignorable="d">
<ContentDialog.Resources>
<x:Double x:Key="ContentDialogMinWidth">600</x:Double>
<x:Double x:Key="ContentDialogMaxWidth">600</x:Double>
<x:Double x:Key="ContentDialogMinHeight">756</x:Double>
<x:Double x:Key="ContentDialogMaxHeight">756</x:Double>
<DataTemplate x:Key="FolderStructureMenuFlyoutItemTemplate" x:DataType="folders:IMailItemFolder">
<TreeViewItem IsExpanded="True" ItemsSource="{x:Bind ChildFolders}">
<StackPanel
Height="32"
Orientation="Horizontal"
Spacing="12">
<coreControls:WinoFontIcon FontSize="20" Icon="{x:Bind helpers:XamlHelpers.GetSpecialFolderPathIconGeometry(SpecialFolderType)}" />
<TextBlock VerticalAlignment="Center" Text="{x:Bind FolderName}" />
</StackPanel>
</TreeViewItem>
</DataTemplate>
</ContentDialog.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock
x:Name="InvalidFolderText"
Margin="0,0,0,6"
Foreground="{ThemeResource InfoBarWarningSeverityIconBackground}"
Visibility="Collapsed" />
<TreeView
x:Name="FolderTreeView"
Grid.Row="1"
CanDragItems="False"
CanReorderItems="False"
ItemTemplate="{StaticResource FolderStructureMenuFlyoutItemTemplate}"
ItemsSource="{x:Bind FolderList, Mode=OneWay}"
SelectedItem="{x:Bind SelectedFolder, Mode=TwoWay}"
SelectionMode="Single" />
</Grid>
</ContentDialog>
@@ -0,0 +1,74 @@
using System.Collections.Generic;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Wino.Core.Domain;
using Wino.Core.Domain.Models.Folders;
namespace Wino.Dialogs;
public sealed partial class MoveMailDialog : ContentDialog
{
public IMailItemFolder SelectedFolder
{
get { return (IMailItemFolder)GetValue(SelectedFolderProperty); }
set { SetValue(SelectedFolderProperty, value); }
}
public static readonly DependencyProperty SelectedFolderProperty = DependencyProperty.Register(nameof(SelectedFolder), typeof(IMailItemFolder), typeof(MoveMailDialog), new PropertyMetadata(null, OnSelectedFolderChanged));
public List<IMailItemFolder> FolderList { get; set; }
public MoveMailDialog(List<IMailItemFolder> allFolders)
{
InitializeComponent();
if (allFolders == null) return;
FolderList = allFolders;
}
private static void OnSelectedFolderChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
if (obj is MoveMailDialog dialog)
{
dialog.VerifySelection();
}
}
private void VerifySelection()
{
if (SelectedFolder != null)
{
// Don't select non-move capable folders like Categories or More.
if (!SelectedFolder.IsMoveTarget)
{
// Warn users for only proper mail folders. Not ghost folders.
InvalidFolderText.Visibility = Visibility.Visible;
InvalidFolderText.Text = string.Format(Translator.MoveMailDialog_InvalidFolderMessage, SelectedFolder.FolderName);
if (FolderTreeView.SelectedItem != null)
{
// Toggle the expansion for the selected container if available.
// I don't like the expand arrow touch area. It's better this way.
if (FolderTreeView.ContainerFromItem(FolderTreeView.SelectedItem) is Microsoft.UI.Xaml.Controls.TreeViewItem container)
{
container.IsExpanded = !container.IsExpanded;
}
}
SelectedFolder = null;
}
else
{
Hide();
}
}
}
private void CancelClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
Hide();
}
}
@@ -0,0 +1,25 @@
<ContentDialog
x:Class="Wino.Dialogs.NewImapSetupDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Wino.Dialogs"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Closed="ImapSetupDialogClosed"
Closing="OnDialogClosing"
DefaultButton="Secondary"
FullSizeDesired="False"
Opened="ImapSetupDialogOpened"
Style="{StaticResource WinoDialogStyle}"
mc:Ignorable="d">
<ContentDialog.Resources>
<Thickness x:Key="ContentDialogPadding">0,0,0,0</Thickness>
<!--<x:Double x:Key="ContentDialogMinWidth">768</x:Double>-->
<x:Double x:Key="ContentDialogMaxWidth">1920</x:Double>
<!--<x:Double x:Key="ContentDialogMinHeight">768</x:Double>
<x:Double x:Key="ContentDialogMaxHeight">2000</x:Double>-->
</ContentDialog.Resources>
<Frame x:Name="ImapFrame" />
</ContentDialog>
@@ -0,0 +1,111 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Animation;
using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Accounts;
using Wino.Messaging.Client.Mails;
using Wino.Views.ImapSetup;
namespace Wino.Dialogs;
public enum ImapSetupState
{
Welcome,
AutoDiscovery,
TestingConnection,
PreparingFolder
}
public sealed partial class NewImapSetupDialog : ContentDialog,
IRecipient<ImapSetupNavigationRequested>,
IRecipient<ImapSetupBackNavigationRequested>,
IRecipient<ImapSetupDismissRequested>,
IImapAccountCreationDialog
{
private TaskCompletionSource<CustomServerInformation> _getServerInfoTaskCompletionSource = new TaskCompletionSource<CustomServerInformation>();
private TaskCompletionSource<bool> dialogOpened = new TaskCompletionSource<bool>();
private bool isDismissRequested = false;
public NewImapSetupDialog()
{
InitializeComponent();
}
// Not used for now.
public AccountCreationDialogState State { get; set; }
public void Complete(bool cancel)
{
if (!_getServerInfoTaskCompletionSource.Task.IsCompleted)
_getServerInfoTaskCompletionSource.TrySetResult(null);
isDismissRequested = true;
Hide();
}
public Task<CustomServerInformation> GetCustomServerInformationAsync() => _getServerInfoTaskCompletionSource.Task;
public async void Receive(ImapSetupBackNavigationRequested message)
{
// Frame go back
if (message.PageType == null)
{
if (ImapFrame.CanGoBack)
{
// Go back using Dispatcher to allow navigations in OnNavigatedTo.
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
ImapFrame.GoBack();
});
}
}
else
{
ImapFrame.Navigate(message.PageType, message.Parameter, new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromLeft });
}
}
public void Receive(ImapSetupNavigationRequested message)
{
ImapFrame.Navigate(message.PageType, message.Parameter, new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromRight });
}
public void Receive(ImapSetupDismissRequested message) => _getServerInfoTaskCompletionSource.TrySetResult(message.CompletedServerInformation);
public async Task ShowDialogAsync(CancellationTokenSource cancellationTokenSource)
{
Opened += DialogOpened;
_ = ShowAsync();
await dialogOpened.Task;
}
private void DialogOpened(ContentDialog sender, ContentDialogOpenedEventArgs args)
{
Opened -= DialogOpened;
dialogOpened?.SetResult(true);
}
public void ShowPreparingFolders()
{
ImapFrame.Navigate(typeof(PreparingImapFoldersPage), new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromLeft });
}
public void StartImapConnectionSetup(MailAccount account) => ImapFrame.Navigate(typeof(WelcomeImapSetupPage), account, new DrillInNavigationTransitionInfo());
public void StartImapConnectionSetup(AccountCreationDialogResult accountCreationDialogResult) => ImapFrame.Navigate(typeof(WelcomeImapSetupPage), accountCreationDialogResult, new DrillInNavigationTransitionInfo());
private void ImapSetupDialogClosed(ContentDialog sender, ContentDialogClosedEventArgs args) => WeakReferenceMessenger.Default.UnregisterAll(this);
private void ImapSetupDialogOpened(ContentDialog sender, ContentDialogOpenedEventArgs args) => WeakReferenceMessenger.Default.RegisterAll(this);
// Don't hide the dialog unless dismiss is requested from the inner pages specifically.
private void OnDialogClosing(ContentDialog sender, ContentDialogClosingEventArgs args) => args.Cancel = !isDismissRequested;
}
@@ -0,0 +1,266 @@
<ContentDialog
x:Class="Wino.Dialogs.SignatureEditorDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:accounts="using:Wino.Core.Domain.Models.Accounts"
xmlns:controls="using:Wino.Controls"
xmlns:controls1="using:CommunityToolkit.WinUI.Controls"
xmlns:controls2="using:Wino.Mail.Controls"
xmlns:coreControls="using:Wino.Core.UWP.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:domain="using:Wino.Core.Domain"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
Title="{x:Bind domain:Translator.SignatureEditorDialog_Title}"
HorizontalContentAlignment="Stretch"
Closed="DialogClosed"
DefaultButton="Primary"
IsPrimaryButtonEnabled="False"
Opened="SignatureDialogOpened"
PrimaryButtonClick="SaveClicked"
PrimaryButtonText="{x:Bind domain:Translator.Buttons_Save}"
SecondaryButtonClick="CancelClicked"
SecondaryButtonText="{x:Bind domain:Translator.Buttons_Cancel}"
Style="{StaticResource WinoDialogStyle}"
mc:Ignorable="d">
<ContentDialog.Resources>
<x:Double x:Key="ContentDialogMaxWidth">1200</x:Double>
</ContentDialog.Resources>
<Grid Margin="0,20,0,0" RowSpacing="30">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" MaxHeight="400" />
</Grid.RowDefinitions>
<TextBox
x:Name="SignatureNameTextBox"
MinWidth="300"
MaxWidth="500"
HorizontalAlignment="Left"
PlaceholderText="{x:Bind domain:Translator.SignatureEditorDialog_SignatureName_Placeholder}"
TextChanged="SignatureNameTextBoxTextChanged" />
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="300" />
</Grid.RowDefinitions>
<CommandBar
Grid.Row="0"
HorizontalAlignment="Left"
Background="Transparent"
DefaultLabelPosition="Collapsed"
IsOpen="False">
<AppBarButton
Width="Auto"
MinWidth="40"
Click="{x:Bind WebViewEditor.ToggleEditorTheme}"
LabelPosition="Collapsed"
ToolTipService.ToolTip="Light Theme"
Visibility="{x:Bind WebViewEditor.IsEditorDarkMode, Mode=OneWay}">
<AppBarButton.Icon>
<coreControls:WinoFontIcon Icon="LightEditor" />
</AppBarButton.Icon>
</AppBarButton>
<AppBarButton
Width="Auto"
MinWidth="40"
Click="{x:Bind WebViewEditor.ToggleEditorTheme}"
LabelPosition="Collapsed"
ToolTipService.ToolTip="Dark Theme"
Visibility="{x:Bind WebViewEditor.IsEditorDarkMode, Mode=OneWay, Converter={StaticResource ReverseBooleanToVisibilityConverter}}">
<AppBarButton.Icon>
<coreControls:WinoFontIcon Icon="DarkEditor" />
</AppBarButton.Icon>
</AppBarButton>
<AppBarSeparator />
<AppBarToggleButton
Width="Auto"
MinWidth="40"
IsChecked="{x:Bind WebViewEditor.IsEditorBold, Mode=TwoWay}"
Label="Bold"
ToolTipService.ToolTip="Bold">
<AppBarToggleButton.Icon>
<PathIcon Data="{StaticResource BoldPathIcon}" />
</AppBarToggleButton.Icon>
</AppBarToggleButton>
<AppBarToggleButton
Width="Auto"
MinWidth="40"
IsChecked="{x:Bind WebViewEditor.IsEditorItalic, Mode=TwoWay}"
Label="Italic"
ToolTipService.ToolTip="Italic">
<AppBarToggleButton.Icon>
<PathIcon Data="{StaticResource ItalicPathIcon}" />
</AppBarToggleButton.Icon>
</AppBarToggleButton>
<AppBarToggleButton
Width="Auto"
MinWidth="40"
IsChecked="{x:Bind WebViewEditor.IsEditorUnderline, Mode=TwoWay}"
Label="Underline"
ToolTipService.ToolTip="Underline">
<AppBarToggleButton.Icon>
<PathIcon Data="{StaticResource UnderlinePathIcon}" />
</AppBarToggleButton.Icon>
</AppBarToggleButton>
<AppBarToggleButton
Width="Auto"
MinWidth="40"
IsChecked="{x:Bind WebViewEditor.IsEditorStrikethrough, Mode=TwoWay}"
Label="Stroke"
ToolTipService.ToolTip="Stroke">
<AppBarToggleButton.Icon>
<PathIcon Data="{StaticResource StrikePathIcon}" />
</AppBarToggleButton.Icon>
</AppBarToggleButton>
<AppBarSeparator />
<AppBarToggleButton
Width="Auto"
MinWidth="40"
IsChecked="{x:Bind WebViewEditor.IsEditorUl, Mode=TwoWay}"
Label="Bullet List"
ToolTipService.ToolTip="Bullet List">
<AppBarToggleButton.Icon>
<PathIcon Data="{StaticResource BulletedListPathIcon}" />
</AppBarToggleButton.Icon>
</AppBarToggleButton>
<AppBarToggleButton
Width="Auto"
MinWidth="40"
IsChecked="{x:Bind WebViewEditor.IsEditorOl, Mode=TwoWay}"
Label="Ordered List"
ToolTipService.ToolTip="Ordered List">
<AppBarToggleButton.Icon>
<PathIcon Data="{StaticResource OrderedListPathIcon}" />
</AppBarToggleButton.Icon>
</AppBarToggleButton>
<AppBarSeparator />
<AppBarButton
Width="Auto"
MinWidth="40"
Click="{x:Bind WebViewEditor.EditorOutdentAsync}"
IsEnabled="{x:Bind WebViewEditor.IsEditorOutdentEnabled, Mode=OneWay}"
Label="Decrease Indent"
ToolTipService.ToolTip="Decrease Indent">
<AppBarButton.Icon>
<PathIcon Data="{StaticResource DecreaseIndentPathIcon}" />
</AppBarButton.Icon>
</AppBarButton>
<AppBarButton
Width="Auto"
MinWidth="40"
Click="{x:Bind WebViewEditor.EditorIndentAsync}"
IsEnabled="{x:Bind WebViewEditor.IsEditorIndentEnabled, Mode=OneWay}"
Label="Increase Indent"
ToolTipService.ToolTip="Increase Indent">
<AppBarButton.Icon>
<PathIcon Data="{StaticResource IncreaseIndentPathIcon}" />
</AppBarButton.Icon>
</AppBarButton>
<AppBarElementContainer
Width="Auto"
MinWidth="40"
VerticalAlignment="Center">
<ComboBox
Background="Transparent"
BorderBrush="Transparent"
SelectedIndex="{x:Bind WebViewEditor.EditorAlignmentSelectedIndex, Mode=TwoWay}">
<ComboBoxItem IsSelected="True" Tag="left">
<StackPanel Orientation="Horizontal" Spacing="8">
<Viewbox Width="16">
<PathIcon Data="{StaticResource AlignLeftPathIcon}" />
</Viewbox>
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Left}" />
</StackPanel>
</ComboBoxItem>
<ComboBoxItem Tag="center">
<StackPanel Orientation="Horizontal" Spacing="8">
<Viewbox Width="16">
<PathIcon Data="{StaticResource AlignCenterPathIcon}" />
</Viewbox>
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Center}" />
</StackPanel>
</ComboBoxItem>
<ComboBoxItem Tag="right">
<StackPanel Orientation="Horizontal" Spacing="8">
<Viewbox Width="16">
<PathIcon Data="{StaticResource AlignRightPathIcon}" />
</Viewbox>
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Right}" />
</StackPanel>
</ComboBoxItem>
<ComboBoxItem Tag="justify">
<StackPanel Orientation="Horizontal" Spacing="8">
<Viewbox Width="16">
<PathIcon Data="{StaticResource AlignJustifyPathIcon}" />
</Viewbox>
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Justify}" />
</StackPanel>
</ComboBoxItem>
</ComboBox>
</AppBarElementContainer>
<AppBarSeparator />
<AppBarButton
Width="Auto"
MinWidth="40"
Click="{x:Bind WebViewEditor.ShowImagePicker}"
Label="Add Image"
ToolTipService.ToolTip="{x:Bind domain:Translator.Photos}">
<AppBarButton.Icon>
<PathIcon Data="{StaticResource AddPhotoPathIcon}" />
</AppBarButton.Icon>
<AppBarButton.Content>
<StackPanel Orientation="Horizontal" Spacing="8">
<Viewbox Width="16" VerticalAlignment="Center">
<PathIcon Data="{StaticResource AddPhotoPathIcon}" />
</Viewbox>
<TextBlock Text="{x:Bind domain:Translator.Photos}" />
</StackPanel>
</AppBarButton.Content>
</AppBarButton>
<AppBarButton
Width="Auto"
MinWidth="40"
Click="{x:Bind WebViewEditor.ShowEmojiPicker}"
Label="Add Emoji"
ToolTipService.ToolTip="{x:Bind domain:Translator.Emoji}">
<AppBarButton.Icon>
<PathIcon Data="{StaticResource EmojiPathIcon}" />
</AppBarButton.Icon>
</AppBarButton>
<AppBarToggleButton
Width="Auto"
MinWidth="40"
IsChecked="{x:Bind WebViewEditor.IsEditorWebViewEditor, Mode=TwoWay}"
Label="Webview ToolBar"
ToolTipService.ToolTip="Webview ToolBar">
<AppBarToggleButton.Icon>
<PathIcon Data="{StaticResource WebviewToolBarPathIcon}" />
</AppBarToggleButton.Icon>
</AppBarToggleButton>
</CommandBar>
<Border
Grid.Row="1"
Margin="0,6,0,0"
BorderBrush="{StaticResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="3">
<controls2:WebViewEditorControl x:Name="WebViewEditor" />
</Border>
</Grid>
</Grid>
</ContentDialog>
@@ -0,0 +1,80 @@
using System;
using System.Text.RegularExpressions;
using Microsoft.UI.Xaml.Controls;
using Wino.Core.Domain;
using Wino.Core.Domain.Entities.Mail;
namespace Wino.Dialogs;
public sealed partial class SignatureEditorDialog : ContentDialog
{
public AccountSignature Result;
public SignatureEditorDialog()
{
InitializeComponent();
SignatureNameTextBox.Header = Translator.SignatureEditorDialog_SignatureName_TitleNew;
// TODO: Should be added additional logic to enable/disable primary button when webview content changed.
IsPrimaryButtonEnabled = true;
}
public SignatureEditorDialog(AccountSignature signatureModel)
{
InitializeComponent();
SignatureNameTextBox.Text = signatureModel.Name.Trim();
SignatureNameTextBox.Header = string.Format(Translator.SignatureEditorDialog_SignatureName_TitleEdit, signatureModel.Name);
Result = new AccountSignature
{
Id = signatureModel.Id,
Name = signatureModel.Name,
MailAccountId = signatureModel.MailAccountId,
HtmlBody = signatureModel.HtmlBody
};
// TODO: Should be added additional logic to enable/disable primary button when webview content changed.
IsPrimaryButtonEnabled = true;
}
private async void SignatureDialogOpened(ContentDialog sender, ContentDialogOpenedEventArgs args)
{
await WebViewEditor.RenderHtmlAsync(Result?.HtmlBody ?? string.Empty);
}
private void DialogClosed(ContentDialog sender, ContentDialogClosedEventArgs args)
{
WebViewEditor.Dispose();
}
private async void SaveClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
var newSignature = Regex.Unescape(await WebViewEditor.GetHtmlBodyAsync());
if (Result == null)
{
Result = new AccountSignature
{
Id = Guid.NewGuid(),
Name = SignatureNameTextBox.Text.Trim(),
HtmlBody = newSignature
};
}
else
{
Result.Name = SignatureNameTextBox.Text.Trim();
Result.HtmlBody = newSignature;
}
Hide();
}
private void CancelClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
Hide();
}
private void SignatureNameTextBoxTextChanged(object sender, TextChangedEventArgs e) => IsPrimaryButtonEnabled = !string.IsNullOrWhiteSpace(SignatureNameTextBox.Text);
}
@@ -0,0 +1,100 @@
<ContentDialog
x:Class="Wino.Dialogs.SystemFolderConfigurationDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Wino.Controls"
xmlns:controls1="using:CommunityToolkit.WinUI.Controls"
xmlns:coreControls="using:Wino.Core.UWP.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:domain="using:Wino.Core.Domain"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="{x:Bind domain:Translator.SettingsConfigureSpecialFolders_Title}"
Closing="DialogClosing"
DefaultButton="Primary"
IsPrimaryButtonEnabled="True"
PrimaryButtonClick="SaveClicked"
PrimaryButtonText="{x:Bind domain:Translator.Buttons_SaveConfiguration}"
SecondaryButtonClick="CancelClicked"
SecondaryButtonText="{x:Bind domain:Translator.Buttons_Cancel}"
Style="{StaticResource WinoDialogStyle}"
mc:Ignorable="d">
<ContentDialog.Resources>
<Style TargetType="ComboBox">
<Setter Property="Width" Value="100" />
</Style>
</ContentDialog.Resources>
<ScrollViewer>
<Grid RowSpacing="12">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Style="{StaticResource BodyTextBlockStyle}">
<Run Text="{x:Bind domain:Translator.SystemFolderConfigDialog_MessageFirstLine}" />
<LineBreak />
<LineBreak />
<Run
FontWeight="SemiBold"
Foreground="{StaticResource SystemErrorTextColor}"
Text="{x:Bind domain:Translator.SystemFolderConfigDialog_MessageSecondLine}" />
</TextBlock>
<StackPanel Grid.Row="1" Spacing="6">
<controls1:SettingsCard
x:Name="SentCard"
Description="{x:Bind domain:Translator.SystemFolderConfigDialog_SentFolderDescription}"
Header="{x:Bind domain:Translator.SystemFolderConfigDialog_SentFolderHeader}">
<controls1:SettingsCard.HeaderIcon>
<coreControls:WinoFontIcon FontSize="16" Icon="SpecialFolderSent" />
</controls1:SettingsCard.HeaderIcon>
<ComboBox ItemsSource="{x:Bind AvailableFolders}" SelectedItem="{x:Bind Sent, Mode=TwoWay}" />
</controls1:SettingsCard>
<controls1:SettingsCard
x:Name="DraftCard"
Description="{x:Bind domain:Translator.SystemFolderConfigDialog_DraftFolderDescription}"
Header="{x:Bind domain:Translator.SystemFolderConfigDialog_DraftFolderHeader}">
<controls1:SettingsCard.HeaderIcon>
<coreControls:WinoFontIcon FontSize="16" Icon="SpecialFolderDraft" />
</controls1:SettingsCard.HeaderIcon>
<ComboBox ItemsSource="{x:Bind AvailableFolders}" SelectedItem="{x:Bind Draft, Mode=TwoWay}" />
</controls1:SettingsCard>
<controls1:SettingsCard
x:Name="ArchiveCard"
Description="{x:Bind domain:Translator.SystemFolderConfigDialog_ArchiveFolderDescription}"
Header="{x:Bind domain:Translator.SystemFolderConfigDialog_ArchiveFolderHeader}">
<controls1:SettingsCard.HeaderIcon>
<coreControls:WinoFontIcon FontSize="16" Icon="SpecialFolderArchive" />
</controls1:SettingsCard.HeaderIcon>
<ComboBox ItemsSource="{x:Bind AvailableFolders}" SelectedItem="{x:Bind Archive, Mode=TwoWay}" />
</controls1:SettingsCard>
<controls1:SettingsCard
x:Name="DeletedCard"
Description="{x:Bind domain:Translator.SystemFolderConfigDialog_DeletedFolderDescription}"
Header="{x:Bind domain:Translator.SystemFolderConfigDialog_DeletedFolderHeader}">
<controls1:SettingsCard.HeaderIcon>
<coreControls:WinoFontIcon FontSize="16" Icon="SpecialFolderDeleted" />
</controls1:SettingsCard.HeaderIcon>
<ComboBox ItemsSource="{x:Bind AvailableFolders}" SelectedItem="{x:Bind Trash, Mode=TwoWay}" />
</controls1:SettingsCard>
<controls1:SettingsCard
x:Name="JunkCard"
Description="{x:Bind domain:Translator.SystemFolderConfigDialog_JunkFolderDescription}"
Header="{x:Bind domain:Translator.SystemFolderConfigDialog_JunkFolderHeader}">
<controls1:SettingsCard.HeaderIcon>
<coreControls:WinoFontIcon FontSize="16" Icon="SpecialFolderJunk" />
</controls1:SettingsCard.HeaderIcon>
<ComboBox ItemsSource="{x:Bind AvailableFolders}" SelectedItem="{x:Bind Junk, Mode=TwoWay}" />
</controls1:SettingsCard>
<TextBlock x:Name="ValidationErrorTextBlock" Foreground="{StaticResource SystemErrorTextColor}" />
</StackPanel>
</Grid>
</ScrollViewer>
</ContentDialog>
@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.UI.Xaml.Controls;
using Wino.Core.Domain;
using Wino.Core.Domain.Entities.Mail;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Exceptions;
using Wino.Core.Domain.Models.Folders;
namespace Wino.Dialogs;
public sealed partial class SystemFolderConfigurationDialog : ContentDialog
{
private bool canDismissDialog = false;
public SystemFolderConfiguration Configuration { get; set; }
public List<MailItemFolder> AvailableFolders { get; }
public MailItemFolder Sent { get; set; }
public MailItemFolder Draft { get; set; }
public MailItemFolder Archive { get; set; }
public MailItemFolder Junk { get; set; }
public MailItemFolder Trash { get; set; }
public SystemFolderConfigurationDialog(List<MailItemFolder> availableFolders)
{
InitializeComponent();
AvailableFolders = availableFolders;
Sent = AvailableFolders.Find(a => a.SpecialFolderType == Core.Domain.Enums.SpecialFolderType.Sent);
Draft = AvailableFolders.Find(a => a.SpecialFolderType == Core.Domain.Enums.SpecialFolderType.Draft);
Archive = AvailableFolders.Find(a => a.SpecialFolderType == Core.Domain.Enums.SpecialFolderType.Archive);
Junk = AvailableFolders.Find(a => a.SpecialFolderType == Core.Domain.Enums.SpecialFolderType.Junk);
Trash = AvailableFolders.Find(a => a.SpecialFolderType == Core.Domain.Enums.SpecialFolderType.Deleted);
}
private void DialogClosing(ContentDialog sender, ContentDialogClosingEventArgs args)
{
args.Cancel = !canDismissDialog;
}
private void CancelClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args)
=> canDismissDialog = true;
private void SaveClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
ValidationErrorTextBlock.Text = string.Empty;
var allSpecialFolders = new List<MailItemFolder>()
{
Sent, Draft, Archive, Trash, Junk
};
if (allSpecialFolders.Any(a => a != null && a.SpecialFolderType == SpecialFolderType.Inbox))
ValidationErrorTextBlock.Text = Translator.SystemFolderConfigDialogValidation_InboxSelected;
if (new HashSet<Guid>(allSpecialFolders.Where(a => a != null).Select(x => x.Id)).Count != allSpecialFolders.Where(a => a != null).Count())
ValidationErrorTextBlock.Text = Translator.SystemFolderConfigDialogValidation_DuplicateSystemFolders;
// Check if we can save.
if (string.IsNullOrEmpty(ValidationErrorTextBlock.Text))
{
var configuration = new SystemFolderConfiguration(Sent, Draft, Archive, Trash, Junk);
canDismissDialog = true;
Configuration = configuration;
}
}
}