docs: translate all code comments to English (language policy)
Translate every Italian /// XML doc comment, <!-- --> XAML comment, and // inline comment to English across all source files (Core, App, tests). Add the language policy to CLAUDE.md (conversation Italian; all code and docs English). Update one test assertion that checked an Italian exception message that was also translated.
This commit is contained in:
@@ -6,8 +6,8 @@ using Avalonia.Data.Converters;
|
||||
namespace PalladiumWallet.App.ViewModels;
|
||||
|
||||
/// <summary>
|
||||
/// true (mobile) → Dock.Bottom — tab strip in basso, standard Android.
|
||||
/// false (desktop) → Dock.Top — comportamento predefinito Avalonia.
|
||||
/// true (mobile) → Dock.Bottom — tab strip at the bottom, Android standard.
|
||||
/// false (desktop) → Dock.Top — Avalonia default behavior.
|
||||
/// </summary>
|
||||
public sealed class BoolToTabPlacementConverter : IValueConverter
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@ public partial class MainWindowViewModel
|
||||
[ObservableProperty]
|
||||
private ContactEntry? selectedContactInList;
|
||||
|
||||
/// <summary>Contatto selezionato nella ComboBox del pannello Invia: riempie SendTo.</summary>
|
||||
/// <summary>Contact selected in the Send panel's ComboBox: fills SendTo.</summary>
|
||||
[ObservableProperty]
|
||||
private ContactEntry? sendToContact;
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace PalladiumWallet.App.ViewModels;
|
||||
|
||||
public partial class MainWindowViewModel
|
||||
{
|
||||
// ---- saldo e info wallet ----
|
||||
// ---- balance and wallet info ----
|
||||
|
||||
[ObservableProperty]
|
||||
private string balanceText = "—";
|
||||
@@ -28,7 +28,7 @@ public partial class MainWindowViewModel
|
||||
[ObservableProperty]
|
||||
private string networkInfo = "";
|
||||
|
||||
// ---- indirizzo di ricezione e QR ----
|
||||
// ---- receive address and QR ----
|
||||
|
||||
[ObservableProperty]
|
||||
private string receiveAddress = "";
|
||||
@@ -60,7 +60,7 @@ public partial class MainWindowViewModel
|
||||
}
|
||||
}
|
||||
|
||||
// ---- tab indirizzi ----
|
||||
// ---- addresses tab ----
|
||||
|
||||
[ObservableProperty]
|
||||
private AddressRow? selectedAddressRow;
|
||||
@@ -74,7 +74,7 @@ public partial class MainWindowViewModel
|
||||
[RelayCommand]
|
||||
private void CloseAddressInfo() => AddressInfo = null;
|
||||
|
||||
// ---- overlay dettaglio transazione ----
|
||||
// ---- transaction detail overlay ----
|
||||
|
||||
[ObservableProperty]
|
||||
private bool isTxDetailsOpen;
|
||||
@@ -169,7 +169,7 @@ public partial class MainWindowViewModel
|
||||
}
|
||||
}
|
||||
|
||||
// ---- aggiorna display dal risultato della sync ----
|
||||
// ---- update display from the sync result ----
|
||||
|
||||
private void ApplyCache(SyncCache? cache)
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ public partial class MainWindowViewModel
|
||||
if (PlatformServices.ScanQrAsync is not { } scan) return;
|
||||
var raw = await scan();
|
||||
if (string.IsNullOrWhiteSpace(raw)) return;
|
||||
// Gestisce URI tipo "palladium:ADDRESS?amount=X" estraendo solo l'indirizzo
|
||||
// Handle URIs like "palladium:ADDRESS?amount=X" — extract address only
|
||||
var address = raw.Contains(':') ? raw.Split(':')[1] : raw;
|
||||
if (address.Contains('?')) address = address.Split('?')[0];
|
||||
SendTo = address.Trim();
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace PalladiumWallet.App.ViewModels;
|
||||
|
||||
public partial class MainWindowViewModel
|
||||
{
|
||||
// ---- server e connessione ----
|
||||
// ---- server and connection ----
|
||||
|
||||
[ObservableProperty]
|
||||
private string serverHost = "";
|
||||
@@ -118,20 +118,20 @@ public partial class MainWindowViewModel
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restituisce i server da provare in ordine: prima quello selezionato nella UI
|
||||
/// (o digitato manualmente), poi gli altri in KnownServers, evitando duplicati.
|
||||
/// Returns servers to try in order: first the one selected in the UI
|
||||
/// (or manually typed), then the remaining KnownServers, with duplicates skipped.
|
||||
/// </summary>
|
||||
private IEnumerable<(string Host, int Port)> BuildServerCandidates(string selectedHost, int selectedPort)
|
||||
{
|
||||
var seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
// 1. Server corrente (selezionato o digitato manualmente).
|
||||
// 1. Current server (selected or manually typed).
|
||||
if (!string.IsNullOrWhiteSpace(selectedHost))
|
||||
{
|
||||
var key = $"{selectedHost}:{selectedPort}";
|
||||
if (seen.Add(key))
|
||||
yield return (selectedHost, selectedPort);
|
||||
}
|
||||
// 2. Altri server noti, in ordine di lista.
|
||||
// 2. Other known servers, in list order.
|
||||
foreach (var s in KnownServers)
|
||||
{
|
||||
var p = s.PortFor(UseSsl);
|
||||
@@ -163,14 +163,14 @@ public partial class MainWindowViewModel
|
||||
|
||||
if (_client is null || !_client.IsConnected)
|
||||
{
|
||||
// Salva le cache prima di distruggere il synchronizer: il nuovo
|
||||
// synchronizer userà un client diverso e deve essere ricreato,
|
||||
// ma i dati già scaricati vengono preservati via _doc.Cache.
|
||||
// Persist caches before destroying the synchronizer: the new
|
||||
// synchronizer will use a different client and must be recreated,
|
||||
// but already-downloaded data is preserved via _doc.Cache.
|
||||
PersistPartialTxCache();
|
||||
_synchronizer = null;
|
||||
|
||||
// Prova tutti i server noti in ordine; parte da quello selezionato
|
||||
// e scorre la lista fino al primo che risponde.
|
||||
// Try all known servers in order; starts with the selected one
|
||||
// and walks the list until the first that responds.
|
||||
var candidates = BuildServerCandidates(host, port);
|
||||
Exception? lastError = null;
|
||||
foreach (var (h, p) in candidates)
|
||||
@@ -189,7 +189,7 @@ public partial class MainWindowViewModel
|
||||
IsConnected = true;
|
||||
_autoReconnect = true;
|
||||
ConnectionStatus = Loc.Tr("conn.connectedto");
|
||||
// Aggiorna la UI per riflettere il server effettivamente connesso.
|
||||
// Update the UI to reflect the server actually connected.
|
||||
_syncingServerFields = true;
|
||||
ServerHost = h;
|
||||
ServerPort = p.ToString();
|
||||
@@ -215,8 +215,8 @@ public partial class MainWindowViewModel
|
||||
if (_synchronizer is null)
|
||||
{
|
||||
_synchronizer = new WalletSynchronizer(_account, _client!, _doc.GapLimit);
|
||||
// Ricarica dalla cache su disco: evita di riscaricale le tx già note
|
||||
// (fondamentale per wallet con migliaia di tx storiche — previene -101).
|
||||
// Reload from disk cache: avoids re-downloading already known transactions
|
||||
// (essential for wallets with thousands of historical txs — prevents -101).
|
||||
var net = PalladiumNetworks.For(_account.Profile.Kind);
|
||||
_synchronizer.PreloadCaches(
|
||||
_doc.Cache?.RawTxHex ?? [],
|
||||
@@ -271,8 +271,8 @@ public partial class MainWindowViewModel
|
||||
if (_account is not null)
|
||||
{
|
||||
_syncFailed = true;
|
||||
// Salva le tx già scaricate: al retry il synchronizer riparte
|
||||
// da qui invece di ricominciare da zero (es. dopo -101).
|
||||
// Persist already-downloaded transactions: on retry the synchronizer
|
||||
// resumes from here instead of starting from scratch (e.g. after -101).
|
||||
PersistPartialTxCache();
|
||||
}
|
||||
}
|
||||
@@ -327,9 +327,9 @@ public partial class MainWindowViewModel
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Salva nel SyncCache le tx e le prove di Merkle già accumulate dal synchronizer,
|
||||
/// anche se la sync non è ancora completa. Consente al retry successivo
|
||||
/// (o al riavvio dell'app) di riprendere senza riscaricale da zero.
|
||||
/// Persists the transactions and Merkle proofs already accumulated by the synchronizer
|
||||
/// into SyncCache, even if sync is not yet complete. Allows the next retry
|
||||
/// (or app restart) to resume without re-downloading from scratch.
|
||||
/// </summary>
|
||||
private void PersistPartialTxCache()
|
||||
{
|
||||
@@ -346,7 +346,7 @@ public partial class MainWindowViewModel
|
||||
_doc.Cache.BlockHeaders = blockHeaders;
|
||||
WalletStore.Save(_doc, _walletPath, _password);
|
||||
}
|
||||
catch { /* non fatale: il prossimo salvataggio completo recupererà */ }
|
||||
catch { /* non-fatal: the next full save will recover */ }
|
||||
}
|
||||
|
||||
private async Task DisconnectAsync()
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace PalladiumWallet.App.ViewModels;
|
||||
|
||||
public partial class MainWindowViewModel
|
||||
{
|
||||
// ---- wizard di setup
|
||||
// ---- setup wizard
|
||||
|
||||
public const string StepDataLocation = "data-location";
|
||||
public const string StepStart = "start";
|
||||
@@ -85,7 +85,7 @@ public partial class MainWindowViewModel
|
||||
[ObservableProperty]
|
||||
private string importWifInput = "";
|
||||
|
||||
// Tipo di script rilevato durante la decodifica dell'xkey (per mostrarlo all'utente)
|
||||
// Script type detected during xkey decoding (to display to the user)
|
||||
[ObservableProperty]
|
||||
private string importXkeyDetectedKind = "";
|
||||
|
||||
@@ -268,7 +268,7 @@ public partial class MainWindowViewModel
|
||||
StatusMessage = Loc.Tr("msg.xkey.required");
|
||||
return;
|
||||
}
|
||||
// Valida e rileva il tipo: prova prima come xpub, poi come xprv.
|
||||
// Validate and detect the type: try as xpub first, then as xprv.
|
||||
if (Slip132.TryDecodePublic(ImportXkeyInput.Trim(), Profile, out _, out var pubKind))
|
||||
{
|
||||
SelectedScriptKind = pubKind;
|
||||
@@ -298,7 +298,7 @@ public partial class MainWindowViewModel
|
||||
StatusMessage = Loc.Tr("msg.wif.required");
|
||||
return;
|
||||
}
|
||||
// Valida il WIF con un parsing anticipato.
|
||||
// Validate the WIF with an early parse.
|
||||
try
|
||||
{
|
||||
_ = new NBitcoin.BitcoinSecret(ImportWifInput.Trim(), PalladiumNetworks.For(Net));
|
||||
@@ -421,9 +421,9 @@ public partial class MainWindowViewModel
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Costruisce il percorso file dal nome inserito dall'utente.
|
||||
/// Se il nome è vuoto genera un nome automatico (default, wallet-2, …).
|
||||
/// Rimuove i caratteri non validi per il filesystem.
|
||||
/// Builds the file path from the name entered by the user.
|
||||
/// If the name is empty, generates an automatic name (default, wallet-2, …).
|
||||
/// Removes characters that are invalid for the filesystem.
|
||||
/// </summary>
|
||||
private string WalletPathFromName(string name)
|
||||
{
|
||||
@@ -435,7 +435,7 @@ public partial class MainWindowViewModel
|
||||
|
||||
if (string.IsNullOrEmpty(clean))
|
||||
{
|
||||
// Nessun nome → nome automatico
|
||||
// No name provided → auto-generated name
|
||||
var def = AppPaths.DefaultWalletPath(Net);
|
||||
for (var n = 2; WalletStore.Exists(def); n++)
|
||||
def = Path.Combine(AppPaths.WalletsDir(Net), $"wallet-{n}.wallet.json");
|
||||
@@ -547,8 +547,8 @@ public partial class MainWindowViewModel
|
||||
ApplyCache(doc.Cache);
|
||||
IsWalletOpen = true;
|
||||
StatusMessage = Loc.Tr("msg.opened");
|
||||
_autoReconnect = true; // keepalive riprova la connessione anche se il primo tentativo fallisce
|
||||
_syncFailed = true; // forza la prima sync automatica
|
||||
_autoReconnect = true; // keepalive retries the connection even if the first attempt fails
|
||||
_syncFailed = true; // force the first automatic sync
|
||||
_ = ConnectAndSync();
|
||||
}
|
||||
}
|
||||
@@ -16,10 +16,10 @@ using PalladiumWallet.Core.Wallet;
|
||||
|
||||
namespace PalladiumWallet.App.ViewModels;
|
||||
|
||||
/// <summary>Riga dello storico transazioni per la vista.</summary>
|
||||
/// <summary>Transaction history row for the view.</summary>
|
||||
public sealed record HistoryRow(string Conferma, string Importo, string Txid, string Verificata);
|
||||
|
||||
/// <summary>Riga della vista indirizzi con chiavi e derivation path pre-calcolati.</summary>
|
||||
/// <summary>Address view row with pre-computed keys and derivation path.</summary>
|
||||
public sealed record AddressRow(
|
||||
string Tipo, int Indice, string Indirizzo, string Saldo, string NumTx,
|
||||
bool IsChange = false, string PubKey = "", string PrivKey = "", string DerivPath = "")
|
||||
@@ -27,7 +27,7 @@ public sealed record AddressRow(
|
||||
public bool HasPrivKey => !string.IsNullOrEmpty(PrivKey);
|
||||
}
|
||||
|
||||
/// <summary>Dati completi di un indirizzo passati alla finestra di dettaglio.</summary>
|
||||
/// <summary>Full address data passed to the address detail overlay.</summary>
|
||||
public sealed record AddressInfo(
|
||||
Loc Loc,
|
||||
string Address, string DerivPath, string PubKey, string PrivKey)
|
||||
@@ -35,38 +35,38 @@ public sealed record AddressInfo(
|
||||
public bool HasPrivKey => !string.IsNullOrEmpty(PrivKey);
|
||||
}
|
||||
|
||||
/// <summary>Contatto in rubrica: nome + indirizzo blockchain.</summary>
|
||||
/// <summary>Address book contact: name + blockchain address.</summary>
|
||||
public sealed record ContactEntry(string Name, string Address);
|
||||
|
||||
/// <summary>Voce della lista di scelta wallet: nome file + percorso completo.</summary>
|
||||
/// <summary>Wallet list entry: display name + full file path.</summary>
|
||||
public sealed record WalletFileEntry(string Name, string Path);
|
||||
|
||||
/// <summary>
|
||||
/// ViewModel unico dell'applicazione (wizard + dashboard). Suddiviso in file
|
||||
/// partial per area: Wizard, Settings, Sync, Send, Contacts, Receive.
|
||||
/// Single application ViewModel (wizard + dashboard). Split into partial files
|
||||
/// by area: Wizard, Settings, Sync, Send, Contacts, Receive.
|
||||
/// </summary>
|
||||
public partial class MainWindowViewModel : ViewModelBase
|
||||
{
|
||||
// ---- stato sessione wallet ----
|
||||
// ---- wallet session state ----
|
||||
private WalletDocument? _doc;
|
||||
private IWalletAccount? _account;
|
||||
private string? _walletPath;
|
||||
private string? _password;
|
||||
private WalletLock? _walletLock;
|
||||
|
||||
// ---- rete ----
|
||||
// ---- network ----
|
||||
private ElectrumClient? _client;
|
||||
private WalletSynchronizer? _synchronizer;
|
||||
private IReadOnlyDictionary<string, Transaction>? _lastTransactions;
|
||||
private bool _resyncRequested;
|
||||
|
||||
// ---- invio ----
|
||||
// ---- send ----
|
||||
private BuiltTransaction? _pendingSend;
|
||||
|
||||
// ---- dettaglio transazione ----
|
||||
// ---- transaction detail ----
|
||||
private CancellationTokenSource? _txDetailsCts;
|
||||
|
||||
// ---- configurazione e localizzazione ----
|
||||
// ---- configuration and localisation ----
|
||||
private AppConfig _config = AppConfig.Load();
|
||||
private Loc _loc = Loc.Instance;
|
||||
public Loc Loc => _loc;
|
||||
@@ -82,7 +82,7 @@ public partial class MainWindowViewModel : ViewModelBase
|
||||
// ---- server UI sync ----
|
||||
private bool _syncingServerFields;
|
||||
|
||||
// ---- proprietà di app ----
|
||||
// ---- app properties ----
|
||||
|
||||
public static string AppVersion =>
|
||||
typeof(MainWindowViewModel).Assembly.GetName().Version is { } v
|
||||
@@ -91,7 +91,7 @@ public partial class MainWindowViewModel : ViewModelBase
|
||||
|
||||
public string WindowTitle => $"Palladium Wallet {AppVersion}";
|
||||
|
||||
/// <summary>true su desktop; false su Android/iOS — nasconde le funzioni legate al filesystem libero.</summary>
|
||||
/// <summary>True on desktop; false on Android/iOS — hides filesystem-dependent features.</summary>
|
||||
public bool IsDesktop => !OperatingSystem.IsAndroid() && !OperatingSystem.IsIOS();
|
||||
|
||||
public bool IsMobile => !IsDesktop;
|
||||
@@ -99,7 +99,7 @@ public partial class MainWindowViewModel : ViewModelBase
|
||||
public string UnitLabel => _config.Unit;
|
||||
public AppConfig CurrentConfig => _config;
|
||||
|
||||
// ---- stato pannelli ----
|
||||
// ---- panel state ----
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(IsSetupVisible))]
|
||||
@@ -116,7 +116,7 @@ public partial class MainWindowViewModel : ViewModelBase
|
||||
[RelayCommand]
|
||||
private void SelectTab(string index) => SelectedTabIndex = int.Parse(index);
|
||||
|
||||
// ---- collections per la dashboard ----
|
||||
// ---- dashboard collections ----
|
||||
|
||||
public ObservableCollection<HistoryRow> History { get; } = [];
|
||||
public ObservableCollection<AddressRow> Addresses { get; } = [];
|
||||
@@ -141,7 +141,7 @@ public partial class MainWindowViewModel : ViewModelBase
|
||||
catch { return ""; }
|
||||
}
|
||||
|
||||
// ---- costruttore ----
|
||||
// ---- constructor ----
|
||||
|
||||
public MainWindowViewModel()
|
||||
{
|
||||
@@ -161,7 +161,7 @@ public partial class MainWindowViewModel : ViewModelBase
|
||||
return;
|
||||
if (_client is { IsConnected: true })
|
||||
{
|
||||
// Se il wallet è aperto e l'ultima sync è fallita, riprova automaticamente.
|
||||
// If the wallet is open and the last sync failed, retry automatically.
|
||||
if (_syncFailed && _account is not null)
|
||||
{
|
||||
await ConnectAndSync();
|
||||
@@ -177,7 +177,7 @@ public partial class MainWindowViewModel : ViewModelBase
|
||||
}
|
||||
}
|
||||
|
||||
// ---- ciclo di vita wallet ----
|
||||
// ---- wallet lifecycle ----
|
||||
|
||||
[RelayCommand]
|
||||
private void CloseWallet()
|
||||
|
||||
@@ -7,8 +7,8 @@ using Avalonia.Media;
|
||||
namespace PalladiumWallet.App.ViewModels;
|
||||
|
||||
/// <summary>
|
||||
/// bool → pennello: gli indirizzi del wallet (input/output "nostri") sono
|
||||
/// evidenziati in verde, gli altri usano il colore di testo predefinito.
|
||||
/// bool → brush: the wallet's own addresses ("our" inputs/outputs) are
|
||||
/// highlighted in green, the others use the default text color.
|
||||
/// </summary>
|
||||
public sealed class MineColorConverter : IValueConverter
|
||||
{
|
||||
|
||||
@@ -7,13 +7,13 @@ using PalladiumWallet.Core.Wallet;
|
||||
|
||||
namespace PalladiumWallet.App.ViewModels;
|
||||
|
||||
/// <summary>Riga input/output per le tabelle della finestra di dettaglio.</summary>
|
||||
/// <summary>Input/output row for the transaction detail tables.</summary>
|
||||
public sealed record TxIoRow(string Position, string Address, string Amount, bool IsMine);
|
||||
|
||||
/// <summary>
|
||||
/// ViewModel della finestra di dettaglio transazione: prende un
|
||||
/// <see cref="TransactionDetails"/> (assemblato dal server) e ne ricava tutte
|
||||
/// le stringhe già formattate e localizzate per la vista. È di sola lettura.
|
||||
/// ViewModel for the transaction detail view: takes a
|
||||
/// <see cref="TransactionDetails"/> (assembled from server data) and produces
|
||||
/// all strings already formatted and localised for the view. Read-only.
|
||||
/// </summary>
|
||||
public sealed class TransactionDetailsViewModel
|
||||
{
|
||||
@@ -35,14 +35,14 @@ public sealed class TransactionDetailsViewModel
|
||||
|
||||
var counterparties = d.CounterpartyAddresses;
|
||||
CounterpartyHeader = d.IsIncoming ? loc["tx.from"] : loc["tx.to"];
|
||||
// Una coinbase non ha mittente: le monete sono generate dal mining.
|
||||
// Coinbase has no sender: coins are newly generated by mining.
|
||||
CounterpartyText = d.IsCoinbase
|
||||
? loc["tx.coinbase.newcoins"]
|
||||
: counterparties.Count > 0
|
||||
? string.Join(Environment.NewLine, counterparties)
|
||||
: "—";
|
||||
|
||||
// Debito (uscita verso terzi) o Credito (entrata netta sui nostri output).
|
||||
// Debit (outflow to third parties) or Credit (net inflow on our outputs).
|
||||
AmountHeader = d.IsIncoming ? loc["tx.credit"] : loc["tx.debit"];
|
||||
AmountText = d.IsIncoming
|
||||
? Signed(d.ReceivedSats)
|
||||
|
||||
Reference in New Issue
Block a user