feat(lite): show connection + sync status in the Network tab
Add a status panel at the top of the Network tab driven by the live WalletState: - Connection: a colored dot + Connected / Syncing / Not connected, with the in-use server host (or "Random server") and its latency on the right. - Sync: "<pct>% · <walletHeight> / <chainHeight>" while syncing (with a thin progress bar), "Synced · block N" when complete, or "No wallet open" when disconnected. Reads app->state().sync (populated by the lite refresh: progress / wallet+chain height / complete) and state().connected (= walletOpen). Advances with a Dummy so the bounds grow correctly. Both variants build; suite passes; hygiene clean; lite GUI smoke OK. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "../../app.h"
|
||||
#include "../../config/settings.h"
|
||||
#include "../../data/wallet_state.h"
|
||||
#include "../../util/i18n.h"
|
||||
#include "../../util/lite_server_probe.h"
|
||||
#include "../../wallet/lite_connection_service.h"
|
||||
@@ -18,6 +19,7 @@
|
||||
#include "../../embedded/IconsMaterialDesign.h"
|
||||
#include "imgui.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <map>
|
||||
@@ -84,6 +86,70 @@ void RenderLiteNetworkTab(App* app)
|
||||
Type().textColored(TypeStyle::Caption, OnSurfaceMedium(), TR("lite_net_intro"));
|
||||
ImGui::Spacing();
|
||||
|
||||
// ── Connection + sync status panel ─────────────────────────────────────────
|
||||
{
|
||||
const WalletState& ws = app->state();
|
||||
const SyncInfo& sync = ws.sync;
|
||||
const bool connected = ws.connected;
|
||||
ImDrawList* sdl = ImGui::GetWindowDrawList();
|
||||
const float panelH = 56.0f * dp;
|
||||
const float panelW = ImGui::GetContentRegionAvail().x;
|
||||
const float pad2 = 12.0f * dp;
|
||||
ImVec2 pMin = ImGui::GetCursorScreenPos();
|
||||
ImVec2 pMax(pMin.x + panelW, pMin.y + panelH);
|
||||
GlassPanelSpec sspec; sspec.rounding = 8.0f * dp;
|
||||
DrawGlassPanel(sdl, pMin, pMax, sspec);
|
||||
|
||||
// Top row: status dot + connection label (left); in-use server + latency (right).
|
||||
ImU32 dotCol; const char* connLabel;
|
||||
if (!connected) { dotCol = OnSurfaceDisabled(); connLabel = TR("lite_net_disconnected"); }
|
||||
else if (sync.syncing) { dotCol = Warning(); connLabel = TR("lite_net_syncing"); }
|
||||
else { dotCol = Success(); connLabel = TR("lite_net_synced"); }
|
||||
const float dotR = 5.0f * dp;
|
||||
sdl->AddCircleFilled(ImVec2(pMin.x + pad2 + dotR, pMin.y + 17.0f * dp), dotR, dotCol);
|
||||
sdl->AddText(sub2, sub2->LegacySize, ImVec2(pMin.x + pad2 + dotR * 2 + 8.0f * dp, pMin.y + 9.0f * dp),
|
||||
OnSurface(), connLabel);
|
||||
|
||||
std::string inUse = randomMode ? std::string(TR("lite_net_random_server"))
|
||||
: (sticky.empty() ? std::string("—") : util::liteServerHost(sticky));
|
||||
if (!randomMode && !sticky.empty()) {
|
||||
const auto it = probe.find(sticky);
|
||||
if (it != probe.end() && it->second.online)
|
||||
inUse += " · " + std::to_string(it->second.latencyMs) + "ms";
|
||||
}
|
||||
const ImVec2 inUseSz = cap->CalcTextSizeA(cap->LegacySize, FLT_MAX, 0, inUse.c_str());
|
||||
sdl->AddText(cap, cap->LegacySize, ImVec2(pMax.x - pad2 - inUseSz.x, pMin.y + 12.0f * dp),
|
||||
OnSurfaceMedium(), inUse.c_str());
|
||||
|
||||
// Bottom row: sync detail + (while syncing) a thin progress bar.
|
||||
char syncBuf[96];
|
||||
if (!connected)
|
||||
snprintf(syncBuf, sizeof(syncBuf), "%s: %s", TR("lite_net_sync_label"), TR("lite_net_no_wallet"));
|
||||
else if (sync.syncing)
|
||||
snprintf(syncBuf, sizeof(syncBuf), "%s: %.1f%% · %d / %d", TR("lite_net_sync_label"),
|
||||
sync.verification_progress * 100.0, sync.blocks, sync.headers);
|
||||
else
|
||||
snprintf(syncBuf, sizeof(syncBuf), "%s: %s · block %d", TR("lite_net_sync_label"),
|
||||
TR("lite_net_synced"), sync.blocks);
|
||||
sdl->AddText(cap, cap->LegacySize, ImVec2(pMin.x + pad2, pMin.y + 32.0f * dp),
|
||||
OnSurfaceMedium(), syncBuf);
|
||||
if (connected && sync.syncing) {
|
||||
const float barY = pMin.y + panelH - 6.0f * dp;
|
||||
const float barX = pMin.x + pad2;
|
||||
const float barW = panelW - pad2 * 2;
|
||||
const float barH = 2.5f * dp;
|
||||
const float pct = static_cast<float>(std::max(0.0, std::min(1.0, sync.verification_progress)));
|
||||
sdl->AddRectFilled(ImVec2(barX, barY), ImVec2(barX + barW, barY + barH),
|
||||
WithAlpha(OnSurface(), 25), barH * 0.5f);
|
||||
if (pct > 0)
|
||||
sdl->AddRectFilled(ImVec2(barX, barY), ImVec2(barX + barW * pct, barY + barH),
|
||||
Primary(), barH * 0.5f);
|
||||
}
|
||||
|
||||
ImGui::Dummy(ImVec2(panelW, panelH)); // reserve the panel (proper boundary growth)
|
||||
ImGui::Spacing();
|
||||
}
|
||||
|
||||
bool useRandom = randomMode;
|
||||
if (ImGui::Checkbox(TR("lite_net_use_random"), &useRandom)) {
|
||||
st->setLiteServerSelectionMode(useRandom ? LiteMode::Random : LiteMode::Sticky);
|
||||
|
||||
@@ -1080,6 +1080,13 @@ void I18n::loadBuiltinEnglish()
|
||||
strings_["lite_net_unhide"] = "Unhide";
|
||||
strings_["lite_net_show_hidden"] = "Show hidden servers";
|
||||
strings_["lite_net_hidden_section"] = "Hidden servers";
|
||||
strings_["lite_net_connected"] = "Connected";
|
||||
strings_["lite_net_disconnected"] = "Not connected";
|
||||
strings_["lite_net_syncing"] = "Syncing";
|
||||
strings_["lite_net_synced"] = "Synced";
|
||||
strings_["lite_net_random_server"] = "Random server";
|
||||
strings_["lite_net_sync_label"] = "Sync";
|
||||
strings_["lite_net_no_wallet"] = "No wallet open";
|
||||
|
||||
// --- Peers Tab ---
|
||||
strings_["peers_avg_ping"] = "Avg Ping";
|
||||
|
||||
Reference in New Issue
Block a user