Ground work for Wino Calendar. (#475)

Wino Calendar abstractions.
This commit is contained in:
Burak Kaan Köse
2024-11-10 23:28:25 +01:00
committed by GitHub
parent a979e8430f
commit d1d6f12f05
486 changed files with 7969 additions and 2708 deletions

View File

@@ -0,0 +1,37 @@
using System.Threading.Tasks;
namespace Wino.Activation
{
public abstract class ActivationHandler
{
public abstract bool CanHandle(object args);
public abstract Task HandleAsync(object args);
}
// Extend this class to implement new ActivationHandlers
public abstract class ActivationHandler<T> : ActivationHandler
where T : class
{
// Override this method to add the activation logic in your activation handler
protected abstract Task HandleInternalAsync(T args);
public override async Task HandleAsync(object args)
{
await HandleInternalAsync(args as T);
}
public override bool CanHandle(object args)
{
// CanHandle checks the args is of type you have configured
return args is T && CanHandleInternal(args as T);
}
// You can override this method to add extra validation on activation args
// to determine if your ActivationHandler should handle this activation args
protected virtual bool CanHandleInternal(T args)
{
return true;
}
}
}

View File

@@ -0,0 +1,37 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Microsoft.UI.Xaml.Media"
xmlns:xaml="using:Windows.UI.Xaml">
<x:String x:Key="ThemeName">Acrylic</x:String>
<x:Boolean x:Key="UseMica">False</x:Boolean>
<SolidColorBrush x:Key="AppBarBackgroundColor">Transparent</SolidColorBrush>
<!-- Acrylic Template -->
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Name="Light">
<!-- Reading Page Date/Name Group Header Background -->
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#ecf0f1</SolidColorBrush>
<local:AcrylicBrush
x:Key="WinoApplicationBackgroundColor"
BackgroundSource="HostBackdrop"
FallbackColor="#F9F9F9"
TintColor="#FCFCFC"
TintOpacity="0.75" />
</ResourceDictionary>
<ResourceDictionary x:Name="Dark">
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#2C2C2C</SolidColorBrush>
<local:AcrylicBrush
x:Key="WinoApplicationBackgroundColor"
BackgroundSource="HostBackdrop"
FallbackColor="#2C2C2C"
TintColor="#2C2C2C"
TintOpacity="0.30" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>

View File

@@ -0,0 +1,21 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xaml="using:Windows.UI.Xaml">
<x:String x:Key="ThemeName">Clouds</x:String>
<x:String x:Key="ThemeBackgroundImage">ms-appx:///BackgroundImages/Clouds.jpg</x:String>
<x:Boolean x:Key="UseMica">False</x:Boolean>
<ImageBrush x:Key="WinoApplicationBackgroundColor" ImageSource="{StaticResource ThemeBackgroundImage}" />
<SolidColorBrush x:Key="AppBarBackgroundColor">Transparent</SolidColorBrush>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Name="Light">
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#b2dffc</SolidColorBrush>
</ResourceDictionary>
<ResourceDictionary x:Name="Dark">
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#b2dffc</SolidColorBrush>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>

View File

@@ -0,0 +1,47 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xaml="using:Windows.UI.Xaml">
<x:String x:Key="ThemeName">Custom</x:String>
<x:String x:Key="ThemeBackgroundImage">ms-appdata:///local/CustomWallpaper.jpg</x:String>
<x:Boolean x:Key="UseMica">False</x:Boolean>
<ImageBrush
x:Key="WinoApplicationBackgroundColor"
ImageSource="{StaticResource ThemeBackgroundImage}"
Stretch="UniformToFill" />
<!-- Navigation View Settings -->
<xaml:CornerRadius x:Key="NavigationViewContentGridCornerRadius">0,0,0,0</xaml:CornerRadius>
<xaml:CornerRadius x:Key="OverlayCornerRadius">0,1,0,0</xaml:CornerRadius>
<Thickness x:Key="NavigationViewContentMargin">0,0,0,0</Thickness>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Name="Light">
<!-- Reading Page Date/Name Group Header Background -->
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#ecf0f1</SolidColorBrush>
<Color x:Key="MainCustomThemeColor">#D9FFFFFF</Color>
<SolidColorBrush x:Key="AppBarBackgroundColor" Color="{StaticResource MainCustomThemeColor}" />
<SolidColorBrush x:Key="NavigationViewContentBackground" Color="Transparent" />
<SolidColorBrush x:Key="NavigationViewExpandedPaneBackground" Color="{StaticResource MainCustomThemeColor}" />
<SolidColorBrush x:Key="NavigationViewDefaultPaneBackground" Color="{StaticResource MainCustomThemeColor}" />
</ResourceDictionary>
<ResourceDictionary x:Name="Dark">
<!-- Reading Page Date/Name Group Header Background -->
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#1f1f1f</SolidColorBrush>
<Color x:Key="MainCustomThemeColor">#E61F1F1F</Color>
<!-- Reading Pane Background -->
<SolidColorBrush x:Key="ReadingPaneBackgroundColorBrush" Color="{StaticResource MainCustomThemeColor}" />
<SolidColorBrush x:Key="AppBarBackgroundColor" Color="{StaticResource MainCustomThemeColor}" />
<SolidColorBrush x:Key="NavigationViewContentBackground" Color="Transparent" />
<SolidColorBrush x:Key="NavigationViewExpandedPaneBackground" Color="{StaticResource MainCustomThemeColor}" />
<SolidColorBrush x:Key="NavigationViewDefaultPaneBackground" Color="{StaticResource MainCustomThemeColor}" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>

View File

@@ -0,0 +1,21 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xaml="using:Windows.UI.Xaml">
<x:String x:Key="ThemeName">Forest</x:String>
<x:String x:Key="ThemeBackgroundImage">ms-appx:///BackgroundImages/Forest.jpg</x:String>
<x:Boolean x:Key="UseMica">False</x:Boolean>
<ImageBrush x:Key="WinoApplicationBackgroundColor" ImageSource="{StaticResource ThemeBackgroundImage}" />
<SolidColorBrush x:Key="AppBarBackgroundColor">Transparent</SolidColorBrush>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Name="Light">
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#A800D608</SolidColorBrush>
</ResourceDictionary>
<ResourceDictionary x:Name="Dark">
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#59001C01</SolidColorBrush>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>

View File

@@ -0,0 +1,21 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xaml="using:Windows.UI.Xaml">
<x:String x:Key="ThemeName">Garden</x:String>
<x:String x:Key="ThemeBackgroundImage">ms-appx:///BackgroundImages/Garden.jpg</x:String>
<x:Boolean x:Key="UseMica">False</x:Boolean>
<ImageBrush x:Key="WinoApplicationBackgroundColor" ImageSource="{StaticResource ThemeBackgroundImage}" />
<SolidColorBrush x:Key="AppBarBackgroundColor">Transparent</SolidColorBrush>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Name="Light">
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#dcfad8</SolidColorBrush>
</ResourceDictionary>
<ResourceDictionary x:Name="Dark">
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#dcfad8</SolidColorBrush>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>

View File

@@ -0,0 +1,22 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xaml="using:Windows.UI.Xaml">
<x:String x:Key="ThemeName">Mica</x:String>
<x:Boolean x:Key="UseMica">True</x:Boolean>
<SolidColorBrush x:Key="WinoApplicationBackgroundColor">Transparent</SolidColorBrush>
<SolidColorBrush x:Key="AppBarBackgroundColor">Transparent</SolidColorBrush>
<!-- Mica Template -->
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Name="Light">
<!-- Reading Page Date/Name Group Header Background -->
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#ecf0f1</SolidColorBrush>
</ResourceDictionary>
<ResourceDictionary x:Name="Dark">
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#1f1f1f</SolidColorBrush>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>

View File

@@ -0,0 +1,23 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xaml="using:Windows.UI.Xaml">
<x:String x:Key="ThemeName">Nighty</x:String>
<x:String x:Key="ThemeBackgroundImage">ms-appx:///BackgroundImages/Nighty.jpg</x:String>
<x:Boolean x:Key="UseMica">False</x:Boolean>
<ImageBrush x:Key="WinoApplicationBackgroundColor" ImageSource="{StaticResource ThemeBackgroundImage}" />
<SolidColorBrush x:Key="AppBarBackgroundColor">Transparent</SolidColorBrush>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Name="Light">
<!-- Brushes -->
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#fdcb6e</SolidColorBrush>
</ResourceDictionary>
<ResourceDictionary x:Name="Dark">
<!-- Brushes -->
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#5413191F</SolidColorBrush>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>

View File

@@ -0,0 +1,23 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xaml="using:Windows.UI.Xaml">
<x:String x:Key="ThemeName">Snowflake</x:String>
<x:String x:Key="ThemeBackgroundImage">ms-appx:///BackgroundImages/Snowflake.jpg</x:String>
<x:Boolean x:Key="UseMica">False</x:Boolean>
<ImageBrush x:Key="WinoApplicationBackgroundColor" ImageSource="{StaticResource ThemeBackgroundImage}" />
<SolidColorBrush x:Key="AppBarBackgroundColor">Transparent</SolidColorBrush>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Name="Light">
<!-- Brushes -->
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#b0c6dd</SolidColorBrush>
</ResourceDictionary>
<ResourceDictionary x:Name="Dark">
<!-- Brushes -->
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#b0c6dd</SolidColorBrush>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>

View File

@@ -0,0 +1,22 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<x:String x:Key="ThemeName">TestTheme.xaml</x:String>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Name="Light">
<!-- Background Image -->
<x:String x:Key="ThemeBackgroundImage">ms-appx:///BackgroundImages/bg6.jpg</x:String>
<SolidColorBrush x:Key="ShellTitleBarBackgroundColorBrush">#A3FFFFFF</SolidColorBrush>
<SolidColorBrush x:Key="ShellNavigationViewBackgroundColorBrush">#A3FFFFFF</SolidColorBrush>
<SolidColorBrush x:Key="ReadingPaneBackgroundColorBrush">#fdcb6e</SolidColorBrush>
</ResourceDictionary>
<ResourceDictionary x:Name="Dark">
<!-- Background Image -->
<x:String x:Key="ThemeBackgroundImage">ms-appx:///BackgroundImages/bg6.jpg</x:String>
<SolidColorBrush x:Key="ShellTitleBarBackgroundColorBrush">#A3000000</SolidColorBrush>
<SolidColorBrush x:Key="ShellNavigationViewBackgroundColorBrush">#A3000000</SolidColorBrush>
<SolidColorBrush x:Key="ReadingPaneBackgroundColorBrush">#A3262626</SolidColorBrush>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 504 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 678 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 599 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 712 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 962 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

88
Wino.Core.UWP/BasePage.cs Normal file
View File

@@ -0,0 +1,88 @@
using System;
using System.Diagnostics;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.Extensions.DependencyInjection;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using Wino.Core.ViewModels;
using Wino.Messaging.Client.Shell;
namespace Wino.Core.UWP
{
public class BasePage : Page, IRecipient<LanguageChanged>
{
public UIElement ShellContent
{
get { return (UIElement)GetValue(ShellContentProperty); }
set { SetValue(ShellContentProperty, value); }
}
public static readonly DependencyProperty ShellContentProperty = DependencyProperty.Register(nameof(ShellContent), typeof(UIElement), typeof(BasePage), new PropertyMetadata(null));
public void Receive(LanguageChanged message)
{
OnLanguageChanged();
}
public virtual void OnLanguageChanged() { }
}
public abstract class BasePage<T> : BasePage where T : CoreBaseViewModel
{
public T ViewModel { get; } = WinoApplication.Current.Services.GetService<T>();
protected BasePage()
{
ViewModel.Dispatcher = new UWPDispatcher(Dispatcher);
Loaded += PageLoaded;
Unloaded += PageUnloaded;
}
private void PageUnloaded(object sender, RoutedEventArgs e)
{
Loaded -= PageLoaded;
Unloaded -= PageUnloaded;
}
private void PageLoaded(object sender, RoutedEventArgs e) => ViewModel.OnPageLoaded();
~BasePage()
{
Debug.WriteLine($"Disposed {GetType().Name}");
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var mode = GetNavigationMode(e.NavigationMode);
var parameter = e.Parameter;
WeakReferenceMessenger.Default.UnregisterAll(this);
WeakReferenceMessenger.Default.RegisterAll(this);
ViewModel.OnNavigatedTo(mode, parameter);
}
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
base.OnNavigatingFrom(e);
var mode = GetNavigationMode(e.NavigationMode);
var parameter = e.Parameter;
WeakReferenceMessenger.Default.UnregisterAll(this);
ViewModel.OnNavigatedFrom(mode, parameter);
GC.Collect();
}
private Domain.Models.Navigation.NavigationMode GetNavigationMode(NavigationMode mode)
{
return (Domain.Models.Navigation.NavigationMode)mode;
}
}
}

View File

@@ -0,0 +1,77 @@
using System.Collections.Generic;
namespace Wino.Core.UWP.Controls
{
public static class ControlConstants
{
public static Dictionary<WinoIconGlyph, string> WinoIconFontDictionary = new Dictionary<WinoIconGlyph, string>()
{
{ WinoIconGlyph.None, "\u0020" },
{ WinoIconGlyph.Archive, "\uE066" },
{ WinoIconGlyph.UnArchive, "\uE06C" },
{ WinoIconGlyph.Reply, "\uF176" },
{ WinoIconGlyph.ReplyAll, "\uF17A" },
{ WinoIconGlyph.Sync, "\uE895" },
{ WinoIconGlyph.Send, "\uEA8E" },
{ WinoIconGlyph.LightEditor, "\uE1F6" },
{ WinoIconGlyph.Delete, "\uEEA6" },
{ WinoIconGlyph.DarkEditor, "\uEE44" },
{ WinoIconGlyph.Draft, "\uF3BE" },
{ WinoIconGlyph.Flag, "\uF40C" },
{ WinoIconGlyph.ClearFlag, "\uF40F" },
{ WinoIconGlyph.Folder, "\uE643" },
{ WinoIconGlyph.Forward, "\uE7AA" },
{ WinoIconGlyph.Inbox, "\uF516" },
{ WinoIconGlyph.MarkRead, "\uF522" },
{ WinoIconGlyph.MarkUnread, "\uF529" },
{ WinoIconGlyph.MultiSelect, "\uE84D" },
{ WinoIconGlyph.Save, "\uEA43" },
{ WinoIconGlyph.CreateFolder, "\uE645" },
{ WinoIconGlyph.Pin, "\uF5FF" },
{ WinoIconGlyph.UnPin, "\uE985" },
{ WinoIconGlyph.Star, "\uE734" },
{ WinoIconGlyph.Ignore, "\uF5D0" },
{ WinoIconGlyph.Find, "\uEA7D" },
{ WinoIconGlyph.Zoom, "\uEE8E" },
{ WinoIconGlyph.SpecialFolderInbox, "\uF516" },
{ WinoIconGlyph.SpecialFolderStarred, "\uF70D" },
{ WinoIconGlyph.SpecialFolderImportant, "\uE2F4" },
{ WinoIconGlyph.SpecialFolderSent, "\uEA8E" },
{ WinoIconGlyph.SpecialFolderDraft, "\uF3BE" },
{ WinoIconGlyph.SpecialFolderArchive, "\uE066" },
{ WinoIconGlyph.SpecialFolderDeleted, "\uEEA6" },
{ WinoIconGlyph.SpecialFolderJunk, "\uF140" },
{ WinoIconGlyph.SpecialFolderChat, "\uE8BD" },
{ WinoIconGlyph.SpecialFolderCategory, "\uF599" },
{ WinoIconGlyph.SpecialFolderUnread, "\uF529" },
{ WinoIconGlyph.SpecialFolderForums, "\uF5B8" },
{ WinoIconGlyph.SpecialFolderUpdated, "\uF565" },
{ WinoIconGlyph.SpecialFolderPersonal, "\uE25A" },
{ WinoIconGlyph.SpecialFolderPromotions, "\uF7B6" },
{ WinoIconGlyph.SpecialFolderSocial, "\uEEEB" },
{ WinoIconGlyph.SpecialFolderOther, "\uE643" },
{ WinoIconGlyph.SpecialFolderMore, "\uF0F4" },
{ WinoIconGlyph.Microsoft, "\uE904" },
{ WinoIconGlyph.Google, "\uE905" },
{ WinoIconGlyph.NewMail, "\uF107" },
{ WinoIconGlyph.TurnOfNotifications, "\uF11D" },
{ WinoIconGlyph.Rename, "\uF668" },
{ WinoIconGlyph.EmptyFolder, "\uE47E" },
{ WinoIconGlyph.DontSync, "\uF195" },
{ WinoIconGlyph.Move, "\uE7B8" },
{ WinoIconGlyph.Mail, "\uF509" },
{ WinoIconGlyph.More, "\uE824" },
{ WinoIconGlyph.CustomServer, "\uF509" },
{ WinoIconGlyph.Print, "\uE954" },
{ WinoIconGlyph.Attachment, "\uE723" },
{ WinoIconGlyph.SortTextDesc, "\U000F3606" },
{ WinoIconGlyph.SortLinesDesc, "\U000F038A" },
{ WinoIconGlyph.Certificate, "\uEB95" },
{ WinoIconGlyph.OpenInNewWindow, "\uE8A7" },
{ WinoIconGlyph.Message, "\uE8BD" },
{ WinoIconGlyph.New, "\U000F002A" },
{ WinoIconGlyph.Blocked,"\uF140" },
{ WinoIconGlyph.IMAP, "\uE715" }
};
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,241 @@
using System.Windows.Input;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Wino.Core.Domain.Enums;
namespace Wino.Core.UWP.Controls
{
public sealed partial class WinoAppTitleBar : UserControl
{
public event TypedEventHandler<WinoAppTitleBar, RoutedEventArgs> BackButtonClicked;
public static readonly DependencyProperty IsRenderingPaneVisibleProperty = DependencyProperty.Register(nameof(IsRenderingPaneVisible), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(false, OnDrawingPropertyChanged));
public static readonly DependencyProperty IsReaderNarrowedProperty = DependencyProperty.Register(nameof(IsReaderNarrowed), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(false, OnIsReaderNarrowedChanged));
public static readonly DependencyProperty IsBackButtonVisibleProperty = DependencyProperty.Register(nameof(IsBackButtonVisible), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(false, OnDrawingPropertyChanged));
public static readonly DependencyProperty OpenPaneLengthProperty = DependencyProperty.Register(nameof(OpenPaneLength), typeof(double), typeof(WinoAppTitleBar), new PropertyMetadata(0d, OnDrawingPropertyChanged));
public static readonly DependencyProperty IsNavigationPaneOpenProperty = DependencyProperty.Register(nameof(IsNavigationPaneOpen), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(false, OnDrawingPropertyChanged));
public static readonly DependencyProperty NavigationViewDisplayModeProperty = DependencyProperty.Register(nameof(NavigationViewDisplayMode), typeof(Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode), typeof(WinoAppTitleBar), new PropertyMetadata(Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Compact, OnDrawingPropertyChanged));
public static readonly DependencyProperty ShellFrameContentProperty = DependencyProperty.Register(nameof(ShellFrameContent), typeof(UIElement), typeof(WinoAppTitleBar), new PropertyMetadata(null, OnDrawingPropertyChanged));
public static readonly DependencyProperty SystemReservedProperty = DependencyProperty.Register(nameof(SystemReserved), typeof(double), typeof(WinoAppTitleBar), new PropertyMetadata(0, OnDrawingPropertyChanged));
public static readonly DependencyProperty CoreWindowTextProperty = DependencyProperty.Register(nameof(CoreWindowText), typeof(string), typeof(WinoAppTitleBar), new PropertyMetadata(string.Empty, OnDrawingPropertyChanged));
public static readonly DependencyProperty ReadingPaneLengthProperty = DependencyProperty.Register(nameof(ReadingPaneLength), typeof(double), typeof(WinoAppTitleBar), new PropertyMetadata(420d, OnDrawingPropertyChanged));
public static readonly DependencyProperty ConnectionStatusProperty = DependencyProperty.Register(nameof(ConnectionStatus), typeof(WinoServerConnectionStatus), typeof(WinoAppTitleBar), new PropertyMetadata(WinoServerConnectionStatus.None, new PropertyChangedCallback(OnConnectionStatusChanged)));
public static readonly DependencyProperty ReconnectCommandProperty = DependencyProperty.Register(nameof(ReconnectCommand), typeof(ICommand), typeof(WinoAppTitleBar), new PropertyMetadata(null));
public static readonly DependencyProperty ShrinkShellContentOnExpansionProperty = DependencyProperty.Register(nameof(ShrinkShellContentOnExpansion), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(true));
public static readonly DependencyProperty IsDragAreaProperty = DependencyProperty.Register(nameof(IsDragArea), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(false, new PropertyChangedCallback(OnIsDragAreaChanged)));
public ICommand ReconnectCommand
{
get { return (ICommand)GetValue(ReconnectCommandProperty); }
set { SetValue(ReconnectCommandProperty, value); }
}
public WinoServerConnectionStatus ConnectionStatus
{
get { return (WinoServerConnectionStatus)GetValue(ConnectionStatusProperty); }
set { SetValue(ConnectionStatusProperty, value); }
}
public string CoreWindowText
{
get { return (string)GetValue(CoreWindowTextProperty); }
set { SetValue(CoreWindowTextProperty, value); }
}
public bool IsDragArea
{
get { return (bool)GetValue(IsDragAreaProperty); }
set { SetValue(IsDragAreaProperty, value); }
}
public double SystemReserved
{
get { return (double)GetValue(SystemReservedProperty); }
set { SetValue(SystemReservedProperty, value); }
}
public UIElement ShellFrameContent
{
get { return (UIElement)GetValue(ShellFrameContentProperty); }
set { SetValue(ShellFrameContentProperty, value); }
}
public Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode NavigationViewDisplayMode
{
get { return (Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode)GetValue(NavigationViewDisplayModeProperty); }
set { SetValue(NavigationViewDisplayModeProperty, value); }
}
public bool ShrinkShellContentOnExpansion
{
get { return (bool)GetValue(ShrinkShellContentOnExpansionProperty); }
set { SetValue(ShrinkShellContentOnExpansionProperty, value); }
}
public bool IsNavigationPaneOpen
{
get { return (bool)GetValue(IsNavigationPaneOpenProperty); }
set { SetValue(IsNavigationPaneOpenProperty, value); }
}
public double OpenPaneLength
{
get { return (double)GetValue(OpenPaneLengthProperty); }
set { SetValue(OpenPaneLengthProperty, value); }
}
public bool IsBackButtonVisible
{
get { return (bool)GetValue(IsBackButtonVisibleProperty); }
set { SetValue(IsBackButtonVisibleProperty, value); }
}
public bool IsReaderNarrowed
{
get { return (bool)GetValue(IsReaderNarrowedProperty); }
set { SetValue(IsReaderNarrowedProperty, value); }
}
public bool IsRenderingPaneVisible
{
get { return (bool)GetValue(IsRenderingPaneVisibleProperty); }
set { SetValue(IsRenderingPaneVisibleProperty, value); }
}
public double ReadingPaneLength
{
get { return (double)GetValue(ReadingPaneLengthProperty); }
set { SetValue(ReadingPaneLengthProperty, value); }
}
private static void OnIsReaderNarrowedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
if (obj is WinoAppTitleBar bar)
{
bar.DrawTitleBar();
}
}
private static void OnDrawingPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
if (obj is WinoAppTitleBar bar)
{
bar.DrawTitleBar();
}
}
private static void OnConnectionStatusChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
if (obj is WinoAppTitleBar bar)
{
bar.UpdateConnectionStatus();
}
}
private static void OnIsDragAreaChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
if (obj is WinoAppTitleBar bar)
{
bar.SetDragArea();
}
}
private void SetDragArea()
{
if (IsDragArea)
{
Window.Current.SetTitleBar(this);
}
}
private void UpdateConnectionStatus()
{
}
private void DrawTitleBar()
{
UpdateLayout();
CoreWindowTitleTextBlock.Visibility = Visibility.Collapsed;
ShellContentContainer.Width = double.NaN;
ShellContentContainer.Margin = new Thickness(0, 0, 0, 0);
ShellContentContainer.HorizontalAlignment = HorizontalAlignment.Stretch;
EmptySpaceWidth.Width = new GridLength(1, GridUnitType.Star);
// Menu is not visible.
if (NavigationViewDisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Minimal)
{
}
else if (NavigationViewDisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Compact)
{
// Icons are visible.
if (!IsReaderNarrowed && ShrinkShellContentOnExpansion)
{
ShellContentContainer.HorizontalAlignment = HorizontalAlignment.Left;
ShellContentContainer.Width = ReadingPaneLength;
}
}
else if (NavigationViewDisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Expanded)
{
if (IsNavigationPaneOpen)
{
CoreWindowTitleTextBlock.Visibility = Visibility.Visible;
// LMargin = OpenPaneLength - LeftMenuStackPanel
ShellContentContainer.Margin = new Thickness(OpenPaneLength - LeftMenuStackPanel.ActualSize.X, 0, 0, 0);
if (!IsReaderNarrowed && ShrinkShellContentOnExpansion)
{
ShellContentContainer.HorizontalAlignment = HorizontalAlignment.Left;
ShellContentContainer.Width = ReadingPaneLength;
}
}
else
{
// EmptySpaceWidth.Width = new GridLength(ReadingPaneLength, GridUnitType.Pixel);
EmptySpaceWidth.Width = new GridLength(ReadingPaneLength, GridUnitType.Star);
}
}
}
public WinoAppTitleBar()
{
InitializeComponent();
}
private void BackClicked(object sender, RoutedEventArgs e)
{
BackButtonClicked?.Invoke(this, e);
}
private void PaneClicked(object sender, RoutedEventArgs e)
{
IsNavigationPaneOpen = !IsNavigationPaneOpen;
}
private void TitlebarSizeChanged(object sender, SizeChangedEventArgs e) => DrawTitleBar();
private void ReconnectClicked(object sender, RoutedEventArgs e)
{
// Close the popup for reconnect button.
ReconnectFlyout.Hide();
// Execute the reconnect command.
ReconnectCommand?.Execute(null);
}
}
}

