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:
117
src/ui/windows/balance_tab_helpers.cpp
Normal file
117
src/ui/windows/balance_tab_helpers.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
#include "balance_tab_helpers.h"
|
||||
|
||||
#include "../../config/version.h"
|
||||
#include "../../embedded/IconsMaterialDesign.h"
|
||||
#include "../../util/i18n.h"
|
||||
#include "../material/colors.h"
|
||||
#include "../material/type.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
|
||||
namespace dragonx {
|
||||
namespace ui {
|
||||
|
||||
std::string TrId(const char* trKey, const char* id)
|
||||
{
|
||||
std::string value = TR(trKey);
|
||||
value += "##";
|
||||
value += id;
|
||||
return value;
|
||||
}
|
||||
|
||||
bool containsIgnoreCase(const std::string& value, const std::string& search)
|
||||
{
|
||||
if (search.empty()) return true;
|
||||
std::string haystack = value;
|
||||
std::string needle = search;
|
||||
std::transform(haystack.begin(), haystack.end(), haystack.begin(), ::tolower);
|
||||
std::transform(needle.begin(), needle.end(), needle.begin(), ::tolower);
|
||||
return haystack.find(needle) != std::string::npos;
|
||||
}
|
||||
|
||||
std::string timeAgo(int64_t timestamp)
|
||||
{
|
||||
if (timestamp <= 0) return "";
|
||||
int64_t now = static_cast<int64_t>(std::time(nullptr));
|
||||
int64_t diff = now - timestamp;
|
||||
if (diff < 0) diff = 0;
|
||||
if (diff < 60) return std::to_string(diff) + "s ago";
|
||||
if (diff < 3600) return std::to_string(diff / 60) + "m ago";
|
||||
if (diff < 86400) return std::to_string(diff / 3600) + "h ago";
|
||||
return std::to_string(diff / 86400) + "d ago";
|
||||
}
|
||||
|
||||
std::string truncateAddress(const std::string& address, int maxLen)
|
||||
{
|
||||
if (address.length() <= static_cast<size_t>(maxLen)) return address;
|
||||
int half = (maxLen - 3) / 2;
|
||||
return address.substr(0, half) + "..." + address.substr(address.length() - half);
|
||||
}
|
||||
|
||||
ImU32 recentTxIconColor(const std::string& type)
|
||||
{
|
||||
using namespace material;
|
||||
if (type == "send") return Error();
|
||||
if (type == "receive") return Success();
|
||||
return Warning();
|
||||
}
|
||||
|
||||
ImU32 recentTxAmountColor(const std::string& type)
|
||||
{
|
||||
using namespace material;
|
||||
return type == "send" ? Error() : Success();
|
||||
}
|
||||
|
||||
std::string formatRecentTxAmount(const std::string& type, double amount)
|
||||
{
|
||||
char buffer[32];
|
||||
snprintf(buffer, sizeof(buffer), "%s%.4f %s",
|
||||
type == "send" ? "-" : "+",
|
||||
std::abs(amount), DRAGONX_TICKER);
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
void DrawTxIcon(ImDrawList* drawList, const std::string& type,
|
||||
float centerX, float centerY, float, ImU32 color)
|
||||
{
|
||||
using namespace material;
|
||||
ImFont* iconFont = Type().iconSmall();
|
||||
const char* icon = ICON_MD_CONSTRUCTION;
|
||||
if (type == "send") {
|
||||
icon = ICON_MD_CALL_MADE;
|
||||
} else if (type == "receive") {
|
||||
icon = ICON_MD_CALL_RECEIVED;
|
||||
}
|
||||
ImVec2 size = iconFont->CalcTextSizeA(iconFont->LegacySize, 1000.0f, 0.0f, icon);
|
||||
drawList->AddText(iconFont, iconFont->LegacySize,
|
||||
ImVec2(centerX - size.x * 0.5f, centerY - size.y * 0.5f), color, icon);
|
||||
}
|
||||
|
||||
void DrawSparkline(ImDrawList* drawList, const ImVec2& min, const ImVec2& max,
|
||||
const std::vector<double>& data, ImU32 color, float thickness)
|
||||
{
|
||||
if (data.size() < 2) return;
|
||||
double low = *std::min_element(data.begin(), data.end());
|
||||
double high = *std::max_element(data.begin(), data.end());
|
||||
double range = high - low;
|
||||
if (range < 1e-12) range = 1.0;
|
||||
|
||||
float width = max.x - min.x;
|
||||
float height = max.y - min.y;
|
||||
int count = static_cast<int>(data.size());
|
||||
|
||||
std::vector<ImVec2> points;
|
||||
points.reserve(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
float x = min.x + static_cast<float>(i) / static_cast<float>(count - 1) * width;
|
||||
float y = max.y - static_cast<float>((data[i] - low) / range) * height;
|
||||
points.push_back(ImVec2(x, y));
|
||||
}
|
||||
drawList->AddPolyline(points.data(), count, color, ImDrawFlags_None, thickness);
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
} // namespace dragonx
|
||||
Reference in New Issue
Block a user