diff --git a/src/app/commands.ts b/src/app/commands.ts index da7e6331..739771c3 100644 --- a/src/app/commands.ts +++ b/src/app/commands.ts @@ -259,11 +259,13 @@ export const removeSpaceMembership = async (url: string) => { return publishThunk({event, relays}) } -export const addRoomMembership = async (url: string, room: string) => { +export const addRoomMembership = async (url: string, room: string, name: string) => { const list = get(userMembership) || makeList({kind: GROUPS}) - const event = await addToListPublicly(list, ["r", url], ["group", room, url]).reconcile( - nip44EncryptToSelf, - ) + const newTags = [ + ["r", url], + ["group", room, url, name], + ] + const event = await addToListPublicly(list, ...newTags).reconcile(nip44EncryptToSelf) const relays = uniq([...ctx.app.router.FromUser().getUrls(), ...getRelayTagValues(event.tags)]) return publishThunk({event, relays}) @@ -271,7 +273,7 @@ export const addRoomMembership = async (url: string, room: string) => { export const removeRoomMembership = async (url: string, room: string) => { const list = get(userMembership) || makeList({kind: GROUPS}) - const pred = (t: string[]) => equals(["group", room, url], t) + const pred = (t: string[]) => equals(["group", room, url], t.slice(0, 3)) const event = await removeFromListByPredicate(list, pred).reconcile(nip44EncryptToSelf) const relays = uniq([ url, diff --git a/src/app/components/RoomCreate.svelte b/src/app/components/RoomCreate.svelte index 6753b10a..078ca3da 100644 --- a/src/app/components/RoomCreate.svelte +++ b/src/app/components/RoomCreate.svelte @@ -1,5 +1,6 @@ @@ -44,7 +47,7 @@

Room Name

@@ -52,7 +55,7 @@ Go back - diff --git a/src/app/state.ts b/src/app/state.ts index d4f053e5..ca6f1d66 100644 --- a/src/app/state.ts +++ b/src/app/state.ts @@ -358,7 +358,7 @@ export const getMembershipUrls = (list?: List) => { } export const getMembershipRooms = (list?: List) => - getGroupTags(getListTags(list)).map(t => ({url: t[2], room: t[1]})) + getGroupTags(getListTags(list)).map(([_, room, url, name = ""]) => ({url, room, name})) export const getMembershipRoomsByUrl = (url: string, list?: List) => sort( @@ -490,7 +490,6 @@ export type Channel = { url: string room: string name: string - events: TrustedEvent[] meta?: ChannelMeta } @@ -502,45 +501,8 @@ export const channelsById = withGetter( derived( [groupMeta, memberships, messages, getUrlsForEvent], ([$groupMeta, $memberships, $messages, $getUrlsForEvent]) => { - const eventsByChannelId = new Map() - - // Add known rooms by membership so we have a full listing even if there are no messages there - for (const membership of $memberships) { - for (const {url, room} of getMembershipRooms(membership)) { - eventsByChannelId.set(makeChannelId(url, room), []) - } - } - - // Add known messages to rooms - for (const event of $messages) { - const [_, room] = event.tags.find(nthEq(0, ROOM)) || [] - - if (room) { - for (const url of $getUrlsForEvent(event.id)) { - pushToMapKey(eventsByChannelId, makeChannelId(url, room), event) - } - } - } - const channelsById = new Map() - for (const [id, unsorted] of eventsByChannelId.entries()) { - const [url, room] = splitChannelId(id) - const events = sortBy(e => -e.created_at, unsorted) - - let name = room - for (const event of events) { - const tag = event.tags.find(t => t[0] === ROOM && t[2]) - - if (tag) { - name = tag[2] - break - } - } - - channelsById.set(id, {url, room, name, events}) - } - // Add meta using group meta events for (const event of $groupMeta) { const meta = fromPairs(event.tags) @@ -549,25 +511,44 @@ export const channelsById = withGetter( if (room) { for (const url of $getUrlsForEvent(event.id)) { const id = makeChannelId(url, room) - const channel: Channel = channelsById.get(id) || { + + channelsById.set(id, { url, room, - name: room, - events: [], - } + name: meta.name || room, + meta: { + access: meta.private ? "private" : "public", + membership: meta.closed ? "closed" : "open", + picture: meta.picture, + about: meta.about, + }, + }) + } + } + } - if (meta.name) { - channel.name = meta.name - } + // Add known rooms based on membership events + for (const membership of $memberships) { + for (const {url, room, name} of getMembershipRooms(membership)) { + const id = makeChannelId(url, room) - channel.meta = { - access: meta.private ? "private" : "public", - membership: meta.closed ? "closed" : "open", - picture: meta.picture, - about: meta.about, - } + if (!channelsById.has(id)) { + channelsById.set(id, {url, room, name}) + } + } + } - channelsById.set(id, channel) + // Add rooms based on known messages + for (const event of $messages) { + const [_, room] = event.tags.find(nthEq(0, ROOM)) || [] + + if (room) { + for (const url of $getUrlsForEvent(event.id)) { + const id = makeChannelId(url, room) + + if (!channelsById.has(id)) { + channelsById.set(id, {url, room, name: room}) + } } } } @@ -580,9 +561,6 @@ export const channelsById = withGetter( export const deriveChannel = (url: string, room: string) => derived(channelsById, $channelsById => $channelsById.get(makeChannelId(url, room))) -export const deriveChannelMessages = (url: string, room: string) => - derived(channelsById, $channelsById => $channelsById.get(makeChannelId(url, room))?.events || []) - export const channelsByUrl = derived(channelsById, $channelsById => { const $channelsByUrl = new Map() diff --git a/src/routes/spaces/[relay]/[room]/+page.svelte b/src/routes/spaces/[relay]/[room]/+page.svelte index 14b56622..d760ec16 100644 --- a/src/routes/spaces/[relay]/[room]/+page.svelte +++ b/src/routes/spaces/[relay]/[room]/+page.svelte @@ -27,11 +27,12 @@ userSettingValues, userMembership, decodeRelay, - deriveChannelMessages, + deriveEventsForUrl, GENERAL, tagRoom, LEGACY_MESSAGE, getMembershipRoomsByUrl, + displayChannel, } from "@app/state" import {setChecked} from "@app/notifications" import {nip29, addRoomMembership, removeRoomMembership, subscribePersistent} from "@app/commands" @@ -43,7 +44,7 @@ const content = popKey("content") || "" const url = decodeRelay($page.params.relay) const relay = deriveRelay(url) - const events = throttled(300, deriveChannelMessages(url, room)) + const events = throttled(300, deriveEventsForUrl(url, [{kinds: [MESSAGE], "#h": [room]}])) const assertEvent = (e: any) => e as TrustedEvent @@ -58,7 +59,7 @@ } } - addRoomMembership(url, room) + addRoomMembership(url, room, displayChannel(url, room)) } const leaveRoom = () => {