UI: featured hero card, vivid status colors, themed Markdown render

Featured version
----------------
The highest installed version (or highest remote if none installed) now
gets a large hero card at the top of the window: 32px Proserve title,
oversized colored status pill, and a much bigger primary action button
(LANCER / INSTALLER 56px padding). All other versions move below into a
"AUTRES VERSIONS" section with a horizontal divider, displayed as the
existing compact rows.

MainViewModel exposes FeaturedVersion + OtherVersions instead of one
flat Versions collection.

Vivid status colors
-------------------
Card backgrounds were too close (dark gray vs slightly bluer dark gray).
New scheme:
- Installed: card stays dark gray, but a 4px green strip on the left and
  a vivid green "● Installée" pill make it unmistakable.
- Available remote-only: distinct dark blue card + vivid blue strip + blue
  "○ Disponible" pill.
- Busy: amber strip + amber pill, amber progress bar.

Brushes added to Theme.xaml: Brush.Status.Installed (#16A34A),
Brush.Status.Available (#3B82F6), Brush.Status.Busy (#F59E0B), each with
a matching very-dark-tint *Bg variant for card backgrounds.

Markdown theming
----------------
Release notes dialogs were unreadable (white background, near-white text).
Markdig.Wpf produces a FlowDocument with default white bg / black fg
regardless of the host control. Added MarkdownTheming.BuildThemedDocument
which renders the Markdown then walks all blocks/inlines to apply the
launcher's dark palette (Brush.Bg.Card transparent, Brush.Text.Primary
foreground, Brush.Accent links). Both UpdateAvailableDialog and
ReleaseNotesViewerDialog use this helper.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-01 09:50:51 +02:00
parent 4e9f757ce1
commit 6128f7d220
6 changed files with 479 additions and 202 deletions

View File

@@ -3,7 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:PSLauncher.App.ViewModels"
Title="PROSERVE Launcher"
Width="960" Height="720"
Width="980" Height="780"
MinWidth="780" MinHeight="500"
WindowStartupLocation="CenterScreen"
d:DataContext="{d:DesignInstance Type=vm:MainViewModel}"
@@ -11,11 +11,145 @@
mc:Ignorable="d"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
<Window.Resources>
<!-- =================== TEMPLATE : LIGNE COMPACTE (autres versions) =================== -->
<DataTemplate x:Key="CompactRowTemplate" DataType="{x:Type vm:VersionRowViewModel}">
<Border Margin="0,0,0,8" CornerRadius="6" BorderThickness="1">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="{StaticResource Brush.Bg.Card}" />
<Setter Property="BorderBrush" Value="{StaticResource Brush.Border}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsRemoteOnly}" Value="True">
<Setter Property="Background" Value="{StaticResource Brush.Status.AvailableBg}" />
<Setter Property="BorderBrush" Value="{StaticResource Brush.Status.Available}" />
</DataTrigger>
<DataTrigger Binding="{Binding IsBusy}" Value="True">
<Setter Property="Background" Value="{StaticResource Brush.Status.BusyBg}" />
<Setter Property="BorderBrush" Value="{StaticResource Brush.Status.Busy}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4" /> <!-- accent strip -->
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Strip latérale colorée -->
<Rectangle Grid.Column="0" RadiusX="2" RadiusY="2" Margin="0,8">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Setter Property="Fill" Value="{StaticResource Brush.Status.Installed}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsRemoteOnly}" Value="True">
<Setter Property="Fill" Value="{StaticResource Brush.Status.Available}" />
</DataTrigger>
<DataTrigger Binding="{Binding IsBusy}" Value="True">
<Setter Property="Fill" Value="{StaticResource Brush.Status.Busy}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
<Grid Grid.Column="1" Margin="16,12">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<TextBlock Text="{Binding Version, StringFormat='v{0}'}"
FontSize="15" FontWeight="SemiBold"
VerticalAlignment="Center"
Foreground="{StaticResource Brush.Text.Primary}" />
<Border CornerRadius="10" Padding="8,3" Margin="12,0,0,0"
VerticalAlignment="Center">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="{StaticResource Brush.Status.Installed}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsRemoteOnly}" Value="True">
<Setter Property="Background" Value="{StaticResource Brush.Status.Available}" />
</DataTrigger>
<DataTrigger Binding="{Binding IsBusy}" Value="True">
<Setter Property="Background" Value="{StaticResource Brush.Status.Busy}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<TextBlock Text="{Binding StateLabel}" FontSize="11" FontWeight="SemiBold"
Foreground="White" />
</Border>
</StackPanel>
<TextBlock Grid.Row="1" FontSize="11"
Foreground="{StaticResource Brush.Text.Secondary}"
Margin="0,4,0,0">
<Run Text="{Binding SizeDisplay, Mode=OneWay}" />
<Run Text=" • " />
<Run Text="{Binding PrimaryDate, Mode=OneWay}" />
</TextBlock>
</Grid>
<!-- Action button -->
<StackPanel Grid.Column="2" Orientation="Horizontal" VerticalAlignment="Center" Margin="12,0,0,0">
<Button Style="{StaticResource PrimaryButton}"
Content="▶ Lancer" Padding="22,8" FontSize="13"
Command="{Binding LaunchCommand}"
Visibility="{Binding IsInstalled, Converter={StaticResource BoolToVisibility}}" />
<Button Style="{StaticResource AccentButton}"
Content="⬇ Installer" Padding="22,8" FontSize="13"
Command="{Binding InstallCommand}"
Visibility="{Binding IsRemoteOnly, Converter={StaticResource BoolToVisibility}}" />
<StackPanel Orientation="Horizontal"
Visibility="{Binding IsBusy, Converter={StaticResource BoolToVisibility}}">
<ProgressBar Width="140" Height="6"
Value="{Binding ProgressPercent}" Maximum="100"
Foreground="{StaticResource Brush.Status.Busy}"
Background="#2A2A30" BorderThickness="0"
VerticalAlignment="Center" />
<TextBlock Text="{Binding ProgressPercent, StringFormat={}{0:0}%}"
FontSize="11" Margin="8,0,0,0" VerticalAlignment="Center"
Foreground="{StaticResource Brush.Text.Secondary}" />
</StackPanel>
</StackPanel>
<!-- ... menu -->
<Button Grid.Column="3"
Style="{StaticResource IconButton}"
Content="⋯" FontSize="18" FontWeight="Bold"
Margin="8,0,8,0" VerticalAlignment="Center"
ToolTip="Plus d'actions"
Tag="{Binding}"
Click="OnMoreMenuClick">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="📜 Voir les release notes"
Command="{Binding PlacementTarget.Tag.ShowReleaseNotesCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
<MenuItem Header="📁 Ouvrir le dossier"
Command="{Binding PlacementTarget.Tag.OpenFolderCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
Visibility="{Binding PlacementTarget.Tag.IsInstalled, RelativeSource={RelativeSource AncestorType=ContextMenu}, Converter={StaticResource BoolToVisibility}}" />
<Separator Visibility="{Binding PlacementTarget.Tag.IsInstalled, RelativeSource={RelativeSource AncestorType=ContextMenu}, Converter={StaticResource BoolToVisibility}}" />
<MenuItem Header="🗑 Supprimer cette version…"
Command="{Binding PlacementTarget.Tag.UninstallCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
Visibility="{Binding PlacementTarget.Tag.IsInstalled, RelativeSource={RelativeSource AncestorType=ContextMenu}, Converter={StaticResource BoolToVisibility}}" />
</ContextMenu>
</Button.ContextMenu>
</Button>
</Grid>
</Border>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <!-- Top bar -->
<RowDefinition Height="*" /> <!-- Body -->
<RowDefinition Height="Auto" /> <!-- Footer -->
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Top bar -->
@@ -28,172 +162,202 @@
Foreground="{StaticResource Brush.Text.Primary}"
VerticalAlignment="Center" />
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal" VerticalAlignment="Center">
<Button Style="{StaticResource SecondaryButton}"
Content="🔄 Vérifier les MAJ"
Command="{Binding CheckForUpdatesCommand}"
Margin="0,0,8,0" />
<Button Style="{StaticResource SecondaryButton}"
Content="📁 Dossier"
Command="{Binding OpenInstallRootCommand}"
Margin="0,0,12,0" />
<TextBlock Text="{Binding LicenseSummary}"
Foreground="{StaticResource Brush.Text.Secondary}"
VerticalAlignment="Center" Margin="0,0,12,0" />
VerticalAlignment="Center" />
</StackPanel>
</Grid>
</Border>
<!-- Body -->
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<StackPanel Margin="32,24">
<StackPanel Margin="32,28">
<!-- Header / actions -->
<Grid Margin="0,0,0,16">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Text="Versions"
FontSize="22" FontWeight="SemiBold"
Foreground="{StaticResource Brush.Text.Primary}" />
<TextBlock Text="Lance, installe ou supprime une version. Les versions installées et celles disponibles sur le serveur cohabitent."
FontSize="12"
<!-- ========= FEATURED (version courante) ========= -->
<Border CornerRadius="10" BorderThickness="1"
Padding="0"
Margin="0,0,0,32"
Visibility="{Binding HasFeaturedVersion, Converter={StaticResource BoolToVisibility}}">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="{StaticResource Brush.Bg.Card}" />
<Setter Property="BorderBrush" Value="{StaticResource Brush.Status.Installed}" />
<Style.Triggers>
<DataTrigger Binding="{Binding FeaturedVersion.IsRemoteOnly}" Value="True">
<Setter Property="BorderBrush" Value="{StaticResource Brush.Status.Available}" />
</DataTrigger>
<DataTrigger Binding="{Binding FeaturedVersion.IsBusy}" Value="True">
<Setter Property="BorderBrush" Value="{StaticResource Brush.Status.Busy}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="6" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Bande latérale large -->
<Rectangle Grid.Column="0">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Setter Property="Fill" Value="{StaticResource Brush.Status.Installed}" />
<Style.Triggers>
<DataTrigger Binding="{Binding FeaturedVersion.IsRemoteOnly}" Value="True">
<Setter Property="Fill" Value="{StaticResource Brush.Status.Available}" />
</DataTrigger>
<DataTrigger Binding="{Binding FeaturedVersion.IsBusy}" Value="True">
<Setter Property="Fill" Value="{StaticResource Brush.Status.Busy}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
<Grid Grid.Column="1" Margin="32,28">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Label "Version courante" -->
<TextBlock Grid.Row="0" Grid.Column="0"
Text="VERSION COURANTE"
FontSize="11" FontWeight="Bold"
Foreground="{StaticResource Brush.Text.Secondary}"
Margin="0,0,0,4" />
<!-- Numéro version + badge -->
<StackPanel Grid.Row="1" Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Center">
<TextBlock Text="{Binding FeaturedVersion.Version, StringFormat='Proserve v{0}'}"
FontSize="32" FontWeight="Bold"
Foreground="{StaticResource Brush.Text.Primary}" />
<Border CornerRadius="12" Padding="10,4" Margin="16,8,0,0"
VerticalAlignment="Center">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="{StaticResource Brush.Status.Installed}" />
<Style.Triggers>
<DataTrigger Binding="{Binding FeaturedVersion.IsRemoteOnly}" Value="True">
<Setter Property="Background" Value="{StaticResource Brush.Status.Available}" />
</DataTrigger>
<DataTrigger Binding="{Binding FeaturedVersion.IsBusy}" Value="True">
<Setter Property="Background" Value="{StaticResource Brush.Status.Busy}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<TextBlock Text="{Binding FeaturedVersion.StateLabel}" FontSize="12" FontWeight="SemiBold"
Foreground="White" />
</Border>
</StackPanel>
<!-- Meta -->
<TextBlock Grid.Row="2" Grid.Column="0"
FontSize="13"
Foreground="{StaticResource Brush.Text.Secondary}"
Margin="0,8,0,0">
<Run Text="Sortie le " />
<Run Text="{Binding FeaturedVersion.PrimaryDate, Mode=OneWay}" />
<Run Text=" • " />
<Run Text="{Binding FeaturedVersion.SizeDisplay, Mode=OneWay}" />
</TextBlock>
<!-- Action principale (gros bouton) -->
<Button Grid.Row="0" Grid.RowSpan="3" Grid.Column="1"
Style="{StaticResource PrimaryButton}"
Content="▶ LANCER"
FontSize="20" Padding="56,16"
VerticalAlignment="Center"
Command="{Binding FeaturedVersion.LaunchCommand}"
Visibility="{Binding FeaturedVersion.IsInstalled, Converter={StaticResource BoolToVisibility}}" />
<Button Grid.Row="0" Grid.RowSpan="3" Grid.Column="1"
Style="{StaticResource AccentButton}"
Content="⬇ INSTALLER"
FontSize="20" Padding="48,16"
VerticalAlignment="Center"
Command="{Binding FeaturedVersion.InstallCommand}"
Visibility="{Binding FeaturedVersion.IsRemoteOnly, Converter={StaticResource BoolToVisibility}}" />
<StackPanel Grid.Row="0" Grid.RowSpan="3" Grid.Column="1"
Orientation="Vertical" VerticalAlignment="Center" Width="220"
Visibility="{Binding FeaturedVersion.IsBusy, Converter={StaticResource BoolToVisibility}}">
<TextBlock Text="{Binding FeaturedVersion.StateLabel}"
HorizontalAlignment="Center"
Foreground="{StaticResource Brush.Status.Busy}"
FontWeight="SemiBold" Margin="0,0,0,8" />
<ProgressBar Height="8"
Value="{Binding FeaturedVersion.ProgressPercent}" Maximum="100"
Foreground="{StaticResource Brush.Status.Busy}"
Background="#2A2A30" BorderThickness="0" />
<TextBlock Text="{Binding FeaturedVersion.ProgressPercent, StringFormat={}{0:0}%}"
HorizontalAlignment="Center"
FontSize="12" Margin="0,4,0,0"
Foreground="{StaticResource Brush.Text.Secondary}" />
</StackPanel>
<!-- ... menu -->
<Button Grid.Row="0" Grid.RowSpan="3" Grid.Column="2"
Style="{StaticResource IconButton}"
Content="⋯" FontSize="22" FontWeight="Bold"
Margin="12,0,0,0"
VerticalAlignment="Center"
ToolTip="Plus d'actions"
Tag="{Binding FeaturedVersion}"
Click="OnMoreMenuClick">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="📜 Voir les release notes"
Command="{Binding PlacementTarget.Tag.ShowReleaseNotesCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
<MenuItem Header="📁 Ouvrir le dossier"
Command="{Binding PlacementTarget.Tag.OpenFolderCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
Visibility="{Binding PlacementTarget.Tag.IsInstalled, RelativeSource={RelativeSource AncestorType=ContextMenu}, Converter={StaticResource BoolToVisibility}}" />
<Separator Visibility="{Binding PlacementTarget.Tag.IsInstalled, RelativeSource={RelativeSource AncestorType=ContextMenu}, Converter={StaticResource BoolToVisibility}}" />
<MenuItem Header="🗑 Supprimer cette version…"
Command="{Binding PlacementTarget.Tag.UninstallCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
Visibility="{Binding PlacementTarget.Tag.IsInstalled, RelativeSource={RelativeSource AncestorType=ContextMenu}, Converter={StaticResource BoolToVisibility}}" />
</ContextMenu>
</Button.ContextMenu>
</Button>
</Grid>
</Grid>
</Border>
<!-- ========= AUTRES VERSIONS ========= -->
<StackPanel Visibility="{Binding HasOtherVersions, Converter={StaticResource BoolToVisibility}}">
<Grid Margin="0,0,0,12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="AUTRES VERSIONS"
FontSize="12" FontWeight="Bold"
Foreground="{StaticResource Brush.Text.Secondary}"
Margin="0,4,0,0"
TextWrapping="Wrap" />
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center">
<Button Style="{StaticResource SecondaryButton}"
Content="🔄 Vérifier les MAJ"
Command="{Binding CheckForUpdatesCommand}"
Margin="0,0,8,0" />
<Button Style="{StaticResource SecondaryButton}"
Content="📁 Dossier"
Command="{Binding OpenInstallRootCommand}" />
</StackPanel>
</Grid>
VerticalAlignment="Center" />
<Border Grid.Column="1" Background="{StaticResource Brush.Border}"
Height="1" Margin="12,0,0,0" VerticalAlignment="Center" />
</Grid>
<!-- Version list -->
<ItemsControl ItemsSource="{Binding Versions}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type vm:VersionRowViewModel}">
<Border Margin="0,0,0,8"
CornerRadius="6"
BorderThickness="1">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="{StaticResource Brush.Bg.Card}" />
<Setter Property="BorderBrush" Value="{StaticResource Brush.Border}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsRemoteOnly}" Value="True">
<Setter Property="Background" Value="#1F2A3A" />
<Setter Property="BorderBrush" Value="#2C4D7A" />
</DataTrigger>
<DataTrigger Binding="{Binding IsBusy}" Value="True">
<Setter Property="Background" Value="#2A2F26" />
<Setter Property="BorderBrush" Value="#5C8C3F" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid Margin="16,12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Left : version, state, meta -->
<StackPanel Grid.Row="0" Grid.Column="0" Orientation="Horizontal">
<TextBlock Text="{Binding Version, StringFormat='v{0}'}"
FontSize="16" FontWeight="SemiBold"
VerticalAlignment="Center"
Foreground="{StaticResource Brush.Text.Primary}" />
<Border Background="#0F0F12" CornerRadius="10"
Padding="8,3" Margin="12,0,0,0"
VerticalAlignment="Center">
<TextBlock Text="{Binding StateLabel}"
FontSize="11"
Foreground="{StaticResource Brush.Text.Secondary}" />
</Border>
</StackPanel>
<TextBlock Grid.Row="1" Grid.Column="0"
FontSize="11"
Foreground="{StaticResource Brush.Text.Secondary}"
Margin="0,4,0,0">
<Run Text="{Binding SizeDisplay, Mode=OneWay}" />
<Run Text=" • " />
<Run Text="{Binding PrimaryDate, Mode=OneWay}" />
</TextBlock>
<!-- Center : action button (Lancer / Installer / Annuler) -->
<StackPanel Grid.Row="0" Grid.RowSpan="2" Grid.Column="1"
Orientation="Horizontal"
VerticalAlignment="Center"
Margin="12,0,0,0">
<!-- Bouton LANCER (installée) -->
<Button Style="{StaticResource PrimaryButton}"
Content="▶ Lancer"
Padding="22,8"
FontSize="14"
Command="{Binding LaunchCommand}"
Visibility="{Binding IsInstalled, Converter={StaticResource BoolToVisibility}}" />
<!-- Bouton INSTALLER (remote uniquement) -->
<Button Style="{StaticResource AccentButton}"
Content="⬇ Installer"
Padding="22,8"
FontSize="14"
Command="{Binding InstallCommand}"
Visibility="{Binding IsRemoteOnly, Converter={StaticResource BoolToVisibility}}" />
<!-- Pendant DL/install : barre de progression compacte -->
<StackPanel Orientation="Horizontal"
Visibility="{Binding IsBusy, Converter={StaticResource BoolToVisibility}}">
<ProgressBar Width="160" Height="6"
Value="{Binding ProgressPercent}"
Maximum="100"
Foreground="{StaticResource Brush.Play}"
Background="#2A2A30"
BorderThickness="0"
VerticalAlignment="Center" />
<TextBlock Text="{Binding ProgressPercent, StringFormat={}{0:0}%}"
FontSize="11"
Margin="8,0,0,0"
VerticalAlignment="Center"
Foreground="{StaticResource Brush.Text.Secondary}" />
</StackPanel>
</StackPanel>
<!-- Right : ... menu -->
<Button Grid.Row="0" Grid.RowSpan="2" Grid.Column="2"
Style="{StaticResource IconButton}"
Content="⋯"
FontSize="18" FontWeight="Bold"
Margin="8,0,0,0"
VerticalAlignment="Center"
ToolTip="Plus d'actions"
Tag="{Binding}"
Click="OnMoreMenuClick">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="📜 Voir les release notes"
Command="{Binding PlacementTarget.Tag.ShowReleaseNotesCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
<MenuItem Header="📁 Ouvrir le dossier"
Command="{Binding PlacementTarget.Tag.OpenFolderCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
Visibility="{Binding PlacementTarget.Tag.IsInstalled, RelativeSource={RelativeSource AncestorType=ContextMenu}, Converter={StaticResource BoolToVisibility}}" />
<Separator Visibility="{Binding PlacementTarget.Tag.IsInstalled, RelativeSource={RelativeSource AncestorType=ContextMenu}, Converter={StaticResource BoolToVisibility}}" />
<MenuItem Header="🗑 Supprimer cette version…"
Command="{Binding PlacementTarget.Tag.UninstallCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
Visibility="{Binding PlacementTarget.Tag.IsInstalled, RelativeSource={RelativeSource AncestorType=ContextMenu}, Converter={StaticResource BoolToVisibility}}" />
</ContextMenu>
</Button.ContextMenu>
</Button>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl ItemsSource="{Binding OtherVersions}"
ItemTemplate="{StaticResource CompactRowTemplate}" />
</StackPanel>
<!-- Empty state -->
<Border Background="{StaticResource Brush.Bg.Card}"
@@ -223,17 +387,14 @@
<TextBlock Text="{Binding FooterText}"
Foreground="{StaticResource Brush.Text.Secondary}" />
<ProgressBar Height="4" Margin="0,4,0,0"
Value="{Binding ProgressPercent}"
Maximum="100"
Value="{Binding ProgressPercent}" Maximum="100"
Foreground="{StaticResource Brush.Accent}"
Background="#2A2A30"
BorderThickness="0" />
Background="#2A2A30" BorderThickness="0" />
</StackPanel>
<Button Grid.Column="1"
Style="{StaticResource SecondaryButton}"
Content="Annuler"
VerticalAlignment="Center"
Margin="12,0,0,0"
VerticalAlignment="Center" Margin="12,0,0,0"
Command="{Binding CancelDownloadCommand}"
Visibility="{Binding IsBusy, Converter={StaticResource BoolToVisibility}}" />
</Grid>