View File

@@ -0,0 +1,105 @@
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace Wino.Core.UWP.Controls
{
public enum WinoIconGlyph
{
None,
NewMail,
Google,
Microsoft,
CustomServer,
Archive,
UnArchive,
Reply,
ReplyAll,
LightEditor,
DarkEditor,
Delete,
Move,
Mail,
Draft,
Flag,
ClearFlag,
Folder,
Forward,
Inbox,
MarkRead,
MarkUnread,
Send,
Save,
Sync,
MultiSelect,
Zoom,
Pin,
UnPin,
Ignore,
Star,
CreateFolder,
More,
Find,
SpecialFolderInbox,
SpecialFolderStarred,
SpecialFolderImportant,
SpecialFolderSent,
SpecialFolderDraft,
SpecialFolderArchive,
SpecialFolderDeleted,
SpecialFolderJunk,
SpecialFolderChat,
SpecialFolderCategory,
SpecialFolderUnread,
SpecialFolderForums,
SpecialFolderUpdated,
SpecialFolderPersonal,
SpecialFolderPromotions,
SpecialFolderSocial,
SpecialFolderOther,
SpecialFolderMore,
TurnOfNotifications,
EmptyFolder,
Rename,
DontSync,
Attachment,
SortTextDesc,
SortLinesDesc,
Certificate,
OpenInNewWindow,
Blocked,
Message,
New,
IMAP,
Print
}
public class WinoFontIcon : FontIcon
{
public WinoIconGlyph Icon
{
get { return (WinoIconGlyph)GetValue(IconProperty); }
set { SetValue(IconProperty, value); }
}
public static readonly DependencyProperty IconProperty = DependencyProperty.Register(nameof(Icon), typeof(WinoIconGlyph), typeof(WinoFontIcon), new PropertyMetadata(WinoIconGlyph.Flag, OnIconChanged));
public WinoFontIcon()
{
FontFamily = new Windows.UI.Xaml.Media.FontFamily("ms-appx:///Assets/WinoIcons.ttf#WinoIcons");
FontSize = 32;
}
private static void OnIconChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
if (obj is WinoFontIcon fontIcon)
{
fontIcon.UpdateGlyph();
}
}
private void UpdateGlyph()
{
Glyph = ControlConstants.WinoIconFontDictionary[Icon];
}
}
}

View File

@@ -0,0 +1,35 @@
using Windows.UI.Xaml;
using Wino.Core.UWP.Controls;
namespace Wino.Controls
{
public class WinoFontIconSource : Microsoft.UI.Xaml.Controls.FontIconSource
{
public WinoIconGlyph Icon
{
get { return (WinoIconGlyph)GetValue(IconProperty); }
set { SetValue(IconProperty, value); }
}
public static readonly DependencyProperty IconProperty = DependencyProperty.Register(nameof(Icon), typeof(WinoIconGlyph), typeof(WinoFontIconSource), new PropertyMetadata(WinoIconGlyph.Flag, OnIconChanged));
public WinoFontIconSource()
{
FontFamily = new Windows.UI.Xaml.Media.FontFamily("ms-appx:///Assets/WinoIcons.ttf#WinoIcons");
FontSize = 32;
}
private static void OnIconChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
if (obj is WinoFontIconSource fontIcon)
{
fontIcon.UpdateGlyph();
}
}
private void UpdateGlyph()
{
Glyph = ControlConstants.WinoIconFontDictionary[Icon];
}
}
}

View File

@@ -0,0 +1,91 @@
using System;
using System.Numerics;
using CommunityToolkit.WinUI.Animations;
using Microsoft.UI.Xaml.Controls;
using Windows.UI.Xaml;
using Wino.Core.Domain.Enums;
namespace Wino.Core.UWP.Controls
{
public class WinoInfoBar : InfoBar
{
public static readonly DependencyProperty AnimationTypeProperty = DependencyProperty.Register(nameof(AnimationType), typeof(InfoBarAnimationType), typeof(WinoInfoBar), new PropertyMetadata(InfoBarAnimationType.SlideFromRightToLeft));
public static readonly DependencyProperty DismissIntervalProperty = DependencyProperty.Register(nameof(DismissInterval), typeof(int), typeof(WinoInfoBar), new PropertyMetadata(5, new PropertyChangedCallback(OnDismissIntervalChanged)));
public InfoBarAnimationType AnimationType
{
get { return (InfoBarAnimationType)GetValue(AnimationTypeProperty); }
set { SetValue(AnimationTypeProperty, value); }
}
public int DismissInterval
{
get { return (int)GetValue(DismissIntervalProperty); }
set { SetValue(DismissIntervalProperty, value); }
}
private readonly DispatcherTimer _dispatcherTimer = new DispatcherTimer();
public WinoInfoBar()
{
RegisterPropertyChangedCallback(IsOpenProperty, IsOpenChanged);
_dispatcherTimer.Interval = TimeSpan.FromSeconds(DismissInterval);
}
private static void OnDismissIntervalChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
if (obj is WinoInfoBar bar)
{
bar.UpdateInterval(bar.DismissInterval);
}
}
private void UpdateInterval(int seconds) => _dispatcherTimer.Interval = TimeSpan.FromSeconds(seconds);
private async void IsOpenChanged(DependencyObject sender, DependencyProperty dp)
{
if (sender is WinoInfoBar control)
{
// Message shown.
if (!control.IsOpen) return;
Opacity = 1;
_dispatcherTimer.Stop();
_dispatcherTimer.Tick -= TimerTick;
_dispatcherTimer.Tick += TimerTick;
_dispatcherTimer.Start();
// Slide from right.
if (AnimationType == InfoBarAnimationType.SlideFromRightToLeft)
{
await AnimationBuilder.Create().Translation(new Vector3(0, 0, 0), new Vector3(150, 0, 0), null, TimeSpan.FromSeconds(0.5)).StartAsync(this);
}
else if (AnimationType == InfoBarAnimationType.SlideFromBottomToTop)
{
await AnimationBuilder.Create().Translation(new Vector3(0, 0, 0), new Vector3(0, 50, 0), null, TimeSpan.FromSeconds(0.5)).StartAsync(this);
}
}
}
private async void TimerTick(object sender, object e)
{
_dispatcherTimer.Stop();
_dispatcherTimer.Tick -= TimerTick;
if (AnimationType == InfoBarAnimationType.SlideFromRightToLeft)
{
await AnimationBuilder.Create().Translation(new Vector3((float)ActualWidth, 0, 0), new Vector3(0, 0, 0), null, TimeSpan.FromSeconds(0.5)).StartAsync(this);
}
else if (AnimationType == InfoBarAnimationType.SlideFromBottomToTop)
{
await AnimationBuilder.Create().Translation(new Vector3(0, (float)ActualHeight, 0), new Vector3(0, 0, 0), null, TimeSpan.FromSeconds(0.5)).StartAsync(this);
}
IsOpen = false;
}
}
}

View File

@@ -0,0 +1,47 @@
using System.Numerics;
using Microsoft.UI.Xaml.Controls;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Hosting;
namespace Wino.Core.UWP.Controls
{
public class WinoNavigationViewItem : NavigationViewItem
{
public bool IsDraggingItemOver
{
get { return (bool)GetValue(IsDraggingItemOverProperty); }
set { SetValue(IsDraggingItemOverProperty, value); }
}
public static readonly DependencyProperty IsDraggingItemOverProperty = DependencyProperty.Register(nameof(IsDraggingItemOver), typeof(bool), typeof(WinoNavigationViewItem), new PropertyMetadata(false, OnIsDraggingItemOverChanged));
private static void OnIsDraggingItemOverChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
if (obj is WinoNavigationViewItem control)
control.UpdateDragEnterState();
}
private void UpdateDragEnterState()
{
// TODO: Add animation. Maybe after overriding DragUI in shell?
//if (IsDraggingItemOver)
//{
// ScaleAnimation(new System.Numerics.Vector3(1.2f, 1.2f, 1.2f));
//}
//else
//{
// ScaleAnimation(new System.Numerics.Vector3(1f, 1f, 1f));
//}
}
private void ScaleAnimation(Vector3 vector)
{
if (Content is UIElement content)
{
var visual = ElementCompositionPreview.GetElementVisual(content);
visual.Scale = vector;
}
}
}
}

View File

@@ -0,0 +1,27 @@
using System;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml;
namespace Wino.Converters
{
public class GridLengthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is double doubleValue)
{
return new GridLength(doubleValue);
}
return new GridLength(1, GridUnitType.Auto);
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
if (value is GridLength gridLength)
{
return gridLength.Value;
}
return 0.0;
}
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml.Data;
namespace Wino.Converters
{
public class ReverseBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is bool boolval)
return !boolval;
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
namespace Wino.Converters
{
public class ReverseBooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return ((bool)value) ? Visibility.Collapsed : Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary
x:Class="Wino.Core.UWP.CoreGeneric"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:coreControls="using:Wino.Core.UWP.Controls"
xmlns:styles="using:Wino.Core.UWP.Styles">
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<ResourceDictionary Source="Styles/Colors.xaml" />
<ResourceDictionary Source="Styles/ContentPresenters.xaml" />
<ResourceDictionary Source="Styles/Converters.xaml" />
<ResourceDictionary Source="Styles/FontIcons.xaml" />
<ResourceDictionary Source="Styles/WinoInfoBar.xaml" />
<styles:CustomMessageDialogStyles />
<styles:DataTemplates />
<ResourceDictionary>
<Style TargetType="ScrollViewer">
<Setter Property="VerticalScrollBarVisibility" Value="Auto" />
</Style>
<!-- Remove border/backgroud of command bar -->
<SolidColorBrush x:Key="CommandBarBackground" Color="Transparent" />
<SolidColorBrush x:Key="CommandBarBackgroundOpen" Color="Transparent" />
<SolidColorBrush x:Key="CommandBarBorderBrushOpen" Color="Transparent" />
<Thickness x:Key="CommandBarBorderThicknessOpen">0</Thickness>
<x:Double x:Key="AppBarButtonContentHeight">19</x:Double>
<x:Double x:Key="NavigationViewItemOnLeftIconBoxHeight">19</x:Double>
<Thickness x:Key="ImapSetupDialogSubPagePadding">24,24,24,24</Thickness>
<!-- Border style for each page's root border for separation of zones. -->
<Style x:Key="PageRootBorderStyle" TargetType="Border">
<Setter Property="Background" Value="{ThemeResource WinoContentZoneBackgroud}" />
<Setter Property="BorderBrush" Value="{StaticResource CardStrokeColorDefaultBrush}" />
<Setter Property="CornerRadius" Value="7" />
<Setter Property="BorderThickness" Value="1" />
</Style>
<!-- Custom Grid style for info panels. -->
<Style x:Key="InformationAreaGridStyle" TargetType="Grid">
<Setter Property="Background" Value="{ThemeResource CardBackgroundFillColorDefaultBrush}" />
<Setter Property="BorderBrush" Value="{ThemeResource DividerStrokeColorDefaultBrush}" />
<Setter Property="CornerRadius" Value="8" />
<Setter Property="Padding" Value="16" />
</Style>
<!-- Default StackPanel animation. -->
<Style TargetType="StackPanel">
<Setter Property="ChildrenTransitions">
<Setter.Value>
<TransitionCollection>
<EntranceThemeTransition IsStaggeringEnabled="True" />
</TransitionCollection>
</Setter.Value>
</Setter>
</Style>
<!-- Default Style for ContentDialog -->
<Style
x:Key="WinoDialogStyle"
BasedOn="{StaticResource DefaultContentDialogStyle}"
TargetType="ContentDialog" />
<!-- Wino Navigation View Item -->
<Style TargetType="coreControls:WinoNavigationViewItem">
<Setter Property="ContentTransitions">
<Setter.Value>
<TransitionCollection>
<PopupThemeTransition />
</TransitionCollection>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="PageStyle" TargetType="Page">
<Setter Property="Margin" Value="-1,0,0,0" />
<Setter Property="Padding" Value="12" />
<Setter Property="Background" Value="{ThemeResource AppBarBackgroundColor}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Padding="12">
<ContentPresenter />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
<!-- Last item must always be the default theme. -->
<ResourceDictionary Source="AppThemes/Mica.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

View File

@@ -0,0 +1,9 @@
using Windows.UI.Xaml;
namespace Wino.Core.UWP
{
public partial class CoreGeneric : ResourceDictionary
{
public CoreGeneric() => InitializeComponent();
}
}

View File

@@ -1,7 +1,9 @@
using Microsoft.Extensions.DependencyInjection;
using Windows.ApplicationModel.AppService;
using Windows.UI.Xaml;
using Wino.Core.Domain.Interfaces;
using Wino.Core.UWP.Services;
using Wino.Core.ViewModels;
using Wino.Services;
namespace Wino.Core.UWP
@@ -14,11 +16,15 @@ namespace Wino.Core.UWP
services.AddSingleton<IWinoServerConnectionManager>(serverConnectionManager);
services.AddSingleton<IWinoServerConnectionManager<AppServiceConnection>>(serverConnectionManager);
services.AddSingleton<IApplicationResourceManager<ResourceDictionary>, ApplicationResourceManager>();
services.AddSingleton<IUnderlyingThemeService, UnderlyingThemeService>();
services.AddSingleton<INativeAppService, NativeAppService>();
services.AddSingleton<IStoreManagementService, StoreManagementService>();
services.AddSingleton<IBackgroundTaskService, BackgroundTaskService>();
services.AddSingleton<IPreferencesService, PreferencesService>();
services.AddSingleton<IThemeService, ThemeService>();
services.AddSingleton<IStatePersistanceService, StatePersistenceService>();
services.AddTransient<IConfigurationService, ConfigurationService>();
@@ -29,6 +35,17 @@ namespace Wino.Core.UWP
services.AddTransient<IClipboardService, ClipboardService>();
services.AddTransient<IStartupBehaviorService, StartupBehaviorService>();
services.AddSingleton<IPrintService, PrintService>();
}
public static void RegisterCoreViewModels(this IServiceCollection services)
{
services.AddTransient(typeof(SettingsDialogViewModel));
services.AddTransient(typeof(PersonalizationPageViewModel));
services.AddTransient(typeof(SettingOptionsPageViewModel));
services.AddTransient(typeof(AboutPageViewModel));
services.AddTransient(typeof(SettingsPageViewModel));
services.AddTransient(typeof(NewAccountManagementPageViewModel));
}
}
}

View File

