Allow user to configure room for voice, text, or both.

This commit is contained in:
mplorentz
2026-03-02 17:48:06 -05:00
committed by hodlbod
parent 9a2fcec3f6
commit 140440ca4c
+39 -1
View File
@@ -16,6 +16,24 @@
import {pushToast} from "@app/util/toast"
import {uploadFile} from "@app/core/commands"
type RoomMode = "text" | "voice" | "both"
const getRoomModeFromEvent = (event?: {tags?: string[][]}): RoomMode => {
const tags = event?.tags ?? []
const hasLivekit = tags.some(t => t[0] === "livekit")
const hasNoText = tags.some(t => t[0] === "no-text")
if (hasLivekit && hasNoText) return "voice"
if (hasLivekit) return "both"
return "text"
}
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"]]
return filtered
}
type Props = {
url: string
header: Snippet
@@ -27,12 +45,16 @@
const {url, header, footer, onsubmit, initialValues = makeRoomMeta()}: Props = $props()
const values = $state(initialValues)
let roomMode = $state<RoomMode>(getRoomModeFromEvent(initialValues.event))
const submit = async () => {
const room = $state.snapshot(values)
if (imageFile) {
const {error, result} = await uploadFile(imageFile, {maxWidth: 256, maxHeight: 256})
const {error, result} = await uploadFile(imageFile, {
maxWidth: 256,
maxHeight: 256,
})
if (error) {
return pushToast({theme: "error", message: error})
@@ -42,6 +64,10 @@
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")) {
@@ -178,6 +204,18 @@
<input type="checkbox" class="checkbox" bind:checked={values.isClosed} />
<span class="text-sm opacity-75">Ignore requests to join</span>
</div>
<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>
</ModalBody>
{@render footer({loading})}
</Modal>