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:
@@ -128,22 +128,19 @@ void RequestPaymentDialog::render(App* app)
|
||||
auto qr = S.drawElement("dialogs.request-payment", "qr-code");
|
||||
auto actionBtn = S.button("dialogs.request-payment", "action-button");
|
||||
|
||||
if (material::BeginOverlayDialog("Request Payment", &s_open, win.width, 0.94f)) {
|
||||
if (material::BeginOverlayDialog(TR("request_title"), &s_open, win.width, 0.94f)) {
|
||||
const auto& state = app->getWalletState();
|
||||
|
||||
ImGui::TextWrapped(
|
||||
"Generate a payment request that others can scan or copy. "
|
||||
"The QR code contains your address and optional amount/memo."
|
||||
);
|
||||
ImGui::TextWrapped("%s", TR("request_description"));
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
|
||||
// Address selection
|
||||
ImGui::Text("Receive Address:");
|
||||
ImGui::Text("%s", TR("request_receive_address"));
|
||||
|
||||
std::string addr_display = s_address[0] ? s_address : "Select address...";
|
||||
std::string addr_display = s_address[0] ? s_address : TR("request_select_address");
|
||||
if (addr_display.length() > static_cast<size_t>(zAddrLbl.truncate)) {
|
||||
addr_display = addr_display.substr(0, zAddrFrontLbl.truncate) + "..." + addr_display.substr(addr_display.length() - zAddrBackLbl.truncate);
|
||||
}
|
||||
@@ -152,7 +149,7 @@ void RequestPaymentDialog::render(App* app)
|
||||
if (ImGui::BeginCombo("##Address", addr_display.c_str())) {
|
||||
// Z-addresses
|
||||
if (!state.z_addresses.empty()) {
|
||||
ImGui::TextDisabled("-- Shielded Addresses --");
|
||||
ImGui::TextDisabled("%s", TR("request_shielded_addrs"));
|
||||
for (size_t i = 0; i < state.z_addresses.size(); i++) {
|
||||
const auto& addr = state.z_addresses[i];
|
||||
std::string label = addr.address;
|
||||
@@ -169,7 +166,7 @@ void RequestPaymentDialog::render(App* app)
|
||||
|
||||
// T-addresses
|
||||
if (!state.t_addresses.empty()) {
|
||||
ImGui::TextDisabled("-- Transparent Addresses --");
|
||||
ImGui::TextDisabled("%s", TR("request_transparent_addrs"));
|
||||
for (size_t i = 0; i < state.t_addresses.size(); i++) {
|
||||
const auto& addr = state.t_addresses[i];
|
||||
std::string label = addr.address;
|
||||
@@ -189,7 +186,7 @@ void RequestPaymentDialog::render(App* app)
|
||||
ImGui::Spacing();
|
||||
|
||||
// Amount (optional)
|
||||
ImGui::Text("Amount (optional):");
|
||||
ImGui::Text("%s", TR("request_amount"));
|
||||
ImGui::SetNextItemWidth(amountInput.width);
|
||||
if (ImGui::InputDouble("##Amount", &s_amount, 0.1, 1.0, "%.8f")) {
|
||||
s_uri_dirty = true;
|
||||
@@ -200,7 +197,7 @@ void RequestPaymentDialog::render(App* app)
|
||||
ImGui::Spacing();
|
||||
|
||||
// Label (optional)
|
||||
ImGui::Text("Label (optional):");
|
||||
ImGui::Text("%s", TR("request_label"));
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
if (ImGui::InputText("##Label", s_label, sizeof(s_label))) {
|
||||
s_uri_dirty = true;
|
||||
@@ -211,7 +208,7 @@ void RequestPaymentDialog::render(App* app)
|
||||
// Memo (optional, only for z-addr)
|
||||
bool is_zaddr = (s_address[0] == 'z');
|
||||
if (is_zaddr) {
|
||||
ImGui::Text("Memo (optional):");
|
||||
ImGui::Text("%s", TR("request_memo"));
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
if (ImGui::InputTextMultiline("##Memo", s_memo, sizeof(s_memo), ImVec2(-1, memoInput.height > 0 ? memoInput.height : 60))) {
|
||||
s_uri_dirty = true;
|
||||
@@ -245,7 +242,7 @@ void RequestPaymentDialog::render(App* app)
|
||||
|
||||
// Payment URI display
|
||||
if (!s_payment_uri.empty()) {
|
||||
ImGui::Text("Payment URI:");
|
||||
ImGui::Text("%s", TR("request_payment_uri"));
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
|
||||
// Use a selectable text area for the URI
|
||||
@@ -256,23 +253,23 @@ void RequestPaymentDialog::render(App* app)
|
||||
ImGui::Spacing();
|
||||
|
||||
// Copy button
|
||||
if (material::StyledButton("Copy URI", ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
|
||||
if (material::StyledButton(TR("request_copy_uri"), ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
|
||||
ImGui::SetClipboardText(s_payment_uri.c_str());
|
||||
Notifications::instance().success("Payment URI copied to clipboard");
|
||||
Notifications::instance().success(TR("request_uri_copied"));
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (material::StyledButton("Copy Address", ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
|
||||
if (material::StyledButton(TR("copy_address"), ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
|
||||
ImGui::SetClipboardText(s_address);
|
||||
Notifications::instance().success("Address copied to clipboard");
|
||||
Notifications::instance().success(TR("address_copied"));
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
// Close button
|
||||
if (material::StyledButton("Close", ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
|
||||
if (material::StyledButton(TR("close"), ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
|
||||
s_open = false;
|
||||
}
|
||||
material::EndOverlayDialog();
|
||||
|
||||
Reference in New Issue
Block a user