diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/features/withdraw-links.js | 25 | ||||
| -rw-r--r-- | src/i18n.js | 4 |
2 files changed, 28 insertions, 1 deletions
diff --git a/src/features/withdraw-links.js b/src/features/withdraw-links.js index a63d180..38b2d8c 100644 --- a/src/features/withdraw-links.js +++ b/src/features/withdraw-links.js @@ -114,6 +114,18 @@ export function withdrawLinks(ctx) { } finally { s.taking = null; render(); load(); } } + // What became of the latest claim someone made (reclaims aside): on its + // way, or turned back with the sats still here. "I made a transaction for + // 1,000,000 sats using the Withdraw link method, but they never arrived" + // (a user, 2026-11-14): the claim had failed and the link said only + // "1,000,000 sats left". + function lastClaim(l) { + const c = (l.claims || []).filter((x) => !x.reclaim).at(-1); + if (!c || c.status === 'paid') return null; + if (c.status === 'paying') return { kind: 'paying', c }; + return l.status === 'open' && l.remainingSat >= c.sat ? { kind: 'failed', c } : null; + } + function linkCard(l) { const s = st(); const lnurl = lnurlOf(l); @@ -130,6 +142,15 @@ export function withdrawLinks(ctx) { live ? h('div', { class: 'addr-box break mono', style: 'width:100%;font-size:11px' }, lnurl) : h('div', { class: 'notice small' }, l.status === 'closed' ? t('wlClosed') : t('wlUsedUp')), live ? h('div', { class: 'row gap6 wrap', style: 'width:100%' }, copyBtn(lnurl, t('wlCopy'))) : null, live ? h('div', { class: 'small faint', style: 'text-align:center' }, t('wlBearer')) : null, + (() => { + const lc = lastClaim(l); + if (!lc) return null; + // while it's being paid, look again every 10 s so the answer shows up here + if (lc.kind === 'paying' && !s.poll) s.poll = setTimeout(() => { st().poll = null; if (ui.giftMode === 'lnurl') load(); }, 10_000); + return lc.kind === 'paying' + ? h('div', { class: 'notice info small wl-claim-paying', style: 'width:100%' }, t(lc.c.tries > 1 ? 'wlClaimRetrying' : 'wlClaimPaying', { amount: amt(lc.c.sat) })) + : h('div', { class: 'notice err small wl-claim-failed', style: 'width:100%' }, t('wlClaimFailed', { amount: amt(lc.c.sat) })); + })(), s.error && h('div', { class: 'notice err', style: 'width:100%' }, s.error), live || (l.status === 'open' && l.remainingSat > 0) ? (s.taking === l.id @@ -171,7 +192,9 @@ export function withdrawLinks(ctx) { ...s.list.map((l) => h('button', { class: 'row between wl-row', style: 'text-align:left', onClick: () => { s.open = l.id; s.made = null; s.error = ''; render(); } }, h('span', { class: 'small' }, amt(l.sat), l.uses > 1 ? ` × ${l.uses}` : '', l.note ? h('span', { class: 'faint' }, ' · ' + l.note) : null), h('span', { class: 'small faint' }, - l.status === 'closed' ? t('wlClosedTag') : l.remainingSat < 1 || l.used >= l.uses ? t('wlUsedUpTag') : t('wlLeft', { amount: amt(l.remainingSat) }))))); + l.status === 'closed' ? t('wlClosedTag') : l.remainingSat < 1 || l.used >= l.uses ? t('wlUsedUpTag') + : lastClaim(l)?.kind === 'failed' ? t('wlClaimFailedTag', { amount: amt(l.remainingSat) }) + : t('wlLeft', { amount: amt(l.remainingSat) }))))); } function view() { diff --git a/src/i18n.js b/src/i18n.js index baf2012..f4774f6 100644 --- a/src/i18n.js +++ b/src/i18n.js @@ -1805,6 +1805,10 @@ const STR = { wlTakeBackFailed: 'Couldn’t pay it back just now. The link stays open; try again in a moment.', wlClosed: 'This link is closed.', wlUsedUp: 'This link has been used up.', + wlClaimPaying: 'A claim of {amount} is on its way to the wallet that asked.', + wlClaimRetrying: "A claim of {amount} couldn't find a Lightning route yet. Still trying for a few minutes.", + wlClaimFailed: "A claim of {amount} couldn't be delivered: there was no Lightning route to the wallet that asked. Nothing was sent and the sats are still in this link. Claim it again, maybe for less or from another wallet, or take them back.", + wlClaimFailedTag: 'claim failed · {amount} left', wlClosedTag: 'closed', wlUsedUpTag: 'used up', wlYours: 'Your withdraw links', |
