fix(ui): tidy Node maintenance layout + widen the Daemon binary panel
- Delete Blockchain and Repair Wallet now sit on one line, paired with the same uniform button width as Test Connection / Rescan Blockchain (a clean 2-column grid; all maintenance buttons share one rowBtnW sized across the four labels). - The Daemon binary panel lays Installed and Bundled side by side across the node column (version + size·date | version + size) instead of stacked narrow lines, with the status line spanning underneath and Install bundled / Refresh paired below. - Shorten the install button label to "Install bundled" so it fits the shared width; the tooltip still explains the full action. Date shown as YYYY-MM-DD. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2012,7 +2012,8 @@ void RenderSettingsPage(App* app) {
|
||||
float nodeBtnW;
|
||||
{
|
||||
if (btnFont) ImGui::PushFont(btnFont);
|
||||
nodeBtnW = rowBtnW({TR("test_connection"), TR("rescan")});
|
||||
nodeBtnW = rowBtnW({TR("test_connection"), TR("rescan"),
|
||||
TR("delete_blockchain"), TR("repair_wallet")});
|
||||
if (btnFont) ImGui::PopFont(/* btnFont */);
|
||||
}
|
||||
ImGui::SetCursorScreenPos(ImVec2(leftX, ImGui::GetCursorScreenPos().y));
|
||||
@@ -2045,20 +2046,16 @@ void RenderSettingsPage(App* app) {
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("%s", TR("tt_rescan"));
|
||||
ImGui::EndDisabled();
|
||||
|
||||
// Delete blockchain button (always available when using embedded daemon)
|
||||
// Row 2: Delete blockchain | Repair wallet (embedded daemon only) — paired on
|
||||
// one line with the same width/style as the Test connection | Rescan row above.
|
||||
ImGui::SetCursorScreenPos(ImVec2(leftX, ImGui::GetCursorScreenPos().y + Layout::spacingSm()));
|
||||
ImGui::BeginDisabled(!app->isUsingEmbeddedDaemon());
|
||||
if (TactileButton(TR("delete_blockchain"), ImVec2(0, 0), btnFont)) {
|
||||
if (TactileButton(TR("delete_blockchain"), ImVec2(nodeBtnW, 0), btnFont)) {
|
||||
s_settingsState.confirm_delete_blockchain = true;
|
||||
}
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("%s", TR("tt_delete_blockchain"));
|
||||
ImGui::EndDisabled();
|
||||
|
||||
// Repair wallet (-zapwallettxes=2): wipe & rebuild wallet tx/note records from
|
||||
// the chain (keys kept). Fixes notes that fail to spend after a rescan.
|
||||
ImGui::SetCursorScreenPos(ImVec2(leftX, ImGui::GetCursorScreenPos().y + Layout::spacingSm()));
|
||||
ImGui::BeginDisabled(!app->isUsingEmbeddedDaemon());
|
||||
if (TactileButton(TR("repair_wallet"), ImVec2(0, 0), btnFont)) {
|
||||
ImGui::SameLine(0, Layout::spacingMd());
|
||||
if (TactileButton(TR("repair_wallet"), ImVec2(nodeBtnW, 0), btnFont)) {
|
||||
s_settingsState.confirm_repair_wallet = true;
|
||||
}
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("%s", TR("tt_repair_wallet"));
|
||||
@@ -2086,7 +2083,7 @@ void RenderSettingsPage(App* app) {
|
||||
localtime_r(&t, &tmv);
|
||||
#endif
|
||||
char buf[32];
|
||||
std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M", &tmv);
|
||||
std::strftime(buf, sizeof(buf), "%Y-%m-%d", &tmv);
|
||||
return std::string(buf);
|
||||
};
|
||||
|
||||
@@ -2094,25 +2091,40 @@ void RenderSettingsPage(App* app) {
|
||||
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("daemon_binary"));
|
||||
ImGui::Dummy(ImVec2(0, Layout::spacingXs()));
|
||||
|
||||
// Installed | Bundled side by side, spanning the node column's width.
|
||||
const float dbStartY = ImGui::GetCursorScreenPos().y;
|
||||
const float dbLineH = ImGui::GetTextLineHeightWithSpacing();
|
||||
const float dbCol2X = leftX + leftColW * 0.5f;
|
||||
const ImVec4 dbDim = ImGui::ColorConvertU32ToFloat4(OnSurfaceMedium());
|
||||
|
||||
// Column 1 — Installed (version, then size · date)
|
||||
ImGui::SetCursorScreenPos(ImVec2(leftX, dbStartY));
|
||||
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("daemon_installed"));
|
||||
ImGui::SetCursorScreenPos(ImVec2(leftX, dbStartY + dbLineH));
|
||||
if (inst.exists) {
|
||||
ImGui::Text("%s %s", TR("daemon_installed"),
|
||||
inst.version.empty() ? TR("unknown") : inst.version.c_str());
|
||||
ImGui::TextColored(ImGui::ColorConvertU32ToFloat4(OnSurfaceMedium()), " %s · %s",
|
||||
ImGui::TextUnformatted(inst.version.empty() ? TR("unknown") : inst.version.c_str());
|
||||
ImGui::SetCursorScreenPos(ImVec2(leftX, dbStartY + dbLineH * 2));
|
||||
ImGui::TextColored(dbDim, "%s · %s",
|
||||
util::Platform::formatFileSize(inst.size).c_str(),
|
||||
fmtDate(inst.modifiedEpoch).c_str());
|
||||
} else {
|
||||
ImGui::Text("%s %s", TR("daemon_installed"), TR("daemon_not_installed"));
|
||||
ImGui::TextColored(dbDim, "%s", TR("daemon_not_installed"));
|
||||
}
|
||||
|
||||
// Column 2 — Bundled (version, then size)
|
||||
ImGui::SetCursorScreenPos(ImVec2(dbCol2X, dbStartY));
|
||||
Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("daemon_bundled"));
|
||||
ImGui::SetCursorScreenPos(ImVec2(dbCol2X, dbStartY + dbLineH));
|
||||
if (bun.available) {
|
||||
ImGui::Text("%s %s", TR("daemon_bundled"),
|
||||
bun.version.empty() ? TR("unknown") : bun.version.c_str());
|
||||
ImGui::TextColored(ImGui::ColorConvertU32ToFloat4(OnSurfaceMedium()), " %s",
|
||||
util::Platform::formatFileSize(bun.size).c_str());
|
||||
ImGui::TextUnformatted(bun.version.empty() ? TR("unknown") : bun.version.c_str());
|
||||
ImGui::SetCursorScreenPos(ImVec2(dbCol2X, dbStartY + dbLineH * 2));
|
||||
ImGui::TextColored(dbDim, "%s", util::Platform::formatFileSize(bun.size).c_str());
|
||||
} else {
|
||||
ImGui::Text("%s %s", TR("daemon_bundled"), TR("daemon_none_bundled"));
|
||||
ImGui::TextColored(dbDim, "%s", TR("daemon_none_bundled"));
|
||||
}
|
||||
|
||||
// Status line, below both sub-columns, spanning the node column.
|
||||
ImGui::SetCursorScreenPos(ImVec2(leftX, dbStartY + dbLineH * 3 + Layout::spacingXs()));
|
||||
if (bun.available) {
|
||||
const bool sameSize = inst.exists && inst.size == bun.size;
|
||||
if (!inst.exists)
|
||||
@@ -2124,15 +2136,16 @@ void RenderSettingsPage(App* app) {
|
||||
}
|
||||
|
||||
ImGui::Dummy(ImVec2(0, Layout::spacingXs()));
|
||||
// Install bundled daemon | Refresh — paired, same width/style as the rows above.
|
||||
ImGui::SetCursorScreenPos(ImVec2(leftX, ImGui::GetCursorScreenPos().y));
|
||||
ImGui::BeginDisabled(!app->isUsingEmbeddedDaemon() || !bun.available);
|
||||
if (TactileButton(TR("daemon_install_bundled"), ImVec2(0, 0), btnFont)) {
|
||||
if (TactileButton(TR("daemon_install_bundled"), ImVec2(nodeBtnW, 0), btnFont)) {
|
||||
s_settingsState.confirm_reinstall_daemon = true;
|
||||
}
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("%s", TR("tt_daemon_install_bundled"));
|
||||
ImGui::EndDisabled();
|
||||
ImGui::SameLine(0, Layout::spacingMd());
|
||||
if (TactileButton(TR("refresh"), ImVec2(0, 0), btnFont)) {
|
||||
if (TactileButton(TR("refresh"), ImVec2(nodeBtnW, 0), btnFont)) {
|
||||
s_settingsState.daemon_info_loaded = false; // recompute next frame
|
||||
}
|
||||
}
|
||||
|
||||
@@ -424,14 +424,14 @@ void I18n::loadBuiltinEnglish()
|
||||
strings_["confirm_repair_wallet_msg"] = "This restarts the daemon with -zapwallettxes=2: it deletes all of the wallet's transaction and note records, then rebuilds them from the blockchain. Use this when transactions fail to build (\"Invalid sapling spend proof\" / \"shielded requirements not met\") even after a full rescan. It takes a long time and the wallet stays offline until it finishes.";
|
||||
strings_["confirm_repair_wallet_safe"] = "Your keys, addresses and balance are preserved — only the cached transaction records are rebuilt.";
|
||||
strings_["daemon_binary"] = "Daemon binary";
|
||||
strings_["daemon_installed"] = "Installed:";
|
||||
strings_["daemon_bundled"] = "Bundled:";
|
||||
strings_["daemon_installed"] = "Installed";
|
||||
strings_["daemon_bundled"] = "Bundled";
|
||||
strings_["daemon_not_installed"] = "not installed";
|
||||
strings_["daemon_none_bundled"] = "none in this build";
|
||||
strings_["daemon_status_match"] = "Installed binary matches the bundled version.";
|
||||
strings_["daemon_status_differ"] = "Installed binary differs from the bundled version.";
|
||||
strings_["daemon_status_missing"] = "No daemon installed — install the bundled version.";
|
||||
strings_["daemon_install_bundled"] = "Install bundled daemon";
|
||||
strings_["daemon_install_bundled"] = "Install bundled";
|
||||
strings_["tt_daemon_install_bundled"] = "Stop the node, overwrite the installed dragonxd with the version bundled in this wallet build, then restart";
|
||||
strings_["confirm_reinstall_daemon_title"] = "Install Bundled Daemon";
|
||||
strings_["confirm_reinstall_daemon_msg"] = "This stops the daemon, overwrites the installed dragonxd (and dragonx-cli/dragonx-tx) with the versions bundled in this wallet build, then restarts the node. Use this to recover or update the node binary.";
|
||||
|
||||
Reference in New Issue
Block a user