@@ -0,0 +1,121 @@
<dialogs:BaseAccountCreationDialog
x:Class="Wino.Dialogs.AccountCreationDialog"
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:dialogs="using:Wino.Dialogs"
xmlns:domain="using:Wino.Core.Domain"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
x:Name="Root"
Closing="DialogClosing"
CornerRadius="8"
mc:Ignorable="d">
<Grid x:Name="RootGrid" RowSpacing="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Viewbox Width="24">
<PathIcon x:Name="DialogIcon" Data="F1 M 5 4.902344 C 5 4.225262 5.135091 3.588867 5.405273 2.993164 C 5.675456 2.397461 6.040039 1.878256 6.499023 1.435547 C 6.958008 0.99284 7.488606 0.642904 8.09082 0.385742 C 8.693033 0.128582 9.329427 0 10 0 C 10.690104 0 11.339518 0.130209 11.948242 0.390625 C 12.556965 0.651043 13.087564 1.007488 13.540039 1.459961 C 13.992513 1.912436 14.348958 2.443035 14.609375 3.051758 C 14.869791 3.660482 14.999999 4.309896 15 5 C 14.999999 5.690104 14.869791 6.339519 14.609375 6.948242 C 14.348958 7.556967 13.992513 8.087565 13.540039 8.540039 C 13.087564 8.992514 12.556965 9.348959 11.948242 9.609375 C 11.339518 9.869792 10.690104 10 10 10 C 9.290364 10 8.631185 9.866537 8.022461 9.599609 C 7.413737 9.332683 6.884766 8.9681 6.435547 8.505859 C 5.986328 8.043621 5.634766 7.503256 5.380859 6.884766 C 5.126953 6.266276 5 5.605469 5 4.902344 Z M 13.75 4.921875 C 13.75 4.414062 13.649088 3.937176 13.447266 3.491211 C 13.245442 3.045248 12.973633 2.65625 12.631836 2.324219 C 12.290039 1.992188 11.891275 1.730145 11.435547 1.538086 C 10.979817 1.346029 10.501302 1.25 10 1.25 C 9.479166 1.25 8.990885 1.347656 8.535156 1.542969 C 8.079427 1.738281 7.682291 2.005209 7.34375 2.34375 C 7.005208 2.682293 6.738281 3.079428 6.542969 3.535156 C 6.347656 3.990887 6.25 4.479167 6.25 5 C 6.25 5.520834 6.347656 6.009115 6.542969 6.464844 C 6.738281 6.920573 7.005208 7.317709 7.34375 7.65625 C 7.682291 7.994792 8.079427 8.261719 8.535156 8.457031 C 8.990885 8.652344 9.479166 8.75 10 8.75 C 10.533854 8.75 11.030273 8.650717 11.489258 8.452148 C 11.948242 8.253581 12.345377 7.980144 12.680664 7.631836 C 13.015949 7.283529 13.277994 6.876629 13.466797 6.411133 C 13.655599 5.945639 13.75 5.449219 13.75 4.921875 Z M 1.25 13.75 C 1.25 13.417969 1.315104 13.100586 1.445312 12.797852 C 1.575521 12.495117 1.751302 12.229818 1.972656 12.001953 C 2.19401 11.774089 2.452799 11.591797 2.749023 11.455078 C 3.045247 11.318359 3.36263 11.25 3.701172 11.25 L 16.25 11.25 C 16.582031 11.25 16.899414 11.315104 17.202148 11.445312 C 17.504883 11.575521 17.770182 11.751303 17.998047 11.972656 C 18.22591 12.194011 18.408203 12.4528 18.544922 12.749023 C 18.681641 13.045248 18.75 13.362631 18.75 13.701172 C 18.75 14.501953 18.626301 15.214844 18.378906 15.839844 C 18.13151 16.464844 17.796223 17.010092 17.373047 17.475586 C 16.949869 17.94108 16.453449 18.334961 15.883789 18.657227 C 15.314127 18.979492 14.705402 19.239908 14.057617 19.438477 C 13.40983 19.637045 12.739258 19.780273 12.045898 19.868164 C 11.352539 19.956055 10.670572 20 10 20 C 9.355469 20 8.714192 19.96582 8.076172 19.897461 C 7.43815 19.829102 6.809896 19.707031 6.191406 19.53125 C 5.488281 19.329428 4.835612 19.059244 4.233398 18.720703 C 3.631185 18.382162 3.108724 17.973633 2.666016 17.495117 C 2.223307 17.016602 1.876628 16.466473 1.625977 15.844727 C 1.375325 15.222982 1.25 14.52474 1.25 13.75 Z M 17.5 13.75 C 17.5 13.580729 17.467447 13.419597 17.402344 13.266602 C 17.337238 13.113607 17.247721 12.980144 17.133789 12.866211 C 17.019855 12.752279 16.886393 12.662761 16.733398 12.597656 C 16.580402 12.532553 16.41927 12.5 16.25 12.5 L 3.75 12.5 C 3.574219 12.5 3.411458 12.532553 3.261719 12.597656 C 3.111979 12.662761 2.980143 12.752279 2.866211 12.866211 C 2.752279 12.980144 2.66276 13.111979 2.597656 13.261719 C 2.532552 13.411459 2.5 13.574219 2.5 13.75 C 2.5 14.420573 2.610677 15.008139 2.832031 15.512695 C 3.053385 16.017252 3.352864 16.455078 3.730469 16.826172 C 4.108073 17.197266 4.545898 17.50651 5.043945 17.753906 C 5.541992 18.001303 6.069336 18.198242 6.625977 18.344727 C 7.182617 18.491211 7.750651 18.595377 8.330078 18.657227 C 8.909505 18.719076 9.466146 18.75 10 18.75 C 10.533854 18.75 11.090494 18.719076 11.669922 18.657227 C 12.249348 18.595377 12.817382 18.491211 13.374023 18.344727 C 13.930663 18.198242 14.458007 18.001303 14.956055 17.753906 C 15.454101 17.50651 15.891926 17.197266 16.269531 16.826172 C 16.647135 16.455078 16.946613 16.015625 17.167969 15.507812 C 17.389322 15 17.5 14.414062 17.5 13.75 Z " />
</Viewbox>
<muxc:ProgressBar Grid.Row="1" IsIndeterminate="True" />
<TextBlock
x:Name="StatusText"
Grid.Row="2"
HorizontalAlignment="Center"
Text="{x:Bind domain:Translator.AccountCreationDialog_Initializing}"
TextWrapping="Wrap" />
<Button
x:Name="AuthHelpDialogButton"
Grid.Row="0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Visibility="Collapsed">
<Button.Content>
<Viewbox Width="20">
<PathIcon Data="M960 4q132 0 254 34t228 96 194 150 149 193 97 229 34 254q0 132-34 254t-96 228-150 194-193 149-229 97-254 34q-132 0-254-34t-228-96-194-150-149-193-97-229T4 960q0-132 34-254t96-228 150-194 193-149 229-97T960 4zm0 1792q115 0 222-30t200-84 169-131 130-169 85-200 30-222q0-115-30-222t-84-200-131-169-169-130-200-85-222-30q-115 0-222 30t-200 84-169 131-130 169-85 200-30 222q0 115 30 222t84 200 131 169 169 130 200 85 222 30zm-64-388h128v128H896v-128zm64-960q66 0 124 25t101 69 69 102 26 124q0 60-19 104t-47 81-62 65-61 59-48 63-19 76v64H896v-64q0-60 19-104t47-81 62-65 61-59 48-63 19-76q0-40-15-75t-41-61-61-41-75-15q-40 0-75 15t-61 41-41 61-15 75H640q0-66 25-124t68-101 102-69 125-26z" />
</Viewbox>
</Button.Content>
<Button.Flyout>
<Flyout Placement="Bottom">
<Grid MaxWidth="400" RowSpacing="12">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Foreground="Yellow" TextWrapping="WrapWholeWords">
<Run FontWeight="SemiBold" Text="{x:Bind domain:Translator.AccountCreationDialog_GoogleAuthHelpClipboardText_Row0}" />
<LineBreak />
<LineBreak />
<Run Text="{x:Bind domain:Translator.AccountCreationDialog_GoogleAuthHelpClipboardText_Row1}" />
<LineBreak />
<Run Text="{x:Bind domain:Translator.AccountCreationDialog_GoogleAuthHelpClipboardText_Row2}" />
<LineBreak />
<Run Text="{x:Bind domain:Translator.AccountCreationDialog_GoogleAuthHelpClipboardText_Row3}" />
</TextBlock>
<Button
x:Name="CopyClipboard"
Grid.Row="1"
HorizontalAlignment="Center"
Click="CopyClicked"
Content="{x:Bind domain:Translator.Buttons_Copy}" />
</Grid>
</Flyout>
</Button.Flyout>
</Button>
<Button
x:Name="CancelButton"
Grid.Row="3"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
Click="CancelClicked"
Content="{x:Bind domain:Translator.Buttons_Cancel}" />
</Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="DialogStates">
<VisualState x:Name="PreparingFolders">
<VisualState.Setters>
<Setter Target="StatusText.Text" Value="{x:Bind domain:Translator.AccountCreationDialog_PreparingFolders}" />
<Setter Target="CancelButton.Visibility" Value="Collapsed" />
<Setter Target="DialogIcon.Data" Value="M1024,317.5L1024,507C1014.67,495.333 1004.67,484.167 994,473.5C983.333,462.833 972,453 960,444L960,320C960,311.333 958.333,303.083 955,295.25C951.667,287.417 947.083,280.583 941.25,274.75C935.417,268.917 928.583,264.333 920.75,261C912.917,257.667 904.667,256 896,256L522,256L458,298.5C436,312.833 412.333,320 387,320L64,320L64,832C64,841 65.6667,849.417 69,857.25C72.3333,865.083 76.8333,871.833 82.5,877.5C88.1667,883.167 94.9167,887.667 102.75,891C110.583,894.333 119,896 128,896L404.5,896C410.167,907.333 416.25,918.333 422.75,929C429.25,939.667 436.333,950 444,960L125.5,960C108.833,960 92.9167,956.583 77.75,949.75C62.5833,942.917 49.25,933.75 37.75,922.25C26.25,910.75 17.0833,897.417 10.25,882.25C3.41667,867.083 0,851.167 0,834.5L0,189.5C0,172.833 3.41667,156.917 10.25,141.75C17.0833,126.583 26.25,113.25 37.75,101.75C49.25,90.25 62.5833,81.0834 77.75,74.25C92.9167,67.4167 108.833,64.0001 125.5,64L368,64C388,64.0001 407.167,68.5001 425.5,77.5C443.833,86.5001 458.833,99.0001 470.5,115L528,192L898.5,192C915.167,192 931.083,195.417 946.25,202.25C961.417,209.083 974.75,218.25 986.25,229.75C997.75,241.25 1006.92,254.583 1013.75,269.75C1020.58,284.917 1024,300.833 1024,317.5ZM466,216L419,153.5C413,145.5 405.5,139.25 396.5,134.75C387.5,130.25 378,128 368,128L128,128C119,128 110.667,129.667 103,133C95.3333,136.333 88.5833,140.917 82.75,146.75C76.9167,152.583 72.3333,159.333 69,167C65.6667,174.667 64,183 64,192L64,256L387,256C394.333,256 401.5,254.667 408.5,252C415.5,249.333 422.25,246 428.75,242C435.25,238 441.583,233.667 447.75,229C453.917,224.333 460,220 466,216ZM1024,736C1024,775.667 1016.42,813 1001.25,848C986.083,883 965.5,913.5 939.5,939.5C913.5,965.5 883,986.083 848,1001.25C813,1016.42 775.667,1024 736,1024C696,1024 658.5,1016.5 623.5,1001.5C588.5,986.5 558,966 532,940C506,914 485.5,883.5 470.5,848.5C455.5,813.5 448,776 448,736C448,696.333 455.583,659 470.75,624C485.917,589 506.5,558.5 532.5,532.5C558.5,506.5 589,485.917 624,470.75C659,455.583 696.333,448 736,448C762.333,448 787.75,451.417 812.25,458.25C836.75,465.083 859.667,474.75 881,487.25C902.333,499.75 921.833,514.833 939.5,532.5C957.167,550.167 972.25,569.667 984.75,591C997.25,612.333 1006.92,635.25 1013.75,659.75C1020.58,684.25 1024,709.667 1024,736ZM896,576C896,567.333 892.833,559.833 886.5,553.5C880.167,547.167 872.667,544 864,544C857.667,544 852.5,545.167 848.5,547.5C844.5,549.833 841.25,552.917 838.75,556.75C836.25,560.583 834.5,565 833.5,570C832.5,575 832,580.167 832,585.5C816.333,577.167 800.917,570.833 785.75,566.5C770.583,562.167 754,560 736,560C724,560 711.75,561.25 699.25,563.75C686.75,566.25 674.5,569.917 662.5,574.75C650.5,579.583 639.083,585.417 628.25,592.25C617.417,599.083 608,607 600,616C597,619.333 594.667,622.75 593,626.25C591.333,629.75 590.5,633.833 590.5,638.5C590.5,647.5 593.667,655.167 600,661.5C606.333,667.833 614,671 623,671C628.667,671 634.75,668.583 641.25,663.75C647.75,658.917 655.333,653.5 664,647.5C672.667,641.5 682.75,636.083 694.25,631.25C705.75,626.417 719.333,624 735,624C746.667,624 757.5,625.25 767.5,627.75C777.5,630.25 787.667,634.333 798,640L785,640C779,640 773.083,640.25 767.25,640.75C761.417,641.25 756.167,642.583 751.5,644.75C746.833,646.917 743.083,650.167 740.25,654.5C737.417,658.833 736,664.667 736,672C736,680.667 739.167,688.167 745.5,694.5C751.833,700.833 759.333,704 768,704L864,704C872.667,704 880.167,700.833 886.5,694.5C892.833,688.167 896,680.667 896,672ZM881.5,833C881.5,824.333 878.333,816.833 872,810.5C865.667,804.167 858.167,801 849.5,801C842.833,801 836.333,803.417 830,808.25C823.667,813.083 816.333,818.5 808,824.5C799.667,830.5 789.833,835.917 778.5,840.75C767.167,845.583 753.333,848 737,848C725.333,848 714.5,846.75 704.5,844.25C694.5,841.75 684.333,837.667 674,832L687,832C692.667,832 698.417,831.75 704.25,831.25C710.083,830.75 715.333,829.417 720,827.25C724.667,825.083 728.5,821.833 731.5,817.5C734.5,813.167 736,807.333 736,800C736,791.333 732.833,783.833 726.5,777.5C720.167,771.167 712.667,768 704,768L608,768C599.333,768 591.833,771.167 585.5,777.5C579.167,783.833 576,791.333 576,800L576,896C576,904.667 579.167,912.167 585.5,918.5C591.833,924.833 599.333,928 608,928C614.333,928 619.5,926.833 623.5,924.5C627.5,922.167 630.75,919.083 633.25,915.25C635.75,911.417 637.5,907 638.5,902C639.5,897 640,891.833 640,886.5C655.667,894.833 671.083,901.167 686.25,905.5C701.417,909.833 718,912 736,912C748,912 760.333,910.75 773,908.25C785.667,905.75 797.917,902.083 809.75,897.25C821.583,892.417 832.833,886.583 843.5,879.75C854.167,872.917 863.667,865 872,856C878.333,849.333 881.5,841.667 881.5,833Z" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="SigningIn">
<VisualState.Setters>
<Setter Target="CancelButton.Visibility" Value="Collapsed" />
<Setter Target="StatusText.Text" Value="{x:Bind domain:Translator.AccountCreationDialog_SigninIn}" />
<Setter Target="DialogIcon.Data" Value="M128,220C128,190 134.083,161.667 146.25,135C158.417,108.333 174.75,85 195.25,65C215.75,45 239.5,29.1667 266.5,17.5C293.5,5.83337 322,0 352,0C382.667,0 411.583,5.91669 438.75,17.75C465.917,29.5834 489.667,45.6667 510,66C530.333,86.3334 546.417,110.083 558.25,137.25C570.083,164.417 576,193.333 576,224C576,254.667 570.083,283.583 558.25,310.75C546.417,337.917 530.333,361.667 510,382C489.667,402.333 465.917,418.417 438.75,430.25C411.583,442.083 382.667,448 352,448C320.333,448 290.833,442 263.5,430C236.167,418 212.5,401.667 192.5,381C172.5,360.333 156.75,336.167 145.25,308.5C133.75,280.833 128,251.333 128,220ZM512,220.5C512,198.833 507.667,178.5 499,159.5C490.333,140.5 478.667,123.917 464,109.75C449.333,95.5834 432.333,84.4167 413,76.25C393.667,68.0834 373.333,64.0001 352,64C329.667,64.0001 308.833,68.1667 289.5,76.5C270.167,84.8334 253.25,96.25 238.75,110.75C224.25,125.25 212.833,142.167 204.5,161.5C196.167,180.833 192,201.667 192,224C192,246.333 196.167,267.167 204.5,286.5C212.833,305.833 224.25,322.75 238.75,337.25C253.25,351.75 270.167,363.167 289.5,371.5C308.833,379.833 329.667,384 352,384C375,384 396.25,379.75 415.75,371.25C435.25,362.75 452.167,351.083 466.5,336.25C480.833,321.417 492,304.083 500,284.25C508,264.417 512,243.167 512,220.5ZM640,284.5C640,262.833 644.333,242.5 653,223.5C661.667,204.5 673.333,187.917 688,173.75C702.667,159.583 719.667,148.417 739,140.25C758.333,132.083 778.667,128 800,128C822.333,128 843.167,132.167 862.5,140.5C881.833,148.833 898.75,160.25 913.25,174.75C927.75,189.25 939.167,206.167 947.5,225.5C955.833,244.833 960,265.667 960,288C960,310.333 955.833,331.167 947.5,350.5C939.167,369.833 927.75,386.75 913.25,401.25C898.75,415.75 881.833,427.167 862.5,435.5C843.167,443.833 822.333,448 800,448C777,448 755.75,443.75 736.25,435.25C716.75,426.75 699.833,415.083 685.5,400.25C671.167,385.417 660,368.083 652,348.25C644,328.417 640,307.167 640,284.5ZM896,288C896,275 893.5,262.667 888.5,251C883.5,239.333 876.583,229.083 867.75,220.25C858.917,211.417 848.667,204.5 837,199.5C825.333,194.5 813,192 800,192C787,192 774.667,194.5 763,199.5C751.333,204.5 741.083,211.417 732.25,220.25C723.417,229.083 716.5,239.333 711.5,251C706.5,262.667 704,275 704,288C704,301 706.5,313.333 711.5,325C716.5,336.667 723.417,346.917 732.25,355.75C741.083,364.583 751.333,371.5 763,376.5C774.667,381.5 787,384 800,384C813,384 825.333,381.5 837,376.5C848.667,371.5 858.917,364.583 867.75,355.75C876.583,346.917 883.5,336.667 888.5,325C893.5,313.333 896,301 896,288ZM0,638C0,623.667 2.41667,609 7.25,594C12.0833,579 19,565.417 28,553.25C37,541.083 47.9167,531.167 60.75,523.5C73.5833,515.833 88,512 104,512L600,512C616,512 630.417,515.833 643.25,523.5C656.083,531.167 667,541.083 676,553.25C685,565.417 691.917,579 696.75,594C701.583,609 704,623.667 704,638C704,667 701,694.917 695,721.75C689,748.583 679.75,773.833 667.25,797.5C654.75,821.167 639.083,842.917 620.25,862.75C601.417,882.583 579.167,899.833 553.5,914.5C538.5,923.167 522.75,930.417 506.25,936.25C489.75,942.083 473,946.75 456,950.25C439,953.75 421.75,956.25 404.25,957.75C386.75,959.25 369.333,960 352,960C317,960 282.333,956.833 248,950.5C213.667,944.167 181.167,932.167 150.5,914.5C124.5,899.5 102.083,882.167 83.25,862.5C64.4167,842.833 48.8333,821.25 36.5,797.75C24.1667,774.25 15,749.083 9,722.25C3,695.417 0,667.333 0,638ZM698.5,896C714.833,876.333 728.833,854.5 740.5,830.5C771.5,828.167 800.417,822.417 827.25,813.25C854.083,804.083 877.333,791.083 897,774.25C916.667,757.417 932.083,736.583 943.25,711.75C954.417,686.917 960,657.667 960,624C960,619 959.25,613.75 957.75,608.25C956.25,602.75 954.083,597.583 951.25,592.75C948.417,587.917 944.833,583.917 940.5,580.75C936.167,577.583 931.167,576 925.5,576L775,576C771.333,564.667 767,553.583 762,542.75C757,531.917 751.167,521.667 744.5,512L925.5,512C940.167,512 953.583,515.25 965.75,521.75C977.917,528.25 988.333,536.75 997,547.25C1005.67,557.75 1012.33,569.75 1017,583.25C1021.67,596.75 1024,610.333 1024,624C1024,675.333 1012.5,720.833 989.5,760.5C966.5,800.167 932.333,832.333 887,857C858.333,872.667 827.833,883.083 795.5,888.25C763.167,893.417 730.833,896 698.5,896ZM640,640C640,634.333 639.167,627.75 637.5,620.25C635.833,612.75 633.25,605.75 629.75,599.25C626.25,592.75 621.833,587.25 616.5,582.75C611.167,578.25 605,576 598,576L106,576C99,576 92.8333,578.25 87.5,582.75C82.1667,587.25 77.75,592.75 74.25,599.25C70.75,605.75 68.1667,612.75 66.5,620.25C64.8333,627.75 64,634.333 64,640C64,684.333 71.25,722.583 85.75,754.75C100.25,786.917 120.333,813.5 146,834.5C171.667,855.5 202.083,871 237.25,881C272.417,891 310.667,896 352,896C393.333,896 431.583,891 466.75,881C501.917,871 532.333,855.5 558,834.5C583.667,813.5 603.75,786.917 618.25,754.75C632.75,722.583 640,684.333 640,640Z" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="FetchingProfileInformation">
<VisualState.Setters>
<Setter Target="CancelButton.Visibility" Value="Collapsed" />
<Setter Target="StatusText.Text" Value="{x:Bind domain:Translator.AccountCreationDialog_FetchingProfileInformation}" />
<Setter Target="DialogIcon.Data" Value="F1 M 1.875 17.5 C 1.621094 17.5 1.380208 17.451172 1.152344 17.353516 C 0.924479 17.255859 0.724284 17.120768 0.551758 16.948242 C 0.379232 16.775717 0.244141 16.575521 0.146484 16.347656 C 0.048828 16.119791 0 15.878906 0 15.625 L 0 4.375 C 0 4.121094 0.048828 3.880209 0.146484 3.652344 C 0.244141 3.42448 0.379232 3.224285 0.551758 3.051758 C 0.724284 2.879232 0.924479 2.744141 1.152344 2.646484 C 1.380208 2.548828 1.621094 2.5 1.875 2.5 L 18.125 2.5 C 18.378906 2.5 18.619791 2.548828 18.847656 2.646484 C 19.07552 2.744141 19.275715 2.879232 19.448242 3.051758 C 19.620768 3.224285 19.755859 3.42448 19.853516 3.652344 C 19.951172 3.880209 20 4.121094 20 4.375 L 20 15.625 C 20 15.878906 19.951172 16.119791 19.853516 16.347656 C 19.755859 16.575521 19.620768 16.775717 19.448242 16.948242 C 19.275715 17.120768 19.07552 17.255859 18.847656 17.353516 C 18.619791 17.451172 18.378906 17.5 18.125 17.5 Z M 5 16.25 L 5 14.375 C 5 14.121094 5.048828 13.880209 5.146484 13.652344 C 5.244141 13.424479 5.379231 13.224284 5.551758 13.051758 C 5.724284 12.879232 5.924479 12.744141 6.152344 12.646484 C 6.380208 12.548828 6.621094 12.5 6.875 12.5 L 13.125 12.5 C 13.378905 12.5 13.619791 12.548828 13.847656 12.646484 C 14.075521 12.744141 14.275716 12.879232 14.448242 13.051758 C 14.620768 13.224284 14.755858 13.424479 14.853516 13.652344 C 14.951171 13.880209 14.999999 14.121094 15 14.375 L 15 16.25 L 18.125 16.25 C 18.29427 16.25 18.440754 16.188152 18.564453 16.064453 C 18.68815 15.940756 18.75 15.794271 18.75 15.625 L 18.75 4.375 C 18.75 4.20573 18.68815 4.059246 18.564453 3.935547 C 18.440754 3.81185 18.29427 3.75 18.125 3.75 L 1.875 3.75 C 1.705729 3.75 1.559245 3.81185 1.435547 3.935547 C 1.311849 4.059246 1.25 4.20573 1.25 4.375 L 1.25 15.625 C 1.25 15.794271 1.311849 15.940756 1.435547 16.064453 C 1.559245 16.188152 1.705729 16.25 1.875 16.25 Z M 6.875 8.056641 C 6.875 7.633464 6.959635 7.236328 7.128906 6.865234 C 7.298177 6.494141 7.526041 6.170248 7.8125 5.893555 C 8.098958 5.616862 8.430989 5.398764 8.808594 5.239258 C 9.186197 5.079754 9.583333 5.000001 10 5 C 10.436197 5.000001 10.843099 5.081381 11.220703 5.244141 C 11.598307 5.406901 11.928711 5.629883 12.211914 5.913086 C 12.495117 6.196289 12.718099 6.526693 12.880859 6.904297 C 13.043619 7.281901 13.124999 7.688803 13.125 8.125 C 13.124999 8.561198 13.043619 8.9681 12.880859 9.345703 C 12.718099 9.723308 12.495117 10.053711 12.211914 10.336914 C 11.928711 10.620117 11.598307 10.8431 11.220703 11.005859 C 10.843099 11.16862 10.436197 11.25 10 11.25 C 9.550781 11.25 9.135742 11.166992 8.754883 11.000977 C 8.374023 10.834961 8.043619 10.607097 7.763672 10.317383 C 7.483724 10.02767 7.265625 9.689128 7.109375 9.301758 C 6.953125 8.914389 6.875 8.49935 6.875 8.056641 Z M 11.875 8.125 C 11.875 7.871094 11.826172 7.630209 11.728516 7.402344 C 11.630859 7.174479 11.495768 6.974284 11.323242 6.801758 C 11.150716 6.629232 10.950521 6.494141 10.722656 6.396484 C 10.494791 6.298828 10.253906 6.25 10 6.25 C 9.746094 6.25 9.505208 6.298828 9.277344 6.396484 C 9.049479 6.494141 8.849283 6.629232 8.676758 6.801758 C 8.504231 6.974284 8.369141 7.174479 8.271484 7.402344 C 8.173828 7.630209 8.125 7.871094 8.125 8.125 C 8.125 8.378906 8.173828 8.619792 8.271484 8.847656 C 8.369141 9.075521 8.504231 9.275717 8.676758 9.448242 C 8.849283 9.620769 9.049479 9.755859 9.277344 9.853516 C 9.505208 9.951172 9.746094 10 10 10 C 10.253906 10 10.494791 9.951172 10.722656 9.853516 C 10.950521 9.755859 11.150716 9.620769 11.323242 9.448242 C 11.495768 9.275717 11.630859 9.075521 11.728516 8.847656 C 11.826172 8.619792 11.875 8.378906 11.875 8.125 Z M 6.25 16.25 L 13.75 16.25 L 13.75 14.375 C 13.75 14.205729 13.68815 14.059245 13.564453 13.935547 C 13.440755 13.81185 13.294271 13.75 13.125 13.75 L 6.875 13.75 C 6.705729 13.75 6.559244 13.81185 6.435547 13.935547 C 6.311849 14.059245 6.25 14.205729 6.25 14.375 Z " />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Completed">
<VisualState.Setters>
<Setter Target="CancelButton.Visibility" Value="Collapsed" />
<Setter Target="StatusText.Text" Value="{x:Bind domain:Translator.AccountCreationDialog_Completed}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Idle" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</dialogs:BaseAccountCreationDialog>

View File

@@ -0,0 +1,43 @@
using System;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.Extensions.DependencyInjection;
using Wino.Core.Domain.Interfaces;
using Wino.Core.UWP;
using Wino.Messaging.UI;
namespace Wino.Dialogs
{
public sealed partial class AccountCreationDialog : BaseAccountCreationDialog, IRecipient<CopyAuthURLRequested>
{
private string copyClipboardURL;
public AccountCreationDialog()
{
InitializeComponent();
WeakReferenceMessenger.Default.Register(this);
}
public async void Receive(CopyAuthURLRequested message)
{
copyClipboardURL = message.AuthURL;
await Task.Delay(2000);
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
AuthHelpDialogButton.Visibility = Windows.UI.Xaml.Visibility.Visible;
});
}
private void CancelClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e) => Complete(true);
private async void CopyClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
if (string.IsNullOrEmpty(copyClipboardURL)) return;
var clipboardService = WinoApplication.Current.Services.GetService<IClipboardService>();
await clipboardService.CopyClipboardAsync(copyClipboardURL);
}
}
}

View File

@@ -0,0 +1,19 @@
<ContentDialog
x:Class="Wino.Dialogs.AccountEditDialog"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="{x:Bind domain:Translator.AccountEditDialog_Title}"
DefaultButton="Primary"
PrimaryButtonClick="SaveClicked"
PrimaryButtonText="{x:Bind domain:Translator.Buttons_Save}"
SecondaryButtonText="{x:Bind domain:Translator.Buttons_Discard}"
Style="{StaticResource WinoDialogStyle}"
mc:Ignorable="d">
<Grid>
<TextBox Header="{x:Bind domain:Translator.AccountEditDialog_Message}" Text="{x:Bind Account.Name, Mode=TwoWay}" />
</Grid>
</ContentDialog>

View File

@@ -0,0 +1,22 @@
using Windows.UI.Xaml.Controls;
using Wino.Core.Domain.Entities.Shared;
namespace Wino.Dialogs
{
public sealed partial class AccountEditDialog : ContentDialog
{
public MailAccount Account { get; private set; }
public bool IsSaved { get; set; }
public AccountEditDialog(MailAccount account)
{
InitializeComponent();
Account = account;
}
private void SaveClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
IsSaved = true;
}
}
}

View File

@@ -0,0 +1,19 @@
<ContentDialog
x:Class="Wino.Dialogs.AccountPickerDialog"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="{x:Bind domain:Translator.AccountPickerDialog_Title}"
PrimaryButtonText="{x:Bind domain:Translator.Buttons_Cancel}"
Style="{StaticResource WinoDialogStyle}"
mc:Ignorable="d">
<ListView
DisplayMemberPath="Address"
IsItemClickEnabled="True"
ItemClick="AccountClicked"
ItemsSource="{x:Bind AvailableAccounts}"
SelectionMode="None" />
</ContentDialog>

View File

@@ -0,0 +1,27 @@
using System.Collections.Generic;
using Windows.UI.Xaml.Controls;
using Wino.Core.Domain.Entities.Shared;
namespace Wino.Dialogs
{
public sealed partial class AccountPickerDialog : ContentDialog
{
public MailAccount PickedAccount { get; set; }
public List<MailAccount> AvailableAccounts { get; set; }
public AccountPickerDialog(List<MailAccount> availableAccounts)
{
AvailableAccounts = availableAccounts;
InitializeComponent();
}
private void AccountClicked(object sender, ItemClickEventArgs e)
{
PickedAccount = e.ClickedItem as MailAccount;
Hide();
}
}
}

View File

@@ -0,0 +1,52 @@
using System.Threading;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
namespace Wino.Dialogs
{
public abstract class BaseAccountCreationDialog : ContentDialog, IAccountCreationDialog
{
public AccountCreationDialogState State
{
get { return (AccountCreationDialogState)GetValue(StateProperty); }
set { SetValue(StateProperty, value); }
}
public CancellationTokenSource CancellationTokenSource { get; private set; }
public static readonly DependencyProperty StateProperty = DependencyProperty.Register(nameof(State), typeof(AccountCreationDialogState), typeof(BaseAccountCreationDialog), new PropertyMetadata(AccountCreationDialogState.Idle));
// Prevent users from dismissing it by ESC key.
public void DialogClosing(ContentDialog sender, ContentDialogClosingEventArgs args)
{
if (args.Result == ContentDialogResult.None)
{
args.Cancel = true;
}
}
public void ShowDialog(CancellationTokenSource cancellationTokenSource)
{
CancellationTokenSource = cancellationTokenSource;
_ = ShowAsync();
}
public void Complete(bool cancel)
{
State = cancel ? AccountCreationDialogState.Canceled : AccountCreationDialogState.Completed;
// Unregister from closing event.
Closing -= DialogClosing;
if (cancel && !CancellationTokenSource.IsCancellationRequested)
{
CancellationTokenSource.Cancel();
}
Hide();
}
}
}

View File

@@ -0,0 +1,24 @@
using CommunityToolkit.Mvvm.ComponentModel;
using Wino.Core.Domain.Enums;
namespace Wino.Dialogs
{
public partial class CustomMessageDialogInformationContainer : ObservableObject
{
[ObservableProperty]
private bool isDontAskChecked;
public CustomMessageDialogInformationContainer(string title, string description, WinoCustomMessageDialogIcon icon, bool isDontAskAgainEnabled)
{
Title = title;
Description = description;
Icon = icon;
IsDontAskAgainEnabled = isDontAskAgainEnabled;
}
public string Title { get; }
public string Description { get; }
public WinoCustomMessageDialogIcon Icon { get; }
public bool IsDontAskAgainEnabled { get; }
}
}

View File

