Support names for unmanaged groups via kind 10009
This commit is contained in:
+7
-5
@@ -259,11 +259,13 @@ export const removeSpaceMembership = async (url: string) => {
|
|||||||
return publishThunk({event, relays})
|
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 list = get(userMembership) || makeList({kind: GROUPS})
|
||||||
const event = await addToListPublicly(list, ["r", url], ["group", room, url]).reconcile(
|
const newTags = [
|
||||||
nip44EncryptToSelf,
|
["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)])
|
const relays = uniq([...ctx.app.router.FromUser().getUrls(), ...getRelayTagValues(event.tags)])
|
||||||
|
|
||||||
return publishThunk({event, relays})
|
return publishThunk({event, relays})
|
||||||
@@ -271,7 +273,7 @@ export const addRoomMembership = async (url: string, room: string) => {
|
|||||||
|
|
||||||
export const removeRoomMembership = async (url: string, room: string) => {
|
export const removeRoomMembership = async (url: string, room: string) => {
|
||||||
const list = get(userMembership) || makeList({kind: GROUPS})
|
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 event = await removeFromListByPredicate(list, pred).reconcile(nip44EncryptToSelf)
|
||||||
const relays = uniq([
|
const relays = uniq([
|
||||||
url,
|
url,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {goto} from "$app/navigation"
|
import {goto} from "$app/navigation"
|
||||||
|
import {randomId} from "@welshman/lib"
|
||||||
import {displayRelayUrl} from "@welshman/util"
|
import {displayRelayUrl} from "@welshman/util"
|
||||||
import Field from "@lib/components/Field.svelte"
|
import Field from "@lib/components/Field.svelte"
|
||||||
import Spinner from "@lib/components/Spinner.svelte"
|
import Spinner from "@lib/components/Spinner.svelte"
|
||||||
@@ -12,10 +13,12 @@
|
|||||||
|
|
||||||
export let url
|
export let url
|
||||||
|
|
||||||
|
const room = randomId()
|
||||||
|
|
||||||
const back = () => history.back()
|
const back = () => history.back()
|
||||||
|
|
||||||
const tryCreate = async () => {
|
const tryCreate = async () => {
|
||||||
addRoomMembership(url, room)
|
addRoomMembership(url, room, name)
|
||||||
goto(makeSpacePath(url, room))
|
goto(makeSpacePath(url, room))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,7 +32,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let room = ""
|
let name = ""
|
||||||
let loading = false
|
let loading = false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -44,7 +47,7 @@
|
|||||||
<p slot="label">Room Name</p>
|
<p slot="label">Room Name</p>
|
||||||
<label class="input input-bordered flex w-full items-center gap-2" slot="input">
|
<label class="input input-bordered flex w-full items-center gap-2" slot="input">
|
||||||
<Icon icon="hashtag" />
|
<Icon icon="hashtag" />
|
||||||
<input bind:value={room} class="grow" type="text" />
|
<input bind:value={name} class="grow" type="text" />
|
||||||
</label>
|
</label>
|
||||||
</Field>
|
</Field>
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
@@ -52,7 +55,7 @@
|
|||||||
<Icon icon="alt-arrow-left" />
|
<Icon icon="alt-arrow-left" />
|
||||||
Go back
|
Go back
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="submit" class="btn btn-primary" disabled={!room || loading}>
|
<Button type="submit" class="btn btn-primary" disabled={!name || loading}>
|
||||||
<Spinner {loading}>Create Room</Spinner>
|
<Spinner {loading}>Create Room</Spinner>
|
||||||
<Icon icon="alt-arrow-right" />
|
<Icon icon="alt-arrow-right" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
+34
-56
@@ -358,7 +358,7 @@ export const getMembershipUrls = (list?: List) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const getMembershipRooms = (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) =>
|
export const getMembershipRoomsByUrl = (url: string, list?: List) =>
|
||||||
sort(
|
sort(
|
||||||
@@ -490,7 +490,6 @@ export type Channel = {
|
|||||||
url: string
|
url: string
|
||||||
room: string
|
room: string
|
||||||
name: string
|
name: string
|
||||||
events: TrustedEvent[]
|
|
||||||
meta?: ChannelMeta
|
meta?: ChannelMeta
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -502,45 +501,8 @@ export const channelsById = withGetter(
|
|||||||
derived(
|
derived(
|
||||||
[groupMeta, memberships, messages, getUrlsForEvent],
|
[groupMeta, memberships, messages, getUrlsForEvent],
|
||||||
([$groupMeta, $memberships, $messages, $getUrlsForEvent]) => {
|
([$groupMeta, $memberships, $messages, $getUrlsForEvent]) => {
|
||||||
const eventsByChannelId = new Map<string, TrustedEvent[]>()
|
|
||||||
|
|
||||||
// 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<string, Channel>()
|
const channelsById = new Map<string, Channel>()
|
||||||
|
|
||||||
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
|
// Add meta using group meta events
|
||||||
for (const event of $groupMeta) {
|
for (const event of $groupMeta) {
|
||||||
const meta = fromPairs(event.tags)
|
const meta = fromPairs(event.tags)
|
||||||
@@ -549,25 +511,44 @@ export const channelsById = withGetter(
|
|||||||
if (room) {
|
if (room) {
|
||||||
for (const url of $getUrlsForEvent(event.id)) {
|
for (const url of $getUrlsForEvent(event.id)) {
|
||||||
const id = makeChannelId(url, room)
|
const id = makeChannelId(url, room)
|
||||||
const channel: Channel = channelsById.get(id) || {
|
|
||||||
|
channelsById.set(id, {
|
||||||
url,
|
url,
|
||||||
room,
|
room,
|
||||||
name: room,
|
name: meta.name || room,
|
||||||
events: [],
|
meta: {
|
||||||
}
|
access: meta.private ? "private" : "public",
|
||||||
|
membership: meta.closed ? "closed" : "open",
|
||||||
|
picture: meta.picture,
|
||||||
|
about: meta.about,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (meta.name) {
|
// Add known rooms based on membership events
|
||||||
channel.name = meta.name
|
for (const membership of $memberships) {
|
||||||
}
|
for (const {url, room, name} of getMembershipRooms(membership)) {
|
||||||
|
const id = makeChannelId(url, room)
|
||||||
|
|
||||||
channel.meta = {
|
if (!channelsById.has(id)) {
|
||||||
access: meta.private ? "private" : "public",
|
channelsById.set(id, {url, room, name})
|
||||||
membership: meta.closed ? "closed" : "open",
|
}
|
||||||
picture: meta.picture,
|
}
|
||||||
about: meta.about,
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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) =>
|
export const deriveChannel = (url: string, room: string) =>
|
||||||
derived(channelsById, $channelsById => $channelsById.get(makeChannelId(url, room)))
|
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 => {
|
export const channelsByUrl = derived(channelsById, $channelsById => {
|
||||||
const $channelsByUrl = new Map<string, Channel[]>()
|
const $channelsByUrl = new Map<string, Channel[]>()
|
||||||
|
|
||||||
|
|||||||
@@ -27,11 +27,12 @@
|
|||||||
userSettingValues,
|
userSettingValues,
|
||||||
userMembership,
|
userMembership,
|
||||||
decodeRelay,
|
decodeRelay,
|
||||||
deriveChannelMessages,
|
deriveEventsForUrl,
|
||||||
GENERAL,
|
GENERAL,
|
||||||
tagRoom,
|
tagRoom,
|
||||||
LEGACY_MESSAGE,
|
LEGACY_MESSAGE,
|
||||||
getMembershipRoomsByUrl,
|
getMembershipRoomsByUrl,
|
||||||
|
displayChannel,
|
||||||
} from "@app/state"
|
} from "@app/state"
|
||||||
import {setChecked} from "@app/notifications"
|
import {setChecked} from "@app/notifications"
|
||||||
import {nip29, addRoomMembership, removeRoomMembership, subscribePersistent} from "@app/commands"
|
import {nip29, addRoomMembership, removeRoomMembership, subscribePersistent} from "@app/commands"
|
||||||
@@ -43,7 +44,7 @@
|
|||||||
const content = popKey<string>("content") || ""
|
const content = popKey<string>("content") || ""
|
||||||
const url = decodeRelay($page.params.relay)
|
const url = decodeRelay($page.params.relay)
|
||||||
const relay = deriveRelay(url)
|
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
|
const assertEvent = (e: any) => e as TrustedEvent
|
||||||
|
|
||||||
@@ -58,7 +59,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addRoomMembership(url, room)
|
addRoomMembership(url, room, displayChannel(url, room))
|
||||||
}
|
}
|
||||||
|
|
||||||
const leaveRoom = () => {
|
const leaveRoom = () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user