From 4d43840fe9c50c571dbb504e3b747d79a21b2e81 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Mon, 2 Nov 2026 15:36:59 -0700 Subject: A thread's heart count says what its who-panel lists. "Why does the count beside the heart say 1 if I have 2 heart reactions?" (Adam, 2026-11-02): a thread remembers its counts between visits so that a short relay answer can't erase them, and the bar showed the memory alone — while the tally in hand, which the who-panel reads, had the second heart, brought by the feed's own count fetch before the thread was opened again (the memory is only brought up to date while the thread is on screen). The bar now shows the larger of the remembered number and the live tally, hearts, boosts and sats alike. tools/thread-like-count-test.js opens a thread by its link with one heart on the relay, comes back through the feed when there are two, and checks the thread says 2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01VMan6TFgisGKUDhdStLUvs --- src/features/messages.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src/features/messages.js') diff --git a/src/features/messages.js b/src/features/messages.js index b7982c6..e3cdc8d 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -11990,8 +11990,16 @@ export function messagesFeature(ctx) { const rm = reacts.get(ev.id); const cached = ui.noteThread ? threadCache.get(ui.noteThread.rootId)?.counts?.[ev.id] : null; - const likeN = cached ? cached.likes : rm ? [...rm.values()].reduce((n, { who }) => n + visiblePks(who).length, 0) : 0; - const boostN = cached ? cached.boosts : visiblePks(boosts.get(ev.id) || new Set()).length; + // A thread remembers its counts between visits, so a short relay answer + // can't erase them — but what the relays HAVE brought since (a heart + // the feed's own count fetch tallied before this visit) outranks the + // memory: the number says what the who-panel below it lists. "Why does + // the count beside the heart say 1 if I have 2 heart reactions?" + // (Adam, 2026-11-02): the memory said 1, the tally in hand 2. + const liveLikes = rm ? [...rm.values()].reduce((n, { who }) => n + visiblePks(who).length, 0) : 0; + const liveBoosts = visiblePks(boosts.get(ev.id) || new Set()).length; + const likeN = cached ? Math.max(cached.likes || 0, liveLikes) : liveLikes; + const boostN = cached ? Math.max(cached.boosts || 0, liveBoosts) : liveBoosts; const btn = (icon, label, count, on, onClick, cls = '', extra = null) => h('button', { class: 'note-act' + (on ? ' on' : '') + (cls ? ' ' + cls : ''), title: label, 'aria-label': label, 'aria-disabled': onClick ? undefined : 'true', @@ -12007,7 +12015,7 @@ export function messagesFeature(ctx) { const z = zapTotals.get(ev.id) || zapSeeds().get(ev.id); const zp = pendingOf(ev.id); const optimistic = zp ? zp.sats : 0; - const zapSats = (cached ? cached.sats : z ? z.sats : 0) + optimistic; + const zapSats = Math.max(cached ? cached.sats || 0 : 0, z ? z.sats : 0) + optimistic; const zapFlying = !!zp && zp.flying; // tap pays the default amount; hold opens the screen that sets it const zapHold = canZap ? holdable((el) => openZapSettings(pk, ev.id, el.getBoundingClientRect()), -- cgit v1.2.3