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:
@@ -742,9 +742,14 @@ void App::refreshData()
|
||||
state_.sync.headers = blockInfo["headers"].get<int>();
|
||||
if (blockInfo.contains("verificationprogress"))
|
||||
state_.sync.verification_progress = blockInfo["verificationprogress"].get<double>();
|
||||
state_.sync.syncing = (state_.sync.blocks < state_.sync.headers - 2);
|
||||
if (blockInfo.contains("longestchain"))
|
||||
state_.longestchain = blockInfo["longestchain"].get<int>();
|
||||
// Use longestchain (actual network tip) for sync check when available,
|
||||
// since headers can be inflated by misbehaving peers.
|
||||
if (state_.longestchain > 0)
|
||||
state_.sync.syncing = (state_.sync.blocks < state_.longestchain - 2);
|
||||
else
|
||||
state_.sync.syncing = (state_.sync.blocks < state_.sync.headers - 2);
|
||||
if (blockInfo.contains("notarized"))
|
||||
state_.notarized = blockInfo["notarized"].get<int>();
|
||||
}
|
||||
@@ -886,12 +891,12 @@ void App::refreshBalance()
|
||||
state_.sync.headers = blockInfo["headers"].get<int>();
|
||||
if (blockInfo.contains("verificationprogress"))
|
||||
state_.sync.verification_progress = blockInfo["verificationprogress"].get<double>();
|
||||
state_.sync.syncing = (state_.sync.blocks < state_.sync.headers - 2);
|
||||
|
||||
// Consolidate chain-tip fields that were previously fetched
|
||||
// via a separate getinfo call in refreshMiningInfo.
|
||||
if (blockInfo.contains("longestchain"))
|
||||
state_.longestchain = blockInfo["longestchain"].get<int>();
|
||||
if (state_.longestchain > 0)
|
||||
state_.sync.syncing = (state_.sync.blocks < state_.longestchain - 2);
|
||||
else
|
||||
state_.sync.syncing = (state_.sync.blocks < state_.sync.headers - 2);
|
||||
if (blockInfo.contains("notarized"))
|
||||
state_.notarized = blockInfo["notarized"].get<int>();
|
||||
}
|
||||
@@ -1182,7 +1187,7 @@ void App::refreshPrice()
|
||||
}
|
||||
|
||||
std::string response_data;
|
||||
const char* url = "https://api.coingecko.com/api/v3/simple/price?ids=hush&vs_currencies=usd,btc&include_24hr_change=true&include_24hr_vol=true&include_market_cap=true";
|
||||
const char* url = "https://api.coingecko.com/api/v3/simple/price?ids=dragonx-2&vs_currencies=usd,btc&include_24hr_change=true&include_24hr_vol=true&include_market_cap=true";
|
||||
|
||||
auto write_callback = [](void* contents, size_t size, size_t nmemb, std::string* userp) -> size_t {
|
||||
size_t totalSize = size * nmemb;
|
||||
@@ -1205,8 +1210,8 @@ void App::refreshPrice()
|
||||
|
||||
if (res == CURLE_OK && http_code == 200) {
|
||||
auto j = json::parse(response_data);
|
||||
if (j.contains("hush")) {
|
||||
const auto& data = j["hush"];
|
||||
if (j.contains("dragonx-2")) {
|
||||
const auto& data = j["dragonx-2"];
|
||||
market.price_usd = data.value("usd", 0.0);
|
||||
market.price_btc = data.value("btc", 0.0);
|
||||
market.change_24h = data.value("usd_24h_change", 0.0);
|
||||
|
||||
Reference in New Issue
Block a user