Detect nip29 support for create room button

This commit is contained in:
Jon Staab
2025-05-27 16:22:20 -07:00
parent 4ba6c72459
commit e57b5721f6
5 changed files with 67 additions and 40 deletions
+9 -4
View File
@@ -1,6 +1,7 @@
<script lang="ts">
import {onMount} from "svelte"
import {displayRelayUrl} from "@welshman/util"
import {deriveRelay} from "@welshman/app"
import {fly} from "@lib/transition"
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
@@ -20,6 +21,7 @@
memberships,
deriveUserRooms,
deriveOtherRooms,
hasNip29,
} from "@app/state"
import {notifications} from "@app/notifications"
import {pushModal} from "@app/modal"
@@ -27,6 +29,7 @@
const {url} = $props()
const relay = deriveRelay(url)
const threadsPath = makeSpacePath(url, "threads")
const calendarPath = makeSpacePath(url, "calendar")
const userRooms = deriveUserRooms(url)
@@ -143,10 +146,12 @@
{#each $otherRooms as room, i (room)}
<MenuSpaceRoomItem {replaceState} {url} {room} />
{/each}
<SecondaryNavItem {replaceState} onclick={addRoom}>
<Icon icon="add-circle" />
Create room
</SecondaryNavItem>
{#if hasNip29($relay)}
<SecondaryNavItem {replaceState} onclick={addRoom}>
<Icon icon="add-circle" />
Create room
</SecondaryNavItem>
{/if}
</div>
</SecondaryNavSection>
</div>
+30 -25
View File
@@ -23,24 +23,22 @@
const back = () => history.back()
const tryCreate = async () => {
if (hasNip29($relay)) {
const createMessage = await getThunkError(nip29.createRoom(url, room))
const createMessage = await getThunkError(nip29.createRoom(url, room))
if (createMessage && !createMessage.match(/^duplicate:|already a member/)) {
return pushToast({theme: "error", message: createMessage})
}
if (createMessage && !createMessage.match(/^duplicate:|already a member/)) {
return pushToast({theme: "error", message: createMessage})
}
const editMessage = await getThunkError(nip29.editMeta(url, room, {name}))
const editMessage = await getThunkError(nip29.editMeta(url, room, {name}))
if (editMessage) {
return pushToast({theme: "error", message: editMessage})
}
if (editMessage) {
return pushToast({theme: "error", message: editMessage})
}
const joinMessage = await getThunkError(nip29.joinRoom(url, room))
const joinMessage = await getThunkError(nip29.joinRoom(url, room))
if (joinMessage && !joinMessage.includes("already")) {
return pushToast({theme: "error", message: joinMessage})
}
if (joinMessage && !joinMessage.includes("already")) {
return pushToast({theme: "error", message: joinMessage})
}
addRoomMembership(url, room, name)
@@ -72,23 +70,30 @@
</div>
{/snippet}
</ModalHeader>
<Field>
{#snippet label()}
<p>Room Name</p>
{/snippet}
{#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2">
<Icon icon="hashtag" />
<input bind:value={name} class="grow" type="text" />
</label>
{/snippet}
</Field>
{#if hasNip29($relay)}
<Field>
{#snippet label()}
<p>Room Name</p>
{/snippet}
{#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2">
<Icon icon="hashtag" />
<input bind:value={name} class="grow" type="text" />
</label>
{/snippet}
</Field>
{:else}
<p class="bg-alt card2 row-2">
<Icon icon="danger" />
This relay does not support creating rooms.
</p>
{/if}
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon="alt-arrow-left" />
Go back
</Button>
<Button type="submit" class="btn btn-primary" disabled={!name || loading}>
<Button type="submit" class="btn btn-primary" disabled={!name || loading || !hasNip29($relay)}>
<Spinner {loading}>Create Room</Spinner>
<Icon icon="alt-arrow-right" />
</Button>
+10 -3
View File
@@ -3,6 +3,7 @@ import {get, derived} from "svelte/store"
import * as nip19 from "nostr-tools/nip19"
import {
remove,
uniqBy,
sortBy,
sort,
uniq,
@@ -528,7 +529,7 @@ export const channels = derived(
}
}
return $channels
return uniqBy(c => c.id, $channels)
},
)
@@ -594,12 +595,18 @@ export const userMembership = withGetter(
)
export const userRoomsByUrl = withGetter(
derived(userMembership, $userMembership => {
derived([userMembership, channelsById], ([$userMembership, $channelsById]) => {
const tags = getListTags($userMembership)
const $userRoomsByUrl = new Map<string, Set<string>>()
for (const url of getRelayTagValues(tags)) {
$userRoomsByUrl.set(normalizeRelayUrl(url), new Set())
}
for (const [_, room, url] of getGroupTags(tags)) {
addToMapKey($userRoomsByUrl, normalizeRelayUrl(url), room)
if ($channelsById.has(makeChannelId(url, room))) {
addToMapKey($userRoomsByUrl, normalizeRelayUrl(url), room)
}
}
return $userRoomsByUrl
+11 -4
View File
@@ -1,6 +1,9 @@
<script lang="ts">
import {onMount} from "svelte"
import {addToMapKey, dec, gt} from "@welshman/lib"
import {GROUPS} from "@welshman/util"
import {Router} from "@welshman/router"
import {load} from "@welshman/net"
import type {Relay} from "@welshman/app"
import {relays, createSearch, loadRelay, loadRelaySelections} from "@welshman/app"
import {createScroller} from "@lib/html"
@@ -24,8 +27,12 @@
import {pushModal} from "@app/modal"
const discoverRelays = () =>
Promise.all(
getDefaultPubkeys().map(async pubkey => {
Promise.all([
load({
filters: [{kinds: [GROUPS]}],
relays: Router.get().Index().getUrls(),
}),
...getDefaultPubkeys().map(async pubkey => {
await loadRelaySelections(pubkey)
const membership = await loadMembership(pubkey)
@@ -33,7 +40,7 @@
await Promise.all(urls.map(url => loadRelay(url)))
}),
)
])
const wotGraph = $derived.by(() => {
const scores = new Map<string, Set<string>>()
@@ -87,7 +94,7 @@
})
</script>
<Page>
<Page class="cw-full">
<div class="content column gap-4" bind:this={element}>
<PageHeader>
{#snippet title()}
+7 -4
View File
@@ -18,6 +18,7 @@
import RoomCreate from "@app/components/RoomCreate.svelte"
import RelayDescription from "@app/components/RelayDescription.svelte"
import {
hasNip29,
decodeRelay,
channelIsLocked,
makeChannelId,
@@ -183,10 +184,12 @@
</div>
</Link>
{/each}
<Button onclick={addRoom} class="btn btn-neutral whitespace-nowrap">
<Icon icon="add-circle" />
Create
</Button>
{#if hasNip29($relay)}
<Button onclick={addRoom} class="btn btn-neutral whitespace-nowrap">
<Icon icon="add-circle" />
Create
</Button>
{/if}
</div>
{#if pubkey}
<Divider>Recent posts from the relay admin</Divider>