mirror of
https://github.com/suitenumerique/meet.git
synced 2026-07-26 11:58:53 +00:00
✨(frontend) add synchroniser for room metadata updates
Listen to room metadata change events and synchronize the React Query cache with the latest room data fetched from the API. This ensures clients react to live configuration updates, such as showing or hiding mute controls when `everyone_can_mute` changes.
This commit is contained in:
committed by
aleb_the_flash
parent
534cf000b2
commit
aab90650f1
@@ -0,0 +1,76 @@
|
||||
// features/rooms/hooks/useSyncLiveKitMetadata.ts
|
||||
|
||||
import { useEffect } from 'react'
|
||||
import { RoomEvent } from 'livekit-client'
|
||||
import { queryClient } from '@/api/queryClient'
|
||||
import { keys } from '@/api/queryKeys'
|
||||
import type { ApiRoom, RoomConfiguration } from '@/features/rooms/api/ApiRoom'
|
||||
import { useRoomContext } from '@livekit/components-react'
|
||||
import { useRoomData } from './useRoomData'
|
||||
|
||||
/**
|
||||
* Shape of the LiveKit room metadata blob pushed by the backend.
|
||||
* Matches RoomManagement.update_metadata → {"configuration": room.configuration}
|
||||
*/
|
||||
type RoomLiveKitMetadata = {
|
||||
configuration?: RoomConfiguration
|
||||
}
|
||||
|
||||
const parseMetadata = (raw: string | undefined): RoomLiveKitMetadata | null => {
|
||||
if (!raw) return null
|
||||
try {
|
||||
return JSON.parse(raw) as RoomLiveKitMetadata
|
||||
} catch {
|
||||
console.warn('useSyncLiveKitMetadata: failed to parse room metadata')
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync LiveKit room metadata into the React Query cache.
|
||||
*
|
||||
* The backend pushes room configuration into LiveKit's room metadata
|
||||
* whenever it changes. This hook listens for those changes and patches
|
||||
* the ApiRoom cache so every `useRoomData()`
|
||||
* consumer sees the fresh value automatically.
|
||||
*
|
||||
* Mount once, at the level where the LiveKit Room instance lives.
|
||||
*/
|
||||
export const useSyncLiveKitMetadata = () => {
|
||||
const room = useRoomContext()
|
||||
const roomData = useRoomData()
|
||||
const roomSlug = roomData?.slug
|
||||
|
||||
useEffect(() => {
|
||||
if (!room || !roomSlug) return
|
||||
|
||||
const applyMetadata = (raw: string | undefined) => {
|
||||
const parsed = parseMetadata(raw)
|
||||
// No configuration key → leave the cache alone. Don't clobber the
|
||||
// value we already loaded from the API with `undefined`.
|
||||
if (!parsed?.configuration) return
|
||||
|
||||
queryClient.setQueryData<ApiRoom>([keys.room, roomSlug], (prev) => {
|
||||
if (!prev) return prev
|
||||
if (
|
||||
JSON.stringify(prev.configuration) ===
|
||||
JSON.stringify(parsed.configuration)
|
||||
) {
|
||||
return prev
|
||||
}
|
||||
return { ...prev, configuration: parsed.configuration }
|
||||
})
|
||||
}
|
||||
|
||||
// Apply whatever metadata is currently set (covers the case where we
|
||||
// joined the room AFTER the last metadata change, so no event will fire).
|
||||
applyMetadata(room.metadata)
|
||||
|
||||
const handler = (raw: string) => applyMetadata(raw)
|
||||
room.on(RoomEvent.RoomMetadataChanged, handler)
|
||||
|
||||
return () => {
|
||||
room.off(RoomEvent.RoomMetadataChanged, handler)
|
||||
}
|
||||
}, [room, roomSlug])
|
||||
}
|
||||
@@ -32,6 +32,7 @@ import { useRegisterKeyboardShortcut } from '@/features/shortcuts/useRegisterKey
|
||||
import { useSettingsDialog } from '@/features/settings'
|
||||
import { SettingsDialogExtendedKey } from '@/features/settings/type'
|
||||
import { useVideoResolutionSubscription } from '../hooks/useVideoResolutionSubscription'
|
||||
import { useSyncLiveKitMetadata } from '../hooks/useSyncLiveKitMetadata'
|
||||
import { SettingsDialogProvider } from '@/features/settings/components/SettingsDialogProvider'
|
||||
import { IsIdleDisconnectModal } from '../components/IsIdleDisconnectModal'
|
||||
import { getParticipantName } from '@/features/rooms/utils/getParticipantName'
|
||||
@@ -90,6 +91,7 @@ export function VideoConference({ ...props }: VideoConferenceProps) {
|
||||
useConnectionObserver()
|
||||
useRoomPageTitle()
|
||||
useVideoResolutionSubscription()
|
||||
useSyncLiveKitMetadata()
|
||||
|
||||
useRegisterKeyboardShortcut({
|
||||
id: 'open-shortcuts',
|
||||
|
||||
Reference in New Issue
Block a user