feat(wallets): vertical label+icon badge stack + async probing

Redesign the wallet.dat status badges as a right-aligned vertical stack of
"label icon" rows ("Seed phrase 🌱" over "Encrypted 🔒", "Legacy", or "Unknown"),
each with a hover tooltip; name/metadata reserve the stack width and truncate
before it.

Move the wallet.dat probing off the UI thread: scan() now builds the row list
synchronously (filename/size only) and hands the file reads to a detached
background thread whose results land in a shared, index-aligned batch that
render() reads under a mutex. A re-scan supersedes the old batch (cancel + swap);
the thread touches only its own heap batch (never s_rows/statics), so it's safe
across re-scans and shutdown. The dialog opens instantly even with a large
active wallet; badges fill in over the next few frames.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-11 12:47:27 -05:00
parent fadbd6a879
commit 36efe99a0f
2 changed files with 102 additions and 55 deletions

View File

@@ -266,6 +266,10 @@ void I18n::loadBuiltinEnglish()
strings_["wallets_badge_seed"] = "Seed phrase wallet (HD)";
strings_["wallets_badge_legacy"] = "Legacy wallet (no seed phrase)";
strings_["wallets_badge_unknown"] = "Wallet type not fully determined (large file — open to confirm)";
strings_["wallets_badge_seed_short"] = "Seed phrase";
strings_["wallets_badge_encrypted_short"] = "Encrypted";
strings_["wallets_badge_legacy_short"] = "Legacy";
strings_["wallets_badge_unknown_short"] = "Unknown";
strings_["wallets_open"] = "Open";
strings_["wallets_never"] = "Never";
strings_["wallets_import_hint"] = "Import to open";