diff options
| author | Adam Soltys <[email protected]> | 2026-08-15 13:15:45 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-08-15 13:15:45 -0700 |
| commit | e075c24af05e7e3d17277d5fbce32995026f38b6 (patch) | |
| tree | 7486dffd483b0a244935f510748d6f7566a7210c /src | |
| parent | 0b7ae7dbcbfe9688708e5939c94dd01594f43184 (diff) | |
| download | coinosv3-e075c24af05e7e3d17277d5fbce32995026f38b6.tar.gz coinosv3-e075c24af05e7e3d17277d5fbce32995026f38b6.zip | |
Welcome DMs stop echoing: sent-copies thread under their recipient whichever identity authored them, the registrar keeps no sender copy at all, and the old self-thread residue sweeps itself
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_014tE4U5nEjGTQy8PwYqamfv
Diffstat (limited to 'src')
| -rw-r--r-- | src/features/messages.js | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/src/features/messages.js b/src/features/messages.js index 4b11019..c8f2792 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -910,7 +910,14 @@ export function messagesFeature(ctx) { const got = await unwrapDM(wrap, d).catch(() => null); if (!got) continue; if (got.rumor.kind === 14) { - noteDM(got.peer, got.rumor, isMe(got.author)); + // unwrapDM judges "mine" against the key that DECRYPTED, but this + // wallet can hold several identities (wallet key + nostr login). A + // sent-copy authored by any of them must thread under the RECIPIENT, + // or every welcome DM the registrar sends lands in a self-thread. + const mine = isMe(got.author); + const to = got.rumor.tags?.find((x) => x[0] === 'p')?.[1]; + const peer = mine ? (to || got.peer || got.author) : got.author; + noteDM(peer, got.rumor, mine); persistDms(); } else if (got.rumor.kind === 3313 && !isMe(got.author)) { try { @@ -938,11 +945,22 @@ export function messagesFeature(ctx) { const pks = myPubkeys(); if (!pks.length) return; dmStarted = true; - // warm threads from the local cache + // warm threads from the local cache. A self-thread of our own messages is + // the residue of the old sent-copy misthreading (each welcome DM landed + // under our own key) — sweep it rather than resurrect it; the cached + // rows carry no tags, so they cannot be re-threaded to their recipients. const s = st(); - for (const [peer, list] of Object.entries(s.dms)) + let swept = false; + for (const [peer, list] of Object.entries(s.dms)) { + if (isMe(peer) && list.every((m) => isMe(m.from))) { + delete s.dms[peer]; + swept = true; + continue; + } for (const m of list) threadOf(peer).set(m.id, { rumor: { id: m.id, pubkey: m.from, content: m.text, created_at: m.t, kind: 14 }, mine: isMe(m.from) }); + } + if (swept) save(s); allUnsubs.push(subscribeOn(DM_RELAYS, { kinds: [1059], '#p': pks, limit: 400 }, (wrap) => { handleInboxWrap(wrap).catch(() => {}); })); |
