feat: Full UI internationalization, pool hashrate stats, and layout caching
- Replace all hardcoded English strings with TR() translation keys across every tab, dialog, and component (~20 UI files) - Expand all 8 language files (de, es, fr, ja, ko, pt, ru, zh) with complete translations (~37k lines added) - Improve i18n loader with exe-relative path fallback and English base fallback for missing keys - Add pool-side hashrate polling via pool stats API in xmrig_manager - Introduce Layout::beginFrame() per-frame caching and refresh balance layout config only on schema generation change - Offload daemon output parsing to worker thread - Add CJK subset fallback font for Chinese/Japanese/Korean glyphs
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include "peers_tab.h"
|
||||
#include "../../app.h"
|
||||
#include "../../data/wallet_state.h"
|
||||
#include "../../util/i18n.h"
|
||||
#include "../theme.h"
|
||||
#include "../effects/imgui_acrylic.h"
|
||||
#include "../effects/low_spec.h"
|
||||
@@ -148,7 +149,7 @@ void RenderPeersTab(App* app)
|
||||
DrawGlassPanel(dl, cardMin, cardMax, glassSpec);
|
||||
|
||||
// Card header
|
||||
dl->AddText(ovFont, ovFont->LegacySize, ImVec2(cardMin.x + pad, cardMin.y + pad * 0.5f), Primary(), "BLOCKCHAIN");
|
||||
dl->AddText(ovFont, ovFont->LegacySize, ImVec2(cardMin.x + pad, cardMin.y + pad * 0.5f), Primary(), TR("peers_blockchain"));
|
||||
|
||||
float colW = (cardW - pad * 2) / 2.0f;
|
||||
float ry = cardMin.y + pad * 0.5f + headerH;
|
||||
@@ -165,10 +166,11 @@ void RenderPeersTab(App* app)
|
||||
{
|
||||
// Blocks
|
||||
float cx = cardMin.x + pad;
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Blocks");
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_blocks"));
|
||||
int blocks = state.sync.blocks;
|
||||
if (blocks > 0) {
|
||||
int blocksLeft = state.sync.headers - blocks;
|
||||
int chainTip = state.longestchain > 0 ? state.longestchain : state.sync.headers;
|
||||
int blocksLeft = chainTip - blocks;
|
||||
if (blocksLeft < 0) blocksLeft = 0;
|
||||
if (blocksLeft > 0) {
|
||||
snprintf(buf, sizeof(buf), "%d (%d left)", blocks, blocksLeft);
|
||||
@@ -180,7 +182,7 @@ void RenderPeersTab(App* app)
|
||||
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, valY), OnSurface(), blockStr);
|
||||
// Draw "(X left)" in warning color
|
||||
char leftStr[32];
|
||||
snprintf(leftStr, sizeof(leftStr), "(%d left)", blocksLeft);
|
||||
snprintf(leftStr, sizeof(leftStr), TR("peers_blocks_left"), blocksLeft);
|
||||
dl->AddText(capFont, capFont->LegacySize,
|
||||
ImVec2(cx + numSz.x, valY + (sub1->LegacySize - capFont->LegacySize) * 0.5f),
|
||||
Warning(), leftStr);
|
||||
@@ -194,7 +196,7 @@ void RenderPeersTab(App* app)
|
||||
|
||||
// Longest Chain
|
||||
cx = cardMin.x + pad + colW;
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Longest Chain");
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_longest_chain"));
|
||||
if (state.longestchain > 0) {
|
||||
snprintf(buf, sizeof(buf), "%d", state.longestchain);
|
||||
int localHeight = mining.blocks > 0 ? mining.blocks : state.sync.blocks;
|
||||
@@ -213,7 +215,7 @@ void RenderPeersTab(App* app)
|
||||
{
|
||||
// Hashrate
|
||||
float cx = cardMin.x + pad;
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Hashrate");
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_hashrate"));
|
||||
float valY = ry + capFont->LegacySize + Layout::spacingXs();
|
||||
if (mining.networkHashrate > 0) {
|
||||
if (mining.networkHashrate >= 1e12)
|
||||
@@ -233,7 +235,7 @@ void RenderPeersTab(App* app)
|
||||
|
||||
// Difficulty
|
||||
cx = cardMin.x + pad + colW;
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Difficulty");
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("difficulty"));
|
||||
valY = ry + capFont->LegacySize + Layout::spacingXs();
|
||||
if (mining.difficulty > 0) {
|
||||
snprintf(buf, sizeof(buf), "%.4f", mining.difficulty);
|
||||
@@ -251,7 +253,7 @@ void RenderPeersTab(App* app)
|
||||
{
|
||||
// Notarized
|
||||
float cx = cardMin.x + pad;
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Notarized");
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_notarized"));
|
||||
float valY = ry + capFont->LegacySize + Layout::spacingXs();
|
||||
if (state.notarized > 0) {
|
||||
snprintf(buf, sizeof(buf), "%d", state.notarized);
|
||||
@@ -262,7 +264,7 @@ void RenderPeersTab(App* app)
|
||||
|
||||
// Protocol
|
||||
cx = cardMin.x + pad + colW;
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Protocol");
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_protocol"));
|
||||
valY = ry + capFont->LegacySize + Layout::spacingXs();
|
||||
if (state.protocol_version > 0) {
|
||||
snprintf(buf, sizeof(buf), "%d", state.protocol_version);
|
||||
@@ -280,7 +282,7 @@ void RenderPeersTab(App* app)
|
||||
{
|
||||
// Version
|
||||
float cx = cardMin.x + pad;
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Version");
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_version"));
|
||||
float valY = ry + capFont->LegacySize + Layout::spacingXs();
|
||||
if (state.daemon_version > 0) {
|
||||
int major = state.daemon_version / 1000000;
|
||||
@@ -294,7 +296,7 @@ void RenderPeersTab(App* app)
|
||||
|
||||
// Memory
|
||||
cx = cardMin.x + pad + colW;
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Memory");
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_memory"));
|
||||
valY = ry + capFont->LegacySize + Layout::spacingXs();
|
||||
double memMb = state.mining.daemon_memory_mb;
|
||||
if (memMb > 0) {
|
||||
@@ -316,7 +318,7 @@ void RenderPeersTab(App* app)
|
||||
{
|
||||
// Longest Chain
|
||||
float cx = cardMin.x + pad;
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Longest");
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_longest"));
|
||||
float valY = ry + capFont->LegacySize + Layout::spacingXs();
|
||||
if (state.longestchain > 0) {
|
||||
snprintf(buf, sizeof(buf), "%d", state.longestchain);
|
||||
@@ -330,7 +332,7 @@ void RenderPeersTab(App* app)
|
||||
|
||||
// Best Block (truncated hash)
|
||||
cx = cardMin.x + pad + colW;
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Best Block");
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_best_block"));
|
||||
valY = ry + capFont->LegacySize + Layout::spacingXs();
|
||||
if (!state.sync.best_blockhash.empty()) {
|
||||
// Truncate hash to fit: first 6 + "..." + last 6
|
||||
@@ -349,14 +351,14 @@ void RenderPeersTab(App* app)
|
||||
ImGui::InvisibleButton("##BestBlockCopy", ImVec2(hashSz.x + Layout::spacingSm(), sub1->LegacySize + 2 * dp));
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
|
||||
ImGui::SetTooltip("Click to copy: %s", hash.c_str());
|
||||
ImGui::SetTooltip("%s %s", TR("peers_click_copy"), hash.c_str());
|
||||
dl->AddLine(ImVec2(cx, valY + sub1->LegacySize + 1 * dp),
|
||||
ImVec2(cx + hashSz.x, valY + sub1->LegacySize + 1 * dp),
|
||||
WithAlpha(OnSurface(), 60), 1.0f * dp);
|
||||
}
|
||||
if (ImGui::IsItemClicked()) {
|
||||
ImGui::SetClipboardText(hash.c_str());
|
||||
ui::Notifications::instance().info("Block hash copied");
|
||||
ui::Notifications::instance().info(TR("peers_hash_copied"));
|
||||
}
|
||||
} else {
|
||||
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, valY), OnSurfaceDisabled(), "\xE2\x80\x94");
|
||||
@@ -373,7 +375,7 @@ void RenderPeersTab(App* app)
|
||||
DrawGlassPanel(dl, cardMin, cardMax, glassSpec);
|
||||
|
||||
// Card header
|
||||
dl->AddText(ovFont, ovFont->LegacySize, ImVec2(cardMin.x + pad, cardMin.y + pad * 0.5f), Primary(), "PEERS");
|
||||
dl->AddText(ovFont, ovFont->LegacySize, ImVec2(cardMin.x + pad, cardMin.y + pad * 0.5f), Primary(), TR("peers_upper"));
|
||||
|
||||
float colW = (cardW - pad * 2) / 2.0f;
|
||||
float ry = cardMin.y + pad * 0.5f + headerH;
|
||||
@@ -390,13 +392,13 @@ void RenderPeersTab(App* app)
|
||||
{
|
||||
// Connected
|
||||
float cx = cardMin.x + pad;
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Connected");
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_connected"));
|
||||
snprintf(buf, sizeof(buf), "%d", totalPeers);
|
||||
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, ry + capFont->LegacySize + Layout::spacingXs()), OnSurface(), buf);
|
||||
|
||||
// In / Out
|
||||
cx = cardMin.x + pad + colW;
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "In / Out");
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_in_out"));
|
||||
snprintf(buf, sizeof(buf), "%d / %d", inboundCount, outboundCount);
|
||||
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, ry + capFont->LegacySize + Layout::spacingXs()), OnSurface(), buf);
|
||||
}
|
||||
@@ -426,7 +428,7 @@ void RenderPeersTab(App* app)
|
||||
|
||||
// Avg Ping
|
||||
cx = cardMin.x + pad + colW;
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Avg Ping");
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_avg_ping"));
|
||||
ImU32 pingCol;
|
||||
if (avgPing < 100) pingCol = Success();
|
||||
else if (avgPing < 500) pingCol = Warning();
|
||||
@@ -443,13 +445,13 @@ void RenderPeersTab(App* app)
|
||||
{
|
||||
// Received
|
||||
float cx = cardMin.x + pad;
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Received");
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_received"));
|
||||
std::string recvStr = fmtBytes(totalBytesRecv);
|
||||
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, ry + capFont->LegacySize + Layout::spacingXs()), OnSurface(), recvStr.c_str());
|
||||
|
||||
// Sent
|
||||
cx = cardMin.x + pad + colW;
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Sent");
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_sent"));
|
||||
std::string sentStr = fmtBytes(totalBytesSent);
|
||||
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, ry + capFont->LegacySize + Layout::spacingXs()), OnSurface(), sentStr.c_str());
|
||||
}
|
||||
@@ -462,7 +464,7 @@ void RenderPeersTab(App* app)
|
||||
{
|
||||
// P2P Port
|
||||
float cx = cardMin.x + pad;
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "P2P Port");
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_p2p_port"));
|
||||
float valY = ry + capFont->LegacySize + Layout::spacingXs();
|
||||
if (state.p2p_port > 0) {
|
||||
snprintf(buf, sizeof(buf), "%d", state.p2p_port);
|
||||
@@ -472,7 +474,7 @@ void RenderPeersTab(App* app)
|
||||
}
|
||||
// Banned count
|
||||
cx = cardMin.x + pad + colW;
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Banned");
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), TR("peers_banned"));
|
||||
valY = ry + capFont->LegacySize + Layout::spacingXs();
|
||||
size_t bannedCount = state.bannedPeers.size();
|
||||
snprintf(buf, sizeof(buf), "%zu", bannedCount);
|
||||
@@ -488,7 +490,7 @@ void RenderPeersTab(App* app)
|
||||
// Compute remaining space for peer list + footer
|
||||
// ================================================================
|
||||
float footerH = ImGui::GetFrameHeight() + Layout::spacingSm();
|
||||
float toggleH = body2->LegacySize + Layout::spacingMd() * 2;
|
||||
float toggleH = body2->LegacySize + Layout::spacingMd() * 2 + Layout::spacingSm();
|
||||
float remainForPeers = std::max(60.0f, peersAvail.y - (ImGui::GetCursorScreenPos().y - ImGui::GetWindowPos().y) - footerH - Layout::spacingSm());
|
||||
float peerPanelHeight = remainForPeers - toggleH;
|
||||
peerPanelHeight = std::max(S.drawElement("tabs.peers", "peer-panel-min-height").size, peerPanelHeight);
|
||||
@@ -502,8 +504,8 @@ void RenderPeersTab(App* app)
|
||||
float toggleY = ImGui::GetCursorScreenPos().y;
|
||||
{
|
||||
char connLabel[64], banLabel[64];
|
||||
snprintf(connLabel, sizeof(connLabel), "Connected (%zu)", state.peers.size());
|
||||
snprintf(banLabel, sizeof(banLabel), "Banned (%zu)", state.bannedPeers.size());
|
||||
snprintf(connLabel, sizeof(connLabel), TR("peers_connected_count"), state.peers.size());
|
||||
snprintf(banLabel, sizeof(banLabel), TR("peers_banned_count"), state.bannedPeers.size());
|
||||
|
||||
ImVec2 connSz = body2->CalcTextSizeA(body2->LegacySize, FLT_MAX, 0, connLabel);
|
||||
ImVec2 banSz = body2->CalcTextSizeA(body2->LegacySize, FLT_MAX, 0, banLabel);
|
||||
@@ -544,9 +546,14 @@ void RenderPeersTab(App* app)
|
||||
// Refresh button — top-right, glass panel style (similar to mining button)
|
||||
{
|
||||
bool isRefreshing = app->isPeerRefreshInProgress();
|
||||
auto refreshBtn = S.drawElement("tabs.peers", "refresh-button");
|
||||
float btnW = refreshBtn.size;
|
||||
float btnH = toggleH - 4.0f * Layout::dpiScale();
|
||||
ImFont* iconFont = Type().iconMed();
|
||||
float iconSz = iconFont->LegacySize;
|
||||
const char* label = isRefreshing ? TR("peers_refreshing") : TR("peers_refresh");
|
||||
ImVec2 lblSz = ovFont->CalcTextSizeA(ovFont->LegacySize, FLT_MAX, 0, label);
|
||||
float padH = Layout::spacingSm();
|
||||
float padV = Layout::spacingSm();
|
||||
float btnW = padH + iconSz + Layout::spacingXs() + lblSz.x + padH;
|
||||
float btnH = std::max(iconSz, lblSz.y) + padV * 2;
|
||||
float btnX = ImGui::GetWindowPos().x + availWidth - btnW - Layout::spacingSm();
|
||||
float btnY = toggleY + (toggleH - btnH) * 0.5f;
|
||||
ImVec2 bMin(btnX, btnY);
|
||||
@@ -574,10 +581,8 @@ void RenderPeersTab(App* app)
|
||||
}
|
||||
|
||||
// Icon: spinner while refreshing, refresh icon otherwise
|
||||
float cx = bMin.x + btnW * 0.35f;
|
||||
float cx = bMin.x + padH + iconSz * 0.5f;
|
||||
float cy = bMin.y + btnH * 0.5f;
|
||||
ImFont* iconFont = Type().iconMed();
|
||||
float iconSz = iconFont->LegacySize;
|
||||
|
||||
if (isRefreshing) {
|
||||
// Spinning arc spinner (same style as mining toggle)
|
||||
@@ -617,7 +622,6 @@ void RenderPeersTab(App* app)
|
||||
|
||||
// Label to the right of icon
|
||||
{
|
||||
const char* label = isRefreshing ? "REFRESHING" : "REFRESH";
|
||||
ImU32 lblCol;
|
||||
if (isRefreshing) {
|
||||
float pulse = effects::isLowSpecMode()
|
||||
@@ -627,7 +631,6 @@ void RenderPeersTab(App* app)
|
||||
} else {
|
||||
lblCol = btnHovered ? OnSurface() : WithAlpha(OnSurface(), 160);
|
||||
}
|
||||
ImVec2 lblSz = ovFont->CalcTextSizeA(ovFont->LegacySize, FLT_MAX, 0, label);
|
||||
float lblX = cx + iconSz * 0.5f + Layout::spacingXs();
|
||||
float lblY = cy - lblSz.y * 0.5f;
|
||||
dl->AddText(ovFont, ovFont->LegacySize, ImVec2(lblX, lblY), lblCol, label);
|
||||
@@ -645,7 +648,7 @@ void RenderPeersTab(App* app)
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
|
||||
if (!isRefreshing)
|
||||
ImGui::SetTooltip("Refresh peers & blockchain");
|
||||
ImGui::SetTooltip("%s", TR("peers_refresh_tooltip"));
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
@@ -673,10 +676,10 @@ void RenderPeersTab(App* app)
|
||||
// ---- Connected Peers ----
|
||||
if (!app->isConnected()) {
|
||||
ImGui::Dummy(ImVec2(0, 20));
|
||||
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), " Not connected to daemon...");
|
||||
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), TR("not_connected"));
|
||||
} else if (state.peers.empty()) {
|
||||
ImGui::Dummy(ImVec2(0, 20));
|
||||
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), " No connected peers");
|
||||
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), TR("peers_no_connected"));
|
||||
} else {
|
||||
float rowH = body2->LegacySize + capFont->LegacySize + Layout::spacingLg();
|
||||
float rowInset = Layout::spacingLg();
|
||||
@@ -727,7 +730,7 @@ void RenderPeersTab(App* app)
|
||||
}
|
||||
|
||||
{
|
||||
const char* dirLabel = peer.inbound ? "In" : "Out";
|
||||
const char* dirLabel = peer.inbound ? TR("peers_dir_in") : TR("peers_dir_out");
|
||||
ImU32 dirBg = peer.inbound ? WithAlpha(Success(), 30) : WithAlpha(Secondary(), 30);
|
||||
ImU32 dirFg = peer.inbound ? WithAlpha(Success(), 200) : WithAlpha(Secondary(), 200);
|
||||
ImVec2 dirSz = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0, dirLabel);
|
||||
@@ -761,12 +764,12 @@ void RenderPeersTab(App* app)
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(tlsMin.x + 4, cy2 + 1), tlsFg, "TLS");
|
||||
} else {
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx + S.drawElement("tabs.peers", "address-x-offset").size + verW + Layout::spacingSm(), cy2),
|
||||
WithAlpha(Error(), 140), "No TLS");
|
||||
WithAlpha(Error(), 140), TR("peers_no_tls"));
|
||||
}
|
||||
|
||||
if (peer.banscore > 0) {
|
||||
char banBuf[16];
|
||||
snprintf(banBuf, sizeof(banBuf), "Ban: %d", peer.banscore);
|
||||
snprintf(banBuf, sizeof(banBuf), TR("peers_ban_score"), peer.banscore);
|
||||
ImU32 banCol = peer.banscore > 50 ? Error() : Warning();
|
||||
ImVec2 banSz = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0, banBuf);
|
||||
dl->AddText(capFont, capFont->LegacySize,
|
||||
@@ -780,16 +783,16 @@ void RenderPeersTab(App* app)
|
||||
|
||||
const auto& acrylicTheme = GetCurrentAcrylicTheme();
|
||||
if (effects::ImGuiAcrylic::BeginAcrylicContextItem(nullptr, 0, acrylicTheme.menu)) {
|
||||
ImGui::Text("Peer: %s", peer.addr.c_str());
|
||||
ImGui::Text(TR("peers_peer_label"), peer.addr.c_str());
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Copy Address")) {
|
||||
if (ImGui::MenuItem(TR("copy_address"))) {
|
||||
ImGui::SetClipboardText(peer.addr.c_str());
|
||||
}
|
||||
if (ImGui::MenuItem("Copy IP")) {
|
||||
if (ImGui::MenuItem(TR("peers_copy_ip"))) {
|
||||
ImGui::SetClipboardText(ExtractIP(peer.addr).c_str());
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Ban Peer (24h)")) {
|
||||
if (ImGui::MenuItem(TR("peers_ban_24h"))) {
|
||||
app->banPeer(ExtractIP(peer.addr), 86400);
|
||||
}
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
@@ -808,18 +811,18 @@ void RenderPeersTab(App* app)
|
||||
};
|
||||
char ttBuf[128];
|
||||
snprintf(ttBuf, sizeof(ttBuf), "%d", peer.id);
|
||||
TTRow("ID", ttBuf);
|
||||
TTRow("Services", peer.services.c_str());
|
||||
TTRow(TR("peers_tt_id"), ttBuf);
|
||||
TTRow(TR("peers_tt_services"), peer.services.c_str());
|
||||
snprintf(ttBuf, sizeof(ttBuf), "%d", peer.startingheight);
|
||||
TTRow("Start Height", ttBuf);
|
||||
TTRow(TR("peers_tt_start_height"), ttBuf);
|
||||
snprintf(ttBuf, sizeof(ttBuf), "%ld bytes", peer.bytessent);
|
||||
TTRow("Sent", ttBuf);
|
||||
TTRow(TR("peers_tt_sent"), ttBuf);
|
||||
snprintf(ttBuf, sizeof(ttBuf), "%ld bytes", peer.bytesrecv);
|
||||
TTRow("Received", ttBuf);
|
||||
TTRow(TR("peers_tt_received"), ttBuf);
|
||||
snprintf(ttBuf, sizeof(ttBuf), "%d / %d", peer.synced_headers, peer.synced_blocks);
|
||||
TTRow("Synced H/B", ttBuf);
|
||||
TTRow(TR("peers_tt_synced"), ttBuf);
|
||||
if (!peer.tls_cipher.empty())
|
||||
TTRow("TLS Cipher", peer.tls_cipher.c_str());
|
||||
TTRow(TR("peers_tt_tls_cipher"), peer.tls_cipher.c_str());
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
@@ -840,10 +843,10 @@ void RenderPeersTab(App* app)
|
||||
// ---- Banned Peers ----
|
||||
if (!app->isConnected()) {
|
||||
ImGui::Dummy(ImVec2(0, 20));
|
||||
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), " Not connected to daemon...");
|
||||
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), TR("not_connected"));
|
||||
} else if (state.bannedPeers.empty()) {
|
||||
ImGui::Dummy(ImVec2(0, 20));
|
||||
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), " No banned peers");
|
||||
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), TR("peers_no_banned"));
|
||||
} else {
|
||||
float rowH = capFont->LegacySize + S.drawElement("tabs.peers", "banned-row-height-padding").size;
|
||||
float rowInsetB = pad;
|
||||
@@ -886,7 +889,7 @@ void RenderPeersTab(App* app)
|
||||
|
||||
float btnX = rowPos.x + innerW - Layout::spacingXl() * S.drawElement("tabs.peers", "unban-btn-right-offset-multiplier").size;
|
||||
ImGui::SetCursorScreenPos(ImVec2(btnX, cy - 1));
|
||||
if (TactileSmallButton("Unban", S.resolveFont("button"))) {
|
||||
if (TactileSmallButton(TR("peers_unban"), S.resolveFont("button"))) {
|
||||
app->unbanPeer(banned.address);
|
||||
}
|
||||
|
||||
@@ -898,10 +901,10 @@ void RenderPeersTab(App* app)
|
||||
|
||||
const auto& acrylicTheme2 = GetCurrentAcrylicTheme();
|
||||
if (effects::ImGuiAcrylic::BeginAcrylicContextItem(nullptr, 0, acrylicTheme2.menu)) {
|
||||
if (ImGui::MenuItem("Copy Address")) {
|
||||
if (ImGui::MenuItem(TR("copy_address"))) {
|
||||
ImGui::SetClipboardText(banned.address.c_str());
|
||||
}
|
||||
if (ImGui::MenuItem("Unban")) {
|
||||
if (ImGui::MenuItem(TR("peers_unban"))) {
|
||||
app->unbanPeer(banned.address);
|
||||
}
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
@@ -940,7 +943,7 @@ void RenderPeersTab(App* app)
|
||||
// ================================================================
|
||||
if (s_show_banned && !state.bannedPeers.empty()) {
|
||||
ImGui::BeginDisabled(!app->isConnected());
|
||||
if (TactileSmallButton("Clear All Bans", S.resolveFont("button"))) {
|
||||
if (TactileSmallButton(TR("peers_clear_all_bans"), S.resolveFont("button"))) {
|
||||
app->clearBans();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
Reference in New Issue
Block a user