Mechanical, behavior-preserving consolidations from the audit. Rendering extractions were kept byte-equivalent; sites that couldn't be made identical were left as-is (noted below). Shared helpers: - util::truncateMiddle(s,maxLen) / (s,front,back) in text_format.h — replaces 6 file-local middle-ellipsis truncators + several inline substr sites (send/receive/transactions/balance_recent_tx/explorer + app.cpp + 3 dialogs). Carries the maxLen<=3 guard, fixing the latent unsigned-underflow copies. - material::LoadingDots() in draw_helpers.h — one animated-ellipsis source for 8 copy-pasted spinner sites (identical GetTime()*3 phase preserved). - Reuse the existing FormatHashrate() in explorer_tab + peers_tab (dropped two inline hashrate ladders). - material::DrawButtonGlassOverlay() — the glass-fill/rim/tactile overlay block shared by TactileButton / TactileSmallButton / schema TactileButton. - material::CollapsibleHeader() — the invisible-button + label + chevron idiom (3 of 5 settings_page sites; RPC/Debug headers skipped — non-identical). - material::GlassCardScope (RAII) — the ChannelsSplit/Indent/DrawGlassPanel/ ChannelsMerge card scaffold (5 settings_page cards; About/send/receive skipped — different padding / logo interleaving). - material::DialogWarningHeader()/DialogConfirmFooter() — warning header + 50/50 Cancel/danger footer across the confirm dialogs; button height moved from a hardcoded 40px into ui.toml (components.overlay-dialog.confirm-btn-height). - File-local enterLowSpec()/exitLowSpec() collapse the 3 low-spec snapshot copies. i18n: wrapped hardcoded English in the shared balance render paths and the whole Lite lifecycle/security section in TR(), with English defaults added to loadBuiltinEnglish() (res/lang/*.json left for the translation tooling — TR falls back to English, so output is unchanged). Full-node + Lite build clean; ctest 1/1; hygiene clean. These are rendering changes — the Settings page (cards/headers/confirm dialogs), all tactile buttons, and the Lite settings section warrant a screenshot check. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
106 lines
3.0 KiB
C++
106 lines
3.0 KiB
C++
#include "balance_tab_helpers.h"
|
|
|
|
#include "../../config/version.h"
|
|
#include "../../embedded/IconsMaterialDesign.h"
|
|
#include "../../util/i18n.h"
|
|
#include "../../util/text_format.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;
|
|
}
|
|
|
|
// Thin wrappers over the shared, allocation-free helpers (kept for existing call sites).
|
|
bool containsIgnoreCase(const std::string& value, const std::string& search)
|
|
{
|
|
return util::containsIgnoreCase(value, search);
|
|
}
|
|
|
|
std::string timeAgo(int64_t timestamp)
|
|
{
|
|
return util::formatTimeAgoShort(timestamp);
|
|
}
|
|
|
|
std::string truncateAddress(const std::string& address, int maxLen)
|
|
{
|
|
return util::truncateMiddle(address, maxLen);
|
|
}
|
|
|
|
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
|