feat(ui): in-app FAQ, DPI-scaling audit fixes, mining/stratum polish + localize strings

Bundles the session's UI work (the touched files carry several of these
changes together, so they are committed as one coherent UI batch):

- FAQ: new RenderFaqDialog + data-driven faq_content, opened from a
  status-bar "?" (and the Windows title bar), styled like the Wallets
  modal with search, Wallet/Daemon tabs, and smooth scroll.
- DPI/font-scale audit: multiply hand-drawn absolute geometry by
  Layout::dpiScale() across ~30 files so nothing renders native-size at
  HiDPI / font_scale 1.5 (verified with a full sweep at 1.5x).
- Mining: chart now fills the horizontal space; thread stepper +/- buttons
  match the input-box height; move the stratum-host toggle into
  Node & Security (v1.3.0+).
- Settings: fix the auto-shield status text overlapping the grid.
- Sidebar: drop the peer-count badge on the Network button.
- i18n: wrap 193 hardcoded literals with TR() (keys/translations added in
  the preceding i18n commit), so the security/PIN/lock flow, seed-backup
  wizard, and witness-rebuild dialog localize.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-01 19:37:16 -05:00
co-authored by Claude Opus 4.8
parent ed675f90d8
commit d27f387d6d
35 changed files with 867 additions and 366 deletions
+11 -10
View File
@@ -925,7 +925,7 @@ inline void DrawStatCard(ImDrawList* dl,
// Draw a full-height rounded rect with card rounding (left corners)
// and clip to stripe width so the shape follows the corner radius.
if ((card.accentCol & IM_COL32_A_MASK) != 0) {
float stripeW = 4.0f;
float stripeW = 4.0f * Layout::dpiScale();
dl->PushClipRect(cMin, ImVec2(cMin.x + stripeW, cMax.y), true);
dl->AddRectFilled(cMin, cMax, card.accentCol, rnd,
ImDrawFlags_RoundCornersLeft);
@@ -1282,7 +1282,8 @@ inline bool DrawDialogTitleBar(const char* title, bool* p_open, ImU32 accent_col
ImDrawList* dl = ImGui::GetWindowDrawList();
ImVec2 winPos = ImGui::GetWindowPos();
float winWidth = ImGui::GetWindowWidth();
float barHeight = 36.0f;
const float dp = Layout::dpiScale();
float barHeight = 36.0f * dp;
// Get accent color from theme if not provided
if (!accent_col) {
@@ -1306,15 +1307,15 @@ inline bool DrawDialogTitleBar(const char* title, bool* p_open, ImU32 accent_col
ImFont* titleFont = Type().subtitle1();
ImGui::PushFont(titleFont);
ImVec2 titleSize = ImGui::CalcTextSize(title);
float titleX = barMin.x + 16.0f;
float titleX = barMin.x + 16.0f * dp;
float titleY = barMin.y + (barHeight - titleSize.y) * 0.5f;
DrawTextShadow(dl, ImVec2(titleX, titleY), OnSurface(), title);
ImGui::PopFont();
// Close button (X) on right side
if (p_open) {
float btnSize = 24.0f;
float btnX = barMax.x - btnSize - 12.0f;
float btnSize = 24.0f * dp;
float btnX = barMax.x - btnSize - 12.0f * dp;
float btnY = barMin.y + (barHeight - btnSize) * 0.5f;
ImVec2 btnMin(btnX, btnY);
ImVec2 btnMax(btnX + btnSize, btnY + btnSize);
@@ -1327,7 +1328,7 @@ inline bool DrawDialogTitleBar(const char* title, bool* p_open, ImU32 accent_col
// Button background on hover
if (hovered) {
dl->AddRectFilled(btnMin, btnMax, IM_COL32(255, 255, 255, held ? 40 : 25), 4.0f);
dl->AddRectFilled(btnMin, btnMax, IM_COL32(255, 255, 255, held ? 40 : 25), 4.0f * dp);
}
// Draw X icon
@@ -1348,7 +1349,7 @@ inline bool DrawDialogTitleBar(const char* title, bool* p_open, ImU32 accent_col
}
// Reserve space for title bar so content starts below it
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + barHeight + 8.0f);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + barHeight + 8.0f * dp);
return closeClicked;
}
@@ -1648,7 +1649,7 @@ inline bool BeginOverlayDialog(const OverlayDialogSpec& spec)
// Fill/border alpha govern every overlay dialog's card boundary — kept well above the default
// glass panel so the card reads as a distinct surface over busy backdrops (tx lists, mining
// tiles, chat) while staying translucent rather than opaque.
cardGlass.rounding = 16.0f; cardGlass.fillAlpha = 60; cardGlass.borderAlpha = 90; cardGlass.borderWidth = 1.0f;
cardGlass.rounding = 16.0f * dp; cardGlass.fillAlpha = 60; cardGlass.borderAlpha = 90; cardGlass.borderWidth = 1.0f;
DrawGlassPanel(dl, cardMin, cardMax, cardGlass);
}
@@ -1662,8 +1663,8 @@ inline bool BeginOverlayDialog(const OverlayDialogSpec& spec)
// Content child.
ImGui::SetCursorScreenPos(ImVec2(cardX, cardY));
ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, floating ? 20.0f : 16.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, floating ? ImVec2(28, 20) : ImVec2(28, 24));
ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, floating ? 20.0f * dp : 16.0f * dp);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, floating ? ImVec2(28 * dp, 20 * dp) : ImVec2(28 * dp, 24 * dp));
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0, 0, 0, 0)); // transparent (glass/blur behind)
// A card with a known height is a fixed frame (fixed-height dialogs, and auto-height dialogs whose
// content overflowed the viewport); otherwise the child auto-resizes to its content.