aboutsummaryrefslogtreecommitdiffstats
path: root/src/features/gifts.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-07-06 11:12:31 -0700
committerAdam Soltys <[email protected]>2026-07-06 11:12:31 -0700
commitd071a09604599831d370b06563144cf4ba028902 (patch)
treecf5974694de768a5128f044d255b399fa3eb18dd /src/features/gifts.js
parentef1a901314cb667bc8a7c7ff5f080550edef2815 (diff)
downloadcoinosv3-d071a09604599831d370b06563144cf4ba028902.tar.gz
coinosv3-d071a09604599831d370b06563144cf4ba028902.zip
Gift cross-device sync, snapshot size cap, reliable SW updates, gift-detail layout
- Gifts now sync across devices: gift records + reserved/reclaimed coin sets ride the encrypted snapshot as a merge-safe extension (like ark), and every gift state change (create/reclaim/revoke) triggers a saveCache so it actually publishes. A gift made on one device now shows on the others. - Cap the published snapshot at ~40KB JSON (relay rejects >64KB events, nip44 expands ~1.5x): trim oldest on-chain txs when oversized; another device backfills via rescan. Typical wallets untouched. - Service worker: register with updateViaCache:'none' so a new build is detected immediately (not held by the 4h HTTP cache), and reload once on controllerchange so the fresh app runs without a manual second refresh. - Gift detail: View/Reclaim share a row, Revoke on its own full-width line so 'Revoke now' stops wrapping. Co-Authored-By: Claude Fable 5 <[email protected]>
Diffstat (limited to 'src/features/gifts.js')
-rw-r--r--src/features/gifts.js13
1 files changed, 9 insertions, 4 deletions
diff --git a/src/features/gifts.js b/src/features/gifts.js
index 27fea33..86bc3b6 100644
--- a/src/features/gifts.js
+++ b/src/features/gifts.js
@@ -781,10 +781,15 @@ export function giftsFeature(ctx) {
h('span', { class: 'small muted' }, g.reserved ? t('giftReclaimPrompt') : t('giftRevokeConfirm')),
ui.busy
? h('button', { class: 'btn-primary btn-block', disabled: true }, h('span', { class: 'spinner' }))
- : h('div', { class: 'row gap6' },
- rec ? h('button', { class: 'grow', onClick: () => { ui.viewGift = rec; render(); } }, t('giftView')) : null,
- g.reserved ? h('button', { class: 'btn-ghost grow', onClick: () => doReclaim(g.id) }, t('giftReclaim')) : null,
- h('button', { class: 'btn-primary grow', onClick: () => doRevoke(g.id) }, t('giftRevoke')))),
+ // View + Reclaim share a row; Revoke gets its own full-width line
+ // so "Revoke now" never squishes/wraps against the others.
+ : h('div', { class: 'col', style: 'gap:8px' },
+ (rec || g.reserved)
+ ? h('div', { class: 'row gap6' },
+ rec ? h('button', { class: 'grow', onClick: () => { ui.viewGift = rec; render(); } }, t('giftView')) : null,
+ g.reserved ? h('button', { class: 'btn-ghost grow', onClick: () => doReclaim(g.id) }, t('giftReclaim')) : null)
+ : null,
+ h('button', { class: 'btn-primary btn-block', onClick: () => doRevoke(g.id) }, t('giftRevoke')))),
h('button', { class: 'btn-ghost btn-block', onClick: back }, t('back'))
);
}