diff options
Diffstat (limited to 'src/features/messages.js')
| -rw-r--r-- | src/features/messages.js | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/src/features/messages.js b/src/features/messages.js index d6eacc9..0aa7291 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -1592,9 +1592,25 @@ export function messagesFeature(ctx) { node.classList.add('clickable'); node.addEventListener('click', (e) => { e.stopPropagation(); openProfile(pk); }); } - return hook('wrapAvatar', pk, node) || node; + return hook('wrapAvatar', pk, node) || hatStamp(pk, node) || node; }; + // The hats feature is a deferred chunk — until it lands, replay last + // session's boot stamps (hat art + geometry it persisted) so a hat sits on + // the head from the FIRST frame instead of popping in a beat later. Once + // hatsReady answers, the stamps stand down: a null from wrapAvatar then + // genuinely means "bare head". + let _hatStamps = null; + function hatStamp(pk, node) { + if (hook('hatsReady')) return null; + if (_hatStamps === null) { + try { _hatStamps = JSON.parse(localStorage.getItem('hat-stamps') || '{}'); } catch { _hatStamps = {}; } + } + const s = _hatStamps[pk]; + if (!s || !s.a) return null; + return h('span', { class: 'hat-wrap' }, node, h('span', { class: 'ava-hat', style: s.s, html: s.a })); + } + // ---- profiles: view + own kind-0 editor --------------------------------- const fullProfiles = new Map(); // pk -> { raw kind0 content object, fetched_at } |
