Refactor currentVoiceRoom and some related types to use Room instead of RoomRef.

This commit is contained in:
mplorentz
2026-03-27 14:57:18 -04:00
parent 54316db039
commit 0b04076baa
5 changed files with 35 additions and 37 deletions
+3 -6
View File
@@ -9,6 +9,7 @@
import {makeRoomPath} from "@app/util/routes"
import {pushModal} from "@app/util/modal"
import VoiceRoomJoinDialog from "@app/components/VoiceRoomJoinDialog.svelte"
import {makeRoomId} from "@app/core/state"
import {
VoiceState,
deriveVoiceParticipants,
@@ -30,14 +31,10 @@
const participants = deriveVoiceParticipants(url, h)
const isActive = $derived(
$voiceState === VoiceState.Connected &&
$currentVoiceRoom?.url === url &&
$currentVoiceRoom?.h === h,
$voiceState === VoiceState.Connected && $currentVoiceRoom?.id === makeRoomId(url, h),
)
const isJoining = $derived(
$voiceState === VoiceState.Joining &&
$currentVoiceRoom?.url === url &&
$currentVoiceRoom?.h === h,
$voiceState === VoiceState.Joining && $currentVoiceRoom?.id === makeRoomId(url, h),
)
const handleClick = async (e: MouseEvent) => {
@@ -12,7 +12,7 @@
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
import ModalTitle from "@lib/components/ModalTitle.svelte"
import {deriveRoom} from "@app/core/state"
import {displayRoom} from "@app/core/state"
import {joinVoiceRoom} from "@app/voice"
import {popModal} from "@app/util/modal"
@@ -23,7 +23,6 @@
const {url, h}: Props = $props()
const room = deriveRoom(url, h)
const spaceLabel = $derived(displayRelayUrl(url))
let audioInputs = $state<MediaDeviceInfo[]>([])
@@ -64,7 +63,7 @@
<ModalSubtitle>
<span class="inline-flex flex-wrap items-center justify-center gap-x-1.5 gap-y-1">
<Icon icon={Volume} size={4} class="shrink-0" />
<span class="ellipsize min-w-0">{$room?.name || h}</span>
<span class="ellipsize min-w-0">{displayRoom(url, h)}</span>
<span>·</span>
<span>{spaceLabel}</span>
</span>
+10 -3
View File
@@ -12,7 +12,14 @@
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
import VoiceRoomJoinDialog from "@app/components/VoiceRoomJoinDialog.svelte"
import {decodeRelay, deriveRoom, displayRoom, getRoomType, RoomType} from "@app/core/state"
import {
decodeRelay,
deriveRoom,
displayRoom,
getRoomType,
RoomType,
type Room,
} from "@app/core/state"
import {pushModal} from "@app/util/modal"
import {makeRoomPath} from "@app/util/routes"
import {
@@ -32,14 +39,14 @@
)
const routeDisplayedRoom = $derived($displayedRoomStore)
const targetRoom = $derived.by(() => {
const targetRoom = $derived.by((): Room | undefined => {
if ($voiceState === VoiceState.Joining || $voiceState === VoiceState.Connected) {
return $currentVoiceRoom
}
if ($voiceState === VoiceState.Disconnected) {
if (routeDisplayedRoom) {
if (getRoomType(routeDisplayedRoom) === RoomType.Voice) {
return {url: routeDisplayedRoom.url, h: routeDisplayedRoom.h}
return routeDisplayedRoom
}
return undefined
}
+1 -3
View File
@@ -583,8 +583,6 @@ export type Room = PublishedRoomMeta & {
url: string
}
export type RoomRef = {url: string; h: string}
export const getRoomType = (room: RoomMeta): RoomType =>
room.livekit ? RoomType.Voice : RoomType.Text
@@ -671,7 +669,7 @@ export const deriveRoom = call(() => {
return (url: string, h: string) =>
derived(
_deriveRoom(makeRoomId(url, h)),
room => room || {url, id: makeRoomId(url, h), ...makeRoomMeta({h})},
room => (room || {url, id: makeRoomId(url, h), ...makeRoomMeta({h})}) as Room,
)
})
+19 -22
View File
@@ -4,7 +4,7 @@
*/
import {
DisconnectReason,
Room,
Room as LiveKitRoom,
RoomEvent,
Track,
type AudioCaptureOptions,
@@ -17,7 +17,7 @@ import {makeHttpAuth, makeHttpAuthHeader, getTags} from "@welshman/util"
import {signer} from "@welshman/app"
import {getLivekitEndpoint} from "$lib/livekit"
import {AbortError, whenAborted, whenTimeout} from "$lib/util"
import {deriveLatestEventForUrl, type RoomRef} from "@app/core/state"
import {deriveLatestEventForUrl, deriveRoom, makeRoomId, type Room} from "@app/core/state"
import {pushToast} from "@app/util/toast"
export const LIVEKIT_PARTICIPANTS = 39004
@@ -27,7 +27,7 @@ export {checkRelayHasLivekit} from "$lib/livekit"
export type VoiceSession = {
url: string
h: string
room: Room
room: LiveKitRoom
muted: boolean
}
@@ -45,7 +45,7 @@ export const currentVoiceSession = writable<VoiceSession | undefined>(undefined)
export const voiceState = writable<VoiceState>(VoiceState.Disconnected)
export const currentVoiceRoom = writable<RoomRef | undefined>(undefined)
export const currentVoiceRoom = writable<Room | undefined>(undefined)
export const participantPubkeyMap = writable<Map<string, Pubkey>>(new Map())
@@ -121,10 +121,7 @@ export const deriveVoiceParticipants = (url: string, h: string) =>
deriveLatestEventForUrl(url, [{kinds: [LIVEKIT_PARTICIPANTS], "#d": [h]}]),
],
([$participantPubkeyMap, $currentVoiceRoom, $publishedParticipantList]) => {
const inCall =
$participantPubkeyMap.size > 0 &&
$currentVoiceRoom?.url === url &&
$currentVoiceRoom?.h === h
const inCall = $participantPubkeyMap.size > 0 && $currentVoiceRoom?.id === makeRoomId(url, h)
if (inCall) {
const participants = [...$participantPubkeyMap.keys()].map(participantFromLiveKitIdentity)
@@ -228,7 +225,7 @@ export const joinVoiceRoom = async (
const session = get(currentVoiceSession)
if (session) await leaveVoiceRoom()
currentVoiceRoom.set({url, h})
currentVoiceRoom.set(get(deriveRoom(url, h)))
voiceState.set(VoiceState.Joining)
const controller = new AbortController()
@@ -241,37 +238,37 @@ export const joinVoiceRoom = async (
if (signal.aborted) throw new AbortError()
const room = new Room({adaptiveStream: true, dynacast: true})
const liveKitRoom = new LiveKitRoom({adaptiveStream: true, dynacast: true})
room.on(RoomEvent.Disconnected, onRoomDisconnected)
room.on(RoomEvent.ParticipantConnected, onParticipantConnected)
room.on(RoomEvent.ParticipantDisconnected, onParticipantDisconnected)
room.on(RoomEvent.TrackSubscribed, onTrackSubscribed)
room.on(RoomEvent.TrackUnsubscribed, onTrackUnsubscribed)
room.on(RoomEvent.ActiveSpeakersChanged, onActiveSpeakersChanged)
liveKitRoom.on(RoomEvent.Disconnected, onRoomDisconnected)
liveKitRoom.on(RoomEvent.ParticipantConnected, onParticipantConnected)
liveKitRoom.on(RoomEvent.ParticipantDisconnected, onParticipantDisconnected)
liveKitRoom.on(RoomEvent.TrackSubscribed, onTrackSubscribed)
liveKitRoom.on(RoomEvent.TrackUnsubscribed, onTrackUnsubscribed)
liveKitRoom.on(RoomEvent.ActiveSpeakersChanged, onActiveSpeakersChanged)
try {
await Promise.race([
room.connect(server_url, participant_token, {maxRetries: 0}),
liveKitRoom.connect(server_url, participant_token, {maxRetries: 0}),
whenTimeout(5_000, {
message: "Connection timed out. Please check your network and try again.",
}),
whenAborted(signal),
])
} catch (e) {
room.disconnect()
liveKitRoom.disconnect()
throw e
}
participantPubkeyMap.set(new Map())
addParticipant(room.localParticipant.identity)
for (const p of room.remoteParticipants.values()) {
addParticipant(liveKitRoom.localParticipant.identity)
for (const p of liveKitRoom.remoteParticipants.values()) {
addParticipant(p.identity)
}
const muted = await setUpMicrophone(startMuted, preferredMicId, room.localParticipant)
const muted = await setUpMicrophone(startMuted, preferredMicId, liveKitRoom.localParticipant)
currentVoiceSession.set({url, h, room, muted})
currentVoiceSession.set({url, h, room: liveKitRoom, muted})
voiceState.set(VoiceState.Connected)
playJoinSound()
} catch (e) {