aboutsummaryrefslogtreecommitdiffstats
path: root/src/features
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-09-17 15:33:46 -0700
committerAdam Soltys <[email protected]>2026-09-17 15:33:46 -0700
commitec3bd3e3155d312d88f0f215b24ab131901b36b1 (patch)
tree249a9cbd7cd5977a3240bb9c8682a32ce9a56626 /src/features
parent2f8794174fd4c441bf6c4b7553b4458cf23631ea (diff)
downloadcoinosv3-ec3bd3e3155d312d88f0f215b24ab131901b36b1.tar.gz
coinosv3-ec3bd3e3155d312d88f0f215b24ab131901b36b1.zip
Feed: the zap tally rides on the action-bar bolt, not the header.
The sats total used to sit up by the timestamp as its own chip; now it is the count on the zap button, like likes and boosts have theirs. Amber once anyone has zapped, breathing while ours is in flight, and shown read-only (no zap handler) on posts you can't zap so the number still reads. Co-Authored-By: Claude Fable 5.1 <[email protected]>
Diffstat (limited to 'src/features')
-rw-r--r--src/features/messages.js27
1 files changed, 21 insertions, 6 deletions
diff --git a/src/features/messages.js b/src/features/messages.js
index 0e94b87..acde0cb 100644
--- a/src/features/messages.js
+++ b/src/features/messages.js
@@ -4455,14 +4455,24 @@ export function messagesFeature(ctx) {
const rm = reacts.get(ev.id);
const likeN = rm ? [...rm.values()].reduce((n, who) => n + who.size, 0) : 0;
const boostN = (boosts.get(ev.id) || new Set()).size;
- const btn = (icon, label, count, on, onClick) => h('button', {
- class: 'note-act' + (on ? ' on' : ''), title: label, 'aria-label': label,
- onClick: (e) => { e.stopPropagation(); onClick(); },
+ const btn = (icon, label, count, on, onClick, cls = '') => h('button', {
+ class: 'note-act' + (on ? ' on' : '') + (cls ? ' ' + cls : ''), title: label, 'aria-label': label,
+ 'aria-disabled': onClick ? undefined : 'true',
+ onClick: (e) => { e.stopPropagation(); if (onClick) onClick(); },
},
typeof icon === 'string' && icon.startsWith('<svg')
? h('span', { style: 'display:flex', html: icon })
: h('span', { class: 'note-act-emoji' }, icon),
count ? h('span', { class: 'note-act-n' }, String(count)) : null);
+ // the sats tally rides on the zap button, like the like and boost counts
+ // do on theirs — amber once anyone has zapped, breathing while ours flies
+ const z = zapTotals.get(ev.id) || zapSeeds().get(ev.id);
+ const zp = pendingOf(ev.id);
+ const optimistic = zp && zp.state !== 'void' ? zp.sats : 0;
+ const zapSats = (z ? z.sats : 0) + optimistic;
+ const zapFlying = !!zp && zp.state === 'flying';
+ const zapMine = !!((z && z.mine) || optimistic);
+ const zapLabel = zapFlying ? t('zapSending') : zapSats ? t('zapTallyTitle', { n: zapSats.toLocaleString() }) : t('zapTitle');
return h('div', { class: 'row note-acts' },
btn(I_REPLY, t('msgReply'), 0, false, () => replyToNote(ev)),
btn(I_BOOST, t('postBoost'), boostN, iBoosted(ev.id), () => boostNote(ev).catch(() => {})),
@@ -4470,7 +4480,13 @@ export function messagesFeature(ctx) {
// tap to choose how you feel about it; tap again to take it back
btn(mineReact || I_HEART(false), t('postLike'), likeN, !!mineReact,
() => { if (mineReact) unreact(ev).catch(() => {}); else { ui.reactPick = ev; render(); } }),
- canZap ? btn(I_ZAP, t('zapTitle'), 0, false, () => { zapNote(pk, ev); recheckZap(ev.id); }) : null,
+ // shown whenever there is a tally to read, even where zapping is off
+ // (own post, no wallet) — then it is just a number, not a button
+ canZap || zapSats
+ ? btn(I_ZAP, zapLabel, zapSats ? fmtSats(zapSats) : 0, zapMine,
+ canZap ? () => { zapNote(pk, ev); recheckZap(ev.id); } : null,
+ 'note-zap' + (zapSats ? ' zapped' : '') + (zapFlying ? ' flying' : ''))
+ : null,
// who did all that: a small chevron, only once there is anyone to show
whoCount(ev.id)
? h('button', {
@@ -4581,8 +4597,7 @@ export function messagesFeature(ctx) {
onClick: (e) => { e.stopPropagation(); openProfile(pk); },
}, name),
h('span', { class: 'small faint', style: 'white-space:nowrap' },
- (isReply ? '↩ ' + t('profReplyTag') + ' · ' : '') + timeLabel(ev.created_at * 1000)),
- zapChip(ev.id, { onClick: canZap ? () => { zapNote(pk, ev); recheckZap(ev.id); } : null })),
+ (isReply ? '↩ ' + t('profReplyTag') + ' · ' : '') + timeLabel(ev.created_at * 1000))),
pending ? null : h('button', {
// the overflow stays up here; reply, boost, quote, react and zap
// are a row of their own under the post