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:
@@ -32,7 +32,16 @@ public sealed partial class MainViewModel : ObservableObject
|
||||
private CancellationTokenSource? _activeDownloadCts;
|
||||
private VersionRowViewModel? _activeRow;
|
||||
|
||||
public ObservableCollection<VersionRowViewModel> Versions { get; } = new();
|
||||
public ObservableCollection<VersionRowViewModel> OtherVersions { get; } = new();
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(HasFeaturedVersion))]
|
||||
[NotifyPropertyChangedFor(nameof(HasOtherVersions))]
|
||||
[NotifyPropertyChangedFor(nameof(EmptyHintVisibility))]
|
||||
private VersionRowViewModel? _featuredVersion;
|
||||
|
||||
public bool HasFeaturedVersion => FeaturedVersion is not null;
|
||||
public bool HasOtherVersions => OtherVersions.Count > 0;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(FooterText))]
|
||||
@@ -57,7 +66,8 @@ public sealed partial class MainViewModel : ObservableObject
|
||||
_config.InstallRoot;
|
||||
|
||||
public Visibility EmptyHintVisibility =>
|
||||
Versions.Count == 0 ? Visibility.Visible : Visibility.Collapsed;
|
||||
FeaturedVersion is null && OtherVersions.Count == 0
|
||||
? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
public Visibility FooterVisibility =>
|
||||
IsBusy || !string.IsNullOrEmpty(StatusMessage) ? Visibility.Visible : Visibility.Collapsed;
|
||||
@@ -89,7 +99,11 @@ public sealed partial class MainViewModel : ObservableObject
|
||||
RebuildList();
|
||||
}
|
||||
|
||||
/// <summary>Recompose la liste affichée à partir du scan local + du dernier manifest distant.</summary>
|
||||
/// <summary>
|
||||
/// Recompose la liste affichée à partir du scan local + du dernier manifest distant.
|
||||
/// La version « courante » (FeaturedVersion) est la plus haute installée ; à défaut,
|
||||
/// la plus haute disponible côté serveur. Toutes les autres vont dans OtherVersions.
|
||||
/// </summary>
|
||||
private void RebuildList()
|
||||
{
|
||||
var installed = _registry.Scan().ToDictionary(v => v.Version);
|
||||
@@ -100,7 +114,7 @@ public sealed partial class MainViewModel : ObservableObject
|
||||
.OrderByDescending(v => SemVer.Parse(v))
|
||||
.ToList();
|
||||
|
||||
Versions.Clear();
|
||||
var rows = new List<VersionRowViewModel>();
|
||||
foreach (var ver in allVersions)
|
||||
{
|
||||
VersionRowViewModel row;
|
||||
@@ -113,11 +127,24 @@ public sealed partial class MainViewModel : ObservableObject
|
||||
row = VersionRowViewModel.ForRemote(remoteByVer[ver]);
|
||||
}
|
||||
WireRowHandlers(row);
|
||||
Versions.Add(row);
|
||||
rows.Add(row);
|
||||
}
|
||||
|
||||
// Featured : plus haute installée, sinon plus haute distante
|
||||
var featured = rows.FirstOrDefault(r => r.IsInstalled) ?? rows.FirstOrDefault();
|
||||
FeaturedVersion = featured;
|
||||
|
||||
OtherVersions.Clear();
|
||||
foreach (var r in rows)
|
||||
{
|
||||
if (!ReferenceEquals(r, featured))
|
||||
OtherVersions.Add(r);
|
||||
}
|
||||
|
||||
OnPropertyChanged(nameof(EmptyHint));
|
||||
OnPropertyChanged(nameof(EmptyHintVisibility));
|
||||
OnPropertyChanged(nameof(HasFeaturedVersion));
|
||||
OnPropertyChanged(nameof(HasOtherVersions));
|
||||
}
|
||||
|
||||
private void WireRowHandlers(VersionRowViewModel row)
|
||||
|
||||
Reference in New Issue
Block a user