diff --git a/src/PlanViewer.App/AboutWindow.axaml.cs b/src/PlanViewer.App/AboutWindow.axaml.cs index 934d8d8..d05e435 100644 --- a/src/PlanViewer.App/AboutWindow.axaml.cs +++ b/src/PlanViewer.App/AboutWindow.axaml.cs @@ -132,9 +132,18 @@ private async void CheckUpdate_Click(object? sender, RoutedEventArgs e) CheckUpdateButton.IsEnabled = true; } + private bool _updateDownloaded; + private async void UpdateLink_Click(object? sender, PointerPressedEventArgs e) { - // Velopack download + apply + // Step 3: User clicks "Restart now" after download + if (_updateDownloaded && _velopackMgr != null && _velopackUpdate != null) + { + _velopackMgr.ApplyUpdatesAndRestart(_velopackUpdate.TargetFullRelease); + return; + } + + // Step 2: User clicks to download if (_velopackMgr != null && _velopackUpdate != null) { try @@ -144,8 +153,10 @@ private async void UpdateLink_Click(object? sender, PointerPressedEventArgs e) await _velopackMgr.DownloadUpdatesAsync(_velopackUpdate); - UpdateStatusText.Text = "Update downloaded — restarting..."; - _velopackMgr.ApplyUpdatesAndRestart(_velopackUpdate.TargetFullRelease); + _updateDownloaded = true; + UpdateStatusText.Text = "Update downloaded."; + UpdateLink.Text = "Restart now to apply"; + UpdateLink.IsVisible = true; } catch (Exception ex) { diff --git a/src/PlanViewer.App/MainWindow.axaml.cs b/src/PlanViewer.App/MainWindow.axaml.cs index 9254409..81706bf 100644 --- a/src/PlanViewer.App/MainWindow.axaml.cs +++ b/src/PlanViewer.App/MainWindow.axaml.cs @@ -48,6 +48,9 @@ public MainWindow() InitializeComponent(); + // Check for updates on startup (non-blocking) + _ = CheckForUpdatesOnStartupAsync(); + // Build the Recent Plans submenu from saved state RebuildRecentPlansMenu(); @@ -1359,4 +1362,52 @@ private void ShowError(string message) }; dialog.ShowDialog(this); } + + private async Task CheckForUpdatesOnStartupAsync() + { + try + { + await Task.Delay(5000); // Don't slow down startup + + if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform( + System.Runtime.InteropServices.OSPlatform.Windows)) + { + try + { + var mgr = new Velopack.UpdateManager( + new Velopack.Sources.GithubSource( + "https://github.com/erikdarlingdata/PerformanceStudio", null, false)); + + var update = await mgr.CheckForUpdatesAsync(); + if (update != null) + { + await Dispatcher.UIThread.InvokeAsync(() => + { + Title = $"Performance Studio — Update v{update.TargetFullRelease.Version} available (Help > About)"; + }); + return; + } + } + catch + { + // Velopack not available — fall through + } + } + + var currentVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version + ?? new Version(0, 0, 0); + var result = await UpdateChecker.CheckAsync(currentVersion); + if (result.UpdateAvailable) + { + await Dispatcher.UIThread.InvokeAsync(() => + { + Title = $"Performance Studio — Update {result.LatestVersion} available (Help > About)"; + }); + } + } + catch + { + // Never crash on update check + } + } }