diff --git a/src/ClaudeDo.Installer/Views/SettingsViewModel.cs b/src/ClaudeDo.Installer/Views/SettingsViewModel.cs index 9ec9aca..40670c8 100644 --- a/src/ClaudeDo.Installer/Views/SettingsViewModel.cs +++ b/src/ClaudeDo.Installer/Views/SettingsViewModel.cs @@ -1,5 +1,6 @@ using System.Windows; using ClaudeDo.Installer.Core; +using ClaudeDo.Installer.Steps; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; @@ -8,6 +9,11 @@ namespace ClaudeDo.Installer.Views; public partial class SettingsViewModel : ObservableObject { private readonly InstallContext _context; + private readonly IReleaseClient _releases; + private readonly StopServiceStep _stopService; + private readonly StartServiceStep _startService; + private readonly DownloadAndExtractStep _downloadStep; + private readonly UninstallRunner _uninstallRunner; public IReadOnlyList Pages { get; } @@ -20,12 +26,29 @@ public partial class SettingsViewModel : ObservableObject [ObservableProperty] private bool _isStatusError; - public SettingsViewModel(PageResolver resolver, InstallContext context) + [ObservableProperty] + private string _versionLabel = ""; + + public SettingsViewModel( + PageResolver resolver, + InstallContext context, + IReleaseClient releases, + StopServiceStep stopService, + StartServiceStep startService, + DownloadAndExtractStep downloadStep, + UninstallRunner uninstallRunner) { Pages = resolver.SettingsPages; _context = context; + _releases = releases; + _stopService = stopService; + _startService = startService; + _downloadStep = downloadStep; + _uninstallRunner = uninstallRunner; _selectedPage = Pages.FirstOrDefault(); + VersionLabel = $"Installed: {context.InstalledVersion ?? "?"} Installer: {context.InstallerVersion ?? "?"}"; + _ = LoadAllAsync(); } @@ -36,9 +59,8 @@ public partial class SettingsViewModel : ObservableObject } [RelayCommand] - private async Task Apply() + private async Task Save() { - // Validate all pages foreach (var page in Pages) { if (!page.Validate()) @@ -50,11 +72,9 @@ public partial class SettingsViewModel : ObservableObject } } - // Apply all pages (writes to InstallContext) foreach (var page in Pages) await page.ApplyAsync(); - // Write config files directly var workerCfg = new InstallerWorkerConfig { DbPath = _context.DbPath, @@ -75,13 +95,67 @@ public partial class SettingsViewModel : ObservableObject }; uiCfg.Save(); - StatusMessage = "Settings saved successfully."; + StatusMessage = "Settings saved."; IsStatusError = false; } [RelayCommand] - private void Close() + private async Task Repair() { + var confirm = MessageBox.Show( + "Re-download and reinstall the ClaudeDo binaries? Your config and database are NOT affected.", + "Repair ClaudeDo", + MessageBoxButton.OKCancel, + MessageBoxImage.Question); + + if (confirm != MessageBoxResult.OK) return; + + StatusMessage = "Repairing..."; + IsStatusError = false; + + var progress = new Progress(msg => StatusMessage = msg); + var steps = new IInstallStep[] { _stopService, _downloadStep, _startService }; + + foreach (var step in steps) + { + var r = await step.ExecuteAsync(_context, progress, CancellationToken.None); + if (!r.Success) + { + StatusMessage = $"{step.Name} failed: {r.ErrorMessage}"; + IsStatusError = true; + return; + } + } + + StatusMessage = "Repair complete."; + } + + [RelayCommand] + private async Task Uninstall() + { + var confirm = MessageBox.Show( + "This will remove ClaudeDo AND delete all of your tasks, configuration, and database.\n\nContinue?", + "Uninstall ClaudeDo", + MessageBoxButton.YesNo, + MessageBoxImage.Warning); + + if (confirm != MessageBoxResult.Yes) return; + + var progress = new Progress(msg => StatusMessage = msg); + var r = await _uninstallRunner.RunAsync(progress, CancellationToken.None); + + if (!r.Success) + { + StatusMessage = $"Uninstall failed: {r.ErrorMessage}"; + IsStatusError = true; + return; + } + + MessageBox.Show("ClaudeDo has been removed.", "Uninstall complete", + MessageBoxButton.OK, MessageBoxImage.Information); Application.Current.Shutdown(); } + + [RelayCommand] + private void Close() => Application.Current.Shutdown(); } diff --git a/src/ClaudeDo.Installer/Views/SettingsWindow.xaml b/src/ClaudeDo.Installer/Views/SettingsWindow.xaml index fbd25c7..fa01301 100644 --- a/src/ClaudeDo.Installer/Views/SettingsWindow.xaml +++ b/src/ClaudeDo.Installer/Views/SettingsWindow.xaml @@ -61,31 +61,37 @@ + + + - - - - - - + + + + + + + + + -