diff --git a/src/app/components/VoiceRoomItem.svelte b/src/app/components/VoiceRoomItem.svelte index 5676c314..30c7fe9f 100644 --- a/src/app/components/VoiceRoomItem.svelte +++ b/src/app/components/VoiceRoomItem.svelte @@ -5,7 +5,7 @@ import ProfileCircle from "@app/components/ProfileCircle.svelte" import RoomImage from "@app/components/RoomImage.svelte" import RoomName from "@app/components/RoomName.svelte" - import {pushToast} from "@app/util/toast" + import {handleJoinError} from "@app/components/VoiceWidget.svelte" import {makeRoomPath} from "@app/util/routes" import { deriveVoiceParticipants, @@ -42,12 +42,7 @@ return } - try { - await joinVoiceRoom(url, h) - } catch (e) { - console.error("Failed to join voice room", e) - pushToast({theme: "error", message: "Failed to join voice room"}) - } + await joinVoiceRoom(url, h).catch(handleJoinError) } $effect(() => { diff --git a/src/app/components/VoiceWidget.svelte b/src/app/components/VoiceWidget.svelte index ae3f3eb5..239ba8f4 100644 --- a/src/app/components/VoiceWidget.svelte +++ b/src/app/components/VoiceWidget.svelte @@ -1,3 +1,20 @@ + + {#if $currentVoiceRoom} @@ -70,7 +91,7 @@ {/if} diff --git a/src/app/voice.ts b/src/app/voice.ts index e8222e99..8856c2d2 100644 --- a/src/app/voice.ts +++ b/src/app/voice.ts @@ -17,6 +17,13 @@ export const LIVEKIT_PARTICIPANTS = 39004 export {checkRelayHasLivekit} from "$lib/livekit" +export class VoiceJoinMembershipError extends Error { + constructor() { + super("Failed to join voice room: you must be a member.") + this.name = "VoiceJoinMembershipError" + } +} + export type VoiceSession = { url: string h: string @@ -95,6 +102,7 @@ const fetchLivekitToken = async ( if (!response.ok) { const text = await response.text() + if (response.status === 403) throw new VoiceJoinMembershipError() throw new Error(`Token request failed (${response.status}): ${text}`) } @@ -243,7 +251,6 @@ export const joinVoiceRoom = async (url: string, h: string): Promise => { playJoinSound() } catch (e) { if (isActive()) voiceState.set("disconnected") - if (e instanceof AbortError) return throw e } finally { if (isActive()) joinAbortController = undefined @@ -264,9 +271,10 @@ export const leaveVoiceRoom = async () => { participantPubkeyMap.set(new Map()) } -export const rejoinVoiceRoom = () => { +export const rejoinVoiceRoom = async (): Promise => { const target = get(currentVoiceRoom) - if (target) joinVoiceRoom(target.url, target.h) + if (!target) return + return joinVoiceRoom(target.url, target.h) } export const toggleMute = async () => {