diff --git a/src/index.html b/src/index.html index 106ea6d..5cf56ab 100644 --- a/src/index.html +++ b/src/index.html @@ -21117,6 +21117,24 @@ } // Card factory used by both the initial render and the streaming-update diff. + // Encode the bits of a row that affect what gets drawn into the card, + // so diffWallCards can detect when an existing card needs to be + // rebuilt rather than reused. Most importantly: the author's profile + // (and therefore the Tip button's presence) arrives async AFTER the + // initial card render — without this stamp, the card stays in its + // tip-less state forever. + function _feedCardStateStamp(row) { + const pk = row?.e?.pubkey || ''; + const profile = _feedCache.profiles?.[pk] || null; + const hasLn = !!(profile?.lud16 || profile?.lud06); + const reactions = row?.reactions || 0; + const zapBucket = Math.floor((zapTotalForEvent(row?.e?.id || '') || 0) / 1000); + const premiumDecrypted = !!(row?.premium && row.premium.decrypted); + const premiumGated = !!(row?.zapGate && row.zapGate.gated && !row.zapGate.unlocked); + const broken = isPreviewBroken(row) ? 1 : 0; + return `ln=${hasLn ? 1 : 0}|rx=${reactions}|z=${zapBucket}|pd=${premiumDecrypted ? 1 : 0}|pg=${premiumGated ? 1 : 0}|b=${broken}`; + } + function buildFeedCardForRow(row) { const card = buildFeedCard(row, () => { if (tryDesignLayerImportRow(row)) return; @@ -21135,6 +21153,7 @@ $('nostrModal').classList.remove('open'); }); card.dataset.eventId = row.e?.id || ''; + card.dataset.cardStamp = _feedCardStateStamp(row); return card; } @@ -21158,6 +21177,18 @@ let card = existing.get(id); if (card) { existing.delete(id); + // Rebuild the card if its state stamp changed (e.g. the author's + // profile finally arrived → tip button now applicable). The + // stamp is set by buildFeedCardForRow; absent on cards built + // through a different path → always reuse those, to preserve + // legacy behaviour. + const currentStamp = card.dataset?.cardStamp; + const newStamp = (typeof _feedCardStateStamp === 'function') ? _feedCardStateStamp(row) : currentStamp; + if (currentStamp && newStamp && currentStamp !== newStamp) { + const fresh = buildCardFn(row); + card.replaceWith(fresh); + card = fresh; + } } else { card = buildCardFn(row); }