- Init Localizer at app startup (before self-update prompt) and assign to TrExtension.Localizer - Register ILocalizer in DI; inject into WizardViewModel and SettingsViewModel - WizardViewModel: SelectedLanguage ComboBox binding with OnSelectedLanguageChanged -> SetLanguage + InstallContext.Language - WizardWindow.xaml: DockPanel wraps step chips + language ComboBox (right-aligned) - Localize all installer XAML: WizardWindow, WelcomePage, PathsPage, ServicePage, UiSettingsPage, InstallPage, SettingsWindow, SelfUpdatePromptWindow - Localize page Title properties and WizardViewModel.NextButtonText via TrExtension.Localizer - Persist chosen Language in WriteConfigStep and SettingsViewModel.Save into ui.config.json - Append installer section to en.json (nav, welcome, paths, service, uiSettings, install, settings, selfUpdate) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
105 lines
3.0 KiB
C#
105 lines
3.0 KiB
C#
using System.Linq;
|
|
using System.Windows;
|
|
using ClaudeDo.Installer.Core;
|
|
using ClaudeDo.Installer.Pages.InstallPage;
|
|
using ClaudeDo.Installer.Pages.WelcomePage;
|
|
using ClaudeDo.Localization;
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using CommunityToolkit.Mvvm.Input;
|
|
|
|
namespace ClaudeDo.Installer.Views;
|
|
|
|
public partial class WizardViewModel : ObservableObject
|
|
{
|
|
private readonly InstallContext _context;
|
|
private readonly ILocalizer _localizer;
|
|
|
|
public IReadOnlyList<IInstallerPage> Pages { get; }
|
|
public IReadOnlyList<LanguageOption> Languages { get; }
|
|
|
|
[ObservableProperty]
|
|
private LanguageOption? _selectedLanguage;
|
|
|
|
partial void OnSelectedLanguageChanged(LanguageOption? value)
|
|
{
|
|
if (value is null) return;
|
|
_localizer.SetLanguage(value.Value.Code);
|
|
_context.Language = value.Value.Code;
|
|
}
|
|
|
|
[ObservableProperty]
|
|
[NotifyPropertyChangedFor(nameof(CanGoBack))]
|
|
[NotifyPropertyChangedFor(nameof(IsLastPage))]
|
|
[NotifyPropertyChangedFor(nameof(NextButtonText))]
|
|
[NotifyPropertyChangedFor(nameof(CurrentPage))]
|
|
private int _currentPageIndex;
|
|
|
|
public IInstallerPage CurrentPage => Pages[CurrentPageIndex];
|
|
public bool CanGoBack => CurrentPageIndex > 0;
|
|
public bool IsLastPage => CurrentPageIndex == Pages.Count - 1;
|
|
public string NextButtonText => IsLastPage
|
|
? (_localizer["installer.nav.install"])
|
|
: (_localizer["installer.nav.next"]);
|
|
|
|
[ObservableProperty]
|
|
private string? _validationError;
|
|
|
|
public WizardViewModel(PageResolver resolver, InstallContext context, ILocalizer localizer)
|
|
{
|
|
_context = context;
|
|
_localizer = localizer;
|
|
Languages = localizer.AvailableLanguages;
|
|
_selectedLanguage = Languages.FirstOrDefault(l => l.Code == localizer.CurrentCode);
|
|
_context.Language = localizer.CurrentCode;
|
|
|
|
var all = resolver.WizardPages;
|
|
Pages = context.Mode == InstallerMode.Update
|
|
? all.Where(p => p is WelcomePageViewModel
|
|
|| p is InstallPageViewModel).ToList()
|
|
: all;
|
|
|
|
if (Pages.Count > 0)
|
|
_ = InitAsync();
|
|
}
|
|
|
|
private async Task InitAsync()
|
|
{
|
|
try { await Pages[0].LoadAsync(); }
|
|
catch { /* first page loads with defaults on error */ }
|
|
}
|
|
|
|
[RelayCommand]
|
|
private async Task GoBack()
|
|
{
|
|
if (!CanGoBack) return;
|
|
CurrentPageIndex--;
|
|
await CurrentPage.LoadAsync();
|
|
ValidationError = null;
|
|
}
|
|
|
|
[RelayCommand]
|
|
private async Task GoNext()
|
|
{
|
|
if (!CurrentPage.Validate())
|
|
{
|
|
ValidationError = "Please fix the highlighted errors before continuing.";
|
|
return;
|
|
}
|
|
|
|
ValidationError = null;
|
|
await CurrentPage.ApplyAsync();
|
|
|
|
if (CurrentPageIndex < Pages.Count - 1)
|
|
{
|
|
CurrentPageIndex++;
|
|
await CurrentPage.LoadAsync();
|
|
}
|
|
}
|
|
|
|
[RelayCommand]
|
|
private void Close()
|
|
{
|
|
Application.Current.Shutdown();
|
|
}
|
|
}
|