v0.5: settings dialog, persistent Serilog logs, Windows toasts
Settings (⚙ button in top bar)
------------------------------
SettingsDialog opens via OpenSettings command in MainViewModel. Sections:
- Serveur: server URL field + "Tester" button that GETs /api/health
and reports status inline.
- Installation: installRoot path with Browse button
(Microsoft.Win32.OpenFolderDialog, .NET 8 native).
- License: shows status / owner / exp / machine ID (read-only,
copy-to-clipboard button), "Désactiver" wipes the cached license.
- Cache: shows download cache path + current size, opens or empties it.
- Logs & Application: launcher version + logs path with "Open" button.
Apply persists to LocalConfig via IConfigStore. After save, MainViewModel
RebuildList()s so changes to ServerBaseUrl or InstallRoot take effect
without restart.
Persistent Serilog logs
-----------------------
Logs now live in %LocalAppData%/PSLauncher/logs/app-YYYYMMDD.log, rolling
daily, 10 days kept. Output template includes source context and stack
traces. Generic Host wired up via .UseSerilog() so all
ILogger<T>-injected types share the sink. Unhandled AppDomain and
Dispatcher exceptions are routed to Serilog before propagation.
Windows toasts
--------------
IToastService + ToastService backed by Microsoft.Toolkit.Uwp.Notifications
(ToastContentBuilder.Show()). Required bumping the App TFM from
net8.0-windows to net8.0-windows10.0.17763.0 (with explicit
WindowsSdkPackageVersion=10.0.17763.41 to satisfy CommunityToolkit.Mvvm
8.3.2's MVVMTKCFG0003 check). Triggered on:
- successful install completion: "Proserve v{X} est prête à être lancée"
- install/download error: short error excerpt
Misc
----
- InverseBoolConverter for "disable button while busy" patterns.
- Added Markdig.Wpf import to ReleaseNotesViewerDialog (was implicit
before, now required explicitly).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -175,7 +175,11 @@
|
||||
VerticalAlignment="Center" Margin="0,0,8,0" />
|
||||
<Button Style="{StaticResource SecondaryButton}"
|
||||
Content="🔑 Activer / changer"
|
||||
Command="{Binding ActivateLicenseCommand}" />
|
||||
Command="{Binding ActivateLicenseCommand}"
|
||||
Margin="0,0,8,0" />
|
||||
<Button Style="{StaticResource SecondaryButton}"
|
||||
Content="⚙ Paramètres"
|
||||
Command="{Binding OpenSettingsCommand}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
232
src/PSLauncher.App/Views/SettingsDialog.xaml
Normal file
232
src/PSLauncher.App/Views/SettingsDialog.xaml
Normal file
@@ -0,0 +1,232 @@
|
||||
<Window x:Class="PSLauncher.App.Views.SettingsDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="clr-namespace:PSLauncher.App.ViewModels"
|
||||
Title="Paramètres"
|
||||
Width="640" Height="720"
|
||||
MinWidth="540" MinHeight="500"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Background="{StaticResource Brush.Bg.Window}"
|
||||
d:DataContext="{d:DesignInstance Type=vm:SettingsViewModel}"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Header -->
|
||||
<Border Grid.Row="0" Padding="32,24,32,16">
|
||||
<TextBlock Text="Paramètres" FontSize="22" FontWeight="SemiBold"
|
||||
Foreground="{StaticResource Brush.Text.Primary}" />
|
||||
</Border>
|
||||
|
||||
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" Padding="32,0,32,16">
|
||||
<StackPanel>
|
||||
|
||||
<!-- Serveur -->
|
||||
<Border Background="{StaticResource Brush.Bg.Card}"
|
||||
BorderBrush="{StaticResource Brush.Border}" BorderThickness="1"
|
||||
CornerRadius="6" Padding="20" Margin="0,0,0,16">
|
||||
<StackPanel>
|
||||
<TextBlock Text="SERVEUR"
|
||||
FontSize="11" FontWeight="Bold"
|
||||
Foreground="{StaticResource Brush.Text.Secondary}"
|
||||
Margin="0,0,0,8" />
|
||||
<TextBlock Text="URL de l'API"
|
||||
Foreground="{StaticResource Brush.Text.Secondary}"
|
||||
FontSize="12" Margin="0,0,0,4" />
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox Grid.Column="0"
|
||||
Text="{Binding ServerBaseUrl, UpdateSourceTrigger=PropertyChanged}"
|
||||
Background="#1A1A20"
|
||||
Foreground="{StaticResource Brush.Text.Primary}"
|
||||
BorderBrush="{StaticResource Brush.Border}"
|
||||
BorderThickness="1" Padding="8" />
|
||||
<Button Grid.Column="1" Margin="8,0,0,0"
|
||||
Style="{StaticResource SecondaryButton}"
|
||||
Content="Tester"
|
||||
Command="{Binding TestConnectionCommand}"
|
||||
IsEnabled="{Binding IsTestingConnection, Converter={StaticResource InverseBoolToBool}}" />
|
||||
</Grid>
|
||||
<TextBlock Text="{Binding ConnectionStatus}"
|
||||
Foreground="{StaticResource Brush.Text.Secondary}"
|
||||
FontSize="12" Margin="0,8,0,0" TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Installation -->
|
||||
<Border Background="{StaticResource Brush.Bg.Card}"
|
||||
BorderBrush="{StaticResource Brush.Border}" BorderThickness="1"
|
||||
CornerRadius="6" Padding="20" Margin="0,0,0,16">
|
||||
<StackPanel>
|
||||
<TextBlock Text="INSTALLATION"
|
||||
FontSize="11" FontWeight="Bold"
|
||||
Foreground="{StaticResource Brush.Text.Secondary}"
|
||||
Margin="0,0,0,8" />
|
||||
<TextBlock Text="Dossier où sont installées les versions"
|
||||
Foreground="{StaticResource Brush.Text.Secondary}"
|
||||
FontSize="12" Margin="0,0,0,4" />
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox Grid.Column="0"
|
||||
Text="{Binding InstallRoot, UpdateSourceTrigger=PropertyChanged}"
|
||||
Background="#1A1A20"
|
||||
Foreground="{StaticResource Brush.Text.Primary}"
|
||||
BorderBrush="{StaticResource Brush.Border}"
|
||||
BorderThickness="1" Padding="8"
|
||||
FontFamily="Consolas" />
|
||||
<Button Grid.Column="1" Margin="8,0,0,0"
|
||||
Style="{StaticResource SecondaryButton}"
|
||||
Content="📁 Parcourir"
|
||||
Command="{Binding BrowseInstallRootCommand}" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- License -->
|
||||
<Border Background="{StaticResource Brush.Bg.Card}"
|
||||
BorderBrush="{StaticResource Brush.Border}" BorderThickness="1"
|
||||
CornerRadius="6" Padding="20" Margin="0,0,0,16">
|
||||
<StackPanel>
|
||||
<TextBlock Text="LICENSE"
|
||||
FontSize="11" FontWeight="Bold"
|
||||
Foreground="{StaticResource Brush.Text.Secondary}"
|
||||
Margin="0,0,0,8" />
|
||||
<TextBlock Text="{Binding LicenseInfo}"
|
||||
Foreground="{StaticResource Brush.Text.Primary}"
|
||||
FontSize="13" />
|
||||
<Grid Margin="0,12,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock Text="Identifiant machine (anonyme)"
|
||||
FontSize="12"
|
||||
Foreground="{StaticResource Brush.Text.Secondary}" />
|
||||
<TextBlock Text="{Binding MachineId}"
|
||||
FontFamily="Consolas" FontSize="11"
|
||||
Foreground="{StaticResource Brush.Text.Primary}"
|
||||
Margin="0,2,0,0" TextTrimming="CharacterEllipsis" />
|
||||
</StackPanel>
|
||||
<Button Grid.Column="1"
|
||||
Style="{StaticResource SecondaryButton}"
|
||||
Content="📋 Copier"
|
||||
Command="{Binding CopyMachineIdCommand}" />
|
||||
</Grid>
|
||||
<Button Style="{StaticResource SecondaryButton}"
|
||||
Content="Désactiver la license sur cette machine"
|
||||
Command="{Binding DeactivateLicenseCommand}"
|
||||
Margin="0,12,0,0" HorizontalAlignment="Left" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Cache -->
|
||||
<Border Background="{StaticResource Brush.Bg.Card}"
|
||||
BorderBrush="{StaticResource Brush.Border}" BorderThickness="1"
|
||||
CornerRadius="6" Padding="20" Margin="0,0,0,16">
|
||||
<StackPanel>
|
||||
<TextBlock Text="CACHE DE TÉLÉCHARGEMENTS"
|
||||
FontSize="11" FontWeight="Bold"
|
||||
Foreground="{StaticResource Brush.Text.Secondary}"
|
||||
Margin="0,0,0,8" />
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock Text="{Binding CacheDirectory}"
|
||||
FontFamily="Consolas" FontSize="11"
|
||||
Foreground="{StaticResource Brush.Text.Primary}"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
<TextBlock FontSize="12"
|
||||
Foreground="{StaticResource Brush.Text.Secondary}">
|
||||
<Run Text="Taille actuelle : " />
|
||||
<Run Text="{Binding CacheSizeDisplay}" FontWeight="SemiBold" />
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<Button Grid.Column="1" Margin="8,0,0,0"
|
||||
Style="{StaticResource SecondaryButton}"
|
||||
Content="📁"
|
||||
Command="{Binding OpenCacheFolderCommand}" />
|
||||
<Button Grid.Column="2" Margin="8,0,0,0"
|
||||
Style="{StaticResource SecondaryButton}"
|
||||
Content="🗑 Vider"
|
||||
Command="{Binding ClearCacheCommand}" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Logs / About -->
|
||||
<Border Background="{StaticResource Brush.Bg.Card}"
|
||||
BorderBrush="{StaticResource Brush.Border}" BorderThickness="1"
|
||||
CornerRadius="6" Padding="20" Margin="0,0,0,16">
|
||||
<StackPanel>
|
||||
<TextBlock Text="LOGS & APPLICATION"
|
||||
FontSize="11" FontWeight="Bold"
|
||||
Foreground="{StaticResource Brush.Text.Secondary}"
|
||||
Margin="0,0,0,8" />
|
||||
<TextBlock FontSize="13"
|
||||
Foreground="{StaticResource Brush.Text.Primary}">
|
||||
<Run Text="Version : " />
|
||||
<Run Text="{Binding LauncherVersion}" FontWeight="SemiBold" />
|
||||
</TextBlock>
|
||||
<Grid Margin="0,8,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock Text="{Binding LogsDirectory}"
|
||||
FontFamily="Consolas" FontSize="11"
|
||||
Foreground="{StaticResource Brush.Text.Primary}"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
<TextBlock Text="Logs rotation quotidienne, 10 jours conservés"
|
||||
FontSize="12"
|
||||
Foreground="{StaticResource Brush.Text.Secondary}"
|
||||
Margin="0,2,0,0" />
|
||||
</StackPanel>
|
||||
<Button Grid.Column="1" Margin="8,0,0,0"
|
||||
Style="{StaticResource SecondaryButton}"
|
||||
Content="📁 Ouvrir"
|
||||
Command="{Binding OpenLogsFolderCommand}" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- Footer -->
|
||||
<Border Grid.Row="2" Background="{StaticResource Brush.Bg.Footer}"
|
||||
BorderBrush="{StaticResource Brush.Border}" BorderThickness="0,1,0,0"
|
||||
Padding="20,12">
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Style="{StaticResource SecondaryButton}"
|
||||
Content="Annuler"
|
||||
IsCancel="True"
|
||||
Margin="0,0,12,0"
|
||||
Click="OnCancel" />
|
||||
<Button Style="{StaticResource AccentButton}"
|
||||
Content="Enregistrer"
|
||||
Padding="32,8"
|
||||
IsDefault="True"
|
||||
Click="OnSave" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Window>
|
||||
28
src/PSLauncher.App/Views/SettingsDialog.xaml.cs
Normal file
28
src/PSLauncher.App/Views/SettingsDialog.xaml.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System.Windows;
|
||||
using PSLauncher.App.ViewModels;
|
||||
|
||||
namespace PSLauncher.App.Views;
|
||||
|
||||
public partial class SettingsDialog : Window
|
||||
{
|
||||
private readonly SettingsViewModel _vm;
|
||||
|
||||
public SettingsDialog(SettingsViewModel vm)
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = _vm = vm;
|
||||
}
|
||||
|
||||
private void OnSave(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_vm.SaveCommand.Execute(null);
|
||||
DialogResult = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void OnCancel(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DialogResult = false;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user