Wino accounts settings.

This commit is contained in:
Burak Kaan Köse
2026-03-18 09:00:26 +01:00
parent 0d6da30a29
commit aee32228c2
26 changed files with 1220 additions and 27 deletions
@@ -0,0 +1,7 @@
using Wino.Core.ViewModels;
namespace Wino.Views.Abstract;
public abstract class WinoAccountManagementPageAbstract : SettingsPageBase<WinoAccountManagementPageViewModel>
{
}
@@ -180,6 +180,8 @@
MenuItemsSource="{x:Bind ViewModel.MenuItems, Mode=OneWay}"
OpenPaneLength="{x:Bind ViewModel.StatePersistenceService.OpenPaneLength, Mode=TwoWay}"
PaneDisplayMode="Auto"
PaneOpened="NavigationPaneOpened"
PaneClosed="NavigationPaneClosed"
Style="{StaticResource CalendarShellNavigationViewStyle}">
<muxc:NavigationView.PaneCustomContent>
<Grid x:Name="PaneCustomContent" Padding="0,0,0,6">
@@ -79,6 +79,12 @@ public sealed partial class CalendarAppShell : CalendarAppShellAbstract,
private void NavigationViewDisplayModeChanged(NavigationView sender, NavigationViewDisplayModeChangedEventArgs args)
=> UpdateNavigationPaneLayout(args.DisplayMode);
private void NavigationPaneOpened(NavigationView sender, object args)
=> UpdateNavigationPaneLayout(sender.DisplayMode);
private void NavigationPaneClosed(NavigationView sender, object args)
=> UpdateNavigationPaneLayout(sender.DisplayMode);
private Task InvokeNewCalendarEventAsync()
=> ViewModel.HandleNavigationItemInvokedAsync(new NewCalendarEventMenuItem());
+103 -13
View File
@@ -80,22 +80,18 @@
</TransitionCollection>
</StackPanel.ChildrenTransitions>
<!-- About hero card. -->
<!-- App About hero card -->
<Border
Padding="24,20"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="8">
<Grid ColumnSpacing="16" RowSpacing="16">
<Grid ColumnSpacing="16">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel
VerticalAlignment="Center"
@@ -108,12 +104,8 @@
Source="ms-appx:///Assets/AppEntries/MailAssets/Square150x150Logo.scale-100.png"
Stretch="Uniform" />
<StackPanel VerticalAlignment="Center">
<TextBlock Style="{StaticResource TitleTextBlockStyle}" Text="Wino Mail" />
<TextBlock
VerticalAlignment="Center"
Style="{StaticResource TitleTextBlockStyle}"
Text="Wino Mail" />
<TextBlock
VerticalAlignment="Top"
Foreground="{ThemeResource TextFillColorTertiaryBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Bind ViewModel.VersionText, Mode=OneWay}" />
@@ -138,7 +130,6 @@
Stretch="Uniform" />
</Viewbox>
</Button>
<Button
Command="{x:Bind ViewModel.NavigateExternalCommand}"
CommandParameter="{x:Bind ViewModel.GitHubUrl, Mode=OneWay}"
@@ -151,7 +142,6 @@
Stretch="Uniform" />
</Viewbox>
</Button>
<Button
Command="{x:Bind ViewModel.NavigateExternalCommand}"
CommandParameter="Store"
@@ -167,6 +157,106 @@
</Grid>
</Border>
<!-- Loading indicator -->
<ProgressRing
x:Name="WinoAccountBusyRing"
Width="24"
Height="24"
HorizontalAlignment="Center"
x:Load="{x:Bind ViewModel.IsWinoAccountBusy, Mode=OneWay}"
IsActive="True" />
<!-- Wino Account: Signed-out state -->
<controls:SettingsCard
x:Name="SignedOutCard"
Description="{x:Bind domain:Translator.SettingsHome_WinoAccount_SignedOutDescription}"
Header="{x:Bind domain:Translator.SettingsHome_WinoAccount_Title}"
x:Load="{x:Bind ViewModel.IsWinoAccountSignedOut, Mode=OneWay}">
<controls:SettingsCard.HeaderIcon>
<FontIcon Glyph="&#xE77B;" />
</controls:SettingsCard.HeaderIcon>
<StackPanel Orientation="Horizontal" Spacing="8">
<Button
Command="{x:Bind ViewModel.WinoAccountSignInCommand}"
Content="{x:Bind domain:Translator.Buttons_SignIn}"
Style="{StaticResource AccentButtonStyle}" />
<Button Command="{x:Bind ViewModel.WinoAccountRegisterCommand}" Content="{x:Bind domain:Translator.Buttons_CreateAccount}" />
</StackPanel>
</controls:SettingsCard>
<!-- Wino Account: Signed-in state -->
<controls:SettingsExpander
x:Name="SignedInExpander"
Description="{x:Bind ViewModel.WinoAccountStatusText, Mode=OneWay}"
Header="{x:Bind ViewModel.WinoAccountEmail, Mode=OneWay}"
x:Load="{x:Bind ViewModel.IsWinoAccountSignedIn, Mode=OneWay}">
<controls:SettingsExpander.HeaderIcon>
<FontIcon Glyph="&#xE77B;" />
</controls:SettingsExpander.HeaderIcon>
<Button
Command="{x:Bind ViewModel.WinoAccountSignOutCommand}"
Content="{x:Bind domain:Translator.WinoAccount_SignOutButton_Action}" />
<controls:SettingsExpander.Items>
<!-- AI Pack active (with progress bar) -->
<controls:SettingsCard
x:Name="AiPackActiveCard"
Description="{x:Bind ViewModel.AiUsageSummary, Mode=OneWay}"
Header="{x:Bind domain:Translator.SettingsHome_AiPack_Title}"
x:Load="{x:Bind ViewModel.CanShowAiUsage, Mode=OneWay}">
<controls:SettingsCard.HeaderIcon>
<ImageIcon Source="ms-appx:///Assets/AIPackIcon.png" />
</controls:SettingsCard.HeaderIcon>
<StackPanel MinWidth="200" Spacing="4">
<ProgressBar
Height="8"
Maximum="100"
Value="{x:Bind ViewModel.AiUsagePercent, Mode=OneWay}" />
<TextBlock
Foreground="{ThemeResource TextFillColorTertiaryBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Bind ViewModel.AiBillingPeriodSummary, Mode=OneWay}" />
</StackPanel>
</controls:SettingsCard>
<!-- AI Pack not purchased -->
<controls:SettingsCard
x:Name="AiPackBuyCard"
Description="{x:Bind domain:Translator.WinoAccount_Management_AiPackBuyDescription}"
Header="{x:Bind domain:Translator.SettingsHome_AiPack_Title}"
x:Load="{x:Bind ViewModel.CanShowBuyAiPack, Mode=OneWay}">
<controls:SettingsCard.HeaderIcon>
<ImageIcon Source="ms-appx:///Assets/AIPackIcon.png" />
</controls:SettingsCard.HeaderIcon>
<Button
Command="{x:Bind ViewModel.OpenBuyAiPackPageCommand}"
Content="{x:Bind domain:Translator.Buttons_Purchase}"
Style="{StaticResource AccentButtonStyle}" />
</controls:SettingsCard>
<!-- Settings sync -->
<controls:SettingsCard
Click="WinoAccountManagementClicked"
Description="{x:Bind domain:Translator.SettingsHome_SettingsSync_Description}"
Header="{x:Bind domain:Translator.SettingsHome_SettingsSync_Title}"
IsClickEnabled="True">
<controls:SettingsCard.HeaderIcon>
<FontIcon Glyph="&#xE895;" />
</controls:SettingsCard.HeaderIcon>
</controls:SettingsCard>
<!-- Manage Wino Account -->
<controls:SettingsCard
Click="WinoAccountManagementClicked"
Header="{x:Bind domain:Translator.SettingsHome_WinoAccount_ManageLink}"
IsClickEnabled="True">
<controls:SettingsCard.HeaderIcon>
<FontIcon Glyph="&#xE713;" />
</controls:SettingsCard.HeaderIcon>
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<Border
Padding="12,0,34,20"
@@ -51,6 +51,11 @@ public sealed partial class SettingOptionsPage : SettingOptionsPageAbstract
ViewModel.NavigateToAddAccount();
}
private void WinoAccountManagementClicked(object sender, RoutedEventArgs e)
{
ViewModel.NavigateToWinoAccountManagementCommand.Execute(null);
}
private void SettingsSearchTextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
{
if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput || string.IsNullOrWhiteSpace(sender.Text))
@@ -0,0 +1,107 @@
<abstract:WinoAccountManagementPageAbstract
x:Class="Wino.Views.Settings.WinoAccountManagementPage"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="{x:Bind domain:Translator.WinoAccount_SettingsSection_Title}"
mc:Ignorable="d">
<ScrollViewer>
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<TextBlock
Margin="0,0,0,8"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Style="{StaticResource BodyTextBlockStyle}"
Text="{x:Bind domain:Translator.WinoAccount_Management_Description}" />
<StackPanel
x:Name="BusyPanel"
HorizontalAlignment="Center"
x:Load="{x:Bind ViewModel.IsBusy, Mode=OneWay}"
Spacing="8">
<ProgressRing
Width="32"
Height="32"
IsActive="True" />
<TextBlock HorizontalAlignment="Center" Text="{x:Bind domain:Translator.Busy}" />
</StackPanel>
<StackPanel
x:Name="SignedOutPanel"
x:Load="{x:Bind ViewModel.IsSignedOut, Mode=OneWay}"
Spacing="{StaticResource SettingsCardSpacing}">
<controls:SettingsCard Description="{x:Bind domain:Translator.WinoAccount_Management_SignedOutDescription}" Header="{x:Bind domain:Translator.WinoAccount_Management_SignedOutTitle}">
<controls:SettingsCard.HeaderIcon>
<SymbolIcon Symbol="Contact" />
</controls:SettingsCard.HeaderIcon>
<StackPanel Orientation="Horizontal" Spacing="12">
<Button Command="{x:Bind ViewModel.RegisterCommand}" Content="{x:Bind domain:Translator.Buttons_CreateAccount}" />
<Button Command="{x:Bind ViewModel.SignInCommand}" Content="{x:Bind domain:Translator.Buttons_SignIn}" />
</StackPanel>
</controls:SettingsCard>
</StackPanel>
<StackPanel
x:Name="SignedInPanel"
x:Load="{x:Bind ViewModel.IsSignedIn, Mode=OneWay}"
Spacing="{StaticResource SettingsCardSpacing}">
<controls:SettingsCard Description="{x:Bind domain:Translator.WinoAccount_Management_AccountCardDescription}" Header="{x:Bind domain:Translator.WinoAccount_Management_AccountCardTitle}">
<controls:SettingsCard.HeaderIcon>
<SymbolIcon Symbol="Contact" />
</controls:SettingsCard.HeaderIcon>
<StackPanel Spacing="8">
<TextBlock FontWeight="SemiBold" Text="{x:Bind ViewModel.AccountEmail, Mode=OneWay}" />
<TextBlock Text="{x:Bind ViewModel.AccountStatusText, Mode=OneWay}" />
<Button
HorizontalAlignment="Left"
Command="{x:Bind ViewModel.SignOutCommand}"
Content="{x:Bind domain:Translator.WinoAccount_SignOutButton_Action}" />
</StackPanel>
</controls:SettingsCard>
<controls:SettingsCard Description="{x:Bind domain:Translator.WinoAccount_Management_AiPackCardDescription}" Header="{x:Bind domain:Translator.WinoAccount_Management_AiPackCardTitle}">
<StackPanel Spacing="8">
<TextBlock FontWeight="SemiBold" Text="{x:Bind ViewModel.AiPackStateText, Mode=OneWay}" />
<TextBlock
x:Name="CanShowAITextBlock"
x:Load="{x:Bind ViewModel.CanShowAiUsage, Mode=OneWay}"
Text="{x:Bind ViewModel.AiUsageSummary, Mode=OneWay}"
TextWrapping="WrapWholeWords" />
<TextBlock
x:Name="BillingBlock"
x:Load="{x:Bind ViewModel.CanShowAiUsage, Mode=OneWay}"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="{x:Bind ViewModel.AiBillingPeriodSummary, Mode=OneWay}"
TextWrapping="WrapWholeWords" />
<TextBlock
x:Name="CanBuyAIPack"
x:Load="{x:Bind ViewModel.CanShowBuyAiPack, Mode=OneWay}"
Text="{x:Bind domain:Translator.WinoAccount_Management_AiPackBuyDescription}"
TextWrapping="WrapWholeWords" />
<Button
x:Name="OpenBuyPageButton"
HorizontalAlignment="Left"
x:Load="{x:Bind ViewModel.CanShowBuyAiPack, Mode=OneWay}"
Command="{x:Bind ViewModel.OpenBuyPageCommand}"
Content="{x:Bind domain:Translator.Buttons_Purchase}" />
</StackPanel>
</controls:SettingsCard>
<controls:SettingsCard Description="{x:Bind domain:Translator.WinoAccount_Management_SettingsCardDescription}" Header="{x:Bind domain:Translator.WinoAccount_Management_SettingsCardTitle}">
<controls:SettingsCard.HeaderIcon>
<SymbolIcon Symbol="Sync" />
</controls:SettingsCard.HeaderIcon>
<StackPanel Orientation="Horizontal" Spacing="12">
<Button Command="{x:Bind ViewModel.ExportSettingsCommand}" Content="{x:Bind domain:Translator.Buttons_Export}" />
<Button Command="{x:Bind ViewModel.ImportSettingsCommand}" Content="{x:Bind domain:Translator.Buttons_Import}" />
</StackPanel>
</controls:SettingsCard>
</StackPanel>
</StackPanel>
</ScrollViewer>
</abstract:WinoAccountManagementPageAbstract>
@@ -0,0 +1,11 @@
using Wino.Views.Abstract;
namespace Wino.Views.Settings;
public sealed partial class WinoAccountManagementPage : WinoAccountManagementPageAbstract
{
public WinoAccountManagementPage()
{
InitializeComponent();
}
}
@@ -61,6 +61,13 @@ public sealed partial class SettingsPage : SettingsPageAbstract,
manageAccountsEntry.Title = Translator.SettingsManageAccountSettings_Title;
}
var winoAccountEntry = PageHistory.FirstOrDefault(a => a.Request.PageType == WinoPage.WinoAccountManagementPage);
if (winoAccountEntry != null)
{
winoAccountEntry.Title = Translator.WinoAccount_SettingsSection_Title;
}
_ = RefreshCurrentPageStateAsync();
UpdateWindowTitle();
}
+2
View File
@@ -525,6 +525,8 @@
OpenPaneLength="{x:Bind ViewModel.StatePersistenceService.OpenPaneLength, Mode=TwoWay}"
PaneDisplayMode="Auto"
PaneOpening="NavigationPaneOpening"
PaneOpened="NavigationPaneOpened"
PaneClosed="NavigationPaneClosed"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
SelectionChanged="MenuSelectionChanged"
Style="{StaticResource CalendarShellNavigationViewStyle}">
@@ -471,6 +471,12 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract,
}
}
private void NavigationPaneOpened(NavigationView sender, object args)
=> UpdateNavigationPaneLayout(sender.DisplayMode);
private void NavigationPaneClosed(NavigationView sender, object args)
=> UpdateNavigationPaneLayout(sender.DisplayMode);
private void NavigationViewDisplayModeChanged(NavigationView sender, NavigationViewDisplayModeChangedEventArgs args)
=> UpdateNavigationPaneLayout(args.DisplayMode);