fix(node): show recovery actions in the daemon-error overlay (not a separate dialog)
Reported with a screenshot: on a salvage-then-abort, the status correctly read "Wallet needs recovery — see the prompt" but no prompt appeared — the separate BeginOverlayDialog is occluded by the full-frame loading/daemon-error overlay that's drawn every frame while the node is down. Render the recovery actions directly IN the daemon-error overlay when a salvage is detected: a concise message + prominent one-click "Rebuild wallet database" / "Restore original" / "Open data folder" buttons (same handlers as the dialog), placed right after the title and skipping the verbose daemon-output dump so they stay on-screen. The verbose diagnostics + crash-count hint still show for non-recovery errors. Build clean, suite green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
64
src/app.cpp
64
src/app.cpp
@@ -5679,26 +5679,50 @@ void App::renderLoadingOverlay(float contentH)
|
|||||||
IM_COL32(255, 90, 90, 255), errTitle);
|
IM_COL32(255, 90, 90, 255), errTitle);
|
||||||
curY += ts.y + gap * 0.5f;
|
curY += ts.y + gap * 0.5f;
|
||||||
|
|
||||||
// Error details (wrapped) — show full diagnostic info
|
// Wallet auto-recovery/salvage takes over the error card: a concise message + prominent one-click
|
||||||
const std::string& errDetail = daemon_controller_->lastError();
|
// actions, RIGHT HERE in the overlay the user is looking at (the separate dialog can be occluded
|
||||||
if (!errDetail.empty()) {
|
// by this full-frame overlay while the node is down). Skip the verbose daemon dump so the buttons
|
||||||
float wrapW = ws.x * 0.8f;
|
// stay on-screen. Same handlers as the dialog.
|
||||||
if (wrapW > 700.0f) wrapW = 700.0f;
|
if (wallet_auto_recovered_) {
|
||||||
ImVec2 es = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, wrapW, errDetail.c_str());
|
const char* msg = TR("wallet_recovered_warn");
|
||||||
dl->AddText(capFont, capFont->LegacySize,
|
float wrapW = ws.x * 0.8f; if (wrapW > 640.0f) wrapW = 640.0f;
|
||||||
ImVec2(wp.x + cx - wrapW * 0.5f, curY),
|
ImVec2 ms = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, wrapW, msg);
|
||||||
IM_COL32(255, 180, 180, 220), errDetail.c_str(), nullptr, wrapW);
|
dl->AddText(capFont, capFont->LegacySize, ImVec2(wp.x + cx - wrapW * 0.5f, curY),
|
||||||
curY += es.y + gap;
|
IM_COL32(230, 210, 210, 235), msg, nullptr, wrapW);
|
||||||
}
|
curY += ms.y + gap;
|
||||||
|
const float dpi = ui::Layout::dpiScale();
|
||||||
// Crash count hint
|
const float bw = 340.0f * dpi;
|
||||||
if (daemon_controller_->crashCount() >= 3) {
|
auto placeBtn = [&](const char* label) -> bool {
|
||||||
const char* hint = "Use Settings > Restart Daemon to try again";
|
ImGui::SetCursorScreenPos(ImVec2(wp.x + cx - bw * 0.5f, curY));
|
||||||
ImVec2 hs2 = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0.0f, hint);
|
const bool clicked = ui::material::TactileButton(label, ImVec2(bw, 0));
|
||||||
dl->AddText(capFont, capFont->LegacySize,
|
curY = ImGui::GetItemRectMax().y + gap * 0.4f;
|
||||||
ImVec2(wp.x + cx - hs2.x * 0.5f, curY),
|
return clicked;
|
||||||
IM_COL32(200, 200, 200, 180), hint);
|
};
|
||||||
curY += hs2.y + gap;
|
if (walletRebuildAvailable() && placeBtn(TR("wallet_recovered_rebuild"))) rebuildWalletDatabase();
|
||||||
|
if (placeBtn(TR("wallet_recovered_restore"))) restoreOriginalWallet();
|
||||||
|
if (placeBtn(TR("wallet_recovered_open_folder")))
|
||||||
|
util::Platform::openFolder(util::Platform::getDragonXDataDir());
|
||||||
|
} else {
|
||||||
|
// Error details (wrapped) — full diagnostic info.
|
||||||
|
const std::string& errDetail = daemon_controller_->lastError();
|
||||||
|
if (!errDetail.empty()) {
|
||||||
|
float wrapW = ws.x * 0.8f;
|
||||||
|
if (wrapW > 700.0f) wrapW = 700.0f;
|
||||||
|
ImVec2 es = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, wrapW, errDetail.c_str());
|
||||||
|
dl->AddText(capFont, capFont->LegacySize,
|
||||||
|
ImVec2(wp.x + cx - wrapW * 0.5f, curY),
|
||||||
|
IM_COL32(255, 180, 180, 220), errDetail.c_str(), nullptr, wrapW);
|
||||||
|
curY += es.y + gap;
|
||||||
|
}
|
||||||
|
// Crash count hint
|
||||||
|
if (daemon_controller_->crashCount() >= 3) {
|
||||||
|
const char* hint = "Use Settings > Restart Daemon to try again";
|
||||||
|
ImVec2 hs2 = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0.0f, hint);
|
||||||
|
dl->AddText(capFont, capFont->LegacySize,
|
||||||
|
ImVec2(wp.x + cx - hs2.x * 0.5f, curY),
|
||||||
|
IM_COL32(200, 200, 200, 180), hint);
|
||||||
|
curY += hs2.y + gap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user