fix(history): stop the "refreshing wallet history" banner from never clearing

The banner was driven by transactions_dirty_, which refreshTransactionData() sets to
!shieldedScanComplete. The shielded-receive scan marks each z-address "scanned at tip,"
but every new block (~36s on DRGX) advances the tip and invalidates all prior per-address
scans, so for a wallet with more z-addresses than the per-cycle budget (8 on History) the
scan can never catch the tip — shieldedScanComplete stays false, transactions_dirty_ stays
true, and the banner stayed lit indefinitely.

Decouple the user-facing banner from that perpetual background scan:
- A just-sent transaction being enriched still surfaces (the user is waiting on it).
- Once any history is displayed, stay quiet for routine background refreshes — new receives
  still appear live as they're scanned.
- The loading banner now only shows during the genuine INITIAL load (nothing displayed yet)
  and send enrichment.

This is a UI-visibility fix; the underlying per-block full shielded rescan (and the related
send-progress flag that maybeFinishTransactionSendProgress gates on transactions_dirty_) are
separate follow-ups.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-09 22:41:03 -05:00
parent 560f2bcf91
commit cf77c6cbe0

View File

@@ -3633,18 +3633,23 @@ std::string App::transactionRefreshProgressText() const
bool canRefresh = state_.connected && !state_.warming_up && !state_.isLocked();
if (!running && !(canRefresh && transactions_dirty_)) return {};
if (!running && transactions_dirty_) return TR("tx_loading_queued");
char buf[128];
// A just-sent transaction being enriched always surfaces — the user is actively waiting on it.
if (!send_txids_.empty()) {
snprintf(buf, sizeof(buf), TR("tx_loading_enriching_sends"), (int)send_txids_.size());
return buf;
}
if (!state_.transactions.empty()) {
snprintf(buf, sizeof(buf), TR("tx_loading_refreshing_cached"), (int)state_.transactions.size());
return buf;
}
// Once history is on screen, stay quiet for routine background refreshes. The incremental
// shielded-receive scan re-dirties transactions_dirty_ on EVERY new block (each block moves the
// "scanned at tip" bar, invalidating prior per-address scans), so for a wallet with more
// z-addresses than the per-cycle scan budget the flag never clears — which left this banner lit
// indefinitely. New receives still appear live as they're scanned; only the INITIAL load
// (nothing displayed yet) and send enrichment (above) warrant a loading banner.
if (!state_.transactions.empty()) return {};
if (!running && transactions_dirty_) return TR("tx_loading_queued");
if (!state_.z_addresses.empty()) {
snprintf(buf, sizeof(buf), TR("tx_loading_scanning_shielded"), (int)state_.z_addresses.size());