From de9efec9205f5faa0245d1d0182e87931f2d26c2 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Mon, 14 Sep 2026 19:08:34 -0700 Subject: A community whose invite grants no channels still shows its public ones. A Vector invite carries only private channel keys, so its channel list can be empty; the public channels arrive through the Control fold. The room only ever subscribed to the invite's channels, so FOSS Apps folded to 58 members and "No messages yet". Channels the fold discovers are subscribed as they land, and warm from the message cache on reopen. Co-Authored-By: Claude Fable 5.1 --- src/features/messages.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src') diff --git a/src/features/messages.js b/src/features/messages.js index b832ab5..127dc08 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -728,6 +728,11 @@ export function messagesFeature(ctx) { foldTimer = setTimeout(() => { refold(); refoldGuestbook(); + // An invite may grant no channels at all (a Vector link carries only + // the private ones): the public channels are learned from the + // Control fold, so a room open on the relays follows them as they + // fold in — otherwise the room stays "No messages yet" forever. + if (room.subscribed) for (const c of roomChannels(room)) subChannel(room, c.id); // remember the settled count — next session's list paints it // immediately instead of "encrypted" flipping to a number const s = st(); @@ -785,6 +790,13 @@ export function messagesFeature(ctx) { function subChannel(room, id) { if (room.subbed.has(id)) return; room.subbed.add(id); + // a fold-discovered channel warms from its cache here, the way the + // invite's own channels do when the room is built + if (!room.byChannel.has(id)) { + const msgs = new Map(); + for (const m of st().cache[id] || []) msgs.set(m.rumor.id, m); + if (msgs.size) { room.byChannel.set(id, msgs); bumpMsgRev(); } + } // derive the stream key once per channel, not once per wrap — groupKey // does an hkdf + ECDH each call, real curve work on a 200-wrap backfill const stream = room.chStream(id); -- cgit v1.2.3