Add nip29 join/leave room

This commit is contained in:
Jon Staab
2024-12-10 09:44:04 -08:00
parent 7e3cf94ee8
commit 523c54a1f1
2 changed files with 54 additions and 5 deletions
+25 -1
View File
@@ -8,6 +8,8 @@ import {
FOLLOWS,
REACTION,
AUTH_JOIN,
GROUP_JOIN,
GROUP_LEAVE,
isSignedEvent,
createEvent,
displayProfile,
@@ -49,8 +51,10 @@ import {
clearStorage,
dropSession,
} from "@welshman/app"
import type {Relay} from "@welshman/app"
import {
COMMENT,
tagRoom,
userMembership,
MEMBERSHIPS,
INDEXER_RELAYS,
@@ -216,6 +220,22 @@ export const broadcastUserData = async (relays: string[]) => {
}
}
// NIP 29 stuff
export const nip29 = {
isSupported: (relay?: Relay) => relay?.profile?.supported_nips?.map(String)?.includes("29"),
joinRoom: (url: string, room: string) => {
const event = createEvent(GROUP_JOIN, {tags: [tagRoom(room, url)]})
return publishThunk({event, relays: [url]})
},
leaveRoom: (url: string, room: string) => {
const event = createEvent(GROUP_LEAVE, {tags: [tagRoom(room, url)]})
return publishThunk({event, relays: [url]})
},
}
// List updates
export const addSpaceMembership = async (url: string) => {
@@ -327,7 +347,11 @@ export const checkRelayAccess = async (url: string, claim = "") => {
result[url].message?.replace(/^.*: /, "") ||
"join request rejected"
return `Failed to join relay (${message})`
// If it's a strict NIP 29 relay don't worry about requesting access
// TODO: remove this if relay29 ever gets less strict
if (message !== "missing group (`h`) tag") {
return `Failed to join relay (${message})`
}
}
}
+29 -4
View File
@@ -9,7 +9,8 @@
import type {TrustedEvent, EventContent} from "@welshman/util"
import {throttled} from "@welshman/store"
import {createEvent, DELETE} from "@welshman/util"
import {formatTimestampAsDate, publishThunk} from "@welshman/app"
import {PublishStatus} from "@welshman/net"
import {formatTimestampAsDate, publishThunk, deriveRelay} from "@welshman/app"
import {slide} from "@lib/transition"
import {createScroller, type Scroller} from "@lib/html"
import Icon from "@lib/components/Icon.svelte"
@@ -33,17 +34,41 @@
getMembershipRoomsByUrl,
} from "@app/state"
import {setChecked} from "@app/notifications"
import {addRoomMembership, removeRoomMembership, subscribePersistent} from "@app/commands"
import {nip29, addRoomMembership, removeRoomMembership, subscribePersistent} from "@app/commands"
import {PROTECTED} from "@app/state"
import {popKey} from "@app/implicit"
import {pushToast} from "@app/toast"
const {room = GENERAL} = $page.params
const content = popKey<string>("content") || ""
const url = decodeRelay($page.params.relay)
const relay = deriveRelay(url)
const events = throttled(300, deriveChannelMessages(url, room))
const assertEvent = (e: any) => e as TrustedEvent
const joinRoom = async () => {
if (nip29.isSupported($relay)) {
const thunk = nip29.joinRoom(url, room)
const result = await thunk.result
const {status, message} = result[url]!
if (status !== PublishStatus.Success) {
return pushToast({theme: "error", message})
}
}
addRoomMembership(url, room)
}
const leaveRoom = () => {
if (nip29.isSupported($relay)) {
nip29.leaveRoom(url, room)
}
removeRoomMembership(url, room)
}
const replyTo = (event: TrustedEvent) => {
const relays = ctx.app.router.Event(event).getUrls()
const nevent = nip19.neventEncode({...event, relays})
@@ -141,12 +166,12 @@
<div slot="action" class="row-2">
{#if room !== GENERAL}
{#if getMembershipRoomsByUrl(url, $userMembership).includes(room)}
<Button class="btn btn-neutral btn-sm" on:click={() => removeRoomMembership(url, room)}>
<Button class="btn btn-neutral btn-sm" on:click={leaveRoom}>
<Icon icon="arrows-a-logout-2" />
Leave Room
</Button>
{:else}
<Button class="btn btn-neutral btn-sm" on:click={() => addRoomMembership(url, room)}>
<Button class="btn btn-neutral btn-sm" on:click={joinRoom}>
<Icon icon="login-2" />
Join Room
</Button>