diff options
| author | Adam Soltys <[email protected]> | 2026-10-13 13:04:52 +0000 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-10-13 13:04:52 +0000 |
| commit | f3d03c642bef06b3afc8a3038136c5e0fc1e21f7 (patch) | |
| tree | 11f43f80c14d9c712d12ba86820ca38fa51b9bf1 /src/features/messages.js | |
| parent | cd058495e11d76bb5afe4fe85b5131adaa387ca1 (diff) | |
| download | coinosv3-f3d03c642bef06b3afc8a3038136c5e0fc1e21f7.tar.gz coinosv3-f3d03c642bef06b3afc8a3038136c5e0fc1e21f7.zip | |
Profiles show boosts as boosts, and their saved copy keeps each post's kind
A boost that reached a profile from the feed was saved as a kind 1 note,
so reopened it drew its raw JSON as a reply; video events and polls lost
their kind and tags the same way. The saved copy now keeps kinds (boosts
whole), old copies are dropped, and profiles ask for boosts too.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01KPw21NEpWeTGu6swVASmBt
Diffstat (limited to 'src/features/messages.js')
| -rw-r--r-- | src/features/messages.js | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/src/features/messages.js b/src/features/messages.js index 1d9fd61..3cb94fd 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -566,7 +566,8 @@ export function messagesFeature(ctx) { } let repostBy = null; // set while noteRow draws a repost's note // A profile shows its articles (NIP-23) among the notes, as Amethyst does. - const PROFILE_KINDS = [...FEED_KINDS, 30023]; + // Their boosts too, under "<name> reposted", as in a feed. + const PROFILE_KINDS = [...FEED_KINDS, 30023, REPOST]; // An edited article is a new event at the same address: keep the newest. const newestArticles = (evs) => { const best = new Map(); @@ -3825,13 +3826,16 @@ export function messagesFeature(ctx) { const pageCache = () => { try { const c = wallet.loadFeatureState(PROF_PAGE_CACHE, {}) || {}; - return { full: c.full || {}, notes: c.notes || {} }; + // (notes saved before nv 2 were all flattened to kind 1: a boost's + // JSON, a clip without its imeta — not worth keeping) + return { full: c.full || {}, notes: c.nv === 2 ? c.notes || {} : {} }; } catch { return { full: {}, notes: {} }; } }; function persistPage(kind, pk, value) { try { const c = pageCache(); c[kind][pk] = { t: Date.now(), v: value }; + c.nv = 2; for (const k of ['full', 'notes']) { const keys = Object.keys(c[k]).sort((a, b) => c[k][b].t - c[k][a].t); for (const drop of keys.slice(10)) delete c[k][drop]; @@ -3842,14 +3846,20 @@ export function messagesFeature(ctx) { // (an article keeps its kind, its card's tags and, near enough, all of // itself: a tap opens it to read) const ARTICLE_TAGS = ['d', 'title', 'summary', 'image', 'published_at']; + // (a note keeps its kind and what draws it: its clips, a poll's options) + const NOTE_TAGS = ['e', 'p', 'q', 'd', 'imeta', 'title', 'option', 'polltype', 'endsAt', 'relay', 'emoji', 'content-warning']; const slimNote = (ev) => ev.kind === 30023 ? { id: ev.id, pubkey: ev.pubkey, kind: 30023, created_at: ev.created_at, content: String(ev.content || '').slice(0, 30000), tags: (ev.tags || []).filter((x) => ARTICLE_TAGS.includes(x[0])), + } : ev.kind === REPOST ? { + // a boost whole: the note inside is checked against its signature + id: ev.id, pubkey: ev.pubkey, kind: REPOST, created_at: ev.created_at, + content: String(ev.content || ''), tags: (ev.tags || []).filter((x) => x[0] === 'e' || x[0] === 'p'), } : { - id: ev.id, pubkey: ev.pubkey, kind: 1, created_at: ev.created_at, + id: ev.id, pubkey: ev.pubkey, kind: ev.kind, created_at: ev.created_at, content: String(ev.content || '').slice(0, 3000), - tags: (ev.tags || []).filter((x) => x[0] === 'e' || x[0] === 'p'), + tags: (ev.tags || []).filter((x) => NOTE_TAGS.includes(x[0])), }; function fetchFullProfile(pk) { |
