feat(i18n,mining): translate warmup block/tx-type labels; fix the disconnected-solo mine tooltip

- Warmup/daemon status no longer appends a hardcoded English " (Block N)" — it
  uses a translated warmup_block_fmt key.
- Recent-transaction type labels (Sent/Received/Mined) are now translated in the
  UI consumer (recentTypeLabel in balance_recent_tx.cpp) with a generic
  "Transaction" fallback, instead of the data layer's raw English getTypeDisplay().
- Mining: a disconnected solo miner hovering the dead Mine button now gets a
  "not connected to the node" tooltip instead of a misleading "Start Mining"
  (the tooltip chain had no branch for the solo !isConnected() disable).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-10-18 11:42:29 -05:00
co-authored by Claude Opus 4.8
parent 74c497922e
commit fb281714f9
4 changed files with 19 additions and 3 deletions
+2 -2
View File
@@ -999,7 +999,7 @@ std::string App::applyDaemonInitStatus(bool reachableButBusy)
std::string title = wt.title;
const int h = daemon_controller_ ? daemon_controller_->lastBlockHeight() : -1;
if (h > 0) title += " (Block " + std::to_string(h) + ")";
if (h > 0) { char hb[48]; std::snprintf(hb, sizeof(hb), TR("warmup_block_fmt"), h); title += " "; title += hb; }
state_.warmup_status = title;
state_.warmup_description = wt.description ? wt.description : "";
@@ -1023,7 +1023,7 @@ void App::applyWarmupText(const std::string& rpcMessage)
}
// Append current block height from daemon output
const int h = daemon_controller_ ? daemon_controller_->lastBlockHeight() : -1;
if (h > 0) state_.warmup_status += " (Block " + std::to_string(h) + ")";
if (h > 0) { char hb[48]; std::snprintf(hb, sizeof(hb), TR("warmup_block_fmt"), h); state_.warmup_status += " "; state_.warmup_status += hb; }
connection_status_ = state_.warmup_status;
}
+12 -1
View File
@@ -1,6 +1,7 @@
#include "balance_recent_tx.h"
#include "../../config/version.h"
#include "../../util/text_format.h"
#include "../../util/i18n.h"
#include <cmath>
#include <cstdio>
@@ -23,12 +24,22 @@ std::string recentTimeAgo(int64_t timestamp)
{
return util::formatTimeAgoShort(timestamp);
}
// Translated type label (the data layer's getTypeDisplay() returns raw English). Never leak a raw RPC
// category: anything unrecognized (including "shield") falls back to a generic "Transaction".
std::string recentTypeLabel(const std::string& type)
{
if (type == "send") return TR("sent_type");
if (type == "receive") return TR("received_label");
if (type == "mined" || type == "generate" || type == "immature") return TR("mined_type");
return TR("tx_type_generic");
}
}
RecentTxDisplay buildRecentTxDisplay(const TransactionInfo& tx, int addressMaxLen)
{
return {
tx.getTypeDisplay(),
recentTypeLabel(tx.type),
util::truncateMiddle(tx.address, addressMaxLen),
formatRecentAmount(tx.type, tx.amount),
recentTimeAgo(tx.timestamp)
+2
View File
@@ -957,6 +957,8 @@ void RenderMiningControls(App* app, const WalletState& state, const MiningInfo&
material::Tooltip("%s", isMiningActive ? TR("mining_stopping_tooltip") : TR("mining_starting_tooltip"));
else if (isSyncing && !s_pool_mode)
material::Tooltip(TR("mining_syncing_tooltip"), state.sync.verification_progress * 100.0);
else if (!s_pool_mode && !poolStillRunning && !app->isConnected())
material::Tooltip("%s", TR("mining_not_connected_tooltip")); // was falling through to "Start Mining" on a dead button
else if (poolBlockedBySolo)
material::Tooltip("%s", TR("mining_stop_solo_for_pool"));
else if (poolNeedsPayout)
+3
View File
@@ -1223,6 +1223,7 @@ void I18n::loadBuiltinEnglish()
strings_["shielded_self_type"] = "Shielded";
strings_["immature_type"] = "Immature";
strings_["mined_type"] = "Mined";
strings_["tx_type_generic"] = "Transaction";
strings_["mature"] = "Mature";
strings_["copy_txid"] = "Copy TxID";
strings_["view_details"] = "View Details";
@@ -1944,6 +1945,7 @@ void I18n::loadBuiltinEnglish()
strings_["toast_finish_send_first"] = "Finish or cancel the pending send before switching wallets.";
strings_["toast_rescan_complete"] = "Blockchain rescan complete.";
strings_["toast_rescan_from_fmt"] = "Rescanning the blockchain from block %d — this can take a while.";
strings_["warmup_block_fmt"] = "(Block %d)";
strings_["toast_solo_unavailable_lite"] = "Solo mining isn't available in the lite wallet.";
strings_["toast_pool_unavailable"] = "Pool mining isn't available in this build.";
strings_["toast_no_address_generate_z"] = "No wallet address yet — generate a shielded (Z) address in the Receive tab.";
@@ -2354,6 +2356,7 @@ void I18n::loadBuiltinEnglish()
strings_["mining_stopping"] = "Stopping...";
strings_["mining_stopping_tooltip"] = "Miner is stopping...";
strings_["mining_syncing_tooltip"] = "Blockchain is syncing...";
strings_["mining_not_connected_tooltip"] = "Not connected to the node. Wait for the daemon to connect before mining.";
strings_["mining_to_save"] = "to save";
strings_["mining_today"] = "Today";
strings_["mining_uptime"] = "Uptime";