feat(node): show a live daemon console tail on the initializing overlay
The full-node Console tab already streams the daemon's output, but during startup the user is held on the loading overlay (wallet-data tabs are blocked), so they can't watch progress without navigating away. Surface the last few console lines the node printed (UpdateTip height=…, "Verifying blocks…", etc.) directly under the status/description on the overlay while initializing or warming up, so progress is visible where the user is already looking. Full-node only (guarded on daemon_controller_); each line is trimmed and ellipsis-truncated to one row. Reuses DaemonController::recentLines(). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
35
src/app.cpp
35
src/app.cpp
@@ -3318,6 +3318,41 @@ void App::renderLoadingOverlay(float contentH)
|
|||||||
curY += ts.y + gap;
|
curY += ts.y + gap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// 2c. Live daemon console tail (init/warmup only) — show the last few lines the node
|
||||||
|
// printed so the user can watch real progress (UpdateTip height=…, Verifying blocks…)
|
||||||
|
// without leaving the blocked overlay. Full-node only (lite has no daemon_controller_).
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
if ((state_.daemon_initializing || state_.warming_up) && daemon_controller_) {
|
||||||
|
const auto lines = daemon_controller_->recentLines(4);
|
||||||
|
if (!lines.empty()) {
|
||||||
|
ImFont* logFont = Type().caption();
|
||||||
|
if (!logFont) logFont = ImGui::GetFont();
|
||||||
|
const float blockW = std::min(ws.x * 0.8f, 560.0f);
|
||||||
|
const ImU32 logCol = IM_COL32(140, 150, 165, 150);
|
||||||
|
curY += gap * 0.5f;
|
||||||
|
for (const auto& raw : lines) {
|
||||||
|
// Trim trailing CR/whitespace; skip blanks.
|
||||||
|
std::string line = raw;
|
||||||
|
while (!line.empty() && (line.back() == '\r' || line.back() == '\n' ||
|
||||||
|
line.back() == ' ' || line.back() == '\t'))
|
||||||
|
line.pop_back();
|
||||||
|
if (line.empty()) continue;
|
||||||
|
// Truncate (with an ellipsis) to keep each line on one row within blockW.
|
||||||
|
if (logFont->CalcTextSizeA(logFont->LegacySize, FLT_MAX, 0.0f, line.c_str()).x > blockW) {
|
||||||
|
while (line.size() > 1 &&
|
||||||
|
logFont->CalcTextSizeA(logFont->LegacySize, FLT_MAX, 0.0f, (line + "…").c_str()).x > blockW)
|
||||||
|
line.pop_back();
|
||||||
|
line += "…";
|
||||||
|
}
|
||||||
|
dl->AddText(logFont, logFont->LegacySize,
|
||||||
|
ImVec2(wp.x + cx - blockW * 0.5f, curY), logCol, line.c_str());
|
||||||
|
curY += logFont->LegacySize + 2.0f;
|
||||||
|
}
|
||||||
|
curY += gap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// 3. Sync progress bar (if connected and syncing)
|
// 3. Sync progress bar (if connected and syncing)
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user