From 2f86bec98e569d8b7bd73edb28f8cefb701d5df8 Mon Sep 17 00:00:00 2001 From: DanS Date: Sun, 12 Jul 2026 07:17:34 -0500 Subject: [PATCH] feat(wallets): subtle empty-state hint in the fixed-height list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the list now pinned at max height, a few wallets leave blank space below the cards. Fill it — only when there's real room to spare — with a subtle centered folder glyph + "Scan a folder to find more wallets" (OnSurfaceDisabled), so the area reads as a gentle nudge toward the scan action rather than dead space. Purely decorative (draw-list only, clipped to the list); the actions stay below. New i18n key wallets_empty_hint, translated across all 8 languages. Verified on the sweep: the hint centers in the gap and reads subtly on both dark and light themes. Co-Authored-By: Claude Opus 4.8 (1M context) --- res/fonts/NotoSansCJK-Subset.ttf | Bin 618560 -> 618560 bytes res/lang/de.json | 1 + res/lang/es.json | 1 + res/lang/fr.json | 1 + res/lang/ja.json | 1 + res/lang/ko.json | 1 + res/lang/pt.json | 1 + res/lang/ru.json | 1 + res/lang/zh.json | 1 + scripts/add_missing_translations.py | 10 ++++++++++ src/ui/windows/wallets_dialog.h | 22 ++++++++++++++++++++++ src/util/i18n.cpp | 1 + 12 files changed, 41 insertions(+) diff --git a/res/fonts/NotoSansCJK-Subset.ttf b/res/fonts/NotoSansCJK-Subset.ttf index d908fd28afd13d2517f85c8ed966b89a4571bd8d..1051892820f2b181016865251302b021bce8536c 100644 GIT binary patch delta 82 zcmX@`K=r@_)d@vR9GfPVOp+4Z5zlY)m4T7@1p^S=+0bVSqMuco&TCd+Y*%0eVJ0AE X24WTSk4wl delta 82 zcmX@`K=r@_)d@vRtWpz8CP_)Wi08NY%D~9{f&mEbZ0Iuu(a$Q4*qRj>+Z7l=mzX diff --git a/res/lang/de.json b/res/lang/de.json index e707e69..02a710d 100644 --- a/res/lang/de.json +++ b/res/lang/de.json @@ -1343,6 +1343,7 @@ "wallets_created": "erstellt", "wallets_creating": "Wallet wird erstellt — der Node wird neu gestartet…", "wallets_current": "aktuell", + "wallets_empty_hint": "Ordner durchsuchen, um weitere Wallets zu finden", "wallets_exists": "Eine Wallet mit diesem Namen existiert bereits.", "wallets_external_tt": "Außerhalb deines Datenverzeichnisses — Öffnen verlinkt sie an ihrem Ort (keine Kopie).", "wallets_folder_hint": "/pfad/zum/ordner mit .dat-Wallet-Dateien", diff --git a/res/lang/es.json b/res/lang/es.json index 7da60f6..a1ec805 100644 --- a/res/lang/es.json +++ b/res/lang/es.json @@ -1343,6 +1343,7 @@ "wallets_created": "creada", "wallets_creating": "Creando cartera — el nodo se reiniciará…", "wallets_current": "actual", + "wallets_empty_hint": "Escanea una carpeta para encontrar más carteras", "wallets_exists": "Ya existe una cartera con ese nombre.", "wallets_external_tt": "Fuera de tu directorio de datos — Abrir lo enlaza en su lugar (sin copiar).", "wallets_folder_hint": "/ruta/a/carpeta con archivos .dat de cartera", diff --git a/res/lang/fr.json b/res/lang/fr.json index 01ba68b..c961ea3 100644 --- a/res/lang/fr.json +++ b/res/lang/fr.json @@ -1343,6 +1343,7 @@ "wallets_created": "créé", "wallets_creating": "Création du portefeuille — le nœud va redémarrer…", "wallets_current": "actuel", + "wallets_empty_hint": "Analysez un dossier pour trouver d'autres portefeuilles", "wallets_exists": "Un portefeuille portant ce nom existe déjà.", "wallets_external_tt": "Hors de votre répertoire de données — Ouvrir le lie sur place (sans copie).", "wallets_folder_hint": "/chemin/vers/le/dossier contenant les fichiers .dat", diff --git a/res/lang/ja.json b/res/lang/ja.json index c7de9c1..3d87dd3 100644 --- a/res/lang/ja.json +++ b/res/lang/ja.json @@ -1343,6 +1343,7 @@ "wallets_created": "作成", "wallets_creating": "ウォレットを作成中 — ノードが再起動します…", "wallets_current": "現在", + "wallets_empty_hint": "フォルダーをスキャンして他のウォレットを探す", "wallets_exists": "その名前のウォレットは既に存在します。", "wallets_external_tt": "データディレクトリの外 —「開く」はその場でリンクします(コピーなし)。", "wallets_folder_hint": "wallet .dat ファイルのあるフォルダのパス", diff --git a/res/lang/ko.json b/res/lang/ko.json index 3246144..c1f3a49 100644 --- a/res/lang/ko.json +++ b/res/lang/ko.json @@ -1343,6 +1343,7 @@ "wallets_created": "생성", "wallets_creating": "지갑을 만드는 중 — 노드가 재시작됩니다…", "wallets_current": "현재", + "wallets_empty_hint": "폴더를 스캔하여 다른 지갑 찾기", "wallets_exists": "같은 이름의 지갑이 이미 존재합니다.", "wallets_external_tt": "데이터 디렉터리 밖 — '열기'는 제자리에 링크합니다 (복사 없음).", "wallets_folder_hint": "wallet-*.dat 파일이 있는 폴더 경로", diff --git a/res/lang/pt.json b/res/lang/pt.json index 51d71f0..4930e31 100644 --- a/res/lang/pt.json +++ b/res/lang/pt.json @@ -1343,6 +1343,7 @@ "wallets_created": "criada", "wallets_creating": "Criando carteira — o nó será reiniciado…", "wallets_current": "atual", + "wallets_empty_hint": "Verifique uma pasta para encontrar mais carteiras", "wallets_exists": "Já existe uma carteira com esse nome.", "wallets_external_tt": "Fora do seu diretório de dados — Abrir o vincula no lugar (sem cópia).", "wallets_folder_hint": "/caminho/para/pasta com arquivos .dat de carteira", diff --git a/res/lang/ru.json b/res/lang/ru.json index c4b49e8..411a114 100644 --- a/res/lang/ru.json +++ b/res/lang/ru.json @@ -1343,6 +1343,7 @@ "wallets_created": "создан", "wallets_creating": "Создание кошелька — узел будет перезапущен…", "wallets_current": "текущий", + "wallets_empty_hint": "Просканируйте папку, чтобы найти другие кошельки", "wallets_exists": "Кошелёк с таким именем уже существует.", "wallets_external_tt": "Вне каталога данных — «Открыть» создаёт ссылку на месте (без копирования).", "wallets_folder_hint": "/путь/к/папке с файлами кошельков .dat", diff --git a/res/lang/zh.json b/res/lang/zh.json index 076aabb..7c0f123 100644 --- a/res/lang/zh.json +++ b/res/lang/zh.json @@ -1343,6 +1343,7 @@ "wallets_created": "创建于", "wallets_creating": "正在创建钱包——节点将重启…", "wallets_current": "当前", + "wallets_empty_hint": "扫描文件夹以查找更多钱包", "wallets_exists": "已存在同名钱包。", "wallets_external_tt": "在数据目录之外 —「打开」会就地链接(不复制)。", "wallets_folder_hint": "/含 .dat 钱包文件的文件夹路径", diff --git a/scripts/add_missing_translations.py b/scripts/add_missing_translations.py index fac0c86..7a07fd3 100644 --- a/scripts/add_missing_translations.py +++ b/scripts/add_missing_translations.py @@ -2244,6 +2244,16 @@ TRANSLATIONS = { "ru": "Больше не сканировать эту папку", "zh": "停止扫描此文件夹", "ja": "このフォルダーのスキャンを停止", "ko": "이 폴더 스캔 중지" }, + "wallets_empty_hint": { + "es": "Escanea una carpeta para encontrar más carteras", + "de": "Ordner durchsuchen, um weitere Wallets zu finden", + "fr": "Analysez un dossier pour trouver d'autres portefeuilles", + "pt": "Verifique uma pasta para encontrar mais carteiras", + "ru": "Просканируйте папку, чтобы найти другие кошельки", + "zh": "扫描文件夹以查找更多钱包", + "ja": "フォルダーをスキャンして他のウォレットを探す", + "ko": "폴더를 스캔하여 다른 지갑 찾기" + }, } def main(): diff --git a/src/ui/windows/wallets_dialog.h b/src/ui/windows/wallets_dialog.h index b132f35..1cac7d9 100644 --- a/src/ui/windows/wallets_dialog.h +++ b/src/ui/windows/wallets_dialog.h @@ -386,6 +386,28 @@ public: ImGui::Dummy(ImVec2(rowW, walRowH)); if (i + 1 < s_rows.size()) ImGui::Dummy(ImVec2(rowW, cardGap)); } + // Empty-state nudge: the list sits at a fixed max height, so a handful of wallets leave blank + // space below. When there's real room to spare, fill it with a subtle centered hint (a folder + // glyph + one line) instead of dead space; it's purely decorative — the actions live below. + { + const float remainY = ImGui::GetContentRegionAvail().y; + if (remainY > walRowH * 1.6f) { + ImDrawList* wdl = ImGui::GetWindowDrawList(); + ImFont* hIco = Type().iconLarge(); + ImFont* hTxt = Type().caption(); + const char* icon = ICON_MD_CREATE_NEW_FOLDER; + const char* hint = TR("wallets_empty_hint"); + const ImU32 col = OnSurfaceDisabled(); + const ImVec2 is = hIco->CalcTextSizeA(hIco->LegacySize, FLT_MAX, 0, icon); + const ImVec2 ts = hTxt->CalcTextSizeA(hTxt->LegacySize, FLT_MAX, 0, hint); + const float gap = Layout::spacingXs(); + const ImVec2 o = ImGui::GetCursorScreenPos(); + const float cx = o.x + ImGui::GetContentRegionAvail().x * 0.5f; + const float top = o.y + (remainY - (is.y + gap + ts.y)) * 0.5f; + wdl->AddText(hIco, hIco->LegacySize, ImVec2(cx - is.x * 0.5f, top), col, icon); + wdl->AddText(hTxt, hTxt->LegacySize, ImVec2(cx - ts.x * 0.5f, top + is.y + gap), col, hint); + } + } ImGui::PopStyleVar(); // ItemSpacing ImGui::EndChild(); diff --git a/src/util/i18n.cpp b/src/util/i18n.cpp index 00c78d5..516e4f8 100644 --- a/src/util/i18n.cpp +++ b/src/util/i18n.cpp @@ -289,6 +289,7 @@ void I18n::loadBuiltinEnglish() strings_["wallets_scan_folder"] = "Scan another folder for wallets\xE2\x80\xA6"; strings_["wallets_scanned_folders"] = "Scanned folders:"; strings_["wallets_remove_folder"] = "Stop scanning this folder"; + strings_["wallets_empty_hint"] = "Scan a folder to find more wallets"; strings_["wallets_folder_invalid"] = "That folder doesn't exist."; strings_["wallets_new_label"] = "Create a new wallet:"; strings_["wallets_new_hint"] = "Name (e.g. savings)";