Address PR comments on RoomForm

This commit is contained in:
mplorentz
2026-03-04 16:42:49 -05:00
parent 02b2ccdee3
commit 9c2d2093ec
4 changed files with 65 additions and 61 deletions
+34 -40
View File
@@ -1,7 +1,9 @@
<script lang="ts">
import {get} from "svelte/store"
import type {Snippet} from "svelte"
import {assoc, append, nth, type Maybe, uniqBy} from "@welshman/lib"
import type {RoomMeta} from "@welshman/util"
import {makeRoomMeta} from "@welshman/util"
import {getTag, makeRoomMeta} from "@welshman/util"
import {waitForThunkError, createRoom, editRoom, joinRoom} from "@welshman/app"
import StickerSmileSquare from "@assets/icons/sticker-smile-square.svg?dataurl"
import Hashtag from "@assets/icons/hashtag.svg?dataurl"
@@ -15,14 +17,14 @@
import ModalBody from "@lib/components/ModalBody.svelte"
import {pushToast} from "@app/util/toast"
import {uploadFile} from "@app/core/commands"
import {checkRelayHasLivekit} from "@app/voice"
import {deriveHasLivekit} from "@app/core/state"
type RoomMode = "text" | "voice" | "both"
const getRoomModeFromEvent = (event?: {tags?: string[][]}): RoomMode => {
const getRoomModeFromEvent = (event: Maybe<{tags: Maybe<string[][]>}>): RoomMode => {
const tags = event?.tags ?? []
const hasLivekit = tags.some(t => t[0] === "livekit")
const hasNoText = tags.some(t => t[0] === "no-text")
const hasLivekit = !!getTag("livekit", tags)
const hasNoText = !!getTag("no-text", tags)
if (hasLivekit && hasNoText) return "voice"
if (hasLivekit) return "both"
return "text"
@@ -30,8 +32,9 @@
const buildTagsWithRoomMode = (existingTags: string[][], roomMode: RoomMode): string[][] => {
const filtered = existingTags.filter(t => t[0] !== "livekit" && t[0] !== "no-text")
if (roomMode === "both") return [...filtered, ["livekit"]]
if (roomMode === "voice") return [...filtered, ["livekit"], ["no-text"]]
if (roomMode === "both") return uniqBy(nth(0), append(["livekit"], filtered))
if (roomMode === "voice")
return uniqBy(nth(0), append(["no-text"], append(["livekit"], filtered)))
return filtered
}
@@ -47,23 +50,12 @@
const values = $state(initialValues)
let roomMode = $state<RoomMode>(getRoomModeFromEvent(initialValues.event))
let relayHasLivekit = $state<boolean | undefined>(undefined)
$effect(() => {
const u = url
let cancelled = false
checkRelayHasLivekit(u).then(has => {
if (!cancelled) relayHasLivekit = has
})
return () => {
cancelled = true
}
})
const relayHasLivekit = deriveHasLivekit(url)
const submit = async () => {
const room = $state.snapshot(values)
if ((roomMode === "voice" || roomMode === "both") && !relayHasLivekit) {
if ((roomMode === "voice" || roomMode === "both") && !get(relayHasLivekit)) {
return pushToast({
theme: "error",
message: "This relay does not support voice rooms.",
@@ -84,16 +76,17 @@
room.pictureMeta = result.tags
}
const existingTags = room.event?.tags ?? []
const tags = buildTagsWithRoomMode(existingTags, roomMode)
room.event = room.event ? {...room.event, tags} : ({tags} as RoomMeta["event"])
const createMessage = await waitForThunkError(createRoom(url, room))
if (createMessage && !createMessage.includes("already")) {
return pushToast({theme: "error", message: createMessage})
}
if (room.event && get(relayHasLivekit)) {
const existingTags = room.event.tags ?? []
const tags = buildTagsWithRoomMode(existingTags, roomMode)
room.event = assoc("tags", tags)(room.event) as RoomMeta["event"]
}
const editMessage = await waitForThunkError(editRoom(url, room))
if (editMessage) {
@@ -207,22 +200,23 @@
</label>
{/snippet}
</FieldInline>
<FieldInline>
{#snippet label()}
<p>Room type</p>
{/snippet}
{#snippet input()}
<select class="select select-bordered w-full" bind:value={roomMode} aria-label="Room type">
<option value="text">Text only</option>
<option value="both" disabled={relayHasLivekit === false}>
Text and voice{relayHasLivekit === false ? " (not setup)" : ""}
</option>
<option value="voice" disabled={relayHasLivekit === false}>
Voice only{relayHasLivekit === false ? " (not setup)" : ""}
</option>
</select>
{/snippet}
</FieldInline>
{#if $relayHasLivekit}
<FieldInline>
{#snippet label()}
<p>Room type</p>
{/snippet}
{#snippet input()}
<select
class="select select-bordered w-full"
bind:value={roomMode}
aria-label="Room type">
<option value="text">Text only</option>
<option value="both">Text and voice</option>
<option value="voice">Voice only</option>
</select>
{/snippet}
</FieldInline>
{/if}
<strong class="md:hidden">Permissions</strong>
<div class="flex items-center gap-2">
<input type="checkbox" class="checkbox" bind:checked={values.isRestricted} />