Add nip29 join/leave room
This commit is contained in:
+25
-1
@@ -8,6 +8,8 @@ import {
|
|||||||
FOLLOWS,
|
FOLLOWS,
|
||||||
REACTION,
|
REACTION,
|
||||||
AUTH_JOIN,
|
AUTH_JOIN,
|
||||||
|
GROUP_JOIN,
|
||||||
|
GROUP_LEAVE,
|
||||||
isSignedEvent,
|
isSignedEvent,
|
||||||
createEvent,
|
createEvent,
|
||||||
displayProfile,
|
displayProfile,
|
||||||
@@ -49,8 +51,10 @@ import {
|
|||||||
clearStorage,
|
clearStorage,
|
||||||
dropSession,
|
dropSession,
|
||||||
} from "@welshman/app"
|
} from "@welshman/app"
|
||||||
|
import type {Relay} from "@welshman/app"
|
||||||
import {
|
import {
|
||||||
COMMENT,
|
COMMENT,
|
||||||
|
tagRoom,
|
||||||
userMembership,
|
userMembership,
|
||||||
MEMBERSHIPS,
|
MEMBERSHIPS,
|
||||||
INDEXER_RELAYS,
|
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
|
// List updates
|
||||||
|
|
||||||
export const addSpaceMembership = async (url: string) => {
|
export const addSpaceMembership = async (url: string) => {
|
||||||
@@ -327,7 +347,11 @@ export const checkRelayAccess = async (url: string, claim = "") => {
|
|||||||
result[url].message?.replace(/^.*: /, "") ||
|
result[url].message?.replace(/^.*: /, "") ||
|
||||||
"join request rejected"
|
"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})`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
import type {TrustedEvent, EventContent} from "@welshman/util"
|
import type {TrustedEvent, EventContent} from "@welshman/util"
|
||||||
import {throttled} from "@welshman/store"
|
import {throttled} from "@welshman/store"
|
||||||
import {createEvent, DELETE} from "@welshman/util"
|
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 {slide} from "@lib/transition"
|
||||||
import {createScroller, type Scroller} from "@lib/html"
|
import {createScroller, type Scroller} from "@lib/html"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
@@ -33,17 +34,41 @@
|
|||||||
getMembershipRoomsByUrl,
|
getMembershipRoomsByUrl,
|
||||||
} from "@app/state"
|
} from "@app/state"
|
||||||
import {setChecked} from "@app/notifications"
|
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 {PROTECTED} from "@app/state"
|
||||||
import {popKey} from "@app/implicit"
|
import {popKey} from "@app/implicit"
|
||||||
|
import {pushToast} from "@app/toast"
|
||||||
|
|
||||||
const {room = GENERAL} = $page.params
|
const {room = GENERAL} = $page.params
|
||||||
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 events = throttled(300, deriveChannelMessages(url, room))
|
const events = throttled(300, deriveChannelMessages(url, room))
|
||||||
|
|
||||||
const assertEvent = (e: any) => e as TrustedEvent
|
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 replyTo = (event: TrustedEvent) => {
|
||||||
const relays = ctx.app.router.Event(event).getUrls()
|
const relays = ctx.app.router.Event(event).getUrls()
|
||||||
const nevent = nip19.neventEncode({...event, relays})
|
const nevent = nip19.neventEncode({...event, relays})
|
||||||
@@ -141,12 +166,12 @@
|
|||||||
<div slot="action" class="row-2">
|
<div slot="action" class="row-2">
|
||||||
{#if room !== GENERAL}
|
{#if room !== GENERAL}
|
||||||
{#if getMembershipRoomsByUrl(url, $userMembership).includes(room)}
|
{#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" />
|
<Icon icon="arrows-a-logout-2" />
|
||||||
Leave Room
|
Leave Room
|
||||||
</Button>
|
</Button>
|
||||||
{:else}
|
{: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" />
|
<Icon icon="login-2" />
|
||||||
Join Room
|
Join Room
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
Reference in New Issue
Block a user