aboutsummaryrefslogtreecommitdiffstats
path: root/src/app.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-06-16 00:06:09 -0700
committerAdam Soltys <[email protected]>2026-06-16 00:06:09 -0700
commitdb438d1d6feb6edccf782e0e22793cf8e4602cb1 (patch)
tree6fe91c0c7c195f558713c7bcb7a100ce6b9bcf90 /src/app.js
parent6803575cb3fcbe1bb92a6c40b9e810a294f5d657 (diff)
downloadcoinosv3-db438d1d6feb6edccf782e0e22793cf8e4602cb1.tar.gz
coinosv3-db438d1d6feb6edccf782e0e22793cf8e4602cb1.zip
Add "Payment received!" celebration on the Receive tab
When a deposit lands on the shown address, the Receive tab now shows a "Payment received!" dialog (with the amount and a green check) and waits for a tap before revealing the next address/QR — instead of silently swapping it. Tracks the acknowledged fresh index so only payments that arrive while watching trigger it. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Diffstat (limited to 'src/app.js')
-rw-r--r--src/app.js30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/app.js b/src/app.js
index a017841..3f24c1c 100644
--- a/src/app.js
+++ b/src/app.js
@@ -33,6 +33,7 @@ const ui = {
unlockError: '',
tab: 'receive', // receive | send | history | settings
+ receiveSeenIndex: null, // fresh receive index the user has acknowledged
send: blankSend(),
draft: null, // built tx summary awaiting review
sendError: '',
@@ -411,6 +412,9 @@ async function enterWallet(mnemonic, passphrase) {
// a brand-new wallet does one full scan.
if (hadCache || hadNostr) await wallet.refreshLive();
else await wallet.scan();
+ // Align the acknowledged index after load so we only celebrate payments
+ // that land while watching (not historical reconciliation).
+ ui.receiveSeenIndex = wallet.nextReceiveIndex;
wallet.startRealtime();
} catch {
enterOfflineFallback();
@@ -477,6 +481,7 @@ function lock() {
ui.passphrase = '';
ui.confirm = [];
ui.revealShown = false;
+ ui.receiveSeenIndex = null;
render();
}
@@ -638,6 +643,30 @@ function tabContent() {
// ---------------------------------------------------------------- Receive
function receiveTab() {
+ if (ui.receiveSeenIndex == null) ui.receiveSeenIndex = wallet.nextReceiveIndex;
+
+ // A payment landed on the shown address (the fresh index advanced past what
+ // the user last saw) — celebrate, and wait for a tap before showing the next.
+ if (wallet.nextReceiveIndex > ui.receiveSeenIndex) {
+ let amt = 0;
+ for (let i = ui.receiveSeenIndex; i < wallet.nextReceiveIndex; i++) {
+ const e = wallet._addrInfo(0, i);
+ if (e) amt += (e.confirmed || 0) + (e.pending || 0);
+ }
+ return h(
+ 'div',
+ {
+ class: 'card col',
+ style: 'align-items:center;text-align:center;gap:14px;cursor:pointer;padding:48px 20px',
+ onClick: () => { ui.receiveSeenIndex = wallet.nextReceiveIndex; render(); },
+ },
+ h('div', { class: 'check-badge' }, '✓'),
+ h('h2', { style: 'margin:0' }, 'Payment received!'),
+ amt ? h('div', { class: 'amount-pos', style: 'font-size:18px' }, '+' + fmtAmount(amt) + ' ' + unitLabel()) : null,
+ h('div', { class: 'small muted' }, 'Tap anywhere to proceed')
+ );
+ }
+
const fresh = wallet.freshReceive();
return h(
'div',
@@ -1044,3 +1073,4 @@ async function importSnapshotFile(e) {
// ================================================================ start
// Restore a wallet left open in this tab; otherwise show the unlock screen.
if (!restoreSession()) render();
+