From fdbae7472b42cf9bb8bbdf7d069be287a1cb7fc9 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Sat, 4 Jul 2026 08:20:41 -0700 Subject: Gift claim: instant 'Payment received!' after claiming Claiming into an existing wallet used to drop onto the Receive tab (address/QR visibly rotating) until the background scan noticed the credit and fired the celebration. The claim already knows it succeeded and for how much, so the celebration now shows immediately; the scan runs behind it and its receive-index advance is acknowledged so the generic celebration doesn't fire a second time. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy --- src/app.js | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) (limited to 'src/app.js') diff --git a/src/app.js b/src/app.js index cbac144..0c15304 100644 --- a/src/app.js +++ b/src/app.js @@ -2246,9 +2246,19 @@ async function doClaim() { } else { ui.screen = 'wallet'; // existing wallet — straight into it, no new seed to back up ui.claimStep = null; - toast(t('giftClaimedToast')); + ui.tab = 'receive'; + ui.giftJustClaimed = claim.amount; // celebration shows instantly, no scan wait } - wallet.scan().catch(() => {}); + wallet.scan().then(() => { + // The claim credit advances the fresh receive index in the background; + // ack it so the index-based celebration doesn't fire a second time + // behind the instant one we're already showing. + if (ui.giftJustClaimed != null) { + ui.receiveSeenIndex = wallet.nextReceiveIndex; + wallet.setReceiveAck(wallet.nextReceiveIndex); + render(); + } + }).catch(() => {}); } catch (e) { // Broadcast failed — most likely someone claimed it in the race window. // Re-check the funding coin and, if spent, show the "already claimed" screen. @@ -2810,6 +2820,29 @@ function hasRecentIncoming() { // ---------------------------------------------------------------- Receive function receiveTab() { + // A gift was just claimed into this wallet — celebrate immediately (the + // background scan credits the coin and advances the address meanwhile). + if (ui.giftJustClaimed != null) { + const amt = ui.giftJustClaimed; + return h( + 'div', + { + class: 'card col', + style: 'align-items:center;text-align:center;gap:14px;cursor:pointer;padding:48px 20px', + onClick: () => { + ui.giftJustClaimed = null; + ui.receiveSeenIndex = wallet.nextReceiveIndex; + wallet.setReceiveAck(wallet.nextReceiveIndex); + render(); + }, + }, + h('div', { class: 'check-badge' }, '✓'), + h('h2', { style: 'margin:0' }, t('paymentReceived')), + amt ? h('div', { class: 'amount-pos', style: 'font-size:18px' }, '+' + fmtAmount(amt) + ' ' + unitLabel()) : null, + h('div', { class: 'small muted' }, t('tapToProceed')) + ); + } + // A board just broadcast — show its success screen until dismissed. if (ui.arkBoarded) { const b = ui.arkBoarded; -- cgit v1.2.3