v0.16.0 — ThemedMessageBox replacing native MessageBox everywhere
The Win32 MessageBox uses the system white-on-gray look that clashes with the launcher's dark theme (jarring transition every time we confirm a cancel, show an error, etc.). Replaced with a custom WPF dialog that: - Drops in : same Show(message, title, button, icon, default) API as System.Windows.MessageBox, returns the same MessageBoxResult. - Looks native to the launcher : dark Brush.Bg.Window background, Brush.Border outline, Brush.Text.Primary content, AccentButton for the default action and SecondaryButton for the others. - Iconography by emoji + colour code : ⛔ red (Error), ⚠ amber (Warning), ❓ neutral (Question), ℹ blue (Information). Mapped from MessageBoxImage. - Buttons localised via Strings.ActionOk / ActionYes / ActionNo / ActionCancel — works in fr/en/zh/th/ar like the rest of the UI. - Owner = currently active window (falls back to MainWindow then CenterScreen) so it positions correctly even from a child dialog. - Esc resolves to Cancel/No matching MessageBox semantics. The 21 MessageBox.Show call sites across MainViewModel, SettingsViewModel, LicenseDetailsDialog and MainWindow now use ThemedMessageBox.Show with no signature change — full grep replace + tiny `using` adjustments. Versions bumped to 0.16.0. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -438,7 +438,7 @@ public sealed partial class MainViewModel : ObservableObject
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Self-update failed");
|
||||
MessageBox.Show(Strings.MsgSelfUpdateFailed(ex.Message),
|
||||
ThemedMessageBox.Show(Strings.MsgSelfUpdateFailed(ex.Message),
|
||||
Strings.MsgBoxError, MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
StatusMessage = Strings.StatusSelfUpdateError(ex.Message);
|
||||
IsBusy = false;
|
||||
@@ -518,7 +518,7 @@ public sealed partial class MainViewModel : ObservableObject
|
||||
private void CancelDownload()
|
||||
{
|
||||
if (_activeDownloadCts is null || _activeRow is null) return;
|
||||
var confirm = MessageBox.Show(
|
||||
var confirm = ThemedMessageBox.Show(
|
||||
Strings.MsgCancelDownloadConfirm(_activeRow.Version),
|
||||
Strings.MsgBoxCancelDl,
|
||||
MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No);
|
||||
@@ -535,7 +535,7 @@ public sealed partial class MainViewModel : ObservableObject
|
||||
// Si un DL est actif sur cette même row, on doit d'abord l'annuler proprement.
|
||||
var st = _downloadManager.GetResumableState(row.Version);
|
||||
var sizeStr = FormatSize(st?.DownloadedBytes ?? 0);
|
||||
var confirm = MessageBox.Show(
|
||||
var confirm = ThemedMessageBox.Show(
|
||||
Strings.MsgRestartDownloadConfirm(row.Version, sizeStr),
|
||||
Strings.MsgBoxRestartDl,
|
||||
MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
|
||||
@@ -605,7 +605,7 @@ public sealed partial class MainViewModel : ObservableObject
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Launch failed");
|
||||
MessageBox.Show(Strings.MsgLaunchFailed(ex.Message),
|
||||
ThemedMessageBox.Show(Strings.MsgLaunchFailed(ex.Message),
|
||||
Strings.MsgBoxLaunchError, MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
@@ -613,7 +613,7 @@ public sealed partial class MainViewModel : ObservableObject
|
||||
private async Task InstallVersionAsync(VersionRowViewModel row)
|
||||
{
|
||||
if (row.Remote is null) return;
|
||||
if (IsBusy) { MessageBox.Show(Strings.MsgBusy, Strings.MsgBoxPatience, MessageBoxButton.OK, MessageBoxImage.Information); return; }
|
||||
if (IsBusy) { ThemedMessageBox.Show(Strings.MsgBusy, Strings.MsgBoxPatience, MessageBoxButton.OK, MessageBoxImage.Information); return; }
|
||||
|
||||
IsBusy = true;
|
||||
_activeRow = row;
|
||||
@@ -738,7 +738,7 @@ public sealed partial class MainViewModel : ObservableObject
|
||||
// notifie l'utilisateur que la DB n'a pas été migrée — la prochaine relance
|
||||
// de l'install (ou un Settings → "Rejouer migrations") tentera à nouveau.
|
||||
_logger.LogError("DB migration failed for v{Version}: {Detail}", row.Version, migResult.FailureMessage);
|
||||
MessageBox.Show(
|
||||
ThemedMessageBox.Show(
|
||||
Strings.MsgMigrationFailed(migResult.FailureMessage ?? "?"),
|
||||
Strings.MsgBoxMigrationFailed,
|
||||
MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
@@ -779,13 +779,13 @@ public sealed partial class MainViewModel : ObservableObject
|
||||
_logger.LogInformation("No _report/ in v{Version} ZIP, report tool unchanged", row.Version);
|
||||
break;
|
||||
case DeployStatus.XamppNotFound:
|
||||
MessageBox.Show(
|
||||
ThemedMessageBox.Show(
|
||||
Strings.MsgReportXamppNotFound(_config.ReportTool.HtdocsRoot),
|
||||
Strings.MsgBoxReportDeployFailed,
|
||||
MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
break;
|
||||
case DeployStatus.Failed:
|
||||
MessageBox.Show(
|
||||
ThemedMessageBox.Show(
|
||||
Strings.MsgReportDeployFailed(rdResult.ErrorMessage ?? "?"),
|
||||
Strings.MsgBoxReportDeployFailed,
|
||||
MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
@@ -818,7 +818,7 @@ public sealed partial class MainViewModel : ObservableObject
|
||||
row.State = VersionRowState.AvailableIdle;
|
||||
row.ProgressDetail = null;
|
||||
row.ProgressPercent = 0;
|
||||
MessageBox.Show(
|
||||
ThemedMessageBox.Show(
|
||||
Strings.MsgInstallFailed(ex.Message),
|
||||
Strings.MsgBoxError, MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
StatusMessage = Strings.StatusError(ex.Message);
|
||||
@@ -841,14 +841,14 @@ public sealed partial class MainViewModel : ObservableObject
|
||||
if (row.Installed is null) return;
|
||||
|
||||
var sizeStr = FormatSize(row.SizeBytes);
|
||||
var confirm = MessageBox.Show(
|
||||
var confirm = ThemedMessageBox.Show(
|
||||
Strings.MsgUninstallConfirm(row.Version, row.FolderPath, sizeStr),
|
||||
Strings.MsgBoxConfirm,
|
||||
MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
|
||||
|
||||
if (confirm != MessageBoxResult.Yes) return;
|
||||
|
||||
if (IsBusy) { MessageBox.Show(Strings.MsgBusy, Strings.MsgBoxPatience, MessageBoxButton.OK, MessageBoxImage.Information); return; }
|
||||
if (IsBusy) { ThemedMessageBox.Show(Strings.MsgBusy, Strings.MsgBoxPatience, MessageBoxButton.OK, MessageBoxImage.Information); return; }
|
||||
|
||||
IsBusy = true;
|
||||
row.State = VersionRowState.Uninstalling;
|
||||
@@ -863,7 +863,7 @@ public sealed partial class MainViewModel : ObservableObject
|
||||
{
|
||||
_logger.LogError(ex, "Uninstall failed for {Version}", row.Version);
|
||||
row.State = VersionRowState.InstalledIdle;
|
||||
MessageBox.Show(Strings.MsgUninstallFailed(ex.Message), Strings.MsgBoxError,
|
||||
ThemedMessageBox.Show(Strings.MsgUninstallFailed(ex.Message), Strings.MsgBoxError,
|
||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
StatusMessage = Strings.StatusError(ex.Message);
|
||||
}
|
||||
@@ -878,7 +878,7 @@ public sealed partial class MainViewModel : ObservableObject
|
||||
var url = row.Remote?.ReleaseNotesUrl;
|
||||
if (string.IsNullOrEmpty(url))
|
||||
{
|
||||
MessageBox.Show(Strings.MsgNoReleaseNotes,
|
||||
ThemedMessageBox.Show(Strings.MsgNoReleaseNotes,
|
||||
Strings.MsgBoxReleaseNotes, MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
return;
|
||||
}
|
||||
@@ -887,7 +887,7 @@ public sealed partial class MainViewModel : ObservableObject
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Failed to fetch release notes");
|
||||
MessageBox.Show(Strings.MsgReleaseNotesFetchFailed(ex.Message),
|
||||
ThemedMessageBox.Show(Strings.MsgReleaseNotesFetchFailed(ex.Message),
|
||||
Strings.MsgBoxError, MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user