@@ -0,0 +1,85 @@
<ContentDialog
x:Class="Wino.Dialogs.CustomThemeBuilderDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
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"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
Title="{x:Bind domain:Translator.CustomThemeBuilder_Title}"
DefaultButton="Primary"
FullSizeDesired="False"
IsPrimaryButtonEnabled="False"
PrimaryButtonClick="ApplyClicked"
PrimaryButtonText="{x:Bind domain:Translator.Buttons_ApplyTheme}"
SecondaryButtonText="{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">900</x:Double>
<x:Double x:Key="ContentDialogMinHeight">200</x:Double>
<x:Double x:Key="ContentDialogMaxHeight">756</x:Double>
</ContentDialog.Resources>
<StackPanel Spacing="6">
<TextBlock x:Name="ErrorTextBlock" Foreground="Gold" />
<controls:SettingsCard Description="{x:Bind domain:Translator.CustomThemeBuilder_ThemeNameDescription}" Header="{x:Bind domain:Translator.CustomThemeBuilder_ThemeNameTitle}">
<controls:SettingsCard.HeaderIcon>
<PathIcon Data="F1 M 10 0.625 C 10 0.45573 10.061849 0.309246 10.185547 0.185547 C 10.309244 0.06185 10.455729 0 10.625 0 L 15.625 0 C 15.79427 0 15.940754 0.06185 16.064453 0.185547 C 16.18815 0.309246 16.25 0.45573 16.25 0.625 C 16.25 0.794271 16.18815 0.940756 16.064453 1.064453 C 15.940754 1.188152 15.79427 1.25 15.625 1.25 L 13.75 1.25 L 13.75 18.75 L 15.625 18.75 C 15.79427 18.75 15.940754 18.81185 16.064453 18.935547 C 16.18815 19.059244 16.25 19.205729 16.25 19.375 C 16.25 19.544271 16.18815 19.690756 16.064453 19.814453 C 15.940754 19.93815 15.79427 20 15.625 20 L 10.625 20 C 10.455729 20 10.309244 19.93815 10.185547 19.814453 C 10.061849 19.690756 10 19.544271 10 19.375 C 10 19.205729 10.061849 19.059244 10.185547 18.935547 C 10.309244 18.81185 10.455729 18.75 10.625 18.75 L 12.5 18.75 L 12.5 1.25 L 10.625 1.25 C 10.455729 1.25 10.309244 1.188152 10.185547 1.064453 C 10.061849 0.940756 10 0.794271 10 0.625 Z M 0 6.25 C 0 5.735678 0.097656 5.250651 0.292969 4.794922 C 0.488281 4.339193 0.756836 3.94043 1.098633 3.598633 C 1.44043 3.256836 1.837565 2.988281 2.290039 2.792969 C 2.742513 2.597656 3.229167 2.5 3.75 2.5 L 11.25 2.5 L 11.25 3.75 L 3.75 3.75 C 3.404948 3.75 3.081055 3.815105 2.77832 3.945312 C 2.475586 4.075521 2.210286 4.254558 1.982422 4.482422 C 1.754557 4.710287 1.575521 4.975587 1.445312 5.27832 C 1.315104 5.581056 1.25 5.904949 1.25 6.25 L 1.25 13.75 C 1.25 14.095053 1.315104 14.418945 1.445312 14.72168 C 1.575521 15.024414 1.754557 15.289714 1.982422 15.517578 C 2.210286 15.745443 2.475586 15.924479 2.77832 16.054688 C 3.081055 16.184896 3.404948 16.25 3.75 16.25 L 11.25 16.25 L 11.25 17.5 L 3.75 17.5 C 3.229167 17.5 2.742513 17.402344 2.290039 17.207031 C 1.837565 17.011719 1.44043 16.743164 1.098633 16.401367 C 0.756836 16.05957 0.488281 15.662436 0.292969 15.209961 C 0.097656 14.757487 0 14.270834 0 13.75 Z M 15 3.75 L 15 2.5 L 16.25 2.5 C 16.764322 2.5 17.249348 2.597656 17.705078 2.792969 C 18.160807 2.988281 18.55957 3.256836 18.901367 3.598633 C 19.243164 3.94043 19.511719 4.339193 19.707031 4.794922 C 19.902344 5.250651 20 5.735678 20 6.25 L 20 13.75 C 20 14.270834 19.902344 14.757487 19.707031 15.209961 C 19.511719 15.662436 19.243164 16.05957 18.901367 16.401367 C 18.55957 16.743164 18.160807 17.011719 17.705078 17.207031 C 17.249348 17.402344 16.764322 17.5 16.25 17.5 L 15 17.5 L 15 16.25 L 16.25 16.25 C 16.595051 16.25 16.918945 16.184896 17.22168 16.054688 C 17.524414 15.924479 17.789713 15.745443 18.017578 15.517578 C 18.245441 15.289714 18.424479 15.024414 18.554688 14.72168 C 18.684895 14.418945 18.75 14.095053 18.75 13.75 L 18.75 6.25 C 18.75 5.904949 18.684895 5.581056 18.554688 5.27832 C 18.424479 4.975587 18.245441 4.710287 18.017578 4.482422 C 17.789713 4.254558 17.524414 4.075521 17.22168 3.945312 C 16.918945 3.815105 16.595051 3.75 16.25 3.75 Z M 7.441406 5.361328 C 7.389323 5.250651 7.312825 5.162761 7.211914 5.097656 C 7.111002 5.032553 6.998697 5.000001 6.875 5 C 6.751302 5.000001 6.638997 5.032553 6.538086 5.097656 C 6.437174 5.162761 6.360677 5.250651 6.308594 5.361328 L 2.871094 12.861328 C 2.799479 13.017578 2.792969 13.177084 2.851562 13.339844 C 2.910156 13.502604 3.017578 13.619792 3.173828 13.691406 C 3.330078 13.763021 3.489583 13.769531 3.652344 13.710938 C 3.815104 13.652344 3.932292 13.544922 4.003906 13.388672 L 4.84375 11.5625 L 8.896484 11.5625 L 8.90625 11.5625 L 9.746094 13.388672 C 9.817708 13.544922 9.934896 13.652344 10.097656 13.710938 C 10.260416 13.769531 10.419922 13.763021 10.576172 13.691406 C 10.732422 13.619792 10.839844 13.502604 10.898438 13.339844 C 10.957031 13.177084 10.950521 13.017578 10.878906 12.861328 Z M 5.410156 10.3125 L 6.875 7.128906 L 8.339844 10.3125 Z " />
</controls:SettingsCard.HeaderIcon>
<controls:SettingsCard.Content>
<TextBox x:Name="ThemeNameBox" />
</controls:SettingsCard.Content>
</controls:SettingsCard>
<controls:SettingsCard
x:Name="CustomWallpaperCard"
Description="{x:Bind domain:Translator.CustomThemeBuilder_WallpaperDescription}"
Header="{x:Bind domain:Translator.CustomThemeBuilder_WallpaperTitle}">
<controls:SettingsCard.HeaderIcon>
<PathIcon Data="F1 M 4.921875 16.25 C 4.433594 16.25 3.966471 16.150717 3.520508 15.952148 C 3.074544 15.753581 2.683919 15.486654 2.348633 15.151367 C 2.013346 14.816081 1.746419 14.425456 1.547852 13.979492 C 1.349284 13.533529 1.25 13.066406 1.25 12.578125 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 12.578125 1.25 C 13.066406 1.25 13.533528 1.349285 13.979492 1.547852 C 14.425455 1.74642 14.81608 2.013348 15.151367 2.348633 C 15.486653 2.68392 15.75358 3.074545 15.952148 3.520508 C 16.150715 3.966473 16.25 4.433594 16.25 4.921875 L 16.25 12.578125 C 16.25 13.066406 16.150715 13.533529 15.952148 13.979492 C 15.75358 14.425456 15.486653 14.816081 15.151367 15.151367 C 14.81608 15.486654 14.425455 15.753581 13.979492 15.952148 C 13.533528 16.150717 13.066406 16.25 12.578125 16.25 Z M 8.75 8.90625 C 9.082031 8.90625 9.401041 8.969727 9.707031 9.09668 C 10.013021 9.223633 10.283203 9.404297 10.517578 9.638672 L 14.658203 13.769531 C 14.768879 13.580729 14.853515 13.377279 14.912109 13.15918 C 14.970702 12.941081 14.999999 12.721354 15 12.5 L 15 4.951172 C 14.999999 4.625651 14.933268 4.314779 14.799805 4.018555 C 14.666341 3.722332 14.487305 3.461914 14.262695 3.237305 C 14.038086 3.012695 13.777669 2.83366 13.481445 2.700195 C 13.185221 2.566732 12.874348 2.5 12.548828 2.5 L 4.951172 2.5 C 4.625651 2.5 4.314778 2.566732 4.018555 2.700195 C 3.722331 2.83366 3.461914 3.012695 3.237305 3.237305 C 3.012695 3.461914 2.833659 3.722332 2.700195 4.018555 C 2.566732 4.314779 2.5 4.625651 2.5 4.951172 L 2.5 12.5 C 2.5 12.721354 2.529297 12.941081 2.587891 13.15918 C 2.646484 13.377279 2.73112 13.580729 2.841797 13.769531 L 6.982422 9.638672 C 7.216797 9.404297 7.486979 9.223633 7.792969 9.09668 C 8.098958 8.969727 8.417969 8.90625 8.75 8.90625 Z M 10.625 5.625 C 10.625 5.449219 10.657552 5.286459 10.722656 5.136719 C 10.78776 4.98698 10.877278 4.855145 10.991211 4.741211 C 11.105143 4.627279 11.236979 4.537761 11.386719 4.472656 C 11.536458 4.407553 11.699219 4.375 11.875 4.375 C 12.04427 4.375 12.205402 4.407553 12.358398 4.472656 C 12.511393 4.537761 12.644856 4.627279 12.758789 4.741211 C 12.872721 4.855145 12.962239 4.988607 13.027344 5.141602 C 13.092447 5.294597 13.124999 5.455729 13.125 5.625 C 13.124999 5.800781 13.092447 5.963542 13.027344 6.113281 C 12.962239 6.263021 12.872721 6.394857 12.758789 6.508789 C 12.644856 6.622722 12.513021 6.71224 12.363281 6.777344 C 12.213541 6.842449 12.050781 6.875001 11.875 6.875 C 11.699219 6.875001 11.53483 6.842449 11.381836 6.777344 C 11.228841 6.71224 11.097005 6.62435 10.986328 6.513672 C 10.87565 6.402996 10.78776 6.27116 10.722656 6.118164 C 10.657552 5.96517 10.625 5.800781 10.625 5.625 Z M 7.5 18.75 C 6.966146 18.75 6.455078 18.642578 5.966797 18.427734 C 5.478516 18.212891 5.058594 17.903646 4.707031 17.5 L 13.193359 17.5 C 13.785807 17.5 14.344075 17.382812 14.868164 17.148438 C 15.392252 16.914062 15.849609 16.59668 16.240234 16.196289 C 16.630859 15.795898 16.938477 15.332031 17.163086 14.804688 C 17.387695 14.277344 17.5 13.717448 17.5 13.125 L 17.5 4.707031 C 17.903645 5.058595 18.212891 5.478517 18.427734 5.966797 C 18.642578 6.455079 18.75 6.966146 18.75 7.5 L 18.75 13.125 C 18.75 13.89974 18.601887 14.628906 18.305664 15.3125 C 18.009439 15.996094 17.607422 16.591797 17.099609 17.099609 C 16.591797 17.607422 15.996094 18.009439 15.3125 18.305664 C 14.628906 18.601889 13.899739 18.75 13.125 18.75 Z M 12.5 15 C 12.721354 15 12.94108 14.970703 13.15918 14.912109 C 13.377278 14.853516 13.580729 14.768881 13.769531 14.658203 L 9.638672 10.517578 C 9.391275 10.270183 9.095052 10.146484 8.75 10.146484 C 8.404947 10.146484 8.108724 10.270183 7.861328 10.517578 L 3.730469 14.658203 C 3.919271 14.768881 4.122721 14.853516 4.34082 14.912109 C 4.558919 14.970703 4.778646 15 5 15 Z " />
</controls:SettingsCard.HeaderIcon>
<controls:SettingsCard.Content>
<Button Click="BrowseWallpaperClicked" Content="{x:Bind domain:Translator.Buttons_Browse}" />
</controls:SettingsCard.Content>
</controls:SettingsCard>
<controls:SettingsCard Description="{x:Bind domain:Translator.CustomThemeBuilder_AccentColorDescription}" Header="{x:Bind domain:Translator.CustomThemeBuilder_AccentColorTitle}">
<controls:SettingsCard.HeaderIcon>
<PathIcon Data="F1 M 4.921875 16.25 C 4.433594 16.25 3.966471 16.150717 3.520508 15.952148 C 3.074544 15.753581 2.683919 15.486654 2.348633 15.151367 C 2.013346 14.816081 1.746419 14.425456 1.547852 13.979492 C 1.349284 13.533529 1.25 13.066406 1.25 12.578125 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 12.578125 1.25 C 13.066406 1.25 13.533528 1.349285 13.979492 1.547852 C 14.425455 1.74642 14.81608 2.013348 15.151367 2.348633 C 15.486653 2.68392 15.75358 3.074545 15.952148 3.520508 C 16.150715 3.966473 16.25 4.433594 16.25 4.921875 L 16.25 12.578125 C 16.25 13.066406 16.150715 13.533529 15.952148 13.979492 C 15.75358 14.425456 15.486653 14.816081 15.151367 15.151367 C 14.81608 15.486654 14.425455 15.753581 13.979492 15.952148 C 13.533528 16.150717 13.066406 16.25 12.578125 16.25 Z M 8.75 8.90625 C 9.082031 8.90625 9.401041 8.969727 9.707031 9.09668 C 10.013021 9.223633 10.283203 9.404297 10.517578 9.638672 L 14.658203 13.769531 C 14.768879 13.580729 14.853515 13.377279 14.912109 13.15918 C 14.970702 12.941081 14.999999 12.721354 15 12.5 L 15 4.951172 C 14.999999 4.625651 14.933268 4.314779 14.799805 4.018555 C 14.666341 3.722332 14.487305 3.461914 14.262695 3.237305 C 14.038086 3.012695 13.777669 2.83366 13.481445 2.700195 C 13.185221 2.566732 12.874348 2.5 12.548828 2.5 L 4.951172 2.5 C 4.625651 2.5 4.314778 2.566732 4.018555 2.700195 C 3.722331 2.83366 3.461914 3.012695 3.237305 3.237305 C 3.012695 3.461914 2.833659 3.722332 2.700195 4.018555 C 2.566732 4.314779 2.5 4.625651 2.5 4.951172 L 2.5 12.5 C 2.5 12.721354 2.529297 12.941081 2.587891 13.15918 C 2.646484 13.377279 2.73112 13.580729 2.841797 13.769531 L 6.982422 9.638672 C 7.216797 9.404297 7.486979 9.223633 7.792969 9.09668 C 8.098958 8.969727 8.417969 8.90625 8.75 8.90625 Z M 10.625 5.625 C 10.625 5.449219 10.657552 5.286459 10.722656 5.136719 C 10.78776 4.98698 10.877278 4.855145 10.991211 4.741211 C 11.105143 4.627279 11.236979 4.537761 11.386719 4.472656 C 11.536458 4.407553 11.699219 4.375 11.875 4.375 C 12.04427 4.375 12.205402 4.407553 12.358398 4.472656 C 12.511393 4.537761 12.644856 4.627279 12.758789 4.741211 C 12.872721 4.855145 12.962239 4.988607 13.027344 5.141602 C 13.092447 5.294597 13.124999 5.455729 13.125 5.625 C 13.124999 5.800781 13.092447 5.963542 13.027344 6.113281 C 12.962239 6.263021 12.872721 6.394857 12.758789 6.508789 C 12.644856 6.622722 12.513021 6.71224 12.363281 6.777344 C 12.213541 6.842449 12.050781 6.875001 11.875 6.875 C 11.699219 6.875001 11.53483 6.842449 11.381836 6.777344 C 11.228841 6.71224 11.097005 6.62435 10.986328 6.513672 C 10.87565 6.402996 10.78776 6.27116 10.722656 6.118164 C 10.657552 5.96517 10.625 5.800781 10.625 5.625 Z M 7.5 18.75 C 6.966146 18.75 6.455078 18.642578 5.966797 18.427734 C 5.478516 18.212891 5.058594 17.903646 4.707031 17.5 L 13.193359 17.5 C 13.785807 17.5 14.344075 17.382812 14.868164 17.148438 C 15.392252 16.914062 15.849609 16.59668 16.240234 16.196289 C 16.630859 15.795898 16.938477 15.332031 17.163086 14.804688 C 17.387695 14.277344 17.5 13.717448 17.5 13.125 L 17.5 4.707031 C 17.903645 5.058595 18.212891 5.478517 18.427734 5.966797 C 18.642578 6.455079 18.75 6.966146 18.75 7.5 L 18.75 13.125 C 18.75 13.89974 18.601887 14.628906 18.305664 15.3125 C 18.009439 15.996094 17.607422 16.591797 17.099609 17.099609 C 16.591797 17.607422 15.996094 18.009439 15.3125 18.305664 C 14.628906 18.601889 13.899739 18.75 13.125 18.75 Z M 12.5 15 C 12.721354 15 12.94108 14.970703 13.15918 14.912109 C 13.377278 14.853516 13.580729 14.768881 13.769531 14.658203 L 9.638672 10.517578 C 9.391275 10.270183 9.095052 10.146484 8.75 10.146484 C 8.404947 10.146484 8.108724 10.270183 7.861328 10.517578 L 3.730469 14.658203 C 3.919271 14.768881 4.122721 14.853516 4.34082 14.912109 C 4.558919 14.970703 4.778646 15 5 15 Z " />
</controls:SettingsCard.HeaderIcon>
<controls:SettingsCard.Content>
<Button>
<Button.Content>
<StackPanel Orientation="Horizontal" Spacing="12">
<TextBlock Text="{x:Bind domain:Translator.CustomThemeBuilder_PickColor}" />
<Grid
x:Name="PreviewAccentColorGrid"
Width="20"
Height="20"
Background="{ThemeResource SystemAccentColor}" />
</StackPanel>
</Button.Content>
<Button.Flyout>
<Flyout Placement="Bottom">
<muxc:ColorPicker
ColorChanged="PickerColorChanged"
ColorSpectrumShape="Box"
IsAlphaEnabled="False"
IsAlphaSliderVisible="False"
IsAlphaTextInputVisible="False"
IsColorChannelTextInputVisible="False"
IsHexInputVisible="False" />
</Flyout>
</Button.Flyout>
</Button>
</controls:SettingsCard.Content>
</controls:SettingsCard>
</StackPanel>
</ContentDialog>

View File

@@ -0,0 +1,65 @@
using System;
using CommunityToolkit.WinUI.Helpers;
using Microsoft.Extensions.DependencyInjection;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Wino.Core.Domain.Interfaces;
using Wino.Core.UWP;
namespace Wino.Dialogs
{
public sealed partial class CustomThemeBuilderDialog : ContentDialog
{
public byte[] WallpaperData { get; private set; }
public string AccentColor { get; private set; }
private IThemeService _themeService;
public CustomThemeBuilderDialog()
{
InitializeComponent();
_themeService = WinoApplication.Current.Services.GetService<IThemeService>();
}
private async void ApplyClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
if (Array.Empty<byte>() == WallpaperData)
return;
var deferal = args.GetDeferral();
try
{
await _themeService.CreateNewCustomThemeAsync(ThemeNameBox.Text, AccentColor, WallpaperData);
}
catch (Exception exception)
{
ErrorTextBlock.Text = exception.Message;
}
finally
{
deferal.Complete();
}
}
private async void BrowseWallpaperClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
var dialogService = WinoApplication.Current.Services.GetService<IMailDialogService>();
var pickedFileData = await dialogService.PickWindowsFileContentAsync(".jpg", ".png");
if (pickedFileData == Array.Empty<byte>()) return;
IsPrimaryButtonEnabled = true;
WallpaperData = pickedFileData;
}
private void PickerColorChanged(Microsoft.UI.Xaml.Controls.ColorPicker sender, Microsoft.UI.Xaml.Controls.ColorChangedEventArgs args)
{
PreviewAccentColorGrid.Background = new SolidColorBrush(args.NewColor);
AccentColor = args.NewColor.ToHex();
}
}
}

View File

@@ -0,0 +1,28 @@
<ContentDialog
x:Class="Wino.Dialogs.TextInputDialog"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
DefaultButton="Primary"
PrimaryButtonClick="UpdateOrCreateClicked"
SecondaryButtonClick="CancelClicked"
SecondaryButtonText="{x:Bind domain:Translator.Buttons_Cancel}"
Style="{StaticResource WinoDialogStyle}"
mc:Ignorable="d">
<ContentDialog.Resources>
<x:Double x:Key="ContentDialogMinWidth">400</x:Double>
<x:Double x:Key="ContentDialogMaxWidth">400</x:Double>
<x:Double x:Key="ContentDialogMinHeight">200</x:Double>
<x:Double x:Key="ContentDialogMaxHeight">756</x:Double>
</ContentDialog.Resources>
<StackPanel Spacing="12">
<TextBlock x:Name="DialogDescription" TextWrapping="Wrap" />
<TextBox x:Name="FolderTextBox" Text="{x:Bind CurrentInput, Mode=TwoWay}" />
</StackPanel>
</ContentDialog>

View File

@@ -0,0 +1,45 @@
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace Wino.Dialogs
{
public sealed partial class TextInputDialog : ContentDialog
{
public bool? HasInput { get; set; }
public string CurrentInput
{
get { return (string)GetValue(CurrentInputProperty); }
set { SetValue(CurrentInputProperty, value); }
}
public static readonly DependencyProperty CurrentInputProperty = DependencyProperty.Register(nameof(CurrentInput), typeof(string), typeof(TextInputDialog), new PropertyMetadata(string.Empty));
public TextInputDialog()
{
InitializeComponent();
}
public void SetDescription(string description)
{
DialogDescription.Text = description;
}
public void SetPrimaryButtonText(string text)
{
PrimaryButtonText = text;
}
private void CancelClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
Hide();
}
private void UpdateOrCreateClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
HasInput = true;
Hide();
}
}
}

View File

@@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Composition;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media.Animation;
namespace Wino.Extensions
{
public static class AnimationExtensions
{
#region Composition
public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation(this Compositor compositor, float? from, float to,
double duration, double delay, CompositionEasingFunction easing, AnimationIterationBehavior iterationBehavior)
{
var animation = compositor.CreateScalarKeyFrameAnimation();
animation.Duration = TimeSpan.FromMilliseconds(duration);
if (!delay.Equals(0)) animation.DelayTime = TimeSpan.FromMilliseconds(delay);
if (from.HasValue) animation.InsertKeyFrame(0.0f, from.Value, easing);
animation.InsertKeyFrame(1.0f, to, easing);
animation.IterationBehavior = iterationBehavior;
return animation;
}
public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation(this Compositor compositor, Vector2? from, Vector2 to,
double duration, double delay, CompositionEasingFunction easing, AnimationIterationBehavior iterationBehavior)
{
var animation = compositor.CreateVector2KeyFrameAnimation();
animation.Duration = TimeSpan.FromMilliseconds(duration);
animation.DelayTime = TimeSpan.FromMilliseconds(delay);
if (from.HasValue) animation.InsertKeyFrame(0.0f, from.Value, easing);
animation.InsertKeyFrame(1.0f, to, easing);
animation.IterationBehavior = iterationBehavior;
return animation;
}
public static Vector3KeyFrameAnimation CreateVector3KeyFrameAnimation(this Compositor compositor, Vector2? from, Vector2 to,
double duration, double delay, CompositionEasingFunction easing, AnimationIterationBehavior iterationBehavior)
{
var animation = compositor.CreateVector3KeyFrameAnimation();
animation.Duration = TimeSpan.FromMilliseconds(duration);
animation.DelayTime = TimeSpan.FromMilliseconds(delay);
if (from.HasValue) animation.InsertKeyFrame(0.0f, new Vector3(from.Value, 1.0f), easing);
animation.InsertKeyFrame(1.0f, new Vector3(to, 1.0f), easing);
animation.IterationBehavior = iterationBehavior;
return animation;
}
public static Vector3KeyFrameAnimation CreateVector3KeyFrameAnimation(this Compositor compositor, Vector3? from, Vector3 to,
double duration, double delay, CompositionEasingFunction easing, AnimationIterationBehavior iterationBehavior)
{
var animation = compositor.CreateVector3KeyFrameAnimation();
animation.Duration = TimeSpan.FromMilliseconds(duration);
animation.DelayTime = TimeSpan.FromMilliseconds(delay);
if (from.HasValue) animation.InsertKeyFrame(0.0f, from.Value, easing);
animation.InsertKeyFrame(1.0f, to, easing);
animation.IterationBehavior = iterationBehavior;
return animation;
}
#endregion
#region Xaml Storyboard
public static void Animate(this DependencyObject target, double? from, double to,
string propertyPath, int duration = 400, int startTime = 0,
EasingFunctionBase easing = null, Action completed = null, bool enableDependentAnimation = false)
{
if (easing == null)
{
easing = new ExponentialEase();
}
var db = new DoubleAnimation
{
EnableDependentAnimation = enableDependentAnimation,
To = to,
From = from,
EasingFunction = easing,
Duration = TimeSpan.FromMilliseconds(duration)
};
Storyboard.SetTarget(db, target);
Storyboard.SetTargetProperty(db, propertyPath);
var sb = new Storyboard
{
BeginTime = TimeSpan.FromMilliseconds(startTime)
};
if (completed != null)
{
sb.Completed += (s, e) =>
{
completed();
};
}
sb.Children.Add(db);
sb.Begin();
}
#endregion
}
}

View File

@@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wino.Extensions
{
public enum TransitionDirection
{
TopToBottom,
BottomToTop,
LeftToRight,
RightToLeft
}
public enum ClipAnimationDirection
{
Top,
Bottom,
Left,
Right
}
public enum AnimationAxis
{
X,
Y,
Z
}
public enum AnimationType
{
KeyFrame,
Expression
}
public enum FlickDirection
{
None,
Up,
Down,
Left,
Right
}
public enum ViewState
{
Empty,
Small,
Big,
Full
}
public enum Gesture
{
Initial,
Tap,
Swipe
}
[Flags]
public enum VisualPropertyType
{
None = 0,
Opacity = 1 << 0,
Offset = 1 << 1,
Scale = 1 << 2,
Size = 1 << 3,
RotationAngleInDegrees = 1 << 4,
All = ~0
}
}

View File

@@ -0,0 +1,200 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Composition;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Hosting;
namespace Wino.Extensions
{
public static partial class CompositionExtensions
{
public static void EnableFluidVisibilityAnimation(this UIElement element, AnimationAxis? axis = null,
float showFromOffset = 0.0f, float hideToOffset = 0.0f, Vector3? centerPoint = null,
float showFromScale = 1.0f, float hideToScale = 1.0f, float showDuration = 800.0f, float hideDuration = 800.0f,
int showDelay = 0, int hideDelay = 0, bool animateOpacity = true)
{
var elementVisual = element.Visual();
var compositor = elementVisual.Compositor;
ElementCompositionPreview.SetIsTranslationEnabled(element, true);
ScalarKeyFrameAnimation hideOpacityAnimation = null;
ScalarKeyFrameAnimation showOpacityAnimation = null;
ScalarKeyFrameAnimation hideOffsetAnimation = null;
ScalarKeyFrameAnimation showOffsetAnimation = null;
Vector2KeyFrameAnimation hideScaleAnimation = null;
Vector2KeyFrameAnimation showeScaleAnimation = null;
if (animateOpacity)
{
hideOpacityAnimation = compositor.CreateScalarKeyFrameAnimation();
hideOpacityAnimation.InsertKeyFrame(1.0f, 0.0f);
hideOpacityAnimation.Duration = TimeSpan.FromMilliseconds(hideDuration);
hideOpacityAnimation.DelayTime = TimeSpan.FromMilliseconds(hideDelay);
hideOpacityAnimation.Target = "Opacity";
}
if (!hideToOffset.Equals(0.0f))
{
hideOffsetAnimation = compositor.CreateScalarKeyFrameAnimation();
hideOffsetAnimation.InsertKeyFrame(1.0f, hideToOffset);
hideOffsetAnimation.Duration = TimeSpan.FromMilliseconds(hideDuration);
hideOffsetAnimation.DelayTime = TimeSpan.FromMilliseconds(hideDelay);
hideOffsetAnimation.Target = $"Translation.{axis}";
}
if (centerPoint.HasValue)
{
elementVisual.CenterPoint = centerPoint.Value;
}
if (!hideToScale.Equals(1.0f))
{
hideScaleAnimation = compositor.CreateVector2KeyFrameAnimation();
hideScaleAnimation.InsertKeyFrame(1.0f, new Vector2(hideToScale));
hideScaleAnimation.Duration = TimeSpan.FromMilliseconds(hideDuration);
hideScaleAnimation.DelayTime = TimeSpan.FromMilliseconds(hideDelay);
hideScaleAnimation.Target = "Scale.XY";
}
var hideAnimationGroup = compositor.CreateAnimationGroup();
if (hideOpacityAnimation != null)
{
hideAnimationGroup.Add(hideOpacityAnimation);
}
if (hideOffsetAnimation != null)
{
hideAnimationGroup.Add(hideOffsetAnimation);
}
if (hideScaleAnimation != null)
{
hideAnimationGroup.Add(hideScaleAnimation);
}
ElementCompositionPreview.SetImplicitHideAnimation(element, hideAnimationGroup);
if (animateOpacity)
{
showOpacityAnimation = compositor.CreateScalarKeyFrameAnimation();
showOpacityAnimation.InsertKeyFrame(1.0f, 1.0f);
showOpacityAnimation.Duration = TimeSpan.FromMilliseconds(showDuration);
showOpacityAnimation.DelayTime = TimeSpan.FromMilliseconds(showDelay);
showOpacityAnimation.Target = "Opacity";
}
if (!showFromOffset.Equals(0.0f))
{
showOffsetAnimation = compositor.CreateScalarKeyFrameAnimation();
showOffsetAnimation.InsertKeyFrame(0.0f, showFromOffset);
showOffsetAnimation.InsertKeyFrame(1.0f, 0.0f);
showOffsetAnimation.Duration = TimeSpan.FromMilliseconds(showDuration);
showOffsetAnimation.DelayTime = TimeSpan.FromMilliseconds(showDelay);
showOffsetAnimation.Target = $"Translation.{axis}";
}
if (!showFromScale.Equals(1.0f))
{
showeScaleAnimation = compositor.CreateVector2KeyFrameAnimation();
showeScaleAnimation.InsertKeyFrame(0.0f, new Vector2(showFromScale));
showeScaleAnimation.InsertKeyFrame(1.0f, Vector2.One);
showeScaleAnimation.Duration = TimeSpan.FromMilliseconds(showDuration);
showeScaleAnimation.DelayTime = TimeSpan.FromMilliseconds(showDelay);
showeScaleAnimation.Target = "Scale.XY";
}
var showAnimationGroup = compositor.CreateAnimationGroup();
if (showOpacityAnimation != null)
{
showAnimationGroup.Add(showOpacityAnimation);
}
if (showOffsetAnimation != null)
{
showAnimationGroup.Add(showOffsetAnimation);
}
if (showeScaleAnimation != null)
{
showAnimationGroup.Add(showeScaleAnimation);
}
ElementCompositionPreview.SetImplicitShowAnimation(element, showAnimationGroup);
}
public static void EnableImplicitAnimation(this UIElement element, VisualPropertyType typeToAnimate,
double duration = 800, double delay = 0, CompositionEasingFunction easing = null)
{
var visual = element.Visual();
var compositor = visual.Compositor;
var animationCollection = compositor.CreateImplicitAnimationCollection();
foreach (var type in UtilExtensions.GetValues<VisualPropertyType>())
{
if (!typeToAnimate.HasFlag(type)) continue;
var animation = CreateAnimationByType(compositor, type, duration, delay, easing);
if (animation != null)
{
animationCollection[type.ToString()] = animation;
}
}
visual.ImplicitAnimations = animationCollection;
}
public static void EnableImplicitAnimation(this Visual visual, VisualPropertyType typeToAnimate,
double duration = 800, double delay = 0, CompositionEasingFunction easing = null)
{
var compositor = visual.Compositor;
var animationCollection = compositor.CreateImplicitAnimationCollection();
foreach (var type in UtilExtensions.GetValues<VisualPropertyType>())
{
if (!typeToAnimate.HasFlag(type)) continue;
var animation = CreateAnimationByType(compositor, type, duration, delay, easing);
if (animation != null)
{
animationCollection[type.ToString()] = animation;
}
}
visual.ImplicitAnimations = animationCollection;
}
private static KeyFrameAnimation CreateAnimationByType(Compositor compositor, VisualPropertyType type,
double duration = 800, double delay = 0, CompositionEasingFunction easing = null)
{
KeyFrameAnimation animation;
switch (type)
{
case VisualPropertyType.Offset:
case VisualPropertyType.Scale:
animation = compositor.CreateVector3KeyFrameAnimation();
break;
case VisualPropertyType.Size:
animation = compositor.CreateVector2KeyFrameAnimation();
break;
case VisualPropertyType.Opacity:
case VisualPropertyType.RotationAngleInDegrees:
animation = compositor.CreateScalarKeyFrameAnimation();
break;
default:
return null;
}
animation.InsertExpressionKeyFrame(1.0f, "this.FinalValue", easing);
animation.Duration = TimeSpan.FromMilliseconds(duration);
animation.DelayTime = TimeSpan.FromMilliseconds(delay);
animation.Target = type.ToString();
return animation;
}
}
}

