diff options
| author | Adam Soltys <[email protected]> | 2026-10-15 15:24:25 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-10-15 15:24:25 -0700 |
| commit | 38ce0b441505d0bdd048d38c82ac95afe4d3b407 (patch) | |
| tree | 111711030a02cd8eec42c8e75c5de8c8ed1bacc5 /src/features/messages.js | |
| parent | 46829a7a54bf21138d8bb068966f7f083ac8df4c (diff) | |
| download | coinosv3-38ce0b441505d0bdd048d38c82ac95afe4d3b407.tar.gz coinosv3-38ce0b441505d0bdd048d38c82ac95afe4d3b407.zip | |
Lightning withdraw (LNURL-withdraw): a site's withdraw lnurl in Send gets paid to you; the media pager says when a picture can't be loaded. (1) LUD-03 (Adam, 2026-10-16: "add lnurlw support"): an lnurl whose terms are a withdrawRequest — found when the pay fetch meets one (fetchPayParams throws with the terms attached, resolve() takes them up) — shows the site, their range (or the fixed amount) and description, the amount field at their max; Withdraw makes an invoice over Ark for the amount (arkLnInvoice), hands it to their callback with k1 (submitWithdraw), and watches it (arkLnWatch): "has your invoice for…", then "Received …" on settlement; their refusal in their words, with Try again; Back before it is paid stops watching. An amount outside their range is told the range, nothing sent; a watch-only device says it can't receive. LUD-17 schemes lnurlw:// and lnurlp:// (and lightning: before them) are the URL over https, http on an onion (parseZapTarget). (2) A pager slide whose picture can't load — the server copy and then the original both failing (isolabellart's relay answering 502 that afternoon: the broken-picture glyph sat in the corner of a black slide) — hides the <img> and says "This picture couldn't be loaded" with the host, caption and controls kept (mp-gone / .mp-missing). tools/lnurl-auth-unit-test.js (lnurlw:// and lnurlp://, an onion, the terms, a pay fetch that finds a withdraw, the callback's k1 and pr, a refusal); tools/lnurl-withdraw-test.js (the zaps feature against a faked Ark and a stand-in site: the terms, max prefilled, out of range refused unsent, the invoice at the callback and watched, Received on settlement, a fixed amount with no field, Back unwatches, a refusal's reason); tools/pager-gone-picture-test.js; lnurl-auth and feed-picture-pager tests pass.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01J1Kon8bxJoHRpJdSzshCkp
Diffstat (limited to 'src/features/messages.js')
| -rw-r--r-- | src/features/messages.js | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/src/features/messages.js b/src/features/messages.js index d5da326..20cfaa6 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -12279,7 +12279,15 @@ export function messagesFeature(ctx) { ? h('video', { class: 'mp-media', 'data-src': url, loop: true, playsinline: true, preload: 'none', poster: videoThumbs.get(url) || posterOf(ev, url) || (videoInfo.get(url) || {}).image || serverThumb(url) }) : h('img', { class: 'mp-media', 'data-src': quick, 'data-full': url, alt: '', draggable: 'false', decoding: 'async', - onError: (e) => { const m = e.currentTarget; if ((m.getAttribute('src') || '') !== url) { m.setAttribute('data-src', url); m.setAttribute('src', url); } } }); + onError: (e) => { + const m = e.currentTarget; + if ((m.getAttribute('src') || '') !== url) { m.setAttribute('data-src', url); m.setAttribute('src', url); return; } + // the original is gone too (its host down, the file deleted): say + // so, in place of the browser's broken-picture glyph + let host = ''; try { host = new URL(url).hostname; } catch {} + m.closest('.mp-slide').classList.add('mp-gone'); + m.insertAdjacentElement('afterend', h('div', { class: 'mp-missing' }, h('div', { class: 'mp-missing-ico' }, '🖼'), h('div', {}, t('mediaPicGone')), host ? h('div', { class: 'small muted' }, host) : null)); + } }); const caption = mediaCaption(ev); const stop = (fn) => (e) => { e.stopPropagation(); fn(e); }; const slide = h('div', { class: 'mp-slide', 'data-k': mediaKey(it) }, |
