UI overhaul: minimal top bar, license-first settings, footer-pinned check
Top bar (3-column layout) ------------------------- - Col 1: PROSERVE Launcher wordmark. - Col 2: license badge centered, the badge IS the click target now (a Border with an InputBindings MouseBinding LeftClick to OpenLicense). No more separate "🔑 Activer / changer" button cluttering the right. - Col 3: ⚙ Paramètres + window chrome (min/max/close). - "📁 Dossier" button removed from the top bar — install root is still reachable from Settings. Footer (always visible) ----------------------- - Row 1: "🔄 Vérifier les MAJ" pinned bottom-left, always shown. The optional "Annuler" button stays bottom-right while a download runs. - Row 2: status text + progress bar, only shown when busy or after a status message — the previous "footer entirely hidden when idle" hid the check button too. License flow split in two ------------------------- Click on the license badge: - License is active (valid / expired / revoked) → LicenseDetailsDialog opens. Header pill in matching status color (green/amber/red), shows owner, validity, issued date, machine ID with copy-to-clipboard. Two buttons: "🗑 Désactiver la license" (with confirmation) and Close. - No license OR after deactivation → falls through to the existing OnboardingDialog for re-keying. Settings rework --------------- LICENSE section is now first in SettingsDialog with the same green/amber/red colored chrome as the top bar — at a glance the user sees the same status everywhere. Machine ID copy moved into this card. Sign-manifest no longer needs exec() ------------------------------------ The "🔁 Sync" button in admin/versions.php previously shelled out to `php tools/sign-manifest.php` via exec(). OVH mutualisé often disables exec(), causing silent no-ops and the symptom the user just hit: the ZIP changed (new size 469,657,770 vs manifest's stale 469,831,428) and the launcher rejected it as size mismatch. Refactor: - New PSLauncher\Tools\SignManifest class with ->run() that does the hashing, latest-bump and Ed25519 signing in-process. - tools/sign-manifest.php is now a 6-line wrapper for the class. - admin/versions.php's 'sync' action calls the class directly via require_once + new — works on any host, no exec dependency. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -175,12 +175,18 @@
|
||||
Opacity="0.25"
|
||||
IsHitTestVisible="False" />
|
||||
|
||||
<!-- Top bar -->
|
||||
<!-- Top bar : 3 colonnes (brand / license center / chrome) -->
|
||||
<Border Grid.Row="0" Background="{StaticResource Brush.Bg.Sidebar}"
|
||||
BorderBrush="{StaticResource Brush.Border}" BorderThickness="0,0,0,1"
|
||||
Padding="20,12">
|
||||
<Grid>
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" /> <!-- brand -->
|
||||
<ColumnDefinition Width="*" /> <!-- license (center) -->
|
||||
<ColumnDefinition Width="*" /> <!-- chrome (right) -->
|
||||
</Grid.ColumnDefinitions>
|
||||
<!-- Col 1 : brand -->
|
||||
<StackPanel Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<TextBlock Text="PROSERVE"
|
||||
FontFamily="{StaticResource Font.Brand}"
|
||||
FontSize="22"
|
||||
@@ -193,92 +199,81 @@
|
||||
VerticalAlignment="Center"
|
||||
Margin="14,0,0,0" />
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<Button Style="{StaticResource SecondaryButton}"
|
||||
Content="🔄 Vérifier les MAJ"
|
||||
Command="{Binding CheckForUpdatesCommand}"
|
||||
shell:WindowChrome.IsHitTestVisibleInChrome="True"
|
||||
Margin="0,0,8,0" />
|
||||
<Button Style="{StaticResource SecondaryButton}"
|
||||
Content="📁 Dossier"
|
||||
Command="{Binding OpenInstallRootCommand}"
|
||||
shell:WindowChrome.IsHitTestVisibleInChrome="True"
|
||||
Margin="0,0,12,0" />
|
||||
<!-- Badge license -->
|
||||
<Border CornerRadius="14" Padding="10,4"
|
||||
VerticalAlignment="Center" Margin="0,0,8,0">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<!-- Default: error (rouge) -->
|
||||
<Setter Property="Background" Value="#2A1414" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource Brush.Status.AvailableBg}" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding LicenseSeverity}" Value="Ok">
|
||||
<Setter Property="Background" Value="{StaticResource Brush.Status.InstalledBg}" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource Brush.Status.Installed}" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding LicenseSeverity}" Value="Warning">
|
||||
<Setter Property="Background" Value="{StaticResource Brush.Status.BusyBg}" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource Brush.Status.Busy}" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding LicenseSeverity}" Value="Error">
|
||||
<Setter Property="Background" Value="#2A1414" />
|
||||
<Setter Property="BorderBrush" Value="#EF4444" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding LicenseIcon}"
|
||||
FontSize="14" FontWeight="Bold"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,8,0">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="#EF4444" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding LicenseSeverity}" Value="Ok">
|
||||
<Setter Property="Foreground" Value="{StaticResource Brush.Status.Installed}" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding LicenseSeverity}" Value="Warning">
|
||||
<Setter Property="Foreground" Value="{StaticResource Brush.Status.Busy}" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
<TextBlock Text="{Binding LicenseSummary}"
|
||||
FontSize="12" FontWeight="SemiBold"
|
||||
VerticalAlignment="Center">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="#FCA5A5" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding LicenseSeverity}" Value="Ok">
|
||||
<Setter Property="Foreground" Value="#86EFAC" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding LicenseSeverity}" Value="Warning">
|
||||
<Setter Property="Foreground" Value="#FCD34D" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<Button Style="{StaticResource SecondaryButton}"
|
||||
Content="🔑 Activer / changer"
|
||||
Command="{Binding ActivateLicenseCommand}"
|
||||
shell:WindowChrome.IsHitTestVisibleInChrome="True"
|
||||
Margin="0,0,8,0" />
|
||||
|
||||
<!-- Col 2 : badge license cliquable, centré -->
|
||||
<Border Grid.Column="1"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
Cursor="Hand"
|
||||
CornerRadius="16" Padding="14,6"
|
||||
shell:WindowChrome.IsHitTestVisibleInChrome="True"
|
||||
ToolTip="Voir / changer la license">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Background" Value="#2A1414" />
|
||||
<Setter Property="BorderBrush" Value="#EF4444" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding LicenseSeverity}" Value="Ok">
|
||||
<Setter Property="Background" Value="{StaticResource Brush.Status.InstalledBg}" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource Brush.Status.Installed}" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding LicenseSeverity}" Value="Warning">
|
||||
<Setter Property="Background" Value="{StaticResource Brush.Status.BusyBg}" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource Brush.Status.Busy}" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<Border.InputBindings>
|
||||
<MouseBinding Gesture="LeftClick" Command="{Binding OpenLicenseCommand}" />
|
||||
</Border.InputBindings>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding LicenseIcon}"
|
||||
FontSize="15" FontWeight="Bold"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,8,0">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="#EF4444" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding LicenseSeverity}" Value="Ok">
|
||||
<Setter Property="Foreground" Value="{StaticResource Brush.Status.Installed}" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding LicenseSeverity}" Value="Warning">
|
||||
<Setter Property="Foreground" Value="{StaticResource Brush.Status.Busy}" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
<TextBlock Text="{Binding LicenseSummary}"
|
||||
FontSize="13" FontWeight="SemiBold"
|
||||
VerticalAlignment="Center">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="#FCA5A5" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding LicenseSeverity}" Value="Ok">
|
||||
<Setter Property="Foreground" Value="#86EFAC" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding LicenseSeverity}" Value="Warning">
|
||||
<Setter Property="Foreground" Value="#FCD34D" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Col 3 : Paramètres + window chrome -->
|
||||
<StackPanel Grid.Column="2" Orientation="Horizontal"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center">
|
||||
<Button Style="{StaticResource SecondaryButton}"
|
||||
Content="⚙ Paramètres"
|
||||
shell:WindowChrome.IsHitTestVisibleInChrome="True"
|
||||
Command="{Binding OpenSettingsCommand}"
|
||||
Margin="0,0,16,0" />
|
||||
|
||||
<!-- Window controls custom (style chrome dark) -->
|
||||
<Button Style="{StaticResource WindowControlButton}"
|
||||
Content="—" ToolTip="Réduire"
|
||||
shell:WindowChrome.IsHitTestVisibleInChrome="True"
|
||||
@@ -491,31 +486,43 @@
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- Footer (busy / status) -->
|
||||
<!-- Footer : toujours visible.
|
||||
Ligne 1 : bouton "Vérifier les MAJ" à gauche (toujours présent)
|
||||
Ligne 2 : statut + progress bar (visible quand busy / status non vide) -->
|
||||
<Border Grid.Row="2" Background="{StaticResource Brush.Bg.Footer}"
|
||||
BorderBrush="{StaticResource Brush.Border}" BorderThickness="0,1,0,0"
|
||||
Padding="20,8"
|
||||
Visibility="{Binding FooterVisibility}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0">
|
||||
Padding="20,10">
|
||||
<StackPanel>
|
||||
<!-- Ligne 1 : actions permanentes -->
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Column="0"
|
||||
Style="{StaticResource SecondaryButton}"
|
||||
Content="🔄 Vérifier les MAJ"
|
||||
Command="{Binding CheckForUpdatesCommand}" />
|
||||
<Button Grid.Column="2"
|
||||
Style="{StaticResource SecondaryButton}"
|
||||
Content="Annuler"
|
||||
Command="{Binding CancelDownloadCommand}"
|
||||
Visibility="{Binding IsBusy, Converter={StaticResource BoolToVisibility}}" />
|
||||
</Grid>
|
||||
|
||||
<!-- Ligne 2 : statut + progression (visible si busy ou message) -->
|
||||
<StackPanel Margin="0,8,0,0"
|
||||
Visibility="{Binding FooterVisibility}">
|
||||
<TextBlock Text="{Binding FooterText}"
|
||||
Foreground="{StaticResource Brush.Text.Secondary}" />
|
||||
Foreground="{StaticResource Brush.Text.Secondary}"
|
||||
FontSize="12" />
|
||||
<ProgressBar Height="4" Margin="0,4,0,0"
|
||||
Value="{Binding ProgressPercent}" Maximum="100"
|
||||
Foreground="{StaticResource Brush.Accent}"
|
||||
Background="#2A2A30" BorderThickness="0" />
|
||||
</StackPanel>
|
||||
<Button Grid.Column="1"
|
||||
Style="{StaticResource SecondaryButton}"
|
||||
Content="Annuler"
|
||||
VerticalAlignment="Center" Margin="12,0,0,0"
|
||||
Command="{Binding CancelDownloadCommand}"
|
||||
Visibility="{Binding IsBusy, Converter={StaticResource BoolToVisibility}}" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
Reference in New Issue
Block a user