diff options
| author | Adam Soltys <[email protected]> | 2026-11-12 23:29:24 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-11-12 23:29:24 -0700 |
| commit | 5dad3fed20be40eaaeb8e7373dd005f61b3e5c8b (patch) | |
| tree | 4c356ca35093b33d3252b5b8897ca43f2b5aff72 /src/nip29-client.js | |
| parent | 5026227de10e424f590d2a042e5a8770266a6b5e (diff) | |
| download | coinosv3-5dad3fed20be40eaaeb8e7373dd005f61b3e5c8b.tar.gz coinosv3-5dad3fed20be40eaaeb8e7373dd005f61b3e5c8b.zip | |
Relay groups with nothing said wait at the bottom of Messages, and a dead relay says so. "They shouldn't be at the top if they have 0 members and no recent activity" (Adam, 2026-11-12), of four groups.0xchat.com groups that came in on his kind 10009 list (saved by Armada) and topped the phone's list. A group's place was its last message, else the moment this device first recorded it, so a list adoption counted as brand new. Now a relay group without messages sorts by when it was joined on this device (joinedAt, set by Join) and one that only arrived on the list sorts last. groups.0xchat.com no longer resolves: a group whose relay can't be reached and that has shown nothing reads "<host> isn't answering" on its row ("On <host>" while it is still quiet) instead of "0 members"; the mark clears with the relay's first event and on every start. nip29-group-test joins gone.invalid'deadgroup on the second device and reads the row
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6UKGJyuGyZFxddYRxS
Diffstat (limited to 'src/nip29-client.js')
| -rw-r--r-- | src/nip29-client.js | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/src/nip29-client.js b/src/nip29-client.js index 4c27b64..cfbd171 100644 --- a/src/nip29-client.js +++ b/src/nip29-client.js @@ -125,7 +125,7 @@ export function nip29Client({ scope, pubkey, identity, on, listRelays, store = m function load() { if (!loaded) loaded = store.all().then((all) => { - for (const [k, v] of all) if (k.startsWith('g:') && v && v.relay && v.gid) groups.set(v.id, { ...v, log: v.log || [] }); + for (const [k, v] of all) if (k.startsWith('g:') && v && v.relay && v.gid) groups.set(v.id, { ...v, log: v.log || [], unreachable: '' }); const l = all.get('list'); if (l && Array.isArray(l.tags)) list = l; }).catch((e) => dlog('nip29: store', e)); @@ -171,8 +171,12 @@ export function nip29Client({ scope, pubkey, identity, on, listRelays, store = m function subscribe(g) { if (subs.has(g.id) || stopped) return; const since = g.seen ? g.seen - 60 : undefined; + // a relay that can't be reached (groups.0xchat.com stopped resolving) + // is said on the group's row instead of "0 members" + const reached = () => { if (g.unreachable) { g.unreachable = ''; touch(g); emit('loaded', g); } }; const a = subscribeAuthed([g.relay], { kinds: CHAT_KINDS, '#h': [g.gid], limit: 300, ...(since ? { since } : {}) }, - (ev) => { if (ev.tags.some((x) => x[0] === 'h' && x[1] === g.gid)) take(g, ev); }, { onauth }); + (ev) => { reached(); if (ev.tags.some((x) => x[0] === 'h' && x[1] === g.gid)) take(g, ev); }, + { onauth, onclose: (why) => { if (!g.log.length && !g.members.length) { g.unreachable = String((why && why[0]) || 'unreachable'); touch(g); emit('loaded', g); } } }); // metadata: only what the group's own relay signed (the copies other // relays carry are read nowhere) const b = subscribeAuthed([g.relay], { kinds: META_KINDS, '#d': [g.gid] }, @@ -238,6 +242,7 @@ export function nip29Client({ scope, pubkey, identity, on, listRelays, store = m await load(); leftNow.delete(keyOf(a.relay, a.gid)); const g = record(a.relay, a.gid); + g.joinedAt = now(); // sorts a group joined here, still quiet, as new touch(g); subscribe(g); emit('joined', g); |
