Refactor app services and stabilize refresh/UI flows

- Add refresh scheduler and network refresh service boundaries for typed
  refresh results, ordered RPC collectors, applicators, and price parsing.
- Add daemon lifecycle and wallet security workflow helpers while preserving
  App-owned command RPC, decrypt, cancellation, and UI handoff behavior.
- Split balance, console, mining, amount formatting, and async task logic into
  focused modules with expanded Phase 4 test coverage.
- Fix market price loading by triggering price refresh immediately, avoiding
  queue-pressure drops, tracking loading/error state, and adding translations.
- Polish send, explorer, peers, settings, theme/schema, and related tab UI.
- Replace checked-in generated language headers with build-generated resources.
- Document the cleanup audit, UI static-state guidance, and architecture updates.
This commit is contained in:
2026-04-29 12:47:57 -05:00
parent ee8a08e569
commit 9edab31728
95 changed files with 8776 additions and 37563 deletions

View File

@@ -21,6 +21,7 @@
#include <algorithm>
#include <unordered_map>
#include <cmath>
#include <string>
namespace dragonx {
namespace ui {
@@ -916,7 +917,7 @@ inline bool DrawDialogTitleBar(const char* title, bool* p_open, ImU32 accent_col
// Similar to the shutdown screen pattern but for interactive dialogs.
inline bool BeginOverlayDialog(const char* title, bool* p_open, float cardWidth = 460.0f, float scrimOpacity = 0.92f,
float cardBottomViewportRatio = 0.85f)
float cardBottomViewportRatio = 0.85f, const char* idSuffix = nullptr)
{
MarkOverlayDialogActive();
@@ -933,7 +934,16 @@ inline bool BeginOverlayDialog(const char* title, bool* p_open, float cardWidth
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
bool opened = ImGui::Begin("##OverlayScrim", nullptr,
std::string scrimId = "##OverlayScrim";
std::string childId = "##OverlayDialogContent";
if (idSuffix && idSuffix[0] != '\0') {
scrimId += "_";
scrimId += idSuffix;
childId += "_";
childId += idSuffix;
}
bool opened = ImGui::Begin(scrimId.c_str(), nullptr,
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar |
ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoNav |
@@ -983,7 +993,7 @@ inline bool BeginOverlayDialog(const char* title, bool* p_open, float cardWidth
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(28, 24));
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0, 0, 0, 0)); // Transparent - glass already drawn
bool childVisible = ImGui::BeginChild("##OverlayDialogContent",
bool childVisible = ImGui::BeginChild(childId.c_str(),
ImVec2(cardWidth, 0), // 0 height = auto-size
ImGuiChildFlags_AutoResizeY | ImGuiChildFlags_AlwaysUseWindowPadding,
ImGuiWindowFlags_NoScrollbar);
@@ -1007,6 +1017,23 @@ inline void EndOverlayDialog()
ImGui::PopStyleColor(); // WindowBg scrim
}
inline void PlaceOverlayDialogActions(float totalWidth)
{
float rowStartX = ImGui::GetCursorPosX();
float contentW = ImGui::GetContentRegionAvail().x;
ImGui::SetCursorPosX(rowStartX + std::max(0.0f, (contentW - totalWidth) * 0.5f));
}
inline void BeginOverlayDialogFooter(float totalActionWidth, bool drawSeparator = true)
{
ImGui::Spacing();
if (drawSeparator) {
ImGui::Separator();
ImGui::Spacing();
}
PlaceOverlayDialogActions(totalActionWidth);
}
} // namespace material
} // namespace ui
} // namespace dragonx