refactor(audit): batch 4 — UI design-system helpers + i18n

Mechanical, behavior-preserving consolidations from the audit. Rendering
extractions were kept byte-equivalent; sites that couldn't be made identical
were left as-is (noted below).

Shared helpers:
- util::truncateMiddle(s,maxLen) / (s,front,back) in text_format.h — replaces
  6 file-local middle-ellipsis truncators + several inline substr sites
  (send/receive/transactions/balance_recent_tx/explorer + app.cpp + 3 dialogs).
  Carries the maxLen<=3 guard, fixing the latent unsigned-underflow copies.
- material::LoadingDots() in draw_helpers.h — one animated-ellipsis source for
  8 copy-pasted spinner sites (identical GetTime()*3 phase preserved).
- Reuse the existing FormatHashrate() in explorer_tab + peers_tab (dropped two
  inline hashrate ladders).
- material::DrawButtonGlassOverlay() — the glass-fill/rim/tactile overlay block
  shared by TactileButton / TactileSmallButton / schema TactileButton.
- material::CollapsibleHeader() — the invisible-button + label + chevron idiom
  (3 of 5 settings_page sites; RPC/Debug headers skipped — non-identical).
- material::GlassCardScope (RAII) — the ChannelsSplit/Indent/DrawGlassPanel/
  ChannelsMerge card scaffold (5 settings_page cards; About/send/receive skipped
  — different padding / logo interleaving).
- material::DialogWarningHeader()/DialogConfirmFooter() — warning header +
  50/50 Cancel/danger footer across the confirm dialogs; button height moved
  from a hardcoded 40px into ui.toml (components.overlay-dialog.confirm-btn-height).
- File-local enterLowSpec()/exitLowSpec() collapse the 3 low-spec snapshot copies.

i18n: wrapped hardcoded English in the shared balance render paths and the
whole Lite lifecycle/security section in TR(), with English defaults added to
loadBuiltinEnglish() (res/lang/*.json left for the translation tooling — TR
falls back to English, so output is unchanged).

Full-node + Lite build clean; ctest 1/1; hygiene clean. These are rendering
changes — the Settings page (cards/headers/confirm dialogs), all tactile
buttons, and the Lite settings section warrant a screenshot check.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-02 17:29:12 -05:00
parent 280a71e973
commit de11850c74
21 changed files with 452 additions and 500 deletions

View File

@@ -452,6 +452,49 @@ void I18n::loadBuiltinEnglish()
strings_["confirm_lite_redownload_title"] = "Redownload Blocks";
strings_["confirm_lite_redownload_msg"] = "This clears the wallet's downloaded block data and re-fetches and re-scans every block from the lite server. It can take a while; the wallet shows sync progress until it finishes.";
strings_["confirm_lite_redownload_safe"] = "Your wallet, keys, and seed are not affected — only the block data is re-downloaded.";
// Lite wallet lifecycle / backup / security section
strings_["lite_servers_network_tab"] = "Lite servers are managed in the Network tab.";
strings_["lite_wallet_request"] = "Lite wallet request";
strings_["lite_action"] = "Action";
strings_["lite_op_create"] = "Create";
strings_["lite_op_open"] = "Open";
strings_["lite_op_restore"] = "Restore";
strings_["lite_wallet_label"] = "Wallet";
strings_["lite_seed_label"] = "Seed";
strings_["lite_word_count"] = "%d / 24 words";
strings_["lite_birthday_label"] = "Birthday";
strings_["lite_birthday_hint"] = "Block height to start scanning from. Leave 0 if unknown (slower full scan).";
strings_["lite_account_label"] = "Account";
strings_["lite_overwrite"] = "Overwrite";
strings_["lite_passphrase_label"] = "Passphrase";
strings_["lite_validate"] = "Validate";
strings_["lite_working"] = "Working…";
strings_["lite_wallet_ready"] = "Wallet ready";
strings_["lite_backup_keys"] = "Backup & keys";
strings_["lite_show_seed"] = "Show seed";
strings_["lite_seed_warning"] = "Seed phrase — the ONLY way to restore your wallet. Write it down, store it offline, never share it.";
strings_["lite_show_private_keys"] = "Show private keys";
strings_["lite_private_keys_warning"] = "Private keys — anyone with these can spend your funds";
strings_["lite_birthday_backup"] = "Birthday: %llu (back this up too)";
strings_["lite_copy"] = "Copy";
strings_["lite_save_to_file"] = "Save to file";
strings_["lite_saved_to"] = "Saved (plaintext, owner-only) to ";
strings_["lite_could_not_write"] = "Could not write ";
strings_["lite_hide_wipe"] = "Hide & wipe";
strings_["lite_import_key_label"] = "Import key";
strings_["lite_import"] = "Import";
strings_["lite_key_imported"] = "Key imported — run a sync to scan its history";
strings_["lite_security"] = "Security";
strings_["lite_encrypt_wallet"] = "Encrypt wallet";
strings_["lite_wallet_encrypted"] = "Wallet encrypted";
strings_["lite_unlock"] = "Unlock";
strings_["lite_wallet_unlocked"] = "Wallet unlocked";
strings_["lite_unlock_failed"] = "Unlock failed";
strings_["lite_lock_now"] = "Lock now";
strings_["lite_wallet_locked"] = "Wallet locked";
strings_["lite_lock_failed"] = "Lock failed";
strings_["lite_remove_encryption"] = "Remove encryption";
strings_["lite_encryption_removed"] = "Encryption removed";
strings_["tt_encrypt"] = "Encrypt wallet.dat with a passphrase";
strings_["tt_change_pass"] = "Change the wallet encryption passphrase";
strings_["tt_lock"] = "Lock the wallet immediately";
@@ -652,6 +695,15 @@ void I18n::loadBuiltinEnglish()
strings_["transparent"] = "Transparent";
strings_["total"] = "Total";
strings_["unconfirmed"] = "Unconfirmed";
strings_["recent_transactions"] = "RECENT TRANSACTIONS";
strings_["view_all"] = "View All";
strings_["no_transactions_yet"] = "No transactions yet";
strings_["privacy_great"] = "Great privacy!";
strings_["privacy_medium"] = "Consider shielding more";
strings_["privacy_low"] = "Low privacy — shield funds";
strings_["balance_history_collecting"] = "Balance history — collecting data...";
strings_["balance_shielded_fmt"] = "Shielded: %.8f";
strings_["balance_transparent_fmt"] = "Transparent: %.8f";
strings_["your_addresses"] = "Your Addresses";
strings_["z_addresses"] = "Z-Addresses";
strings_["t_addresses"] = "T-Addresses";