aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-09-14 19:08:34 -0700
committerAdam Soltys <[email protected]>2026-09-14 19:08:34 -0700
commitde9efec9205f5faa0245d1d0182e87931f2d26c2 (patch)
tree823ea3f0ba37b15711533bd6c91d080a1986296c
parent718d7f2bf077ea27ced17c94f643592003e6bacc (diff)
downloadcoinosv3-de9efec9205f5faa0245d1d0182e87931f2d26c2.tar.gz
coinosv3-de9efec9205f5faa0245d1d0182e87931f2d26c2.zip
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 <[email protected]>
-rw-r--r--src/features/messages.js12
1 files changed, 12 insertions, 0 deletions
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);