diff --git a/src/frontend/src/features/rooms/livekit/components/MediaStateObserver.tsx b/src/frontend/src/features/rooms/livekit/components/MediaStateObserver.tsx new file mode 100644 index 00000000..90687c43 --- /dev/null +++ b/src/frontend/src/features/rooms/livekit/components/MediaStateObserver.tsx @@ -0,0 +1,22 @@ +import { useLocalParticipant } from '@livekit/components-react' + +/** + * Exposes the local participant's media state in the DOM so external tools + * (e.g. bots automating the frontend) can reliably read the microphone and + * camera state, and watch for changes with a MutationObserver: + * + * const el = document.getElementById('media-state') + * new MutationObserver(...).observe(el, { attributes: true }) + */ +export const MediaStateObserver = () => { + const { isMicrophoneEnabled, isCameraEnabled } = useLocalParticipant() + + return ( +
+ ) +} diff --git a/src/frontend/src/features/rooms/livekit/prefabs/VideoConference.tsx b/src/frontend/src/features/rooms/livekit/prefabs/VideoConference.tsx index c28981dc..a92e0289 100644 --- a/src/frontend/src/features/rooms/livekit/prefabs/VideoConference.tsx +++ b/src/frontend/src/features/rooms/livekit/prefabs/VideoConference.tsx @@ -11,6 +11,7 @@ import { SidePanel } from '../components/SidePanel' import { RecordingProvider } from '@/features/recording' import { ScreenShareErrorModal } from '../components/ScreenShareErrorModal' import { ConnectionObserver } from '../components/ConnectionObserver' +import { MediaStateObserver } from '../components/MediaStateObserver' import { RoomMetadataSynchronizer } from '../components/RoomMetadataSynchronizer' import { useRoomPageTitle } from '../hooks/useRoomPageTitle' import { useNoiseReduction } from '../hooks/useNoiseReduction' @@ -63,6 +64,7 @@ export function VideoConference({ ...props }: VideoConferenceProps) { <> +