diff --git a/src/App/Localization/Loc.cs b/src/App/Localization/Loc.cs index c1f450b..71e85cf 100644 --- a/src/App/Localization/Loc.cs +++ b/src/App/Localization/Loc.cs @@ -27,7 +27,7 @@ public sealed class Loc /// internal static Loc SwitchTo(string language) { - if (System.Array.IndexOf(Languages, language) < 0) language = "it"; + if (System.Array.IndexOf(Languages, language) < 0) language = "en"; var loc = new Loc(language); Instance = loc; return loc; @@ -54,6 +54,17 @@ public sealed class Loc ["settings.unit.short"] = ["Unità", "Unit", "Unidad", "Unité", "Unidade", "Einheit"], // Wizard + ["wiz.data.title"] = ["Dove salvare i dati", "Where to store data", "Dónde guardar los datos", "Où enregistrer les données", "Onde salvar os dados", "Wo Daten gespeichert werden"], + ["wiz.data.info"] = [ + "Scegli la cartella in cui salvare wallet, configurazione e certificati. Puoi usare il percorso predefinito o sceglierne uno tuo.", + "Choose the folder where wallets, configuration and certificates are stored. Use the default path or pick your own.", + "Elige la carpeta donde se guardarán wallets, configuración y certificados. Usa la ruta predeterminada o elige la tuya.", + "Choisissez le dossier où enregistrer les wallets, la configuration et les certificats. Utilisez le chemin par défaut ou le vôtre.", + "Escolha a pasta onde salvar carteiras, configuração e certificados. Use o caminho padrão ou escolha o seu.", + "Wählen Sie den Ordner für Wallets, Konfiguration und Zertifikate. Nutzen Sie den Standardpfad oder einen eigenen."], + ["wiz.data.default"] = ["Percorso predefinito:", "Default path:", "Ruta predeterminada:", "Chemin par défaut :", "Caminho padrão:", "Standardpfad:"], + ["wiz.data.usedefault"] = ["Usa il percorso predefinito", "Use the default path", "Usar la ruta predeterminada", "Utiliser le chemin par défaut", "Usar o caminho padrão", "Standardpfad verwenden"], + ["wiz.data.choose"] = ["Scegli una cartella…", "Choose a folder…", "Elegir una carpeta…", "Choisir un dossier…", "Escolher uma pasta…", "Ordner wählen…"], ["wiz.net"] = ["Rete:", "Network:", "Red:", "Réseau :", "Rede:", "Netzwerk:"], ["wiz.open.btn"] = ["Apri il wallet esistente", "Open existing wallet", "Abrir wallet existente", "Ouvrir le wallet existant", "Abrir carteira existente", "Vorhandenes Wallet öffnen"], ["wiz.new.btn"] = ["Crea un nuovo wallet", "Create a new wallet", "Crear nuevo wallet", "Créer un nouveau wallet", "Criar nova carteira", "Neues Wallet erstellen"], diff --git a/src/App/ViewModels/MainWindowViewModel.cs b/src/App/ViewModels/MainWindowViewModel.cs index 58dceb0..8c16b02 100644 --- a/src/App/ViewModels/MainWindowViewModel.cs +++ b/src/App/ViewModels/MainWindowViewModel.cs @@ -165,6 +165,7 @@ public partial class MainWindowViewModel : ViewModelBase // ---- wizard di setup (§15): un passo alla volta ---- + public const string StepDataLocation = "data-location"; public const string StepStart = "start"; public const string StepOpen = "open"; public const string StepShowSeed = "show-seed"; @@ -174,6 +175,7 @@ public partial class MainWindowViewModel : ViewModelBase public const string StepPassword = "password"; [ObservableProperty] + [NotifyPropertyChangedFor(nameof(IsStepDataLocation))] [NotifyPropertyChangedFor(nameof(IsStepStart))] [NotifyPropertyChangedFor(nameof(IsStepOpen))] [NotifyPropertyChangedFor(nameof(IsStepShowSeed))] @@ -183,6 +185,7 @@ public partial class MainWindowViewModel : ViewModelBase [NotifyPropertyChangedFor(nameof(IsStepPassword))] private string setupStep = StepStart; + public bool IsStepDataLocation => SetupStep == StepDataLocation; public bool IsStepStart => SetupStep == StepStart; public bool IsStepOpen => SetupStep == StepOpen; public bool IsStepShowSeed => SetupStep == StepShowSeed; @@ -191,6 +194,9 @@ public partial class MainWindowViewModel : ViewModelBase public bool IsStepPassphrase => SetupStep == StepPassphrase; public bool IsStepPassword => SetupStep == StepPassword; + /// Percorso dati predefinito, mostrato al primo avvio. + public string DefaultDataPath => AppPaths.DefaultDataRoot(); + /// True quando il flusso è "ripristina" (parole inserite dall'utente). private bool _isRestoreFlow; @@ -375,7 +381,12 @@ public partial class MainWindowViewModel : ViewModelBase public MainWindowViewModel() { _loc = Loc.SwitchTo(_config.Language); - RefreshSetupState(); + // Primo avvio: se la posizione dei dati non è ancora determinata, + // chiediamola prima di tutto il resto del wizard. + if (!AppPaths.IsDataLocationConfigured()) + SetupStep = StepDataLocation; + else + RefreshSetupState(); // Aggiornamenti continui (§9): ping periodico per tenere viva la // connessione e accorgersi subito della caduta; se cade, riconnette // e risincronizza da solo. Le notifiche push restano la via principale. @@ -413,6 +424,34 @@ public partial class MainWindowViewModel : ViewModelBase private ServerRegistry Registry => new(Profile, AppPaths.ServersPath(Net)); + /// Primo avvio: usa il percorso dati predefinito di piattaforma. + [RelayCommand] + private void UseDefaultDataLocation() => ApplyDataLocation(AppPaths.DefaultDataRoot()); + + /// + /// Memorizza la radice dati scelta (default o personalizzata), ricarica la + /// configurazione dalla nuova posizione e prosegue col wizard. Chiamata anche + /// dalla View dopo la scelta di una cartella. + /// + public void ApplyDataLocation(string root) + { + try + { + AppPaths.ConfigureDataLocation(root); + } + catch (Exception ex) + { + StatusMessage = $"{Loc.Tr("msg.error")}: {ex.Message}"; + return; + } + // La config globale vive nella radice dati: ricaricala da lì. + _config = AppConfig.Load(); + _loc = Loc.SwitchTo(_config.Language); + OnPropertyChanged(nameof(Loc)); + OnPropertyChanged(nameof(UnitLabel)); + RefreshSetupState(); + } + private void RefreshSetupState() { SetupStep = StepStart; diff --git a/src/App/Views/MainWindow.axaml b/src/App/Views/MainWindow.axaml index a9d82ee..91da29a 100644 --- a/src/App/Views/MainWindow.axaml +++ b/src/App/Views/MainWindow.axaml @@ -41,6 +41,23 @@ + + + + + + + + +