View File

@@ -0,0 +1,127 @@
using System;
using System.Numerics;
using System.Threading.Tasks;
using Windows.UI.Composition;
using Windows.UI.Xaml;
namespace Wino.Extensions
{
public static partial class CompositionExtensions
{
public static void StartSizeAnimation(this UIElement element, Vector2? from = null, Vector2? to = null,
double duration = 800, int delay = 0, CompositionEasingFunction easing = null, Action completed = null,
AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count)
{
CompositionScopedBatch batch = null;
var visual = element.Visual();
var compositor = visual.Compositor;
if (completed != null)
{
batch = compositor.CreateScopedBatch(CompositionBatchTypes.Animation);
batch.Completed += (s, e) => completed();
}
if (to == null)
{
to = Vector2.One;
}
visual.StartAnimation("Size",
compositor.CreateVector2KeyFrameAnimation(from, to.Value, duration, delay, easing, iterationBehavior));
batch?.End();
}
public static void StartSizeAnimation(this Visual visual, Vector2? from = null, Vector2? to = null,
double duration = 800, int delay = 0, CompositionEasingFunction easing = null, Action completed = null,
AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count)
{
CompositionScopedBatch batch = null;
var compositor = visual.Compositor;
if (completed != null)
{
batch = compositor.CreateScopedBatch(CompositionBatchTypes.Animation);
batch.Completed += (s, e) => completed();
}
if (to == null)
{
to = Vector2.One;
}
visual.StartAnimation("Size",
compositor.CreateVector2KeyFrameAnimation(from, to.Value, duration, delay, easing, iterationBehavior));
batch?.End();
}
public static Task StartSizeAnimationAsync(this UIElement element, Vector2? from = null, Vector2? to = null,
double duration = 800, int delay = 0, CompositionEasingFunction easing = null,
AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count)
{
CompositionScopedBatch batch;
var visual = element.Visual();
var compositor = visual.Compositor;
var taskSource = new TaskCompletionSource<bool>();
void Completed(object o, CompositionBatchCompletedEventArgs e)
{
batch.Completed -= Completed;
taskSource.SetResult(true);
}
batch = compositor.CreateScopedBatch(CompositionBatchTypes.Animation);
batch.Completed += Completed;
if (to == null)
{
to = Vector2.One;
}
visual.StartAnimation("Size",
compositor.CreateVector2KeyFrameAnimation(from, to.Value, duration, delay, easing, iterationBehavior));
batch.End();
return taskSource.Task;
}
public static Task StartSizeAnimationAsync(this Visual visual, Vector2? from = null, Vector2? to = null,
double duration = 800, int delay = 0, CompositionEasingFunction easing = null,
AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count)
{
CompositionScopedBatch batch;
var compositor = visual.Compositor;
var taskSource = new TaskCompletionSource<bool>();
void Completed(object o, CompositionBatchCompletedEventArgs e)
{
batch.Completed -= Completed;
taskSource.SetResult(true);
}
batch = compositor.CreateScopedBatch(CompositionBatchTypes.Animation);
batch.Completed += Completed;
if (to == null)
{
to = Vector2.One;
}
visual.StartAnimation("Size",
compositor.CreateVector2KeyFrameAnimation(from, to.Value, duration, delay, easing, iterationBehavior));
batch.End();
return taskSource.Task;
}
}
}

View File

@@ -0,0 +1,20 @@
using Microsoft.UI.Xaml.Controls;
using Wino.Core.Domain.Enums;
namespace Wino.Extensions
{
public static class UIExtensions
{
public static InfoBarSeverity AsMUXCInfoBarSeverity(this InfoBarMessageType messageType)
{
return messageType switch
{
InfoBarMessageType.Error => InfoBarSeverity.Error,
InfoBarMessageType.Warning => InfoBarSeverity.Warning,
InfoBarMessageType.Information => InfoBarSeverity.Informational,
InfoBarMessageType.Success => InfoBarSeverity.Success,
_ => InfoBarSeverity.Informational
};
}
}
}

View File

@@ -0,0 +1,108 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Windows.Foundation;
using Windows.UI.Composition;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Hosting;
using Windows.UI.Xaml.Media;
namespace Wino.Extensions
{
public static class UtilExtensions
{
public static float ToFloat(this double value) => (float)value;
public static List<FrameworkElement> Children(this DependencyObject parent)
{
var list = new List<FrameworkElement>();
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
if (child is FrameworkElement)
{
list.Add(child as FrameworkElement);
}
list.AddRange(Children(child));
}
return list;
}
public static T GetChildByName<T>(this DependencyObject parent, string name)
{
var childControls = Children(parent);
var controls = childControls.OfType<FrameworkElement>();
if (controls == null)
{
return default(T);
}
var control = controls
.Where(x => x.Name.Equals(name))
.Cast<T>()
.First();
return control;
}
public static Visual Visual(this UIElement element) =>
ElementCompositionPreview.GetElementVisual(element);
public static void SetChildVisual(this UIElement element, Visual childVisual) =>
ElementCompositionPreview.SetElementChildVisual(element, childVisual);
public static Point RelativePosition(this UIElement element, UIElement other) =>
element.TransformToVisual(other).TransformPoint(new Point(0, 0));
public static bool IsFullyVisibile(this FrameworkElement element, FrameworkElement parent)
{
if (element == null || parent == null)
return false;
if (element.Visibility != Visibility.Visible)
return false;
var elementBounds = element.TransformToVisual(parent).TransformBounds(new Windows.Foundation.Rect(0, 0, element.ActualWidth, element.ActualHeight));
var containerBounds = new Windows.Foundation.Rect(0, 0, parent.ActualWidth, parent.ActualHeight);
var originalElementWidth = elementBounds.Width;
var originalElementHeight = elementBounds.Height;
elementBounds.Intersect(containerBounds);
var newElementWidth = elementBounds.Width;
var newElementHeight = elementBounds.Height;
return originalElementWidth.Equals(newElementWidth) && originalElementHeight.Equals(newElementHeight);
}
public static void ScrollToElement(this ScrollViewer scrollViewer, FrameworkElement element,
bool isVerticalScrolling = true, bool smoothScrolling = true, float? zoomFactor = null, bool bringToTopOrLeft = true, bool addMargin = true)
{
if (!bringToTopOrLeft && element.IsFullyVisibile(scrollViewer))
return;
var contentArea = (FrameworkElement)scrollViewer.Content;
var position = element.RelativePosition(contentArea);
if (isVerticalScrolling)
{
// Accomodate for additional header.
scrollViewer.ChangeView(null, Math.Max(0, position.Y - (addMargin ? 48 : 0)), zoomFactor, !smoothScrolling);
}
else
{
scrollViewer.ChangeView(position.X, null, zoomFactor, !smoothScrolling);
}
}
public static IEnumerable<T> GetValues<T>() => Enum.GetValues(typeof(T)).Cast<T>();
}
}

View File

@@ -0,0 +1,54 @@
using System.Collections.Generic;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
namespace Wino.Helpers
{
public static class WinoVisualTreeHelper
{
public static T GetChildObject<T>(DependencyObject obj, string name) where T : FrameworkElement
{
DependencyObject child = null;
T grandChild = null;
for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
{
child = VisualTreeHelper.GetChild(obj, i);
if (child is T && (((T)child).Name == name | string.IsNullOrEmpty(name)))
{
return (T)child;
}
else
{
grandChild = GetChildObject<T>(child, name);
}
if (grandChild != null)
{
return grandChild;
}
}
return null;
}
public static IEnumerable<T> FindDescendants<T>(this DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
yield return (T)child;
}
foreach (T childOfChild in FindDescendants<T>(child))
{
yield return childOfChild;
}
}
}
}
}
}

View File

@@ -0,0 +1,286 @@
using System;
using System.Linq;
using Microsoft.Toolkit.Uwp.Helpers;
using Microsoft.UI.Xaml.Controls;
using Windows.UI;
using Windows.UI.Text;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Markup;
using Windows.UI.Xaml.Media;
using Wino.Core.Domain;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.MailItem;
using Wino.Core.UWP.Controls;
namespace Wino.Helpers
{
public static class XamlHelpers
{
private const string TwentyFourHourTimeFormat = "HH:mm";
private const string TwelveHourTimeFormat = "hh:mm tt";
#region Converters
public static Visibility ReverseBoolToVisibilityConverter(bool value) => value ? Visibility.Collapsed : Visibility.Visible;
public static Visibility ReverseVisibilityConverter(Visibility visibility) => visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
public static bool ReverseBoolConverter(bool value) => !value;
public static bool ShouldDisplayPreview(string text) => text.Any(x => char.IsLetter(x));
public static bool CountToBooleanConverter(int value) => value > 0;
public static bool ObjectEquals(object obj1, object obj2) => object.Equals(obj1, obj2);
public static Visibility CountToVisibilityConverter(int value) => value > 0 ? Visibility.Visible : Visibility.Collapsed;
public static Visibility CountToVisibilityConverterWithThreshold(int value, int threshold) => value > threshold ? Visibility.Visible : Visibility.Collapsed;
public static InfoBarSeverity InfoBarSeverityConverter(InfoBarMessageType messageType)
{
return messageType switch
{
InfoBarMessageType.Information => InfoBarSeverity.Informational,
InfoBarMessageType.Success => InfoBarSeverity.Success,
InfoBarMessageType.Warning => InfoBarSeverity.Warning,
InfoBarMessageType.Error => InfoBarSeverity.Error,
_ => InfoBarSeverity.Informational,
};
}
public static SolidColorBrush GetSolidColorBrushFromHex(string colorHex) => string.IsNullOrEmpty(colorHex) ? new SolidColorBrush(Colors.Transparent) : new SolidColorBrush(colorHex.ToColor());
public static Visibility IsSelectionModeMultiple(ListViewSelectionMode mode) => mode == ListViewSelectionMode.Multiple ? Visibility.Visible : Visibility.Collapsed;
public static FontWeight GetFontWeightBySyncState(bool isSyncing) => isSyncing ? FontWeights.SemiBold : FontWeights.Normal;
public static FontWeight GetFontWeightByChildSelectedState(bool isChildSelected) => isChildSelected ? FontWeights.SemiBold : FontWeights.Normal;
public static Visibility StringToVisibilityConverter(string value) => string.IsNullOrWhiteSpace(value) ? Visibility.Collapsed : Visibility.Visible;
public static Visibility StringToVisibilityReversedConverter(string value) => string.IsNullOrWhiteSpace(value) ? Visibility.Visible : Visibility.Collapsed;
public static string GetMailItemDisplaySummaryForListing(bool isDraft, DateTime receivedDate, bool prefer24HourTime)
{
if (isDraft)
return Translator.Draft;
else
{
var localTime = receivedDate.ToLocalTime();
return prefer24HourTime ? localTime.ToString(TwentyFourHourTimeFormat) : localTime.ToString(TwelveHourTimeFormat);
}
}
public static string GetMailItemSubject(string subject) => string.IsNullOrWhiteSpace(subject) ? $"({Translator.MailItemNoSubject})" : subject;
public static string GetCreationDateString(DateTime date, bool prefer24HourTime)
{
var localTime = date.ToLocalTime();
return $"{localTime.ToLongDateString()} {(prefer24HourTime ? localTime.ToString(TwentyFourHourTimeFormat) : localTime.ToString(TwelveHourTimeFormat))}";
}
public static string GetMailGroupDateString(object groupObject)
{
if (groupObject is string stringObject)
return stringObject;
object dateObject = null;
// From regular mail header template
if (groupObject is DateTime groupedDate)
dateObject = groupedDate;
else if (groupObject is IGrouping<object, IMailItem> groupKey)
{
// From semantic group header.
dateObject = groupKey.Key;
}
if (dateObject != null)
{
if (dateObject is DateTime dateTimeValue)
{
if (dateTimeValue == DateTime.Today)
return Translator.Today;
else if (dateTimeValue == DateTime.Today.AddDays(-1))
return Translator.Yesterday;
else
return dateTimeValue.ToLongDateString();
}
else
return dateObject.ToString();
}
return Translator.UnknownDateHeader;
}
public static bool ConnectionStatusEquals(WinoServerConnectionStatus winoServerConnectionStatus, WinoServerConnectionStatus connectionStatus) => winoServerConnectionStatus == connectionStatus;
#endregion
#region Wino Font Icon Transformation
public static WinoIconGlyph GetWinoIconGlyph(FilterOptionType type) => type switch
{
FilterOptionType.All => WinoIconGlyph.Mail,
FilterOptionType.Unread => WinoIconGlyph.MarkUnread,
FilterOptionType.Flagged => WinoIconGlyph.Flag,
FilterOptionType.Mentions => WinoIconGlyph.NewMail,
FilterOptionType.Files => WinoIconGlyph.Attachment,
_ => WinoIconGlyph.None,
};
public static WinoIconGlyph GetWinoIconGlyph(SortingOptionType type) => type switch
{
SortingOptionType.Sender => WinoIconGlyph.SortTextDesc,
SortingOptionType.ReceiveDate => WinoIconGlyph.SortLinesDesc,
_ => WinoIconGlyph.None,
};
public static WinoIconGlyph GetWinoIconGlyph(MailOperation operation)
{
return operation switch
{
MailOperation.None => WinoIconGlyph.None,
MailOperation.Archive => WinoIconGlyph.Archive,
MailOperation.UnArchive => WinoIconGlyph.UnArchive,
MailOperation.SoftDelete => WinoIconGlyph.Delete,
MailOperation.HardDelete => WinoIconGlyph.Delete,
MailOperation.Move => WinoIconGlyph.Forward,
MailOperation.MoveToJunk => WinoIconGlyph.Blocked,
MailOperation.MoveToFocused => WinoIconGlyph.None,
MailOperation.MoveToOther => WinoIconGlyph.None,
MailOperation.AlwaysMoveToOther => WinoIconGlyph.None,
MailOperation.AlwaysMoveToFocused => WinoIconGlyph.None,
MailOperation.SetFlag => WinoIconGlyph.Flag,
MailOperation.ClearFlag => WinoIconGlyph.ClearFlag,
MailOperation.MarkAsRead => WinoIconGlyph.MarkRead,
MailOperation.MarkAsUnread => WinoIconGlyph.MarkUnread,
MailOperation.MarkAsNotJunk => WinoIconGlyph.Blocked,
MailOperation.Ignore => WinoIconGlyph.Ignore,
MailOperation.Reply => WinoIconGlyph.Reply,
MailOperation.ReplyAll => WinoIconGlyph.ReplyAll,
MailOperation.Zoom => WinoIconGlyph.Zoom,
MailOperation.SaveAs => WinoIconGlyph.Save,
MailOperation.Print => WinoIconGlyph.Print,
MailOperation.Find => WinoIconGlyph.Find,
MailOperation.Forward => WinoIconGlyph.Forward,
MailOperation.DarkEditor => WinoIconGlyph.DarkEditor,
MailOperation.LightEditor => WinoIconGlyph.LightEditor,
_ => WinoIconGlyph.None,
};
}
public static WinoIconGlyph GetPathGeometry(FolderOperation operation)
{
return operation switch
{
FolderOperation.None => WinoIconGlyph.None,
FolderOperation.Pin => WinoIconGlyph.Pin,
FolderOperation.Unpin => WinoIconGlyph.UnPin,
FolderOperation.MarkAllAsRead => WinoIconGlyph.MarkRead,
FolderOperation.DontSync => WinoIconGlyph.DontSync,
FolderOperation.Empty => WinoIconGlyph.EmptyFolder,
FolderOperation.Rename => WinoIconGlyph.Rename,
FolderOperation.Delete => WinoIconGlyph.Delete,
FolderOperation.Move => WinoIconGlyph.Forward,
FolderOperation.TurnOffNotifications => WinoIconGlyph.TurnOfNotifications,
FolderOperation.CreateSubFolder => WinoIconGlyph.CreateFolder,
_ => WinoIconGlyph.None,
};
}
public static WinoIconGlyph GetSpecialFolderPathIconGeometry(SpecialFolderType specialFolderType)
{
return specialFolderType switch
{
SpecialFolderType.Inbox => WinoIconGlyph.SpecialFolderInbox,
SpecialFolderType.Starred => WinoIconGlyph.SpecialFolderStarred,
SpecialFolderType.Important => WinoIconGlyph.SpecialFolderImportant,
SpecialFolderType.Sent => WinoIconGlyph.SpecialFolderSent,
SpecialFolderType.Draft => WinoIconGlyph.SpecialFolderDraft,
SpecialFolderType.Archive => WinoIconGlyph.SpecialFolderArchive,
SpecialFolderType.Deleted => WinoIconGlyph.SpecialFolderDeleted,
SpecialFolderType.Junk => WinoIconGlyph.SpecialFolderJunk,
SpecialFolderType.Chat => WinoIconGlyph.SpecialFolderChat,
SpecialFolderType.Category => WinoIconGlyph.SpecialFolderCategory,
SpecialFolderType.Unread => WinoIconGlyph.SpecialFolderUnread,
SpecialFolderType.Forums => WinoIconGlyph.SpecialFolderForums,
SpecialFolderType.Updates => WinoIconGlyph.SpecialFolderUpdated,
SpecialFolderType.Personal => WinoIconGlyph.SpecialFolderPersonal,
SpecialFolderType.Promotions => WinoIconGlyph.SpecialFolderPromotions,
SpecialFolderType.Social => WinoIconGlyph.SpecialFolderSocial,
SpecialFolderType.Other => WinoIconGlyph.SpecialFolderOther,
SpecialFolderType.More => WinoIconGlyph.SpecialFolderMore,
_ => WinoIconGlyph.None,
};
}
public static WinoIconGlyph GetProviderIcon(MailProviderType providerType)
{
return providerType switch
{
MailProviderType.Outlook => WinoIconGlyph.Microsoft,
MailProviderType.Gmail => WinoIconGlyph.Google,
MailProviderType.Office365 => WinoIconGlyph.Microsoft,
MailProviderType.IMAP4 => WinoIconGlyph.IMAP,
_ => WinoIconGlyph.None,
};
}
public static Geometry GetPathGeometry(string pathMarkup)
{
string xaml =
"<Path " +
"xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>" +
"<Path.Data>" + pathMarkup + "</Path.Data></Path>";
var path = XamlReader.Load(xaml) as Windows.UI.Xaml.Shapes.Path;
Geometry geometry = path.Data;
path.Data = null;
return geometry;
}
#endregion
#region Internationalization
public static string GetOperationString(MailOperation operation)
{
return operation switch
{
MailOperation.None => "unknown",
MailOperation.Archive => Translator.MailOperation_Archive,
MailOperation.UnArchive => Translator.MailOperation_Unarchive,
MailOperation.SoftDelete => Translator.MailOperation_Delete,
MailOperation.HardDelete => Translator.MailOperation_Delete,
MailOperation.Move => Translator.MailOperation_Move,
MailOperation.MoveToJunk => Translator.MailOperation_MoveJunk,
MailOperation.MoveToFocused => Translator.MailOperation_MoveFocused,
MailOperation.MoveToOther => Translator.MailOperation_MoveOther,
MailOperation.AlwaysMoveToOther => Translator.MailOperation_AlwaysMoveOther,
MailOperation.AlwaysMoveToFocused => Translator.MailOperation_AlwaysMoveFocused,
MailOperation.SetFlag => Translator.MailOperation_SetFlag,
MailOperation.ClearFlag => Translator.MailOperation_ClearFlag,
MailOperation.MarkAsRead => Translator.MailOperation_MarkAsRead,
MailOperation.MarkAsUnread => Translator.MailOperation_MarkAsUnread,
MailOperation.MarkAsNotJunk => Translator.MailOperation_MarkNotJunk,
MailOperation.Seperator => string.Empty,
MailOperation.Ignore => Translator.MailOperation_Ignore,
MailOperation.Reply => Translator.MailOperation_Reply,
MailOperation.ReplyAll => Translator.MailOperation_ReplyAll,
MailOperation.Zoom => Translator.MailOperation_Zoom,
MailOperation.SaveAs => Translator.MailOperation_SaveAs,
MailOperation.Find => Translator.MailOperation_Find,
MailOperation.Forward => Translator.MailOperation_Forward,
MailOperation.DarkEditor => string.Empty,
MailOperation.LightEditor => string.Empty,
MailOperation.Print => Translator.MailOperation_Print,
MailOperation.Navigate => Translator.MailOperation_Navigate,
_ => "unknown",
};
}
public static string GetOperationString(FolderOperation operation)
{
return operation switch
{
FolderOperation.None => string.Empty,
FolderOperation.Pin => Translator.FolderOperation_Pin,
FolderOperation.Unpin => Translator.FolderOperation_Unpin,
FolderOperation.MarkAllAsRead => Translator.FolderOperation_MarkAllAsRead,
FolderOperation.DontSync => Translator.FolderOperation_DontSync,
FolderOperation.Empty => Translator.FolderOperation_Empty,
FolderOperation.Rename => Translator.FolderOperation_Rename,
FolderOperation.Delete => Translator.FolderOperation_Delete,
FolderOperation.Move => Translator.FolderOperation_Move,
FolderOperation.CreateSubFolder => Translator.FolderOperation_CreateSubFolder,
_ => string.Empty,
};
}
#endregion
}
}

View File

@@ -0,0 +1,25 @@
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Wino.Core.UWP.Models.Personalization;
namespace Wino.Core.UWP.Selectors
{
public class AppThemePreviewTemplateSelector : DataTemplateSelector
{
public DataTemplate SystemThemeTemplate { get; set; }
public DataTemplate PreDefinedThemeTemplate { get; set; }
public DataTemplate CustomAppTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item)
{
if (item is SystemAppTheme)
return SystemThemeTemplate;
else if (item is PreDefinedAppTheme)
return PreDefinedThemeTemplate;
else if (item is CustomAppTheme)
return CustomAppTemplate;
return base.SelectTemplateCore(item);
}
}
}

View File

@@ -0,0 +1,38 @@
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Wino.Core.Domain.Enums;
namespace Wino.Core.UWP.Selectors
{
public class CustomWinoMessageDialogIconSelector : DataTemplateSelector
{
public DataTemplate InfoIconTemplate { get; set; }
public DataTemplate WarningIconTemplate { get; set; }
public DataTemplate QuestionIconTemplate { get; set; }
public DataTemplate ErrorIconTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
if (item == null) return null;
if (item is WinoCustomMessageDialogIcon icon)
{
switch (icon)
{
case WinoCustomMessageDialogIcon.Information:
return InfoIconTemplate;
case WinoCustomMessageDialogIcon.Warning:
return WarningIconTemplate;
case WinoCustomMessageDialogIcon.Error:
return ErrorIconTemplate;
case WinoCustomMessageDialogIcon.Question:
return QuestionIconTemplate;
default:
throw new Exception("Unknown custom message dialog icon.");
}
}
return base.SelectTemplateCore(item, container);
}
}
}

