feature/23-voice-room/poc #93

Merged
hodlbod merged 68 commits from feature/23-voice-room/poc into dev 2026-03-16 20:38:06 +00:00
2 changed files with 18 additions and 2 deletions
Showing only changes of commit 87b37bf0d8 - Show all commits
+10 -2
View File
@@ -1,4 +1,5 @@
<script lang="ts">
import cx from "classnames"
import {loadProfile, displayProfileByPubkey} from "@welshman/app"
import Volume from "@assets/icons/volume.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
@@ -12,6 +13,7 @@
joinVoiceRoom,
leaveVoiceRoom,
currentVoiceSession,
speakingPubkeys,
} from "@app/voice"
interface Props {
8
@@ -71,10 +73,16 @@
<RoomName {url} {h} />
</SecondaryNavItem>
{#if $participants.length > 0}
<div class="flex flex-col gap-1 pb-1 pl-10">
<div class="mt-2 flex flex-col gap-1 pb-1 pl-10">
{#each $participants as pk (pk)}
<div class="flex items-center gap-2">
<ProfileCircle pubkey={pk} size={5} class="h-5 w-5" />
<div
hodlbod marked this conversation as resolved Outdated
Outdated
Review

There's a typescript error here because pubkey may be undefined. Is there a reason for this or can we strengthen the type to guarantee it?

There's a typescript error here because pubkey may be undefined. Is there a reason for this or can we strengthen the type to guarantee it?
Outdated
Review

Yes, in the case where there is a voice participant in the room but we can't derive a pubkey from their LiveKit identity string it seems important to still show that there is someone in the room. I just wanted to reuse the default profile icon for that and this was my way of doing it.

Yes, in the case where there is a voice participant in the room but we can't derive a `pubkey` from their LiveKit identity string it seems important to still show that there is _someone_ in the room. I just wanted to reuse the default profile icon for that and this was my way of doing it.
class={cx(
"inline-flex shrink-0 items-center justify-center rounded-full transition-shadow",
isActive && $speakingPubkeys.has(pk) && "ring-2 ring-success",
)}>
<ProfileCircle pubkey={pk} size={5} class="h-5 w-5" />
</div>
<span class="ellipsize text-xs opacity-70">
{displayProfileByPubkey(pk)}
</span>
+8
View File
@@ -46,6 +46,8 @@ export type VoiceSession = {
export const currentVoiceSession = writable<VoiceSession | undefined>(undefined)
export const speakingPubkeys = writable<Set<string>>(new Set())
hodlbod marked this conversation as resolved Outdated
Outdated
Review

[nit] simpler would be writable(new Set<string>())

[nit] simpler would be `writable(new Set<string>())`
const fetchLivekitToken = async (
url: string,
groupId: string,
3
@@ -157,6 +159,7 @@ export const joinVoiceRoom = async (
})
room.on(RoomEvent.Disconnected, (reason?: DisconnectReason) => {
speakingPubkeys.set(new Set())
currentVoiceSession.set(undefined)
stopPresenceHeartbeat()
if (reason !== undefined && reason !== DisconnectReason.CLIENT_INITIATED) {
@@ -181,6 +184,10 @@ export const joinVoiceRoom = async (
track.detach().forEach(el => el.remove())
})
room.on(RoomEvent.ActiveSpeakersChanged, participants => {
speakingPubkeys.set(new Set(participants.map(p => p.identity)))
})
const onAbort = () => {
room.disconnect()
}
4
@@ -225,6 +232,7 @@ export const leaveVoiceRoom = async () => {
const session = get(currentVoiceSession)
if (!session) return
speakingPubkeys.set(new Set())
stopPresenceHeartbeat()
session.room.disconnect()
deletePresence(session.url)