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:
86
src/PSLauncher.App/Views/LicenseDetailsDialog.xaml.cs
Normal file
86
src/PSLauncher.App/Views/LicenseDetailsDialog.xaml.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using PSLauncher.Core.Licensing;
|
||||
using PSLauncher.Models;
|
||||
|
||||
namespace PSLauncher.App.Views;
|
||||
|
||||
public partial class LicenseDetailsDialog : Window
|
||||
{
|
||||
private readonly ILicenseService _licenseService;
|
||||
private readonly LicenseValidationResponse _license;
|
||||
|
||||
public bool DeactivateRequested { get; private set; }
|
||||
|
||||
public LicenseDetailsDialog(ILicenseService licenseService, LicenseValidationResponse license)
|
||||
{
|
||||
_licenseService = licenseService;
|
||||
_license = license;
|
||||
InitializeComponent();
|
||||
|
||||
var (icon, title, subtitle, color, bgColor) = ResolveStyle(license);
|
||||
StatusIconText.Text = icon;
|
||||
StatusIconText.Foreground = new SolidColorBrush(color);
|
||||
StatusTitleText.Text = title;
|
||||
StatusSubtitleText.Text = subtitle;
|
||||
HeaderBorder.Background = new SolidColorBrush(bgColor);
|
||||
HeaderBorder.BorderBrush = new SolidColorBrush(color);
|
||||
|
||||
OwnerText.Text = license.OwnerName ?? "—";
|
||||
UntilText.Text = license.DownloadEntitlementUntil is { } until
|
||||
? $"jusqu'au {until.ToLocalTime():dddd dd MMMM yyyy}"
|
||||
: "—";
|
||||
IssuedText.Text = license.IssuedAt is { } issued
|
||||
? issued.ToLocalTime().ToString("dd/MM/yyyy")
|
||||
: (license.ServerTime?.ToLocalTime().ToString("dd/MM/yyyy") ?? "—");
|
||||
MachineIdText.Text = licenseService.GetMachineId();
|
||||
}
|
||||
|
||||
private static (string Icon, string Title, string Subtitle, Color Color, Color BgColor) ResolveStyle(LicenseValidationResponse l)
|
||||
{
|
||||
var until = l.DownloadEntitlementUntil;
|
||||
if (l.Status == "valid")
|
||||
{
|
||||
if (until is { } u && (u - DateTime.UtcNow).TotalDays < 30)
|
||||
return ("⏰", "License valide", $"Expire bientôt — le {u.ToLocalTime():dd/MM/yyyy}",
|
||||
Color.FromRgb(0xF5, 0x9E, 0x0B), Color.FromRgb(0x3A, 0x2A, 0x0E));
|
||||
return ("✓", "License valide", "Téléchargements de nouvelles versions autorisés",
|
||||
Color.FromRgb(0x16, 0xA3, 0x4A), Color.FromRgb(0x0E, 0x2A, 0x1B));
|
||||
}
|
||||
if (l.Status == "expired")
|
||||
return ("⚠", "License expirée",
|
||||
until is { } u ? $"Expirée le {u.ToLocalTime():dd/MM/yyyy}" : "Plus de téléchargements possibles",
|
||||
Color.FromRgb(0xEF, 0x44, 0x44), Color.FromRgb(0x2A, 0x14, 0x14));
|
||||
if (l.Status == "revoked")
|
||||
return ("🚫", "License révoquée", "Contacte ASTERION pour plus d'informations",
|
||||
Color.FromRgb(0xEF, 0x44, 0x44), Color.FromRgb(0x2A, 0x14, 0x14));
|
||||
return ("❓", "License inconnue", l.Message ?? l.Status,
|
||||
Color.FromRgb(0xEF, 0x44, 0x44), Color.FromRgb(0x2A, 0x14, 0x14));
|
||||
}
|
||||
|
||||
private void OnCopyMachineId(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try { Clipboard.SetText(MachineIdText.Text); } catch { /* ignore */ }
|
||||
}
|
||||
|
||||
private void OnDeactivate(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var confirm = MessageBox.Show(
|
||||
"Désactiver la license sur cette machine ?\n\n" +
|
||||
"Tu pourras la réactiver plus tard avec ta clé. " +
|
||||
"Les versions déjà installées restent utilisables.",
|
||||
"Confirmer la désactivation",
|
||||
MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No);
|
||||
if (confirm != MessageBoxResult.Yes) return;
|
||||
_licenseService.Clear();
|
||||
DeactivateRequested = true;
|
||||
DialogResult = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void OnClose(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DialogResult = false;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user