From 52b6ed80d2d54f66cce1783e966b68e72e746cec Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Wed, 26 Aug 2026 15:28:16 -0700 Subject: No borrowed faces: the seeded profile entry is marked provisional, so the avatar holds its quiet circle until the real kind 0 answers — punk art means "has no picture", never "picture not here yet" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_019eA8JRq9Wr7z2fRQk99HLi --- src/features/messages.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/features/messages.js b/src/features/messages.js index c4ed990..7bee3f8 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -645,11 +645,13 @@ export function messagesFeature(ctx) { } catch {} // The username is real display material: seed the light cache (stale, // t:0, so the kind 0 still gets fetched) and the page paints the name - // and fallback avatar art immediately instead of an npub prefix and - // an empty circle while the relays answer. + // immediately instead of an npub prefix. `loading` keeps the avatar a + // quiet circle meanwhile — punk art must mean "has no picture", never + // "picture not here yet", or the wrong face flashes before the real + // one loads. if (pk && /^[0-9a-f]{64}$/.test(pk)) { warmProfiles(); - if (!profiles.has(pk)) profiles.set(pk, { name, t: 0 }); + if (!profiles.has(pk)) profiles.set(pk, { name, t: 0, loading: true }); } } if (pk && /^[0-9a-f]{64}$/.test(pk)) { @@ -1132,8 +1134,9 @@ export function messagesFeature(ctx) { const avatar = (pk, cls = 'chat-avatar', clickable = true) => { const p = profileOf(pk); // While the profile is in flight, a quiet empty circle — the punk is a - // statement about having no picture, not a loading state. - const node = p === null + // statement about having no picture, not a loading state. (`loading` on + // an entry marks a provisional seed: name known, picture still unknown.) + const node = p === null || (p && p.loading && !p.picture) ? h('div', { class: cls + ' fallback loading' }) : p.picture // A background paints synchronously from cache; a fresh decodes -- cgit v1.2.3