View File

@@ -0,0 +1,52 @@
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Wino.Core.Domain.Enums;
namespace Wino.Core.UWP.Selectors
{
public class FileAttachmentTypeSelector : DataTemplateSelector
{
public DataTemplate None { get; set; }
public DataTemplate Executable { get; set; }
public DataTemplate Image { get; set; }
public DataTemplate Audio { get; set; }
public DataTemplate Video { get; set; }
public DataTemplate PDF { get; set; }
public DataTemplate HTML { get; set; }
public DataTemplate RarArchive { get; set; }
public DataTemplate Archive { get; set; }
public DataTemplate Other { get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
if (item == null)
return None;
var type = (MailAttachmentType)item;
switch (type)
{
case MailAttachmentType.None:
return None;
case MailAttachmentType.Executable:
return Executable;
case MailAttachmentType.Image:
return Image;
case MailAttachmentType.Audio:
return Audio;
case MailAttachmentType.Video:
return Video;
case MailAttachmentType.PDF:
return PDF;
case MailAttachmentType.HTML:
return HTML;
case MailAttachmentType.RarArchive:
return RarArchive;
case MailAttachmentType.Archive:
return Archive;
default:
return Other;
}
}
}
}

View File

@@ -0,0 +1,59 @@
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Wino.Core.MenuItems;
namespace Wino.Core.UWP.Selectors
{
public class NavigationMenuTemplateSelector : DataTemplateSelector
{
public DataTemplate MenuItemTemplate { get; set; }
public DataTemplate AccountManagementTemplate { get; set; }
public DataTemplate ClickableAccountMenuTemplate { get; set; }
public DataTemplate MergedAccountTemplate { get; set; }
public DataTemplate MergedAccountFolderTemplate { get; set; }
public DataTemplate MergedAccountMoreExpansionItemTemplate { get; set; }
public DataTemplate FolderMenuTemplate { get; set; }
public DataTemplate SettingsItemTemplate { get; set; }
public DataTemplate MoreItemsFolderTemplate { get; set; }
public DataTemplate RatingItemTemplate { get; set; }
public DataTemplate CreateNewFolderTemplate { get; set; }
public DataTemplate SeperatorTemplate { get; set; }
public DataTemplate NewMailTemplate { get; set; }
public DataTemplate CategoryItemsTemplate { get; set; }
public DataTemplate FixAuthenticationIssueTemplate { get; set; }
public DataTemplate FixMissingFolderConfigTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item)
{
if (item is NewMailMenuItem)
return NewMailTemplate;
else if (item is SettingsItem)
return SettingsItemTemplate;
else if (item is SeperatorItem)
return SeperatorTemplate;
else if (item is AccountMenuItem accountMenuItem)
// Merged inbox account menu items must be nested.
return ClickableAccountMenuTemplate;
else if (item is ManageAccountsMenuItem)
return AccountManagementTemplate;
else if (item is RateMenuItem)
return RatingItemTemplate;
else if (item is MergedAccountMenuItem)
return MergedAccountTemplate;
else if (item is MergedAccountMoreFolderMenuItem)
return MergedAccountMoreExpansionItemTemplate;
else if (item is MergedAccountFolderMenuItem)
return MergedAccountFolderTemplate;
else if (item is FolderMenuItem)
return FolderMenuTemplate;
else if (item is FixAccountIssuesMenuItem fixAccountIssuesMenuItem)
return fixAccountIssuesMenuItem.Account.AttentionReason == Domain.Enums.AccountAttentionReason.MissingSystemFolderConfiguration
? FixMissingFolderConfigTemplate : FixAuthenticationIssueTemplate;
else
{
var type = item.GetType();
return null;
}
}
}
}

View File

@@ -0,0 +1,27 @@
using System.Linq;
using Windows.UI.Xaml;
using Wino.Core.Domain.Interfaces;
using Wino.Core.UWP;
namespace Wino.Services
{
public class ApplicationResourceManager : IApplicationResourceManager<ResourceDictionary>
{
public void AddResource(ResourceDictionary resource)
=> WinoApplication.Current.Resources.MergedDictionaries.Add(resource);
public void RemoveResource(ResourceDictionary resource)
=> WinoApplication.Current.Resources.MergedDictionaries.Remove(resource);
public bool ContainsResourceKey(string resourceKey)
=> WinoApplication.Current.Resources.ContainsKey(resourceKey);
public ResourceDictionary GetLastResource()
=> WinoApplication.Current.Resources.MergedDictionaries.LastOrDefault();
public void ReplaceResource(string resourceKey, object resource)
=> WinoApplication.Current.Resources[resourceKey] = resource;
public TReturnType GetResource<TReturnType>(string resourceKey)
=> (TReturnType)WinoApplication.Current.Resources[resourceKey];
}
}

View File

@@ -34,6 +34,11 @@ namespace Wino.Core.UWP.Services
return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromInvariantString(value);
}
if (typeof(T) == typeof(TimeSpan))
{
return (T)(object)TimeSpan.Parse(value);
}
return (T)Convert.ChangeType(value, typeof(T));
}

View File

@@ -0,0 +1,205 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.Toolkit.Uwp.Helpers;
using Serilog;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Wino.Core.Domain;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
using Wino.Core.UWP.Extensions;
using Wino.Dialogs;
using Wino.Messaging.Client.Shell;
namespace Wino.Core.UWP.Services
{
public class DialogServiceBase : IDialogServiceBase
{
private SemaphoreSlim _presentationSemaphore = new SemaphoreSlim(1);
protected IThemeService ThemeService { get; }
protected IConfigurationService ConfigurationService { get; }
protected IApplicationResourceManager<ResourceDictionary> ApplicationResourceManager { get; }
public DialogServiceBase(IThemeService themeService, IConfigurationService configurationService, IApplicationResourceManager<ResourceDictionary> applicationResourceManager)
{
ThemeService = themeService;
ConfigurationService = configurationService;
ApplicationResourceManager = applicationResourceManager;
}
private async Task<StorageFile> PickFileAsync(params object[] typeFilters)
{
var picker = new FileOpenPicker
{
ViewMode = PickerViewMode.Thumbnail
};
foreach (var filter in typeFilters)
{
picker.FileTypeFilter.Add(filter.ToString());
}
var file = await picker.PickSingleFileAsync();
if (file == null) return null;
Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.AddOrReplace("FilePickerPath", file);
return file;
}
public async Task<byte[]> PickWindowsFileContentAsync(params object[] typeFilters)
{
var file = await PickFileAsync(typeFilters);
if (file == null) return [];
return await file.ReadBytesAsync();
}
public Task ShowMessageAsync(string message, string title, WinoCustomMessageDialogIcon icon = WinoCustomMessageDialogIcon.Information)
=> ShowWinoCustomMessageDialogAsync(title, message, Translator.Buttons_Close, icon);
public Task<bool> ShowConfirmationDialogAsync(string question, string title, string confirmationButtonTitle)
=> ShowWinoCustomMessageDialogAsync(title, question, confirmationButtonTitle, WinoCustomMessageDialogIcon.Question, Translator.Buttons_Cancel, string.Empty);
public async Task<bool> ShowWinoCustomMessageDialogAsync(string title,
string description,
string approveButtonText,
WinoCustomMessageDialogIcon? icon,
string cancelButtonText = "",
string dontAskAgainConfigurationKey = "")
{
// This config key has been marked as don't ask again already.
// Return immidiate result without presenting the dialog.
bool isDontAskEnabled = !string.IsNullOrEmpty(dontAskAgainConfigurationKey);
if (isDontAskEnabled && ConfigurationService.Get(dontAskAgainConfigurationKey, false)) return false;
var informationContainer = new CustomMessageDialogInformationContainer(title, description, icon.Value, isDontAskEnabled);
var dialog = new ContentDialog
{
Style = ApplicationResourceManager.GetResource<Style>("WinoDialogStyle"),
RequestedTheme = ThemeService.RootTheme.ToWindowsElementTheme(),
DefaultButton = ContentDialogButton.Primary,
PrimaryButtonText = approveButtonText,
ContentTemplate = ApplicationResourceManager.GetResource<DataTemplate>("CustomWinoContentDialogContentTemplate"),
Content = informationContainer
};
if (!string.IsNullOrEmpty(cancelButtonText))
{
dialog.SecondaryButtonText = cancelButtonText;
}
var dialogResult = await HandleDialogPresentationAsync(dialog);
// Mark this key to not ask again if user checked the checkbox.
if (informationContainer.IsDontAskChecked)
{
ConfigurationService.Set(dontAskAgainConfigurationKey, true);
}
return dialogResult == ContentDialogResult.Primary;
}
/// <summary>
/// Waits for PopupRoot to be available before presenting the dialog and returns the result after presentation.
/// </summary>
/// <param name="dialog">Dialog to present and wait for closing.</param>
/// <returns>Dialog result from WinRT.</returns>
public async Task<ContentDialogResult> HandleDialogPresentationAsync(ContentDialog dialog)
{
await _presentationSemaphore.WaitAsync();
try
{
return await dialog.ShowAsync();
}
catch (Exception ex)
{
Log.Error(ex, $"Handling dialog service failed. Dialog was {dialog.GetType().Name}");
}
finally
{
_presentationSemaphore.Release();
}
return ContentDialogResult.None;
}
public void InfoBarMessage(string title, string message, InfoBarMessageType messageType)
=> WeakReferenceMessenger.Default.Send(new InfoBarMessageRequested(messageType, title, message));
public void InfoBarMessage(string title, string message, InfoBarMessageType messageType, string actionButtonText, Action action)
=> WeakReferenceMessenger.Default.Send(new InfoBarMessageRequested(messageType, title, message, actionButtonText, action));
public void ShowNotSupportedMessage()
=> InfoBarMessage(Translator.Info_UnsupportedFunctionalityTitle,
Translator.Info_UnsupportedFunctionalityDescription,
InfoBarMessageType.Error);
public async Task<string> ShowTextInputDialogAsync(string currentInput, string dialogTitle, string dialogDescription, string primaryButtonText)
{
var inputDialog = new TextInputDialog()
{
CurrentInput = currentInput,
RequestedTheme = ThemeService.RootTheme.ToWindowsElementTheme(),
Title = dialogTitle
};
inputDialog.SetDescription(dialogDescription);
inputDialog.SetPrimaryButtonText(primaryButtonText);
await HandleDialogPresentationAsync(inputDialog);
if (inputDialog.HasInput.GetValueOrDefault() && !currentInput.Equals(inputDialog.CurrentInput))
return inputDialog.CurrentInput;
return string.Empty;
}
public async Task<string> PickWindowsFolderAsync()
{
var picker = new FolderPicker
{
SuggestedStartLocation = PickerLocationId.DocumentsLibrary
};
picker.FileTypeFilter.Add("*");
var pickedFolder = await picker.PickSingleFolderAsync();
if (pickedFolder != null)
{
Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.AddOrReplace("FolderPickerToken", pickedFolder);
return pickedFolder.Path;
}
return string.Empty;
}
public async Task<bool> ShowCustomThemeBuilderDialogAsync()
{
var themeBuilderDialog = new CustomThemeBuilderDialog()
{
RequestedTheme = ThemeService.RootTheme.ToWindowsElementTheme()
};
var dialogResult = await HandleDialogPresentationAsync(themeBuilderDialog);
return dialogResult == ContentDialogResult.Primary;
}
}
}

View File

@@ -0,0 +1,28 @@
using System;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Animation;
using Wino.Core.Domain.Models.Navigation;
namespace Wino.Core.UWP.Services
{
public class NavigationServiceBase
{
public NavigationTransitionInfo GetNavigationTransitionInfo(NavigationTransitionType transition)
{
return transition switch
{
NavigationTransitionType.DrillIn => new DrillInNavigationTransitionInfo(),
NavigationTransitionType.Entrance => new EntranceNavigationTransitionInfo(),
_ => new SuppressNavigationTransitionInfo(),
};
}
public Type GetCurrentFrameType(ref Frame _frame)
{
if (_frame != null && _frame.Content != null)
return _frame.Content.GetType();
return null;
}
}
}

View File

@@ -7,7 +7,7 @@ using Serilog;
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;
using Wino.Core.Domain;
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Entities.Mail;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.MailItem;

View File

@@ -1,10 +1,14 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using CommunityToolkit.Mvvm.ComponentModel;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Calendar;
using Wino.Core.Domain.Models.Reader;
using Wino.Core.Domain.Translations;
using Wino.Core.Services;
namespace Wino.Core.UWP.Services
@@ -213,5 +217,77 @@ namespace Wino.Core.UWP.Services
get => _configurationService.Get(nameof(ServerTerminationBehavior), ServerBackgroundMode.MinimizedTray);
set => SaveProperty(propertyName: nameof(ServerTerminationBehavior), value);
}
public DayOfWeek FirstDayOfWeek
{
get => _configurationService.Get(nameof(FirstDayOfWeek), DayOfWeek.Monday);
set => SaveProperty(propertyName: nameof(FirstDayOfWeek), value);
}
public double HourHeight
{
get => _configurationService.Get(nameof(HourHeight), 60.0);
set => SaveProperty(propertyName: nameof(HourHeight), value);
}
public TimeSpan WorkingHourStart
{
get => _configurationService.Get(nameof(WorkingHourStart), new TimeSpan(8, 0, 0));
set => SaveProperty(propertyName: nameof(WorkingHourStart), value);
}
public TimeSpan WorkingHourEnd
{
get => _configurationService.Get(nameof(WorkingHourEnd), new TimeSpan(17, 0, 0));
set => SaveProperty(propertyName: nameof(WorkingHourEnd), value);
}
public DayOfWeek WorkingDayStart
{
get => _configurationService.Get(nameof(WorkingDayStart), DayOfWeek.Monday);
set => SaveProperty(propertyName: nameof(WorkingDayStart), value);
}
public DayOfWeek WorkingDayEnd
{
get => _configurationService.Get(nameof(WorkingDayEnd), DayOfWeek.Friday);
set => SaveProperty(propertyName: nameof(WorkingDayEnd), value);
}
public CalendarSettings GetCurrentCalendarSettings()
{
var workingDays = GetDaysBetween(WorkingDayStart, WorkingDayEnd);
return new CalendarSettings(FirstDayOfWeek,
workingDays,
WorkingHourStart,
WorkingHourEnd,
HourHeight,
Prefer24HourTimeFormat ? DayHeaderDisplayType.TwentyFourHour : DayHeaderDisplayType.TwelveHour,
new CultureInfo(WinoTranslationDictionary.GetLanguageFileNameRelativePath(CurrentLanguage)));
}
private List<DayOfWeek> GetDaysBetween(DayOfWeek startDay, DayOfWeek endDay)
{
var daysOfWeek = new List<DayOfWeek>();
int currentDay = (int)startDay;
int endDayInt = (int)endDay;
// If endDay is before startDay in the week, wrap around
if (endDayInt < currentDay)
{
endDayInt += 7;
}
// Collect days from startDay to endDay
while (currentDay <= endDayInt)
{
daysOfWeek.Add((DayOfWeek)(currentDay % 7));
currentDay++;
}
return daysOfWeek;
}
}
}

View File

