feat(balance): inline period-earnings in the address list and totals
Surfaces the period-earnings aggregator in the Balance tab: - Toolbar (shared address list): interval pills (1H/1D/1M/1Y), a received- vs-net mode toggle, and a global show-all toggle, placed right of "Hide 0 Balances". The New Z-Address / New mining address buttons move to a footer row across from "Showing X of Y" to make room. - Per address: the row draws its earnings on line 2, left of the $USD value (green positive, red negative in net mode), shown when the global toggle is on or the address is opted in via a new "Show/Hide earnings" right-click item. Works in every layout via the shared list. - Total: FormatTotalEarnings (gated on the global toggle, so the default appearance is unchanged) is wired into the compact hero (dashboard/minimal) and the classic layout, left of / beside their USD figure. The remaining layouts' totals are not wired yet. - Settings > Appearance: an "Earnings Display Format" selector (Coin / Coin + fiat / Fiat). New i18n keys are translated into all eight locales; the CJK subset font is rebuilt for the new glyphs. Builds + test suites pass on both variants. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
@@ -639,6 +639,11 @@
|
||||
"download": "Herunterladen",
|
||||
"download_bootstrap": "Bootstrap herunterladen",
|
||||
"dragonx_green": "DragonX (Grün)",
|
||||
"earnings_format": "Anzeigeformat für Erträge",
|
||||
"earnings_format_coin": "Nur Münze",
|
||||
"earnings_format_coin_fiat": "Münze + Fiat",
|
||||
"earnings_format_fiat": "Nur Fiat",
|
||||
"earnings_label": "Erträge",
|
||||
"edit": "Bearbeiten",
|
||||
"empty_wallet_keys_suffix": "Schlüssel",
|
||||
"empty_wallet_open_manager": "Wallet-Verwaltung öffnen",
|
||||
@@ -942,6 +947,7 @@
|
||||
"hidden_tag": " (versteckt)",
|
||||
"hide": "Ausblenden",
|
||||
"hide_address": "Adresse ausblenden",
|
||||
"hide_earnings": "Erträge ausblenden",
|
||||
"hide_qr": "QR ausblenden",
|
||||
"hide_zero_balances": "Nullsalden ausblenden",
|
||||
"history": "Verlauf",
|
||||
@@ -1920,6 +1926,7 @@
|
||||
"shielded_type": "Abgeschirmt",
|
||||
"shielding_notice": "Hinweis: Dies wird Gelder von einer transparenten (T) Adresse auf eine private (Z) Adresse schirmen.",
|
||||
"show": "Anzeigen",
|
||||
"show_earnings": "Erträge anzeigen",
|
||||
"show_hidden": "Ausgeblendete anzeigen (%d)",
|
||||
"show_qr": "QR anzeigen",
|
||||
"show_qr_code": "QR-Code anzeigen",
|
||||
@@ -2068,6 +2075,11 @@
|
||||
"tt_debug_expand": "Debug-Protokollierungsoptionen ausklappen",
|
||||
"tt_delete_blockchain": "Alle Blockchain-Daten löschen und neu synchronisieren. wallet.dat und Konfiguration bleiben erhalten.",
|
||||
"tt_download_bootstrap": "Blockchain-Bootstrap herunterladen, um die Synchronisierung zu beschleunigen\nVorhandene Blockdaten werden ersetzt",
|
||||
"tt_earn_interval": "Ertragszeitraum: 1H = diese Stunde, 1D = heute, 1M = dieser Monat, 1Y = dieses Jahr",
|
||||
"tt_earn_mode_inflows": "Ertragsmodus: erhaltene Beträge (einschließlich Mining)",
|
||||
"tt_earn_mode_net": "Ertragsmodus: netto (erhalten minus gesendet)",
|
||||
"tt_earn_show_all": "Ertragswert für jede Adresse anzeigen",
|
||||
"tt_earnings_format": "Wie die Ertragswerte pro Adresse und insgesamt angezeigt werden",
|
||||
"tt_encrypt": "wallet.dat mit einer Passphrase verschlüsseln",
|
||||
"tt_export_all": "Alle privaten Schlüssel in eine Datei exportieren",
|
||||
"tt_export_csv": "Transaktionsverlauf als CSV-Tabelle exportieren",
|
||||
|
||||
@@ -639,6 +639,11 @@
|
||||
"download": "Descargar",
|
||||
"download_bootstrap": "Descargar Bootstrap",
|
||||
"dragonx_green": "DragonX (Verde)",
|
||||
"earnings_format": "Formato de visualización de ganancias",
|
||||
"earnings_format_coin": "Solo moneda",
|
||||
"earnings_format_coin_fiat": "Moneda + fíat",
|
||||
"earnings_format_fiat": "Solo fíat",
|
||||
"earnings_label": "Ganancias",
|
||||
"edit": "Editar",
|
||||
"empty_wallet_keys_suffix": "claves",
|
||||
"empty_wallet_open_manager": "Abrir administrador de carteras",
|
||||
@@ -942,6 +947,7 @@
|
||||
"hidden_tag": " (oculto)",
|
||||
"hide": "Ocultar",
|
||||
"hide_address": "Ocultar dirección",
|
||||
"hide_earnings": "Ocultar ganancias",
|
||||
"hide_qr": "Ocultar QR",
|
||||
"hide_zero_balances": "Ocultar saldos 0",
|
||||
"history": "Historial",
|
||||
@@ -1920,6 +1926,7 @@
|
||||
"shielded_type": "Protegido",
|
||||
"shielding_notice": "Nota: Esto blindará fondos de una dirección transparente (T) a una dirección privada (Z).",
|
||||
"show": "Mostrar",
|
||||
"show_earnings": "Mostrar ganancias",
|
||||
"show_hidden": "Mostrar ocultos (%d)",
|
||||
"show_qr": "Mostrar QR",
|
||||
"show_qr_code": "Mostrar Código QR",
|
||||
@@ -2068,6 +2075,11 @@
|
||||
"tt_debug_expand": "Expandir opciones de registro de depuración",
|
||||
"tt_delete_blockchain": "Eliminar todos los datos de la blockchain e iniciar una nueva sincronización. Se preservan wallet.dat y la configuración.",
|
||||
"tt_download_bootstrap": "Descargar bootstrap de blockchain para acelerar la sincronización\nLos datos de bloques existentes serán reemplazados",
|
||||
"tt_earn_interval": "Periodo de ganancias: 1H = esta hora, 1D = hoy, 1M = este mes, 1Y = este año",
|
||||
"tt_earn_mode_inflows": "Modo de ganancias: importes recibidos (incluida la minería)",
|
||||
"tt_earn_mode_net": "Modo de ganancias: neto (recibido menos enviado)",
|
||||
"tt_earn_show_all": "Mostrar la cifra de ganancias para cada dirección",
|
||||
"tt_earnings_format": "Cómo se muestran las cifras de ganancias por dirección y totales",
|
||||
"tt_encrypt": "Cifrar wallet.dat con una contraseña",
|
||||
"tt_export_all": "Exportar todas las claves privadas a un archivo",
|
||||
"tt_export_csv": "Exportar historial de transacciones como hoja de cálculo CSV",
|
||||
|
||||
@@ -639,6 +639,11 @@
|
||||
"download": "Télécharger",
|
||||
"download_bootstrap": "Télécharger Bootstrap",
|
||||
"dragonx_green": "DragonX (Vert)",
|
||||
"earnings_format": "Format d'affichage des gains",
|
||||
"earnings_format_coin": "Pièce uniquement",
|
||||
"earnings_format_coin_fiat": "Pièce + fiat",
|
||||
"earnings_format_fiat": "Fiat uniquement",
|
||||
"earnings_label": "Gains",
|
||||
"edit": "Modifier",
|
||||
"empty_wallet_keys_suffix": "clés",
|
||||
"empty_wallet_open_manager": "Ouvrir le gestionnaire de portefeuilles",
|
||||
@@ -942,6 +947,7 @@
|
||||
"hidden_tag": " (masqué)",
|
||||
"hide": "Masquer",
|
||||
"hide_address": "Masquer l'adresse",
|
||||
"hide_earnings": "Masquer les gains",
|
||||
"hide_qr": "Masquer le QR",
|
||||
"hide_zero_balances": "Masquer les soldes à 0",
|
||||
"history": "Historique",
|
||||
@@ -1920,6 +1926,7 @@
|
||||
"shielded_type": "Blindé",
|
||||
"shielding_notice": "Note : Cela blindera des fonds d'une adresse transparente (T) vers une adresse privée (Z).",
|
||||
"show": "Afficher",
|
||||
"show_earnings": "Afficher les gains",
|
||||
"show_hidden": "Afficher masqués (%d)",
|
||||
"show_qr": "Afficher le QR",
|
||||
"show_qr_code": "Afficher le code QR",
|
||||
@@ -2068,6 +2075,11 @@
|
||||
"tt_debug_expand": "Développer les options de journalisation de débogage",
|
||||
"tt_delete_blockchain": "Supprimer toutes les données de la blockchain et démarrer une nouvelle synchronisation. wallet.dat et la configuration sont préservés.",
|
||||
"tt_download_bootstrap": "Télécharger le bootstrap blockchain pour accélérer la synchronisation\nLes données de blocs existantes seront remplacées",
|
||||
"tt_earn_interval": "Période de gains : 1H = cette heure, 1D = aujourd'hui, 1M = ce mois, 1Y = cette année",
|
||||
"tt_earn_mode_inflows": "Mode de gains : montants reçus (minage inclus)",
|
||||
"tt_earn_mode_net": "Mode de gains : net (reçu moins envoyé)",
|
||||
"tt_earn_show_all": "Afficher le montant des gains pour chaque adresse",
|
||||
"tt_earnings_format": "Comment les montants de gains par adresse et totaux sont affichés",
|
||||
"tt_encrypt": "Chiffrer wallet.dat avec une phrase secrète",
|
||||
"tt_export_all": "Exporter toutes les clés privées dans un fichier",
|
||||
"tt_export_csv": "Exporter l'historique des transactions en feuille de calcul CSV",
|
||||
|
||||
@@ -639,6 +639,11 @@
|
||||
"download": "ダウンロード",
|
||||
"download_bootstrap": "ブートストラップをダウンロード",
|
||||
"dragonx_green": "DragonX(グリーン)",
|
||||
"earnings_format": "収益の表示形式",
|
||||
"earnings_format_coin": "コインのみ",
|
||||
"earnings_format_coin_fiat": "コイン+法定通貨",
|
||||
"earnings_format_fiat": "法定通貨のみ",
|
||||
"earnings_label": "収益",
|
||||
"edit": "編集",
|
||||
"empty_wallet_keys_suffix": "個の鍵",
|
||||
"empty_wallet_open_manager": "ウォレットマネージャーを開く",
|
||||
@@ -942,6 +947,7 @@
|
||||
"hidden_tag": " (非表示)",
|
||||
"hide": "非表示",
|
||||
"hide_address": "アドレスを非表示",
|
||||
"hide_earnings": "収益を非表示",
|
||||
"hide_qr": "QRを非表示",
|
||||
"hide_zero_balances": "残高0を非表示",
|
||||
"history": "履歴",
|
||||
@@ -1920,6 +1926,7 @@
|
||||
"shielded_type": "シールド",
|
||||
"shielding_notice": "注意:トランスペアレント (T) アドレスからプライベート (Z) アドレスへ資金をシールドします。",
|
||||
"show": "表示",
|
||||
"show_earnings": "収益を表示",
|
||||
"show_hidden": "非表示を表示 (%d)",
|
||||
"show_qr": "QRを表示",
|
||||
"show_qr_code": "QRコードを表示",
|
||||
@@ -2068,6 +2075,11 @@
|
||||
"tt_debug_expand": "デバッグログオプションを展開",
|
||||
"tt_delete_blockchain": "すべてのブロックチェーンデータを削除して新規同期を開始します。wallet.dat と設定は保持されます。",
|
||||
"tt_download_bootstrap": "ブロックチェーンブートストラップをダウンロードして同期を高速化\n既存のブロックデータは置き換えられます",
|
||||
"tt_earn_interval": "収益期間:1H=今の時間、1D=今日、1M=今月、1Y=今年",
|
||||
"tt_earn_mode_inflows": "収益モード:受取額(マイニングを含む)",
|
||||
"tt_earn_mode_net": "収益モード:純額(受取から送金を差し引いた額)",
|
||||
"tt_earn_show_all": "すべてのアドレスの収益額を表示",
|
||||
"tt_earnings_format": "アドレスごとおよび合計の収益額の表示方法",
|
||||
"tt_encrypt": "パスフレーズで wallet.dat を暗号化",
|
||||
"tt_export_all": "すべての秘密鍵をファイルにエクスポート",
|
||||
"tt_export_csv": "トランザクション履歴を CSV スプレッドシートとしてエクスポート",
|
||||
|
||||
@@ -639,6 +639,11 @@
|
||||
"download": "다운로드",
|
||||
"download_bootstrap": "부트스트랩 다운로드",
|
||||
"dragonx_green": "DragonX(그린)",
|
||||
"earnings_format": "수익 표시 형식",
|
||||
"earnings_format_coin": "코인만",
|
||||
"earnings_format_coin_fiat": "코인 + 법정화폐",
|
||||
"earnings_format_fiat": "법정화폐만",
|
||||
"earnings_label": "수익",
|
||||
"edit": "편집",
|
||||
"empty_wallet_keys_suffix": "개 키",
|
||||
"empty_wallet_open_manager": "지갑 관리자 열기",
|
||||
@@ -942,6 +947,7 @@
|
||||
"hidden_tag": " (숨김)",
|
||||
"hide": "숨기기",
|
||||
"hide_address": "주소 숨기기",
|
||||
"hide_earnings": "수익 숨기기",
|
||||
"hide_qr": "QR 숨기기",
|
||||
"hide_zero_balances": "잔액 0 숨기기",
|
||||
"history": "내역",
|
||||
@@ -1920,6 +1926,7 @@
|
||||
"shielded_type": "차폐",
|
||||
"shielding_notice": "참고: 투명 (T) 주소에서 프라이빗 (Z) 주소로 자금을 실딩합니다.",
|
||||
"show": "표시",
|
||||
"show_earnings": "수익 표시",
|
||||
"show_hidden": "숨겨진 항목 표시 (%d)",
|
||||
"show_qr": "QR 표시",
|
||||
"show_qr_code": "QR 코드 표시",
|
||||
@@ -2068,6 +2075,11 @@
|
||||
"tt_debug_expand": "디버그 로깅 옵션 펼치기",
|
||||
"tt_delete_blockchain": "모든 블록체인 데이터를 삭제하고 새로 동기화합니다. wallet.dat 및 설정은 보존됩니다.",
|
||||
"tt_download_bootstrap": "블록체인 부트스트랩을 다운로드하여 동기화 가속\n기존 블록 데이터가 교체됩니다",
|
||||
"tt_earn_interval": "수익 기간: 1H = 현재 시간, 1D = 오늘, 1M = 이번 달, 1Y = 올해",
|
||||
"tt_earn_mode_inflows": "수익 모드: 받은 금액(채굴 포함)",
|
||||
"tt_earn_mode_net": "수익 모드: 순액(받은 금액에서 보낸 금액을 뺀 값)",
|
||||
"tt_earn_show_all": "모든 주소의 수익 금액 표시",
|
||||
"tt_earnings_format": "주소별 및 합계 수익 금액의 표시 방식",
|
||||
"tt_encrypt": "비밀번호로 wallet.dat 암호화",
|
||||
"tt_export_all": "모든 개인키를 파일로 내보내기",
|
||||
"tt_export_csv": "거래 내역을 CSV 스프레드시트로 내보내기",
|
||||
|
||||
@@ -639,6 +639,11 @@
|
||||
"download": "Baixar",
|
||||
"download_bootstrap": "Baixar Bootstrap",
|
||||
"dragonx_green": "DragonX (Verde)",
|
||||
"earnings_format": "Formato de exibição de ganhos",
|
||||
"earnings_format_coin": "Apenas moeda",
|
||||
"earnings_format_coin_fiat": "Moeda + fiduciária",
|
||||
"earnings_format_fiat": "Apenas fiduciária",
|
||||
"earnings_label": "Ganhos",
|
||||
"edit": "Editar",
|
||||
"empty_wallet_keys_suffix": "chaves",
|
||||
"empty_wallet_open_manager": "Abrir gerenciador de carteiras",
|
||||
@@ -942,6 +947,7 @@
|
||||
"hidden_tag": " (oculto)",
|
||||
"hide": "Ocultar",
|
||||
"hide_address": "Ocultar endereço",
|
||||
"hide_earnings": "Ocultar ganhos",
|
||||
"hide_qr": "Ocultar QR",
|
||||
"hide_zero_balances": "Ocultar saldos zero",
|
||||
"history": "Histórico",
|
||||
@@ -1920,6 +1926,7 @@
|
||||
"shielded_type": "Blindado",
|
||||
"shielding_notice": "Nota: Isso blindará fundos de um endereço transparente (T) para um endereço privado (Z).",
|
||||
"show": "Mostrar",
|
||||
"show_earnings": "Mostrar ganhos",
|
||||
"show_hidden": "Mostrar ocultos (%d)",
|
||||
"show_qr": "Mostrar QR",
|
||||
"show_qr_code": "Mostrar Código QR",
|
||||
@@ -2068,6 +2075,11 @@
|
||||
"tt_debug_expand": "Expandir opções de registro de depuração",
|
||||
"tt_delete_blockchain": "Excluir todos os dados da blockchain e iniciar uma nova sincronização. wallet.dat e configuração são preservados.",
|
||||
"tt_download_bootstrap": "Baixar bootstrap da blockchain para acelerar a sincronização\nDados de blocos existentes serão substituídos",
|
||||
"tt_earn_interval": "Período de ganhos: 1H = esta hora, 1D = hoje, 1M = este mês, 1Y = este ano",
|
||||
"tt_earn_mode_inflows": "Modo de ganhos: valores recebidos (incluindo mineração)",
|
||||
"tt_earn_mode_net": "Modo de ganhos: líquido (recebido menos enviado)",
|
||||
"tt_earn_show_all": "Mostrar o valor de ganhos para cada endereço",
|
||||
"tt_earnings_format": "Como os valores de ganhos por endereço e totais são exibidos",
|
||||
"tt_encrypt": "Encriptar wallet.dat com uma frase secreta",
|
||||
"tt_export_all": "Exportar todas as chaves privadas para um arquivo",
|
||||
"tt_export_csv": "Exportar histórico de transações como planilha CSV",
|
||||
|
||||
@@ -639,6 +639,11 @@
|
||||
"download": "Скачать",
|
||||
"download_bootstrap": "Скачать бутстрап",
|
||||
"dragonx_green": "DragonX (Зелёная)",
|
||||
"earnings_format": "Формат отображения дохода",
|
||||
"earnings_format_coin": "Только монета",
|
||||
"earnings_format_coin_fiat": "Монета + фиат",
|
||||
"earnings_format_fiat": "Только фиат",
|
||||
"earnings_label": "Доход",
|
||||
"edit": "Редактировать",
|
||||
"empty_wallet_keys_suffix": "ключей",
|
||||
"empty_wallet_open_manager": "Открыть менеджер кошельков",
|
||||
@@ -942,6 +947,7 @@
|
||||
"hidden_tag": " (скрыт)",
|
||||
"hide": "Скрыть",
|
||||
"hide_address": "Скрыть адрес",
|
||||
"hide_earnings": "Скрыть доход",
|
||||
"hide_qr": "Скрыть QR",
|
||||
"hide_zero_balances": "Скрыть нулевые балансы",
|
||||
"history": "История",
|
||||
@@ -1920,6 +1926,7 @@
|
||||
"shielded_type": "Экранированный",
|
||||
"shielding_notice": "Примечание: это переведёт средства с прозрачного (T) адреса на приватный (Z) адрес.",
|
||||
"show": "Показать",
|
||||
"show_earnings": "Показать доход",
|
||||
"show_hidden": "Показать скрытые (%d)",
|
||||
"show_qr": "Показать QR",
|
||||
"show_qr_code": "Показать QR-код",
|
||||
@@ -2068,6 +2075,11 @@
|
||||
"tt_debug_expand": "Развернуть параметры журнала отладки",
|
||||
"tt_delete_blockchain": "Удалить все данные блокчейна и начать синхронизацию заново. wallet.dat и конфигурация сохраняются.",
|
||||
"tt_download_bootstrap": "Скачать бутстрап блокчейна для ускорения синхронизации\nСуществующие данные блоков будут заменены",
|
||||
"tt_earn_interval": "Период дохода: 1H — текущий час, 1D — сегодня, 1M — текущий месяц, 1Y — текущий год",
|
||||
"tt_earn_mode_inflows": "Режим дохода: полученные суммы (включая майнинг)",
|
||||
"tt_earn_mode_net": "Режим дохода: нетто (получено минус отправлено)",
|
||||
"tt_earn_show_all": "Показывать сумму дохода для каждого адреса",
|
||||
"tt_earnings_format": "Как отображаются суммы дохода по адресам и итогам",
|
||||
"tt_encrypt": "Зашифровать wallet.dat паролем",
|
||||
"tt_export_all": "Экспортировать все приватные ключи в файл",
|
||||
"tt_export_csv": "Экспортировать историю транзакций в виде таблицы CSV",
|
||||
|
||||
@@ -639,6 +639,11 @@
|
||||
"download": "下载",
|
||||
"download_bootstrap": "下载引导程序",
|
||||
"dragonx_green": "DragonX(绿色)",
|
||||
"earnings_format": "收益显示格式",
|
||||
"earnings_format_coin": "仅代币",
|
||||
"earnings_format_coin_fiat": "代币+法币",
|
||||
"earnings_format_fiat": "仅法币",
|
||||
"earnings_label": "收益",
|
||||
"edit": "编辑",
|
||||
"empty_wallet_keys_suffix": "个密钥",
|
||||
"empty_wallet_open_manager": "打开钱包管理器",
|
||||
@@ -942,6 +947,7 @@
|
||||
"hidden_tag": " (已隐藏)",
|
||||
"hide": "隐藏",
|
||||
"hide_address": "隐藏地址",
|
||||
"hide_earnings": "隐藏收益",
|
||||
"hide_qr": "隐藏二维码",
|
||||
"hide_zero_balances": "隐藏零余额",
|
||||
"history": "历史",
|
||||
@@ -1920,6 +1926,7 @@
|
||||
"shielded_type": "屏蔽",
|
||||
"shielding_notice": "注意:这将把资金从透明 (T) 地址转移到隐私 (Z) 地址。",
|
||||
"show": "显示",
|
||||
"show_earnings": "显示收益",
|
||||
"show_hidden": "显示已隐藏 (%d)",
|
||||
"show_qr": "显示二维码",
|
||||
"show_qr_code": "显示二维码",
|
||||
@@ -2068,6 +2075,11 @@
|
||||
"tt_debug_expand": "展开调试日志选项",
|
||||
"tt_delete_blockchain": "删除所有区块链数据并重新同步。wallet.dat 和配置将被保留。",
|
||||
"tt_download_bootstrap": "下载区块链引导程序以加速同步\n现有区块数据将被替换",
|
||||
"tt_earn_interval": "收益周期:1H=本小时,1D=今天,1M=本月,1Y=今年",
|
||||
"tt_earn_mode_inflows": "收益模式:收到的金额(含挖矿)",
|
||||
"tt_earn_mode_net": "收益模式:净额(收到减去发送)",
|
||||
"tt_earn_show_all": "为每个地址显示收益数值",
|
||||
"tt_earnings_format": "按地址和总计的收益数值的显示方式",
|
||||
"tt_encrypt": "使用密码加密 wallet.dat",
|
||||
"tt_export_all": "将所有私钥导出到文件",
|
||||
"tt_export_csv": "将交易历史导出为 CSV 电子表格",
|
||||
|
||||
@@ -107,6 +107,7 @@ struct SettingsPageState {
|
||||
float ui_opacity = 1.0f;
|
||||
float window_opacity = 1.0f;
|
||||
float favorite_opacity = 1.0f;
|
||||
int earnings_format = 1;
|
||||
std::string balance_layout = "classic";
|
||||
bool scanline_enabled = true;
|
||||
bool theme_effects_enabled = true;
|
||||
@@ -450,6 +451,7 @@ static void loadSettingsPageState(App* app) {
|
||||
s_settingsState.ui_opacity = settings->getUIOpacity();
|
||||
s_settingsState.window_opacity = settings->getWindowOpacity();
|
||||
s_settingsState.favorite_opacity = settings->getFavoriteOpacity();
|
||||
s_settingsState.earnings_format = settings->getEarningsFormat();
|
||||
s_settingsState.noise_opacity = settings->getNoiseOpacity();
|
||||
|
||||
s_settingsState.gradient_background = settings->getGradientBackground();
|
||||
@@ -535,6 +537,7 @@ static void saveSettingsPageState(config::Settings* settings) {
|
||||
settings->setUIOpacity(lowSpecOverrides ? realPrefs.ui_opacity : s_settingsState.ui_opacity);
|
||||
settings->setWindowOpacity(s_settingsState.window_opacity); // 1.0 under low-spec, as the hotkey saves it
|
||||
settings->setFavoriteOpacity(s_settingsState.favorite_opacity); // not low-spec gated — cosmetic
|
||||
settings->setEarningsFormat(s_settingsState.earnings_format);
|
||||
settings->setNoiseOpacity(s_settingsState.noise_opacity);
|
||||
settings->setGradientBackground(s_settingsState.gradient_background);
|
||||
settings->setScanlineEnabled(lowSpecOverrides ? realPrefs.scanline_enabled : s_settingsState.scanline_enabled);
|
||||
@@ -1052,6 +1055,25 @@ void RenderSettingsPage(App* app) {
|
||||
|
||||
ImGui::Dummy(ImVec2(0, Layout::spacingMd()));
|
||||
|
||||
// --- Earnings display format (Balance tab per-address + total earnings figures) ---
|
||||
{
|
||||
ImGui::PushFont(body2);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(OnSurfaceMedium()));
|
||||
ImGui::TextUnformatted(TR("earnings_format"));
|
||||
ImGui::PopStyleColor();
|
||||
float efW = std::min(std::max(S.drawElement("components.settings-page", "effects-input-min-width").size, contentW), 360.0f * dp);
|
||||
ImGui::SetNextItemWidth(efW);
|
||||
const char* efItems[] = { TR("earnings_format_coin"), TR("earnings_format_coin_fiat"), TR("earnings_format_fiat") };
|
||||
if (ImGui::Combo("##EarningsFormat", &s_settingsState.earnings_format, efItems, IM_ARRAYSIZE(efItems))) {
|
||||
s_settingsState.earnings_format = std::max(0, std::min(2, s_settingsState.earnings_format));
|
||||
if (app->settings()) { app->settings()->setEarningsFormat(s_settingsState.earnings_format); app->settings()->save(); }
|
||||
}
|
||||
if (ImGui::IsItemHovered()) material::Tooltip("%s", TR("tt_earnings_format"));
|
||||
ImGui::PopFont();
|
||||
}
|
||||
|
||||
ImGui::Dummy(ImVec2(0, Layout::spacingMd()));
|
||||
|
||||
// --- Effect toggles (always visible, horizontal wrapping flow) ---
|
||||
{
|
||||
ImGui::PushFont(body2);
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <chrono>
|
||||
#include "../../data/earnings_series.h"
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -56,6 +58,44 @@ void UpdateBalanceLerp(App* app) {
|
||||
StepDisplayLerp(s_dispUnconfirmed, state.unconfirmed_balance, dt, kBalanceLerpSpeed, instant);
|
||||
}
|
||||
|
||||
// Total period-earnings for the whole wallet, formatted per the earnings settings. Only shown when the
|
||||
// global earnings toggle is on, so the default hero/layout appearance is unchanged. Own revision-keyed
|
||||
// cache (independent of the per-row one in RenderSharedAddressList).
|
||||
bool FormatTotalEarnings(App* app, std::string& outText, ImU32& outCol) {
|
||||
using namespace material;
|
||||
if (!app->settings() || !app->settings()->getEarningsShowAll()) return false;
|
||||
auto& S = schema::UI();
|
||||
const auto& state = app->state();
|
||||
auto* est = app->settings();
|
||||
static dragonx::data::EarningsCache s_totalEarnCache;
|
||||
auto iv = (dragonx::data::EarningsInterval)est->getEarningsInterval();
|
||||
auto md = (dragonx::data::EarningsMode)est->getEarningsMode();
|
||||
const int fmt = est->getEarningsFormat();
|
||||
const std::int64_t nowSec = (std::int64_t)std::time(nullptr);
|
||||
const std::int64_t nowMs = (std::int64_t)std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::steady_clock::now().time_since_epoch()).count();
|
||||
dragonx::data::EarningsKey ek;
|
||||
ek.txRevision = state.tx_revision;
|
||||
ek.txCount = state.transactions.size();
|
||||
ek.interval = iv;
|
||||
ek.mode = md;
|
||||
ek.periodStart = dragonx::data::earningsPeriodStart(nowSec, iv);
|
||||
const auto& r = s_totalEarnCache.get(ek, state.transactions, nowSec, nowMs);
|
||||
const double ev = r.total;
|
||||
const double fiat = ev * state.market.price_usd;
|
||||
const bool haveFiat = state.market.price_usd > 0.0;
|
||||
const int f = haveFiat ? fmt : 0;
|
||||
char buf[64];
|
||||
if (f == 0) snprintf(buf, sizeof(buf), "%+.4f", ev);
|
||||
else if (f == 2) snprintf(buf, sizeof(buf), "%s$%.2f", ev < 0 ? "-" : "+", std::fabs(fiat));
|
||||
else snprintf(buf, sizeof(buf), "%+.4f ($%.2f)", ev, fiat);
|
||||
outText = buf;
|
||||
outCol = ev > 1e-12 ? S.resolveColor("var(--accent-shielded)", Success())
|
||||
: (ev < -1e-12 ? S.resolveColor("var(--accent-error)", ReadableError())
|
||||
: OnSurfaceDisabled());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Render compact hero line: logo + balance + USD + mining on one line
|
||||
void RenderCompactHero(App* app, ImDrawList* dl, float availW, float hs, float vs, float heroHeightOverride) {
|
||||
using namespace material;
|
||||
@@ -96,6 +136,18 @@ void RenderCompactHero(App* app, ImDrawList* dl, float availW, float hs, float v
|
||||
ImGui::Dummy(ImVec2(capFont->CalcTextSizeA(tickerFontSize, 10000, 0, DRAGONX_TICKER).x + Layout::spacingLg(), lineH));
|
||||
ImGui::SameLine();
|
||||
|
||||
// Total period-earnings (left of the USD) when the global earnings toggle is on.
|
||||
{
|
||||
std::string earnText; ImU32 earnCol;
|
||||
if (FormatTotalEarnings(app, earnText, earnCol)) {
|
||||
dl->AddText(capFont, tickerFontSize,
|
||||
ImVec2(ImGui::GetCursorScreenPos().x, tickerY), earnCol, earnText.c_str());
|
||||
float ew = capFont->CalcTextSizeA(tickerFontSize, 10000, 0, earnText.c_str()).x;
|
||||
ImGui::Dummy(ImVec2(ew + Layout::spacingLg(), lineH));
|
||||
ImGui::SameLine();
|
||||
}
|
||||
}
|
||||
|
||||
// USD value
|
||||
const auto& state = app->state();
|
||||
double usd_value = state.getBalanceUSD();
|
||||
@@ -164,6 +216,29 @@ void RenderSharedAddressList(App* app, float listH, float availW,
|
||||
addRows(state.t_addresses, false);
|
||||
auto rows = BuildAddressListRows(rowInputs, addr_search, s_hideZeroBalances, s_showHidden);
|
||||
|
||||
// ---- Inline period-earnings: compute once (cached on tx_revision + interval/mode/period) ----
|
||||
static dragonx::data::EarningsCache s_earnCache;
|
||||
const dragonx::data::EarningsResult* earnResult = nullptr;
|
||||
bool earnShowAll = false;
|
||||
int earnFormat = 1; // 0=coin 1=coin+fiat 2=fiat
|
||||
if (app->settings()) {
|
||||
auto* est = app->settings();
|
||||
earnShowAll = est->getEarningsShowAll();
|
||||
earnFormat = est->getEarningsFormat();
|
||||
auto iv = (dragonx::data::EarningsInterval)est->getEarningsInterval();
|
||||
auto md = (dragonx::data::EarningsMode)est->getEarningsMode();
|
||||
const std::int64_t nowSec = (std::int64_t)std::time(nullptr);
|
||||
const std::int64_t nowMs = (std::int64_t)std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::steady_clock::now().time_since_epoch()).count();
|
||||
dragonx::data::EarningsKey ek;
|
||||
ek.txRevision = state.tx_revision;
|
||||
ek.txCount = state.transactions.size();
|
||||
ek.interval = iv;
|
||||
ek.mode = md;
|
||||
ek.periodStart = dragonx::data::earningsPeriodStart(nowSec, iv);
|
||||
earnResult = &s_earnCache.get(ek, state.transactions, nowSec, nowMs);
|
||||
}
|
||||
|
||||
// ---- Toolbar: search + checkboxes + create buttons ----
|
||||
float avail = ImGui::GetContentRegionAvail().x;
|
||||
float schemaMaxW = (searchIn.maxWidth >= 0) ? searchIn.maxWidth : 250.0f;
|
||||
@@ -185,39 +260,46 @@ void RenderSharedAddressList(App* app, float listH, float availW,
|
||||
}
|
||||
}
|
||||
|
||||
float buttonWidth = ((addrBtn.width > 0) ? addrBtn.width : 140.0f) * dp;
|
||||
float spacing = ((addrBtn.gap > 0) ? addrBtn.gap : 8.0f) * dp;
|
||||
float totalButtonsWidth = buttonWidth * 2 + spacing;
|
||||
float kMinButtonsPosition = std::max(S.drawElement("tabs.balance", "min-buttons-position").size,
|
||||
S.drawElement("tabs.balance", "buttons-position").size * hs);
|
||||
ImGui::SameLine(std::max(kMinButtonsPosition,
|
||||
ImGui::GetWindowWidth() - totalButtonsWidth -
|
||||
S.drawElement("tabs.balance", "button-row-right-margin").sizeOr(16.0f)));
|
||||
// ---- Inline period-earnings controls: interval pills (1H/1D/1M/1Y), mode toggle (received /
|
||||
// net), and a global show-all toggle. The create-address buttons moved below the list (footer). ----
|
||||
if (app->settings()) {
|
||||
auto* est = app->settings();
|
||||
ImFont* icoF = Type().iconSmall();
|
||||
const float segH = ImGui::GetFrameHeight(); // fixed height so pills + icon buttons align
|
||||
// A compact selected/unselected toggle. `font` nullptr = default font (text pills).
|
||||
auto segBtn = [&](const char* idlabel, bool selected, const char* tip, ImFont* font) -> bool {
|
||||
if (font) ImGui::PushFont(font);
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, selected ? WithAlpha(Primary(), 70) : IM_COL32(255, 255, 255, 12));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, WithAlpha(Primary(), 110));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, WithAlpha(Primary(), 140));
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(selected ? OnSurface() : OnSurfaceMedium()));
|
||||
bool clk = ImGui::Button(idlabel, ImVec2(0, segH));
|
||||
ImGui::PopStyleColor(4);
|
||||
if (font) ImGui::PopFont();
|
||||
if (tip && ImGui::IsItemHovered()) material::Tooltip("%s", tip);
|
||||
return clk;
|
||||
};
|
||||
|
||||
bool sharedAddrSyncing = state.sync.syncing && !state.sync.isSynced();
|
||||
ImGui::BeginDisabled(sharedAddrSyncing);
|
||||
if (s_generating_z_address) {
|
||||
char genLabel[64];
|
||||
snprintf(genLabel, sizeof(genLabel), "%s%s##shared_z", TR("generating"), material::LoadingDots());
|
||||
TactileButton(genLabel, ImVec2(buttonWidth, 0),
|
||||
S.resolveFont(addrBtn.font.empty() ? "button" : addrBtn.font));
|
||||
} else if (TactileButton(TR("new_z_address"), ImVec2(buttonWidth, 0),
|
||||
S.resolveFont(addrBtn.font.empty() ? "button" : addrBtn.font))) {
|
||||
s_generating_z_address = true;
|
||||
app->createNewZAddress([](const std::string& addr) {
|
||||
s_generating_z_address = false;
|
||||
DEBUG_LOGF("Created new z-address: %s\n", addr.c_str());
|
||||
});
|
||||
ImGui::SameLine(0, Layout::spacingLg());
|
||||
// Interval pills
|
||||
const char* ivText[4] = { "1H", "1D", "1M", "1Y" };
|
||||
int iv = est->getEarningsInterval();
|
||||
for (int k = 0; k < 4; ++k) {
|
||||
char lbl[16]; snprintf(lbl, sizeof(lbl), "%s##earniv%d", ivText[k], k);
|
||||
if (segBtn(lbl, iv == k, TR("tt_earn_interval"), nullptr)) { est->setEarningsInterval(k); est->save(); }
|
||||
if (k < 3) ImGui::SameLine(0, 2.0f * dp);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (TactileButton(TR("new_mining_address"), ImVec2(buttonWidth, 0),
|
||||
S.resolveFont(addrBtn.font.empty() ? "button" : addrBtn.font))) {
|
||||
app->createNewTAddress([](const std::string& addr) {
|
||||
DEBUG_LOGF("Created new t-address: %s\n", addr.c_str());
|
||||
});
|
||||
// Mode toggle (received-only vs net)
|
||||
ImGui::SameLine(0, Layout::spacingMd());
|
||||
int emode = est->getEarningsMode();
|
||||
if (segBtn(ICON_MD_CALL_RECEIVED "##earnmodein", emode == 0, TR("tt_earn_mode_inflows"), icoF)) { est->setEarningsMode(0); est->save(); }
|
||||
ImGui::SameLine(0, 2.0f * dp);
|
||||
if (segBtn(ICON_MD_SWAP_VERT "##earnmodenet", emode == 1, TR("tt_earn_mode_net"), icoF)) { est->setEarningsMode(1); est->save(); }
|
||||
// Global earnings-column toggle
|
||||
ImGui::SameLine(0, Layout::spacingMd());
|
||||
bool showAll = est->getEarningsShowAll();
|
||||
if (segBtn(ICON_MD_TRENDING_UP "##earnshowall", showAll, TR("tt_earn_show_all"), icoF)) { est->setEarningsShowAll(!showAll); est->save(); }
|
||||
}
|
||||
if (ImGui::IsItemHovered()) material::Tooltip("%s", TR("tt_new_mining_address"));
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::Dummy(ImVec2(0, Layout::spacingXs()));
|
||||
|
||||
@@ -279,6 +361,7 @@ void RenderSharedAddressList(App* app, float listH, float availW,
|
||||
addrScrollMaxY = ImGui::GetScrollMaxY();
|
||||
ImU32 greenCol = S.resolveColor("var(--accent-shielded)", Success());
|
||||
ImU32 goldCol = S.resolveColor("var(--accent-transparent)", Warning());
|
||||
ImU32 earnNegCol = S.resolveColor("var(--accent-error)", material::ReadableError()); // negative net earnings
|
||||
float rowPadLeft = Layout::cardInnerPadding();
|
||||
float rowPadRight = Layout::cardInnerPadding();
|
||||
float rowIconSz = std::max(S.drawElement("tabs.balance", "address-icon-min-size").size,
|
||||
@@ -594,9 +677,33 @@ void RenderSharedAddressList(App* app, float listH, float availW,
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Line-2 right content widths: USD + optional period-earnings to its left ----
|
||||
std::string usdText = FormatAddressUsdValue(addr.balance, state.market.price_usd);
|
||||
float usdW = usdText.empty() ? 0.0f
|
||||
: capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0, usdText.c_str()).x;
|
||||
const bool haveFiat = state.market.price_usd > 0.0;
|
||||
bool earnShown = earnResult && app->settings() &&
|
||||
(earnShowAll || app->settings()->isAddressEarningsShown(addr.address));
|
||||
char earnBuf[48]; earnBuf[0] = '\0';
|
||||
float earnW = 0.0f; ImU32 earnCol = OnSurfaceDisabled();
|
||||
if (earnShown) {
|
||||
double ev = dragonx::data::earningsForAddress(*earnResult, addr.address);
|
||||
double fiat = ev * state.market.price_usd;
|
||||
int fmt = (!haveFiat) ? 0 : earnFormat; // no price -> coin only
|
||||
if (fmt == 0) snprintf(earnBuf, sizeof(earnBuf), "%+.4f", ev);
|
||||
else if (fmt == 2) snprintf(earnBuf, sizeof(earnBuf), "%s$%.2f", ev < 0 ? "-" : "+", std::fabs(fiat));
|
||||
else snprintf(earnBuf, sizeof(earnBuf), "%+.4f ($%.2f)", ev, fiat);
|
||||
earnW = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0, earnBuf).x;
|
||||
earnCol = ev > 1e-12 ? greenCol : (ev < -1e-12 ? earnNegCol : OnSurfaceDisabled());
|
||||
if (row.hidden) earnCol = OnSurfaceDisabled();
|
||||
}
|
||||
// Left edge of the line-2 right content, so the address truncates before it.
|
||||
const float line2RightStart = contentRight - usdW
|
||||
- (earnShown && earnBuf[0] ? (earnW + Layout::spacingMd()) : 0.0f);
|
||||
|
||||
// ---- Address (second line) ----
|
||||
{
|
||||
float addrAvailW = contentRight - labelX;
|
||||
float addrAvailW = line2RightStart - Layout::spacingMd() - labelX;
|
||||
ImVec2 fullAddrSz = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0.0f, addr.address.c_str());
|
||||
std::string display_addr;
|
||||
if (fullAddrSz.x <= addrAvailW) {
|
||||
@@ -624,14 +731,17 @@ void RenderSharedAddressList(App* app, float listH, float availW,
|
||||
DrawTextShadow(dl, body2, body2->LegacySize, ImVec2(balX, cy), balCol, balBuf);
|
||||
}
|
||||
|
||||
// ---- USD value (second line, right-aligned) ----
|
||||
// ---- Line 2 right: period-earnings (left of) + USD value, right-aligned ----
|
||||
{
|
||||
std::string usdText = FormatAddressUsdValue(addr.balance, state.market.price_usd);
|
||||
if (!usdText.empty()) {
|
||||
ImVec2 usdSz = capFont->CalcTextSizeA(capFont->LegacySize, FLT_MAX, 0, usdText.c_str());
|
||||
const float line2Y = cy + body2->LegacySize + Layout::spacingXs();
|
||||
if (earnShown && earnBuf[0]) {
|
||||
dl->AddText(capFont, capFont->LegacySize,
|
||||
ImVec2(contentRight - usdSz.x,
|
||||
cy + body2->LegacySize + Layout::spacingXs()),
|
||||
ImVec2(contentRight - usdW - Layout::spacingMd() - earnW, line2Y),
|
||||
earnCol, earnBuf);
|
||||
}
|
||||
if (!usdText.empty()) {
|
||||
dl->AddText(capFont, capFont->LegacySize,
|
||||
ImVec2(contentRight - usdW, line2Y),
|
||||
OnSurfaceDisabled(), usdText.c_str());
|
||||
}
|
||||
}
|
||||
@@ -728,6 +838,15 @@ void RenderSharedAddressList(App* app, float listH, float availW,
|
||||
if (ImGui::MenuItem(TR("favorite_address")))
|
||||
app->favoriteAddress(addr.address);
|
||||
}
|
||||
// Per-address earnings column toggle (when the global show-all toggle is off).
|
||||
if (app->settings()) {
|
||||
const bool shown = app->settings()->isAddressEarningsShown(addr.address);
|
||||
if (ImGui::MenuItem(shown ? TR("hide_earnings") : TR("show_earnings"))) {
|
||||
if (shown) app->settings()->hideAddressEarnings(addr.address);
|
||||
else app->settings()->showAddressEarnings(addr.address);
|
||||
app->settings()->save();
|
||||
}
|
||||
}
|
||||
// Portfolio membership — toggle this address in each Market-tab portfolio entry.
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginMenu(TR("portfolio_add_to"))) {
|
||||
@@ -818,7 +937,8 @@ void RenderSharedAddressList(App* app, float listH, float availW,
|
||||
listPanelMin.y, listPanelMax.y, fadeZone, addrScrollY, addrScrollMaxY);
|
||||
}
|
||||
|
||||
// Address count
|
||||
// Address count + create-address buttons (relocated below the list to free the toolbar row for
|
||||
// the earnings controls). Count on the left, New Z / New mining right-aligned on the same row.
|
||||
{
|
||||
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
|
||||
char countBuf[128];
|
||||
@@ -826,6 +946,38 @@ void RenderSharedAddressList(App* app, float listH, float availW,
|
||||
snprintf(countBuf, sizeof(countBuf), TR("showing_x_of_y"),
|
||||
(int)rows.size(), totalAddrs);
|
||||
Type().textColored(TypeStyle::Caption, OnSurfaceDisabled(), countBuf);
|
||||
|
||||
float buttonWidth = ((addrBtn.width > 0) ? addrBtn.width : 140.0f) * dp;
|
||||
float spacing = ((addrBtn.gap > 0) ? addrBtn.gap : 8.0f) * dp;
|
||||
float totalButtonsWidth = buttonWidth * 2 + spacing;
|
||||
float rightMargin = S.drawElement("tabs.balance", "button-row-right-margin").sizeOr(16.0f);
|
||||
ImGui::SameLine(std::max(ImGui::GetCursorPosX(),
|
||||
ImGui::GetWindowWidth() - totalButtonsWidth - rightMargin));
|
||||
|
||||
bool sharedAddrSyncing = state.sync.syncing && !state.sync.isSynced();
|
||||
ImGui::BeginDisabled(sharedAddrSyncing);
|
||||
if (s_generating_z_address) {
|
||||
char genLabel[64];
|
||||
snprintf(genLabel, sizeof(genLabel), "%s%s##shared_z", TR("generating"), material::LoadingDots());
|
||||
TactileButton(genLabel, ImVec2(buttonWidth, 0),
|
||||
S.resolveFont(addrBtn.font.empty() ? "button" : addrBtn.font));
|
||||
} else if (TactileButton(TR("new_z_address"), ImVec2(buttonWidth, 0),
|
||||
S.resolveFont(addrBtn.font.empty() ? "button" : addrBtn.font))) {
|
||||
s_generating_z_address = true;
|
||||
app->createNewZAddress([](const std::string& addr) {
|
||||
s_generating_z_address = false;
|
||||
DEBUG_LOGF("Created new z-address: %s\n", addr.c_str());
|
||||
});
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (TactileButton(TR("new_mining_address"), ImVec2(buttonWidth, 0),
|
||||
S.resolveFont(addrBtn.font.empty() ? "button" : addrBtn.font))) {
|
||||
app->createNewTAddress([](const std::string& addr) {
|
||||
DEBUG_LOGF("Created new t-address: %s\n", addr.c_str());
|
||||
});
|
||||
}
|
||||
if (ImGui::IsItemHovered()) material::Tooltip("%s", TR("tt_new_mining_address"));
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
namespace dragonx {
|
||||
@@ -31,5 +33,10 @@ void RenderSharedAddressList(App* app, float listH, float availW, float glassRou
|
||||
void RenderSharedRecentTx(App* app, float recentH, float availW, float hs, float vs);
|
||||
void RenderSyncBar(App* app, ImDrawList* dl, float vs);
|
||||
|
||||
// Total period-earnings for the whole wallet, formatted per the earnings settings. Returns false
|
||||
// (and leaves out* untouched) when the global earnings toggle is off, so layouts show it only when
|
||||
// the user has opted into the earnings view. Shared by RenderCompactHero and the layout totals.
|
||||
bool FormatTotalEarnings(App* app, std::string& outText, ImU32& outCol);
|
||||
|
||||
} // namespace ui
|
||||
} // namespace dragonx
|
||||
|
||||
@@ -364,7 +364,7 @@ static void RenderBalanceClassic(App* app)
|
||||
OnSurfaceMedium(), DRAGONX_TICKER);
|
||||
cy += sub1->LegacySize + valGap;
|
||||
|
||||
// USD value
|
||||
// USD value (+ total period-earnings to its right when the earnings toggle is on)
|
||||
{
|
||||
double usd_value = state.getBalanceUSD();
|
||||
if (usd_value > 0.0)
|
||||
@@ -373,6 +373,12 @@ static void RenderBalanceClassic(App* app)
|
||||
snprintf(buf, sizeof(buf), "$-.-- USD");
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, cy),
|
||||
OnSurfaceDisabled(), buf);
|
||||
std::string earnText; ImU32 earnCol;
|
||||
if (FormatTotalEarnings(app, earnText, earnCol)) {
|
||||
float usdW = capFont->CalcTextSizeA(capFont->LegacySize, 10000, 0, buf).x;
|
||||
dl->AddText(capFont, capFont->LegacySize,
|
||||
ImVec2(cx + usdW + tickGap * 3.0f, cy), earnCol, earnText.c_str());
|
||||
}
|
||||
}
|
||||
cy += capFont->LegacySize + 2 * dp;
|
||||
|
||||
|
||||
@@ -1065,6 +1065,18 @@ void I18n::loadBuiltinEnglish()
|
||||
strings_["filter"] = "Filter...";
|
||||
strings_["no_addresses_yet"] = "No addresses yet";
|
||||
strings_["showing_x_of_y"] = "Showing %d of %d addresses";
|
||||
strings_["tt_earn_interval"] = "Earnings period: 1H = this hour, 1D = today, 1M = this month, 1Y = this year";
|
||||
strings_["tt_earn_mode_inflows"] = "Earnings mode: amounts received (including mined)";
|
||||
strings_["tt_earn_mode_net"] = "Earnings mode: net (received minus sent)";
|
||||
strings_["tt_earn_show_all"] = "Show the earnings figure for every address";
|
||||
strings_["show_earnings"] = "Show earnings";
|
||||
strings_["hide_earnings"] = "Hide earnings";
|
||||
strings_["earnings_label"] = "Earnings";
|
||||
strings_["earnings_format"] = "Earnings Display Format";
|
||||
strings_["tt_earnings_format"] = "How the per-address and total earnings figures are shown";
|
||||
strings_["earnings_format_coin"] = "Coin only";
|
||||
strings_["earnings_format_coin_fiat"] = "Coin + fiat";
|
||||
strings_["earnings_format_fiat"] = "Fiat only";
|
||||
strings_["set_label"] = "Set Label";
|
||||
strings_["copied"] = "Copied!";
|
||||
strings_["hidden_tag"] = " (hidden)";
|
||||
|
||||
Reference in New Issue
Block a user