@@ -1,9 +1,8 @@
using System;
using System.ComponentModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
using Wino.Messaging.Client.Shell;
namespace Wino.Services
{
@@ -20,8 +19,10 @@ namespace Wino.Services
{
_configurationService = configurationService;
openPaneLength = _configurationService.Get(OpenPaneLengthKey, 320d);
_openPaneLength = _configurationService.Get(OpenPaneLengthKey, 320d);
_mailListPaneLength = _configurationService.Get(MailListPaneLengthKey, 420d);
_calendarDisplayType = _configurationService.Get(nameof(CalendarDisplayType), CalendarDisplayType.Week);
_dayDisplayCount = _configurationService.Get(nameof(DayDisplayCount), 1);
PropertyChanged += ServicePropertyChanged;
}
@@ -80,15 +81,13 @@ namespace Wino.Services
}
}
#region Settings
private double openPaneLength;
private double _openPaneLength;
public double OpenPaneLength
{
get => openPaneLength;
get => _openPaneLength;
set
{
if (SetProperty(ref openPaneLength, value))
if (SetProperty(ref _openPaneLength, value))
{
_configurationService.Set(OpenPaneLengthKey, value);
}
@@ -106,10 +105,33 @@ namespace Wino.Services
_configurationService.Set(MailListPaneLengthKey, value);
}
}
}
#endregion
private CalendarDisplayType _calendarDisplayType;
public CalendarDisplayType CalendarDisplayType
{
get => _calendarDisplayType;
set
{
if (SetProperty(ref _calendarDisplayType, value))
{
_configurationService.Set(nameof(CalendarDisplayType), value);
}
}
}
private int _dayDisplayCount;
public int DayDisplayCount
{
get => _dayDisplayCount;
set
{
if (SetProperty(ref _dayDisplayCount, value))
{
_configurationService.Set(nameof(DayDisplayCount), value);
}
}
}
private void UpdateAppCoreWindowTitle()
{

View File

@@ -15,9 +15,9 @@ namespace Wino.Core.UWP.Services
private const string LatestAskedKey = nameof(LatestAskedKey);
private readonly IConfigurationService _configurationService;
private readonly IDialogService _dialogService;
private readonly IMailDialogService _dialogService;
public StoreRatingService(IConfigurationService configurationService, IDialogService dialogService)
public StoreRatingService(IConfigurationService configurationService, IMailDialogService dialogService)
{
_configurationService = configurationService;
_dialogService = dialogService;

View File

@@ -0,0 +1,31 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Microsoft.UI.Xaml.Media">
<SolidColorBrush x:Key="FlaggedBrush">#e74c3c</SolidColorBrush>
<SolidColorBrush x:Key="DeleteBrush">#e74c3c</SolidColorBrush>
<SolidColorBrush x:Key="AttentionBrush">#ff7675</SolidColorBrush>
<SolidColorBrush x:Key="FolderSyncBrush">#1abc9c</SolidColorBrush>
<SolidColorBrush x:Key="AliasUnverifiedBrush">#ff7675</SolidColorBrush>
<SolidColorBrush x:Key="AliasVerifiedBrush">#1abc9c</SolidColorBrush>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Name="Light">
<SolidColorBrush x:Key="AttachmentBrush">#fdcb6e</SolidColorBrush>
<SolidColorBrush x:Key="SettingsPaneBorderBrush">#636e72</SolidColorBrush>
<SolidColorBrush x:Key="WinoContentZoneBackgroud" Color="White" />
<SolidColorBrush x:Key="MailItemFlaggedBackgroundBrush" Color="#ffffcc" />
<SolidColorBrush x:Key="InformationBrush">#34495e</SolidColorBrush>
</ResourceDictionary>
<ResourceDictionary x:Name="Dark">
<SolidColorBrush x:Key="AttachmentBrush">#fdcb6e</SolidColorBrush>
<SolidColorBrush x:Key="SettingsPaneBorderBrush">#2d3436</SolidColorBrush>
<StaticResource x:Key="WinoContentZoneBackgroud" ResourceKey="LayerFillColorDefaultBrush" />
<SolidColorBrush x:Key="MailItemFlaggedBackgroundBrush" Color="#576574" />
<SolidColorBrush x:Key="InformationBrush">#ecf0f1</SolidColorBrush>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>

View File

@@ -0,0 +1,32 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Wino.Core.UWP.Controls">
<!-- Flagged -->
<DataTemplate x:Key="FlaggedSymbolControlTemplate">
<Viewbox
Width="14"
HorizontalAlignment="Center"
VerticalAlignment="Top">
<controls:WinoFontIcon
Margin="2,0,0,0"
Foreground="{StaticResource FlaggedBrush}"
Icon="Flag" />
</Viewbox>
</DataTemplate>
<!-- Attachments -->
<DataTemplate x:Key="AttachmentSymbolControlTemplate">
<Viewbox
x:Name="AttachmentSymbol"
Width="14"
HorizontalAlignment="Center"
VerticalAlignment="Bottom">
<controls:WinoFontIcon
Margin="2,0,0,0"
Foreground="{StaticResource AttachmentBrush}"
Icon="Attachment" />
</Viewbox>
</DataTemplate>
</ResourceDictionary>

View File

@@ -0,0 +1,8 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="using:Wino.Converters">
<converters:ReverseBooleanToVisibilityConverter x:Key="ReverseBooleanToVisibilityConverter" />
<converters:ReverseBooleanConverter x:Key="ReverseBooleanConverter" />
<converters:GridLengthConverter x:Key="GridLengthConverter" />
</ResourceDictionary>

View File

@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary
x:Class="Wino.Core.UWP.Styles.CustomMessageDialogStyles"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dialogs="using:Wino.Dialogs"
xmlns:domain="using:Wino.Core.Domain"
xmlns:local="using:Wino.Styles"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
xmlns:selectors="using:Wino.Core.UWP.Selectors">
<!-- Icon templates -->
<DataTemplate x:Key="WinoCustomMessageDialogInformationIconTemplate">
<Path
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" />
</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" />
</DataTemplate>
<DataTemplate x:Key="WinoCustomMessageDialogWarningIconTemplate">
<Path
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="F1 M 2.021484 18.769531 C 1.767578 18.769531 1.52832 18.720703 1.303711 18.623047 C 1.079102 18.525391 0.880534 18.391928 0.708008 18.222656 C 0.535482 18.053385 0.398763 17.856445 0.297852 17.631836 C 0.19694 17.407227 0.146484 17.167969 0.146484 16.914062 C 0.146484 16.614584 0.211589 16.328125 0.341797 16.054688 L 7.695312 1.347656 C 7.851562 1.035156 8.082682 0.784506 8.388672 0.595703 C 8.694661 0.406902 9.023438 0.3125 9.375 0.3125 C 9.726562 0.3125 10.055338 0.406902 10.361328 0.595703 C 10.667317 0.784506 10.898438 1.035156 11.054688 1.347656 L 18.408203 16.054688 C 18.53841 16.328125 18.603516 16.614584 18.603516 16.914062 C 18.603516 17.167969 18.553059 17.407227 18.452148 17.631836 C 18.351236 17.856445 18.216145 18.053385 18.046875 18.222656 C 17.877604 18.391928 17.679035 18.525391 17.451172 18.623047 C 17.223307 18.720703 16.982422 18.769531 16.728516 18.769531 Z M 16.728516 17.519531 C 16.884766 17.519531 17.027994 17.460938 17.158203 17.34375 C 17.28841 17.226562 17.353516 17.086588 17.353516 16.923828 C 17.353516 16.806641 17.330729 16.702475 17.285156 16.611328 L 9.931641 1.904297 C 9.879557 1.793621 9.80306 1.708984 9.702148 1.650391 C 9.601236 1.591797 9.492188 1.5625 9.375 1.5625 C 9.257812 1.5625 9.148763 1.593426 9.047852 1.655273 C 8.946939 1.717123 8.870442 1.800131 8.818359 1.904297 L 1.464844 16.611328 C 1.419271 16.702475 1.396484 16.803387 1.396484 16.914062 C 1.396484 17.083334 1.459961 17.226562 1.586914 17.34375 C 1.713867 17.460938 1.858724 17.519531 2.021484 17.519531 Z M 8.75 11.875 L 8.75 6.875 C 8.75 6.705729 8.811849 6.559245 8.935547 6.435547 C 9.059244 6.31185 9.205729 6.25 9.375 6.25 C 9.544271 6.25 9.690755 6.31185 9.814453 6.435547 C 9.93815 6.559245 10 6.705729 10 6.875 L 10 11.875 C 10 12.044271 9.93815 12.190756 9.814453 12.314453 C 9.690755 12.438151 9.544271 12.5 9.375 12.5 C 9.205729 12.5 9.059244 12.438151 8.935547 12.314453 C 8.811849 12.190756 8.75 12.044271 8.75 11.875 Z M 8.4375 14.375 C 8.4375 14.114584 8.528646 13.893229 8.710938 13.710938 C 8.893229 13.528646 9.114583 13.4375 9.375 13.4375 C 9.635416 13.4375 9.856771 13.528646 10.039062 13.710938 C 10.221354 13.893229 10.3125 14.114584 10.3125 14.375 C 10.3125 14.635417 10.221354 14.856771 10.039062 15.039062 C 9.856771 15.221354 9.635416 15.3125 9.375 15.3125 C 9.114583 15.3125 8.893229 15.221354 8.710938 15.039062 C 8.528646 14.856771 8.4375 14.635417 8.4375 14.375 Z "
Fill="#fdcb6e" />
</DataTemplate>
<DataTemplate x:Key="WinoCustomMessageDialogErrorIconTemplate">
<Path
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="F1 M 18.75 9.375 C 18.75 10.240886 18.639322 11.072592 18.417969 11.870117 C 18.196613 12.667644 17.882486 13.414714 17.475586 14.111328 C 17.068684 14.807943 16.580402 15.441081 16.010742 16.010742 C 15.44108 16.580404 14.807942 17.068686 14.111328 17.475586 C 13.414713 17.882486 12.667643 18.196615 11.870117 18.417969 C 11.072591 18.639322 10.240885 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 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.234375 0 11.062825 0.112305 11.860352 0.336914 C 12.657877 0.561523 13.404947 0.877279 14.101562 1.28418 C 14.798176 1.691082 15.431314 2.179363 16.000977 2.749023 C 16.570637 3.318686 17.058918 3.951824 17.46582 4.648438 C 17.872721 5.345053 18.188477 6.092123 18.413086 6.889648 C 18.637695 7.687175 18.75 8.515625 18.75 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.74642 13.481445 16.391602 C 14.083658 16.036783 14.630533 15.613607 15.12207 15.12207 C 15.613606 14.630534 16.036783 14.083659 16.391602 13.481445 C 16.746418 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 13.4375 5.9375 C 13.4375 6.106771 13.37565 6.253256 13.251953 6.376953 L 10.253906 9.375 L 13.251953 12.373047 C 13.37565 12.496745 13.4375 12.643229 13.4375 12.8125 C 13.4375 12.981771 13.37565 13.128256 13.251953 13.251953 C 13.128254 13.375651 12.98177 13.4375 12.8125 13.4375 C 12.643229 13.4375 12.496744 13.375651 12.373047 13.251953 L 9.375 10.253906 L 6.376953 13.251953 C 6.253255 13.375651 6.106771 13.4375 5.9375 13.4375 C 5.768229 13.4375 5.621745 13.375651 5.498047 13.251953 C 5.374349 13.128256 5.3125 12.981771 5.3125 12.8125 C 5.3125 12.643229 5.374349 12.496745 5.498047 12.373047 L 8.496094 9.375 L 5.498047 6.376953 C 5.374349 6.253256 5.3125 6.106771 5.3125 5.9375 C 5.3125 5.768229 5.374349 5.621745 5.498047 5.498047 C 5.621745 5.37435 5.768229 5.3125 5.9375 5.3125 C 6.106771 5.3125 6.253255 5.37435 6.376953 5.498047 L 9.375 8.496094 L 12.373047 5.498047 C 12.496744 5.37435 12.643229 5.3125 12.8125 5.3125 C 12.98177 5.3125 13.128254 5.37435 13.251953 5.498047 C 13.37565 5.621745 13.4375 5.768229 13.4375 5.9375 Z "
Fill="#d63031" />
</DataTemplate>
<selectors:CustomWinoMessageDialogIconSelector
x:Key="CustomWinoMessageDialogIconSelector"
ErrorIconTemplate="{StaticResource WinoCustomMessageDialogErrorIconTemplate}"
InfoIconTemplate="{StaticResource WinoCustomMessageDialogInformationIconTemplate}"
QuestionIconTemplate="{StaticResource WinoCustomMessageDialogQuestionIconTemplate}"
WarningIconTemplate="{StaticResource WinoCustomMessageDialogWarningIconTemplate}" />
<DataTemplate x:Key="CustomWinoContentDialogTitleTemplate" x:DataType="dialogs:CustomMessageDialogInformationContainer">
<Grid />
</DataTemplate>
<DataTemplate x:Key="CustomWinoContentDialogContentTemplate" x:DataType="dialogs:CustomMessageDialogInformationContainer">
<Grid RowSpacing="12">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Title -->
<StackPanel Orientation="Horizontal" Spacing="12">
<Viewbox Width="28" HorizontalAlignment="Left">
<ContentControl Content="{x:Bind Icon}" ContentTemplateSelector="{StaticResource CustomWinoMessageDialogIconSelector}" />
</Viewbox>
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{x:Bind Title}" />
</StackPanel>
<!-- Description -->
<TextBlock
Grid.Row="1"
Text="{x:Bind Description}"
TextWrapping="WrapWholeWords" />
<CheckBox
Grid.Row="2"
Content="{x:Bind domain:Translator.Dialog_DontAskAgain}"
IsChecked="{x:Bind IsDontAskChecked, Mode=TwoWay}"
Visibility="{x:Bind IsDontAskAgainEnabled}" />
</Grid>
</DataTemplate>
</ResourceDictionary>

View File

@@ -0,0 +1,12 @@
using Windows.UI.Xaml;
namespace Wino.Core.UWP.Styles
{
partial class CustomMessageDialogStyles : ResourceDictionary
{
public CustomMessageDialogStyles()
{
InitializeComponent();
}
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,12 @@
using Windows.UI.Xaml;
namespace Wino.Core.UWP.Styles
{
public partial class DataTemplates : ResourceDictionary
{
public DataTemplates()
{
InitializeComponent();
}
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,61 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:selectors="using:Wino.Core.UWP.Selectors">
<!-- Attachment Icon Templates -->
<DataTemplate x:Key="NoneTemplate">
<Image Source="/Assets/FileTypes/type_none.png" />
</DataTemplate>
<DataTemplate x:Key="ExecutableTemplate">
<Image Source="/Assets/FileTypes/type_executable.png" />
</DataTemplate>
<DataTemplate x:Key="ImageTemplate">
<Image Source="/Assets/FileTypes/type_image.png" />
</DataTemplate>
<DataTemplate x:Key="VideoTemplate">
<Image Source="/Assets/FileTypes/type_video.png" />
</DataTemplate>
<DataTemplate x:Key="AudioTemplate">
<Image Source="/Assets/FileTypes/type_audio.png" />
</DataTemplate>
<DataTemplate x:Key="PDFTemplate">
<Image Source="/Assets/FileTypes/type_pdf.png" />
</DataTemplate>
<DataTemplate x:Key="HTMLTemplate">
<Image Source="/Assets/FileTypes/type_html.png" />
</DataTemplate>
<DataTemplate x:Key="RarTemplate">
<Image Source="/Assets/FileTypes/type_rar.png" />
</DataTemplate>
<DataTemplate x:Key="ArchiveTemplate">
<Image Source="/Assets/FileTypes/type_archive.png" />
</DataTemplate>
<DataTemplate x:Key="OtherTemplate">
<Image Source="/Assets/FileTypes/type_other.png" />
</DataTemplate>
<selectors:FileAttachmentTypeSelector
x:Key="FileTypeIconSelector"
Archive="{StaticResource ArchiveTemplate}"
Executable="{StaticResource ExecutableTemplate}"
HTML="{StaticResource HTMLTemplate}"
Image="{StaticResource ImageTemplate}"
None="{StaticResource NoneTemplate}"
Other="{StaticResource OtherTemplate}"
PDF="{StaticResource PDFTemplate}"
RarArchive="{StaticResource RarTemplate}"
Video="{StaticResource VideoTemplate}" />
</ResourceDictionary>

View File

@@ -0,0 +1,422 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:contract7Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,7)"
xmlns:coreControls="using:Wino.Core.UWP.Controls"
xmlns:local="using:Microsoft.UI.Xaml.Controls"
xmlns:primitives="using:Microsoft.UI.Xaml.Controls.Primitives">
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="InfoBarCustomInformationalBackground">#74b9ff</SolidColorBrush>
<StaticResource x:Key="InfoBarErrorSeverityBackgroundBrush" ResourceKey="SystemFillColorCriticalBackgroundBrush" />
<StaticResource x:Key="InfoBarWarningSeverityBackgroundBrush" ResourceKey="SystemFillColorCautionBackgroundBrush" />
<StaticResource x:Key="InfoBarSuccessSeverityBackgroundBrush" ResourceKey="SystemFillColorSuccessBackgroundBrush" />
<StaticResource x:Key="InfoBarInformationalSeverityBackgroundBrush" ResourceKey="InfoBarCustomInformationalBackground" />
<StaticResource x:Key="InfoBarErrorSeverityIconBackground" ResourceKey="SystemFillColorCriticalBrush" />
<StaticResource x:Key="InfoBarWarningSeverityIconBackground" ResourceKey="SystemFillColorCautionBrush" />
<StaticResource x:Key="InfoBarSuccessSeverityIconBackground" ResourceKey="SystemFillColorSuccessBrush" />
<StaticResource x:Key="InfoBarInformationalSeverityIconBackground" ResourceKey="SystemFillColorAttentionBrush" />
<StaticResource x:Key="InfoBarErrorSeverityIconForeground" ResourceKey="TextFillColorInverseBrush" />
<StaticResource x:Key="InfoBarWarningSeverityIconForeground" ResourceKey="TextFillColorInverseBrush" />
<StaticResource x:Key="InfoBarSuccessSeverityIconForeground" ResourceKey="TextFillColorInverseBrush" />
<StaticResource x:Key="InfoBarInformationalSeverityIconForeground" ResourceKey="TextFillColorInverseBrush" />
<StaticResource x:Key="InfoBarTitleForeground" ResourceKey="TextFillColorPrimaryBrush" />
<StaticResource x:Key="InfoBarMessageForeground" ResourceKey="TextFillColorPrimaryBrush" />
<StaticResource x:Key="InfoBarHyperlinkButtonForeground" ResourceKey="AccentTextFillColorPrimaryBrush" />
<StaticResource x:Key="InfoBarBorderBrush" ResourceKey="CardStrokeColorDefaultBrush" />
<Thickness x:Key="InfoBarBorderThickness">1</Thickness>
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="InfoBarCustomInformationalBackground">#3867d6</SolidColorBrush>
<StaticResource x:Key="InfoBarErrorSeverityBackgroundBrush" ResourceKey="SystemFillColorCriticalBackgroundBrush" />
<StaticResource x:Key="InfoBarWarningSeverityBackgroundBrush" ResourceKey="SystemFillColorCautionBackgroundBrush" />
<StaticResource x:Key="InfoBarSuccessSeverityBackgroundBrush" ResourceKey="SystemFillColorSuccessBackgroundBrush" />
<StaticResource x:Key="InfoBarInformationalSeverityBackgroundBrush" ResourceKey="InfoBarCustomInformationalBackground" />
<StaticResource x:Key="InfoBarErrorSeverityIconBackground" ResourceKey="SystemFillColorCriticalBrush" />
<StaticResource x:Key="InfoBarWarningSeverityIconBackground" ResourceKey="SystemFillColorCautionBrush" />
<StaticResource x:Key="InfoBarSuccessSeverityIconBackground" ResourceKey="SystemFillColorSuccessBrush" />
<StaticResource x:Key="InfoBarInformationalSeverityIconBackground" ResourceKey="SystemFillColorAttentionBrush" />
<StaticResource x:Key="InfoBarErrorSeverityIconForeground" ResourceKey="TextFillColorInverseBrush" />
<StaticResource x:Key="InfoBarWarningSeverityIconForeground" ResourceKey="TextFillColorInverseBrush" />
<StaticResource x:Key="InfoBarSuccessSeverityIconForeground" ResourceKey="TextFillColorInverseBrush" />
<StaticResource x:Key="InfoBarInformationalSeverityIconForeground" ResourceKey="TextFillColorInverseBrush" />
<StaticResource x:Key="InfoBarTitleForeground" ResourceKey="TextFillColorPrimaryBrush" />
<StaticResource x:Key="InfoBarMessageForeground" ResourceKey="TextFillColorPrimaryBrush" />
<StaticResource x:Key="InfoBarHyperlinkButtonForeground" ResourceKey="AccentTextFillColorPrimaryBrush" />
<StaticResource x:Key="InfoBarBorderBrush" ResourceKey="CardStrokeColorDefaultBrush" />
<Thickness x:Key="InfoBarBorderThickness">1</Thickness>
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<SolidColorBrush x:Key="InfoBarErrorSeverityBackgroundBrush" Color="{ThemeResource SystemColorWindowColor}" />
<SolidColorBrush x:Key="InfoBarWarningSeverityBackgroundBrush" Color="{ThemeResource SystemColorWindowColor}" />
<SolidColorBrush x:Key="InfoBarSuccessSeverityBackgroundBrush" Color="{ThemeResource SystemColorWindowColor}" />
<SolidColorBrush x:Key="InfoBarInformationalSeverityBackgroundBrush" Color="{ThemeResource SystemColorWindowColor}" />
<StaticResource x:Key="InfoBarErrorSeverityIconBackground" ResourceKey="SystemColorHighlightColor" />
<StaticResource x:Key="InfoBarWarningSeverityIconBackground" ResourceKey="SystemColorHighlightColor" />
<StaticResource x:Key="InfoBarSuccessSeverityIconBackground" ResourceKey="SystemColorHighlightColor" />
<StaticResource x:Key="InfoBarInformationalSeverityIconBackground" ResourceKey="SystemColorHighlightColor" />
<StaticResource x:Key="InfoBarErrorSeverityIconForeground" ResourceKey="SystemColorHighlightTextColor" />
<StaticResource x:Key="InfoBarWarningSeverityIconForeground" ResourceKey="SystemColorHighlightTextColor" />
<StaticResource x:Key="InfoBarSuccessSeverityIconForeground" ResourceKey="SystemColorHighlightTextColor" />
<StaticResource x:Key="InfoBarInformationalSeverityIconForeground" ResourceKey="SystemColorHighlightTextColor" />
<StaticResource x:Key="InfoBarTitleForeground" ResourceKey="SystemControlForegroundBaseHighBrush" />
<StaticResource x:Key="InfoBarMessageForeground" ResourceKey="SystemControlForegroundBaseHighBrush" />
<StaticResource x:Key="InfoBarHyperlinkButtonForeground" ResourceKey="SystemControlHyperlinkTextBrush" />
<StaticResource x:Key="InfoBarBorderBrush" ResourceKey="SystemControlTransientBorderBrush" />
<Thickness x:Key="InfoBarBorderThickness">2</Thickness>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
<x:Double x:Key="InfoBarTitleFontSize">14</x:Double>
<FontWeight x:Key="InfoBarTitleFontWeight">SemiBold</FontWeight>
<x:Double x:Key="InfoBarMessageFontSize">14</x:Double>
<FontWeight x:Key="InfoBarMessageFontWeight">Normal</FontWeight>
<x:Double x:Key="InfoBarMinHeight">48</x:Double>
<x:Double x:Key="InfoBarCloseButtonSize">38</x:Double>
<x:Double x:Key="InfoBarCloseButtonGlyphSize">16</x:Double>
<!-- This negative margin makes the link visually line up with the title/message -->
<Thickness x:Key="InfoBarHyperlinkButtonMargin">-12,0,0,0</Thickness>
<x:String x:Key="InfoBarIconBackgroundGlyph">&#xF136;</x:String>
<x:String x:Key="InfoBarInformationalIconGlyph">&#xF13F;</x:String>
<x:String x:Key="InfoBarErrorIconGlyph">&#xF13D;</x:String>
<x:String x:Key="InfoBarWarningIconGlyph">&#xF13C;</x:String>
<x:String x:Key="InfoBarSuccessIconGlyph">&#xF13E;</x:String>
<Thickness x:Key="InfoBarContentRootPadding">16,0,0,0</Thickness>
<Thickness x:Key="InfoBarIconMargin">0,16,14,16</Thickness>
<x:Double x:Key="InfoBarIconFontSize">16</x:Double>
<Thickness x:Key="InfoBarPanelMargin">0,0,16,0</Thickness>
<Thickness x:Key="InfoBarPanelHorizontalOrientationPadding">0,0,0,0</Thickness>
<Thickness x:Key="InfoBarPanelVerticalOrientationPadding">0,14,0,18</Thickness>
<Thickness x:Key="InfoBarTitleHorizontalOrientationMargin">0,14,0,0</Thickness>
<Thickness x:Key="InfoBarTitleVerticalOrientationMargin">0,14,0,0</Thickness>
<Thickness x:Key="InfoBarMessageHorizontalOrientationMargin">12,14,0,0</Thickness>
<Thickness x:Key="InfoBarMessageVerticalOrientationMargin">0,4,0,0</Thickness>
<Thickness x:Key="InfoBarActionHorizontalOrientationMargin">16,8,0,0</Thickness>
<Thickness x:Key="InfoBarActionVerticalOrientationMargin">0,12,0,0</Thickness>
<Symbol x:Key="InfoBarCloseButtonSymbol">Cancel</Symbol>
<Style
x:Key="InfoBarCloseButtonStyle"
BasedOn="{StaticResource DefaultButtonStyle}"
TargetType="Button">
<Style.Setters>
<Setter Property="Width" Value="{StaticResource InfoBarCloseButtonSize}" />
<Setter Property="Height" Value="{StaticResource InfoBarCloseButtonSize}" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Margin" Value="5" />
</Style.Setters>
</Style>
<Style TargetType="coreControls:WinoInfoBar">
<Setter Property="IsTabStop" Value="False" />
<Setter Property="CloseButtonStyle" Value="{StaticResource InfoBarCloseButtonStyle}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="{ThemeResource InfoBarBorderBrush}" />
<Setter Property="BorderThickness" Value="{ThemeResource InfoBarBorderThickness}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="coreControls:WinoInfoBar">
<Border
x:Name="ContentRoot"
VerticalAlignment="Top"
contract7Present:CornerRadius="{TemplateBinding CornerRadius}"
Background="{ThemeResource InfoBarInformationalSeverityBackgroundBrush}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<!-- Background is used here so that it overrides the severity status color if set. -->
<Grid
MinHeight="{ThemeResource InfoBarMinHeight}"
Padding="{StaticResource InfoBarContentRootPadding}"
HorizontalAlignment="Stretch"
contract7Present:CornerRadius="{TemplateBinding CornerRadius}"
Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<!-- Icon -->
<ColumnDefinition Width="*" />
<!-- Title, message, and action -->
<ColumnDefinition Width="Auto" />
<!-- Close button -->
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid x:Name="StandardIconArea" Visibility="Collapsed">
<TextBlock
x:Name="IconBackground"
Grid.Column="0"
Margin="{StaticResource InfoBarIconMargin}"
VerticalAlignment="Top"
AutomationProperties.AccessibilityView="Raw"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="{StaticResource InfoBarIconFontSize}"
Foreground="{ThemeResource InfoBarInformationalSeverityIconBackground}"
Text="{StaticResource InfoBarIconBackgroundGlyph}" />
<TextBlock
x:Name="StandardIcon"
Grid.Column="0"
Margin="{StaticResource InfoBarIconMargin}"
VerticalAlignment="Top"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="{StaticResource InfoBarIconFontSize}"
Foreground="{ThemeResource InfoBarInformationalSeverityIconForeground}"
Text="{StaticResource InfoBarInformationalIconGlyph}" />
</Grid>
<Viewbox
x:Name="UserIconBox"
Grid.Column="0"
MaxWidth="{ThemeResource InfoBarIconFontSize}"
MaxHeight="{ThemeResource InfoBarIconFontSize}"
Margin="{ThemeResource InfoBarIconMargin}"
VerticalAlignment="Top"
Child="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.IconElement}"
Visibility="Collapsed" />
<primitives:InfoBarPanel
Grid.Column="1"
Margin="{StaticResource InfoBarPanelMargin}"
HorizontalOrientationPadding="{StaticResource InfoBarPanelHorizontalOrientationPadding}"
VerticalOrientationPadding="{StaticResource InfoBarPanelVerticalOrientationPadding}">
<TextBlock
x:Name="Title"
primitives:InfoBarPanel.HorizontalOrientationMargin="{StaticResource InfoBarTitleHorizontalOrientationMargin}"
primitives:InfoBarPanel.VerticalOrientationMargin="{StaticResource InfoBarTitleVerticalOrientationMargin}"
AutomationProperties.LandmarkType="Navigation"
FontSize="{StaticResource InfoBarTitleFontSize}"
FontWeight="{StaticResource InfoBarTitleFontWeight}"
Foreground="{ThemeResource InfoBarTitleForeground}"
Text="{TemplateBinding Title}"
TextWrapping="WrapWholeWords" />
<TextBlock
x:Name="Message"
primitives:InfoBarPanel.HorizontalOrientationMargin="{StaticResource InfoBarMessageHorizontalOrientationMargin}"
primitives:InfoBarPanel.VerticalOrientationMargin="{StaticResource InfoBarMessageVerticalOrientationMargin}"
FontSize="{StaticResource InfoBarMessageFontSize}"
FontWeight="{StaticResource InfoBarMessageFontWeight}"
Foreground="{ThemeResource InfoBarMessageForeground}"
Text="{TemplateBinding Message}"
TextWrapping="WrapWholeWords" />
<ContentPresenter
VerticalAlignment="Top"
primitives:InfoBarPanel.HorizontalOrientationMargin="{StaticResource InfoBarActionHorizontalOrientationMargin}"
primitives:InfoBarPanel.VerticalOrientationMargin="{StaticResource InfoBarActionVerticalOrientationMargin}"
Content="{TemplateBinding ActionButton}">
<ContentPresenter.Resources>
<Style BasedOn="{StaticResource DefaultHyperlinkButtonStyle}" TargetType="HyperlinkButton">
<Style.Setters>
<Setter Property="Margin" Value="{StaticResource InfoBarHyperlinkButtonMargin}" />
<Setter Property="Foreground" Value="{ThemeResource InfoBarHyperlinkButtonForeground}" />
</Style.Setters>
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
</primitives:InfoBarPanel>
<ContentPresenter
Grid.Row="0"
Grid.Column="1"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
<Button
Name="CloseButton"
Grid.Column="2"
Command="{TemplateBinding CloseButtonCommand}"
CommandParameter="{TemplateBinding CloseButtonCommandParameter}"
Style="{TemplateBinding CloseButtonStyle}">
<Button.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default">
<StaticResource x:Key="ButtonBackground" ResourceKey="AppBarButtonBackground" />
<StaticResource x:Key="ButtonBackgroundPointerOver" ResourceKey="AppBarButtonBackgroundPointerOver" />
<StaticResource x:Key="ButtonBackgroundPressed" ResourceKey="AppBarButtonBackgroundPressed" />
<StaticResource x:Key="ButtonBackgroundDisabled" ResourceKey="AppBarButtonBackgroundDisabled" />
<StaticResource x:Key="ButtonForeground" ResourceKey="AppBarButtonForeground" />
<StaticResource x:Key="ButtonForegroundPointerOver" ResourceKey="AppBarButtonForegroundPointerOver" />
<StaticResource x:Key="ButtonForegroundPressed" ResourceKey="AppBarButtonForegroundPressed" />
<StaticResource x:Key="ButtonForegroundDisabled" ResourceKey="AppBarButtonForegroundDisabled" />
<StaticResource x:Key="ButtonBorderBrush" ResourceKey="AppBarButtonBorderBrush" />
<StaticResource x:Key="ButtonBorderBrushPointerOver" ResourceKey="AppBarButtonBorderBrushPointerOver" />
<StaticResource x:Key="ButtonBorderBrushPressed" ResourceKey="AppBarButtonBorderBrushPressed" />
<StaticResource x:Key="ButtonBorderBrushDisabled" ResourceKey="AppBarButtonBorderBrushDisabled" />
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<StaticResource x:Key="ButtonBackground" ResourceKey="AppBarButtonBackground" />
<StaticResource x:Key="ButtonBackgroundPointerOver" ResourceKey="AppBarButtonBackgroundPointerOver" />
<StaticResource x:Key="ButtonBackgroundPressed" ResourceKey="AppBarButtonBackgroundPressed" />
<StaticResource x:Key="ButtonBackgroundDisabled" ResourceKey="AppBarButtonBackgroundDisabled" />
<StaticResource x:Key="ButtonForeground" ResourceKey="AppBarButtonForeground" />
<StaticResource x:Key="ButtonForegroundPointerOver" ResourceKey="AppBarButtonForegroundPointerOver" />
<StaticResource x:Key="ButtonForegroundPressed" ResourceKey="AppBarButtonForegroundPressed" />
<StaticResource x:Key="ButtonForegroundDisabled" ResourceKey="AppBarButtonForegroundDisabled" />
<StaticResource x:Key="ButtonBorderBrush" ResourceKey="AppBarButtonBorderBrush" />
<StaticResource x:Key="ButtonBorderBrushPointerOver" ResourceKey="AppBarButtonBorderBrushPointerOver" />
<StaticResource x:Key="ButtonBorderBrushPressed" ResourceKey="AppBarButtonBorderBrushPressed" />
<StaticResource x:Key="ButtonBorderBrushDisabled" ResourceKey="AppBarButtonBorderBrushDisabled" />
</ResourceDictionary>
<ResourceDictionary x:Key="Light">
<StaticResource x:Key="ButtonBackground" ResourceKey="AppBarButtonBackground" />
<StaticResource x:Key="ButtonBackgroundPointerOver" ResourceKey="AppBarButtonBackgroundPointerOver" />
<StaticResource x:Key="ButtonBackgroundPressed" ResourceKey="AppBarButtonBackgroundPressed" />
<StaticResource x:Key="ButtonBackgroundDisabled" ResourceKey="AppBarButtonBackgroundDisabled" />
<StaticResource x:Key="ButtonForeground" ResourceKey="AppBarButtonForeground" />
<StaticResource x:Key="ButtonForegroundPointerOver" ResourceKey="AppBarButtonForegroundPointerOver" />
<StaticResource x:Key="ButtonForegroundPressed" ResourceKey="AppBarButtonForegroundPressed" />
<StaticResource x:Key="ButtonForegroundDisabled" ResourceKey="AppBarButtonForegroundDisabled" />
<StaticResource x:Key="ButtonBorderBrush" ResourceKey="AppBarButtonBorderBrush" />
<StaticResource x:Key="ButtonBorderBrushPointerOver" ResourceKey="AppBarButtonBorderBrushPointerOver" />
<StaticResource x:Key="ButtonBorderBrushPressed" ResourceKey="AppBarButtonBorderBrushPressed" />
<StaticResource x:Key="ButtonBorderBrushDisabled" ResourceKey="AppBarButtonBorderBrushDisabled" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Button.Resources>
<Viewbox
Width="{StaticResource InfoBarCloseButtonGlyphSize}"
Height="{StaticResource InfoBarCloseButtonGlyphSize}"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<SymbolIcon Symbol="{StaticResource InfoBarCloseButtonSymbol}" />
</Viewbox>
</Button>
</Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="SeverityLevels">
<VisualState x:Name="Informational">
<VisualState.Setters>
<Setter Target="ContentRoot.Background" Value="{ThemeResource InfoBarInformationalSeverityBackgroundBrush}" />
<Setter Target="IconBackground.Foreground" Value="{ThemeResource InfoBarInformationalSeverityIconBackground}" />
<Setter Target="StandardIcon.Text" Value="{StaticResource InfoBarInformationalIconGlyph}" />
<Setter Target="StandardIcon.Foreground" Value="{ThemeResource InfoBarInformationalSeverityIconForeground}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Error">
<VisualState.Setters>
<Setter Target="ContentRoot.Background" Value="{ThemeResource InfoBarErrorSeverityBackgroundBrush}" />
<Setter Target="IconBackground.Foreground" Value="{ThemeResource InfoBarErrorSeverityIconBackground}" />
<Setter Target="StandardIcon.Text" Value="{StaticResource InfoBarErrorIconGlyph}" />
<Setter Target="StandardIcon.Foreground" Value="{ThemeResource InfoBarErrorSeverityIconForeground}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Warning">
<VisualState.Setters>
<Setter Target="ContentRoot.Background" Value="{ThemeResource InfoBarWarningSeverityBackgroundBrush}" />
<Setter Target="IconBackground.Foreground" Value="{ThemeResource InfoBarWarningSeverityIconBackground}" />
<Setter Target="StandardIcon.Text" Value="{StaticResource InfoBarWarningIconGlyph}" />
<Setter Target="StandardIcon.Foreground" Value="{ThemeResource InfoBarWarningSeverityIconForeground}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Success">
<VisualState.Setters>
<Setter Target="ContentRoot.Background" Value="{ThemeResource InfoBarSuccessSeverityBackgroundBrush}" />
<Setter Target="IconBackground.Foreground" Value="{ThemeResource InfoBarSuccessSeverityIconBackground}" />
<Setter Target="StandardIcon.Text" Value="{StaticResource InfoBarSuccessIconGlyph}" />
<Setter Target="StandardIcon.Foreground" Value="{ThemeResource InfoBarSuccessSeverityIconForeground}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="IconStates">
<VisualState x:Name="StandardIconVisible">
<VisualState.Setters>
<Setter Target="UserIconBox.Visibility" Value="Collapsed" />
<Setter Target="StandardIconArea.Visibility" Value="Visible" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="UserIconVisible">
<VisualState.Setters>
<Setter Target="UserIconBox.Visibility" Value="Visible" />
<Setter Target="StandardIconArea.Visibility" Value="Collapsed" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="NoIconVisible" />
</VisualStateGroup>
<VisualStateGroup>
<VisualState x:Name="CloseButtonVisible" />
<VisualState x:Name="CloseButtonCollapsed">
<VisualState.Setters>
<Setter Target="CloseButton.Visibility" Value="Collapsed" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="InfoBarVisibility">
<VisualState x:Name="InfoBarVisible" />
<VisualState x:Name="InfoBarCollapsed">
<VisualState.Setters>
<Setter Target="ContentRoot.Visibility" Value="Collapsed" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup>
<VisualState x:Name="ForegroundNotSet" />
<VisualState x:Name="ForegroundSet">
<VisualState.Setters>
<Setter Target="Title.Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Foreground}" />
<Setter Target="Message.Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Foreground}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,8 @@
using Wino.Core.ViewModels;
namespace Wino.Views.Abstract
{
public abstract class SettingOptionsPageAbstract : SettingsPageBase<SettingOptionsPageViewModel>
{
}
}

View File

@@ -0,0 +1,7 @@
using Wino.Core.UWP;
using Wino.Core.ViewModels;
namespace Wino.Views.Abstract
{
public abstract class SettingsPageAbstract : BasePage<SettingsPageViewModel> { }
}

View File

@@ -0,0 +1,17 @@
using Windows.UI.Xaml;
using Wino.Core.UWP;
using Wino.Core.ViewModels;
namespace Wino.Views.Abstract
{
public class SettingsPageBase<T> : BasePage<T> where T : CoreBaseViewModel
{
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static readonly DependencyProperty TitleProperty = DependencyProperty.Register(nameof(Title), typeof(string), typeof(SettingsPageBase<T>), new PropertyMetadata(string.Empty));
}
}

View File

@@ -0,0 +1,37 @@
<abstract:SettingOptionsPageAbstract
x:Class="Wino.Views.Settings.SettingOptionsPage"
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:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:domain="using:Wino.Core.Domain"
xmlns:enums="using:Wino.Core.Domain.Enums"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:settings="using:Wino.Core.Domain.Models.Settings"
xmlns:translations="using:Wino.Core.Domain.Models.Translations"
x:Name="root"
Title="{x:Bind domain:Translator.SettingsOptions_Title, Mode=OneWay}"
mc:Ignorable="d">
<ScrollViewer VerticalScrollBarVisibility="Hidden">
<ItemsControl ItemsSource="{x:Bind ViewModel.SettingOptions, Mode=OneWay}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="settings:SettingOption">
<controls:SettingsCard
Margin="0,2"
Command="{Binding ElementName=root, Path=ViewModel.NavigateSubDetailCommand}"
CommandParameter="{x:Bind NavigationPage}"
Description="{x:Bind Description}"
Header="{x:Bind Title}"
IsClickEnabled="True">
<controls:SettingsCard.HeaderIcon>
<PathIcon Data="{x:Bind PathIcon}" />
</controls:SettingsCard.HeaderIcon>
</controls:SettingsCard>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</abstract:SettingOptionsPageAbstract>

View File

@@ -0,0 +1,12 @@
using Wino.Views.Abstract;
namespace Wino.Views.Settings
{
public sealed partial class SettingOptionsPage : SettingOptionsPageAbstract
{
public SettingOptionsPage()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,49 @@
<abstract:SettingsPageAbstract
x:Class="Wino.Views.SettingsPage"
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:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:helpers="using:Wino.Helpers"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModelData="using:Wino.Mail.ViewModels.Data"
xmlns:winuiControls="using:Microsoft.UI.Xaml.Controls"
Style="{StaticResource PageStyle}"
mc:Ignorable="d">
<Border Style="{StaticResource PageRootBorderStyle}">
<Grid
MaxWidth="900"
Padding="20"
HorizontalAlignment="Stretch"
RowSpacing="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<winuiControls:BreadcrumbBar
x:Name="Breadcrumb"
ItemClicked="BreadItemClicked"
ItemsSource="{x:Bind PageHistory, Mode=OneWay}">
<winuiControls:BreadcrumbBar.ItemTemplate>
<DataTemplate>
<winuiControls:BreadcrumbBarItem Margin="0,0,8,0">
<winuiControls:BreadcrumbBarItem.ContentTemplate>
<DataTemplate x:DataType="viewModelData:BreadcrumbNavigationItemViewModel">
<TextBlock
Margin="0,0,8,10"
FontWeight="{x:Bind helpers:XamlHelpers.GetFontWeightBySyncState(IsActive), Mode=OneWay}"
Style="{StaticResource TitleTextBlockStyle}"
Text="{Binding Title}" />
</DataTemplate>
</winuiControls:BreadcrumbBarItem.ContentTemplate>
</winuiControls:BreadcrumbBarItem>
</DataTemplate>
</winuiControls:BreadcrumbBar.ItemTemplate>
</winuiControls:BreadcrumbBar>
<Frame x:Name="SettingsFrame" Grid.Row="1" />
</Grid>
</Border>
</abstract:SettingsPageAbstract>

View File

@@ -0,0 +1,84 @@
using System.Collections.ObjectModel;
using System.Linq;
using CommunityToolkit.Mvvm.Messaging;
using MoreLinq;
using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Navigation;
using Wino.Core.Domain;
using Wino.Core.Domain.Enums;
using Wino.Mail.ViewModels.Data;
using Wino.Messaging.Client.Navigation;
using Wino.Views.Abstract;
using Wino.Views.Settings;
namespace Wino.Views
{
public sealed partial class SettingsPage : SettingsPageAbstract, IRecipient<BreadcrumbNavigationRequested>
{
public ObservableCollection<BreadcrumbNavigationItemViewModel> PageHistory { get; set; } = [];
public SettingsPage()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
SettingsFrame.Navigate(typeof(SettingOptionsPage), null, new SuppressNavigationTransitionInfo());
var initialRequest = new BreadcrumbNavigationRequested(Translator.MenuSettings, WinoPage.SettingOptionsPage);
PageHistory.Add(new BreadcrumbNavigationItemViewModel(initialRequest, true));
if (e.Parameter is WinoPage parameterPage)
{
switch (parameterPage)
{
case WinoPage.AppPreferencesPage:
WeakReferenceMessenger.Default.Send(new BreadcrumbNavigationRequested(Translator.SettingsAppPreferences_Title, WinoPage.AppPreferencesPage));
break;
}
}
}
public override void OnLanguageChanged()
{
base.OnLanguageChanged();
// Update Settings header in breadcrumb.
var settingsHeader = PageHistory.FirstOrDefault();
if (settingsHeader == null) return;
settingsHeader.Title = Translator.MenuSettings;
}
void IRecipient<BreadcrumbNavigationRequested>.Receive(BreadcrumbNavigationRequested message)
{
var pageType = ViewModel.NavigationService.GetPageType(message.PageType);
if (pageType == null) return;
SettingsFrame.Navigate(pageType, message.Parameter, new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromRight });
PageHistory.ForEach(a => a.IsActive = false);
PageHistory.Add(new BreadcrumbNavigationItemViewModel(message, true));
}
private void BreadItemClicked(Microsoft.UI.Xaml.Controls.BreadcrumbBar sender, Microsoft.UI.Xaml.Controls.BreadcrumbBarItemClickedEventArgs args)
{
var clickedPageHistory = PageHistory[args.Index];
var activeIndex = PageHistory.IndexOf(PageHistory.FirstOrDefault(a => a.IsActive));
while (PageHistory.FirstOrDefault(a => a.IsActive) != clickedPageHistory)
{
SettingsFrame.GoBack(new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromRight });
PageHistory.RemoveAt(PageHistory.Count - 1);
PageHistory[PageHistory.Count - 1].IsActive = true;
}
}
}
}

View File

@@ -82,14 +82,59 @@
<LangVersion>12.0</LangVersion>
</PropertyGroup>
<ItemGroup>
<Compile Include="Activation\ActivationHandler.cs" />
<Compile Include="BasePage.cs" />
<Compile Include="Controls\ControlConstants.cs" />
<Compile Include="Controls\WinoAppTitleBar.xaml.cs">
<DependentUpon>WinoAppTitleBar.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\WinoFontIcon.cs" />
<Compile Include="Controls\WinoFontIconSource.cs" />
<Compile Include="Controls\WinoInfoBar.cs" />
<Compile Include="Controls\WinoNavigationViewItem.cs" />
<Compile Include="Converters\GridLengthConverter.cs" />
<Compile Include="Converters\ReverseBooleanConverter.cs" />
<Compile Include="Converters\ReverseBooleanToVisibilityConverter.cs" />
<Compile Include="CoreUWPContainerSetup.cs" />
<Compile Include="Selectors\NavigationMenuTemplateSelector.cs" />
<Compile Include="Services\ApplicationResourceManager.cs" />
<Compile Include="Services\DialogServiceBase.cs" />
<Compile Include="Services\NavigationServiceBase.cs" />
<Compile Include="Dialogs\AccountCreationDialog.xaml.cs">
<DependentUpon>AccountCreationDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Dialogs\AccountEditDialog.xaml.cs">
<DependentUpon>AccountEditDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Dialogs\AccountPickerDialog.xaml.cs">
<DependentUpon>AccountPickerDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Dialogs\BaseAccountCreationDialog.cs" />
<Compile Include="Dialogs\CustomMessageDialogInformationContainer.cs" />
<Compile Include="Dialogs\CustomThemeBuilderDialog.xaml.cs">
<DependentUpon>CustomThemeBuilderDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Dialogs\TextInputDialog.xaml.cs">
<DependentUpon>TextInputDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Dispatcher.cs" />
<Compile Include="Extensions\AnimationExtensions.cs" />
<Compile Include="Extensions\CompositionEnums.cs" />
<Compile Include="Extensions\CompositionExtensions.Implicit.cs" />
<Compile Include="Extensions\CompositionExtensions.Size.cs" />
<Compile Include="Extensions\ElementThemeExtensions.cs" />
<Compile Include="Extensions\StartupTaskStateExtensions.cs" />
<Compile Include="Extensions\UIExtensions.cs" />
<Compile Include="Extensions\UtilExtensions.cs" />
<Compile Include="Helpers\WinoVisualTreeHelper.cs" />
<Compile Include="Helpers\XamlHelpers.cs" />
<Compile Include="Models\Personalization\CustomAppTheme.cs" />
<Compile Include="Models\Personalization\PreDefinedAppTheme.cs" />
<Compile Include="Models\Personalization\SystemAppTheme.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Selectors\AppThemePreviewTemplateSelector.cs" />
<Compile Include="Selectors\CustomWinoMessageDialogIconSelector.cs" />
<Compile Include="Selectors\FileAttachmentTypeSelector.cs" />
<Compile Include="Services\PreferencesService.cs" />
<Compile Include="Services\PrintService.cs" />
<Compile Include="Services\StartupBehaviorService.cs" />
@@ -106,14 +151,61 @@
<Compile Include="Services\StoreRatingService.cs" />
<Compile Include="Services\ThemeService.cs" />
<Compile Include="Services\UnderlyingThemeService.cs" />
<Compile Include="CoreGeneric.xaml.cs">
<DependentUpon>CoreGeneric.xaml</DependentUpon>
</Compile>
<Compile Include="Styles\CustomMessageDialogStyles.xaml.cs">
<DependentUpon>CustomMessageDialogStyles.xaml</DependentUpon>
</Compile>
<Compile Include="Styles\DataTemplates.xaml.cs">
<DependentUpon>DataTemplates.xaml</DependentUpon>
</Compile>
<Compile Include="Views\Abstract\SettingOptionsPageAbstract.cs" />
<Compile Include="Views\Abstract\SettingsPageAbstract.cs" />
<Compile Include="Views\Abstract\SettingsPageBase.cs" />
<Compile Include="Views\SettingOptionsPage.xaml.cs">
<DependentUpon>SettingOptionsPage.xaml</DependentUpon>
</Compile>
<Compile Include="Views\SettingsPage.xaml.cs">
<DependentUpon>SettingsPage.xaml</DependentUpon>
</Compile>
<Compile Include="WinoApplication.cs" />
<EmbeddedResource Include="Properties\Wino.Core.UWP.rd.xml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommunityToolkit.WinUI.Notifications">
<Version>7.1.2</Version>
<PackageReference Include="CommunityToolkit.Common">
<Version>8.3.2</Version>
</PackageReference>
<PackageReference Include="CommunityToolkit.Diagnostics">
<Version>8.3.2</Version>
</PackageReference>
<PackageReference Include="CommunityToolkit.Mvvm">
<Version>8.3.2</Version>
</PackageReference>
<PackageReference Include="CommunityToolkit.Uwp.Animations">
<Version>8.1.240916</Version>
</PackageReference>
<PackageReference Include="CommunityToolkit.Uwp.Behaviors">
<Version>8.1.240916</Version>
</PackageReference>
<PackageReference Include="CommunityToolkit.Uwp.Controls.Segmented">
<Version>8.1.240916</Version>
</PackageReference>
<PackageReference Include="CommunityToolkit.Uwp.Controls.SettingsControls">
<Version>8.1.240916</Version>
</PackageReference>
<PackageReference Include="CommunityToolkit.Uwp.Controls.Sizers">
<Version>8.1.240916</Version>
</PackageReference>
<PackageReference Include="CommunityToolkit.Uwp.Extensions">
<Version>8.1.240916</Version>
</PackageReference>
<PackageReference Include="CommunityToolkit.WinUI.Notifications" Version="7.1.2" />
<PackageReference Include="CommunityToolkit.Uwp.Controls.TabbedCommandBar">
<Version>8.1.240916</Version>
</PackageReference>
<PackageReference Include="Microsoft.AppCenter.Analytics">
<Version>5.0.5</Version>
<Version>5.0.6</Version>
</PackageReference>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.2.14</Version>
@@ -121,6 +213,9 @@
<PackageReference Include="Microsoft.Toolkit.Uwp">
<Version>7.1.3</Version>
</PackageReference>
<PackageReference Include="Microsoft.UI.Xaml">
<Version>2.8.6</Version>
</PackageReference>
<PackageReference Include="Win2D.uwp">
<Version>1.28.0</Version>
</PackageReference>
@@ -130,6 +225,10 @@
<Project>{cf3312e5-5da0-4867-9945-49ea7598af1f}</Project>
<Name>Wino.Core.Domain</Name>
</ProjectReference>
<ProjectReference Include="..\Wino.Core.ViewModels\Wino.Core.ViewModels.csproj">
<Project>{53723ae8-7e7e-4d54-adab-0a6033255cc8}</Project>
<Name>Wino.Core.ViewModels</Name>
</ProjectReference>
<ProjectReference Include="..\Wino.Core\Wino.Core.csproj">
<Project>{e6b1632a-8901-41e8-9ddf-6793c7698b0b}</Project>
<Name>Wino.Core</Name>
@@ -144,8 +243,148 @@
<Name>Windows Desktop Extensions for the UWP</Name>
</SDKReference>
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Folder Include="Models\Printing\" />
<Content Include="Assets\FileTypes\type_archive.png" />
<Content Include="Assets\FileTypes\type_audio.png" />
<Content Include="Assets\FileTypes\type_executable.png" />
<Content Include="Assets\FileTypes\type_html.png" />
<Content Include="Assets\FileTypes\type_image.png" />
<Content Include="Assets\FileTypes\type_none.png" />
<Content Include="Assets\FileTypes\type_other.png" />
<Content Include="Assets\FileTypes\type_pdf.png" />
<Content Include="Assets\FileTypes\type_rar.png" />
<Content Include="Assets\FileTypes\type_video.png" />
<Content Include="Assets\Providers\Gmail.png" />
<Content Include="Assets\Providers\IMAP4.png" />
<Content Include="Assets\Providers\Office 365.png" />
<Content Include="Assets\Providers\Outlook.png" />
<Content Include="Assets\Providers\Yahoo.png" />
<Content Include="BackgroundImages\Acrylic.jpg" />
<Content Include="BackgroundImages\Clouds.jpg" />
<Content Include="BackgroundImages\Forest.jpg" />
<Content Include="BackgroundImages\Garden.jpg" />
<Content Include="BackgroundImages\Mica.jpg" />
<Content Include="BackgroundImages\Nighty.jpg" />
<Content Include="BackgroundImages\Snowflake.jpg" />
</ItemGroup>
<ItemGroup>
<Content Include="AppThemes\Acrylic.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="AppThemes\Clouds.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="AppThemes\Custom.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="AppThemes\Forest.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="AppThemes\Garden.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="AppThemes\Mica.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="AppThemes\Nighty.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="AppThemes\Snowflake.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup>
<Page Include="Controls\WinoAppTitleBar.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Dialogs\AccountCreationDialog.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Dialogs\AccountEditDialog.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Dialogs\AccountPickerDialog.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Dialogs\CustomThemeBuilderDialog.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Dialogs\TextInputDialog.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="CoreGeneric.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Styles\Colors.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Styles\ContentPresenters.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Styles\Converters.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Styles\CustomMessageDialogStyles.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Styles\FontIcons.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Styles\IconTemplates.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Styles\DataTemplates.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Styles\WinoInfoBar.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\SettingOptionsPage.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\SettingsPage.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion>

View File

@@ -0,0 +1,250 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AppCenter;
using Microsoft.AppCenter.Analytics;
using Microsoft.AppCenter.Crashes;
using Microsoft.Extensions.DependencyInjection;
using Nito.AsyncEx;
using Serilog;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.ApplicationModel.AppService;
using Windows.ApplicationModel.Core;
using Windows.Foundation.Metadata;
using Windows.Storage;
using Windows.UI;
using Windows.UI.Core.Preview;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Wino.Activation;
using Wino.Core.Domain;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Services;
namespace Wino.Core.UWP
{
public abstract class WinoApplication : Application
{
public new static WinoApplication Current => (WinoApplication)Application.Current;
public const string WinoLaunchLogPrefix = "[Wino Launch] ";
public IServiceProvider Services { get; }
protected ILogInitializer LogInitializer { get; }
protected IApplicationConfiguration AppConfiguration { get; }
protected IWinoServerConnectionManager<AppServiceConnection> AppServiceConnectionManager { get; }
protected IThemeService ThemeService { get; }
protected IDatabaseService DatabaseService { get; }
protected ITranslationService TranslationService { get; }
protected IMailDialogService DialogService { get; }
// Order matters.
private List<IInitializeAsync> initializeServices => new List<IInitializeAsync>()
{
DatabaseService,
TranslationService,
ThemeService,
};
public abstract string AppCenterKey { get; }
protected WinoApplication()
{
ConfigureAppCenter();
ConfigurePrelaunch();
Services = ConfigureServices();
UnhandledException += OnAppUnhandledException;
Resuming += OnResuming;
Suspending += OnSuspending;
LogInitializer = Services.GetService<ILogInitializer>();
AppConfiguration = Services.GetService<IApplicationConfiguration>();
AppServiceConnectionManager = Services.GetService<IWinoServerConnectionManager<AppServiceConnection>>();
ThemeService = Services.GetService<IThemeService>();
DatabaseService = Services.GetService<IDatabaseService>();
TranslationService = Services.GetService<ITranslationService>();
DialogService = Services.GetService<IMailDialogService>();
// Make sure the paths are setup on app start.
AppConfiguration.ApplicationDataFolderPath = ApplicationData.Current.LocalFolder.Path;
AppConfiguration.PublisherSharedFolderPath = ApplicationData.Current.GetPublisherCacheFolder(ApplicationConfiguration.SharedFolderName).Path;
AppConfiguration.ApplicationTempFolderPath = ApplicationData.Current.TemporaryFolder.Path;
ConfigureLogging();
}
protected abstract void OnApplicationCloseRequested(object sender, SystemNavigationCloseRequestedPreviewEventArgs e);
protected abstract IEnumerable<ActivationHandler> GetActivationHandlers();
protected abstract ActivationHandler<IActivatedEventArgs> GetDefaultActivationHandler();
protected override void OnWindowCreated(WindowCreatedEventArgs args)
{
base.OnWindowCreated(args);
ConfigureTitleBar();
LogActivation($"OnWindowCreated -> IsWindowNull: {args.Window == null}");
TryRegisterAppCloseChange();
}
public IEnumerable<IInitializeAsync> GetActivationServices()
{
yield return DatabaseService;
yield return TranslationService;
yield return ThemeService;
}
public Task InitializeServicesAsync() => GetActivationServices().Select(a => a.InitializeAsync()).WhenAll();
public bool IsInteractiveLaunchArgs(object args) => args is IActivatedEventArgs;
public void LogActivation(string log) => Log.Information($"{WinoLaunchLogPrefix}{log}");
private void ConfigureTitleBar()
{
var coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
var applicationViewTitleBar = ApplicationView.GetForCurrentView().TitleBar;
// Extend shell content into core window to meet design requirements.
coreTitleBar.ExtendViewIntoTitleBar = true;
// Change system buttons and background colors to meet design requirements.
applicationViewTitleBar.ButtonBackgroundColor = Colors.Transparent;
applicationViewTitleBar.BackgroundColor = Colors.Transparent;
applicationViewTitleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
applicationViewTitleBar.ButtonForegroundColor = Colors.White;
}
public async Task ActivateWinoAsync(object args)
{
await InitializeServicesAsync();
if (IsInteractiveLaunchArgs(args))
{
if (Window.Current.Content == null)
{
var mainFrame = new Frame();
Window.Current.Content = mainFrame;
await ThemeService.InitializeAsync();
}
}
await HandleActivationAsync(args);
if (IsInteractiveLaunchArgs(args))
{
Window.Current.Activate();
LogActivation("Window activated");
}
}
public async Task HandleActivationAsync(object activationArgs)
{
if (GetActivationHandlers() != null)
{
var activationHandler = GetActivationHandlers().FirstOrDefault(h => h.CanHandle(activationArgs)) ?? null;
if (activationHandler != null)
{
await activationHandler.HandleAsync(activationArgs);
}
}
if (IsInteractiveLaunchArgs(activationArgs))
{
var defaultHandler = GetDefaultActivationHandler();
if (defaultHandler.CanHandle(activationArgs))
{
await defaultHandler.HandleAsync(activationArgs);
}
}
}
protected override async void OnLaunched(LaunchActivatedEventArgs args)
{
LogActivation($"OnLaunched -> {args.GetType().Name}, Kind -> {args.Kind}, PreviousExecutionState -> {args.PreviousExecutionState}, IsPrelaunch -> {args.PrelaunchActivated}");
if (!args.PrelaunchActivated)
{
await ActivateWinoAsync(args);
}
}
protected override async void OnFileActivated(FileActivatedEventArgs args)
{
base.OnFileActivated(args);
LogActivation($"OnFileActivated -> ItemCount: {args.Files.Count}, Kind: {args.Kind}, PreviousExecutionState: {args.PreviousExecutionState}");
await ActivateWinoAsync(args);
}
protected override async void OnActivated(IActivatedEventArgs args)
{
base.OnActivated(args);
Log.Information($"OnActivated -> {args.GetType().Name}, Kind -> {args.Kind}, Prev Execution State -> {args.PreviousExecutionState}");
await ActivateWinoAsync(args);
}
private void TryRegisterAppCloseChange()
{
try
{
var systemNavigationManagerPreview = SystemNavigationManagerPreview.GetForCurrentView();
systemNavigationManagerPreview.CloseRequested -= OnApplicationCloseRequested;
systemNavigationManagerPreview.CloseRequested += OnApplicationCloseRequested;
}
catch { }
}
private void ConfigurePrelaunch()
{
if (ApiInformation.IsMethodPresent("Windows.ApplicationModel.Core.CoreApplication", "EnablePrelaunch"))
CoreApplication.EnablePrelaunch(true);
}
private void OnAppUnhandledException(object sender, Windows.UI.Xaml.UnhandledExceptionEventArgs e)
{
var parameters = new Dictionary<string, string>()
{
{ "BaseMessage", e.Exception.GetBaseException().Message },
{ "BaseStackTrace", e.Exception.GetBaseException().StackTrace },
{ "StackTrace", e.Exception.StackTrace },
{ "Message", e.Exception.Message },
};
Log.Error(e.Exception, "[Wino Crash]");
Crashes.TrackError(e.Exception, parameters);
Analytics.TrackEvent("Wino Crashed", parameters);
}
public virtual void OnResuming(object sender, object e) { }
public virtual void OnSuspending(object sender, SuspendingEventArgs e) { }
public abstract IServiceProvider ConfigureServices();
public void ConfigureAppCenter()
=> AppCenter.Start(AppCenterKey, typeof(Analytics), typeof(Crashes));
public void ConfigureLogging()
{
string logFilePath = Path.Combine(ApplicationData.Current.LocalFolder.Path, Constants.ClientLogFile);
LogInitializer.SetupLogger(logFilePath);
}
}
}