projects/deliberation_at_scale/packages/frontend/components/LocalMedia/provider.tsx (34 lines of code) (raw):
'use client';
import { useLocalMedia as useBaseLocalMedia } from '@whereby.com/browser-sdk';
import { PropsWithChildren, useState, useCallback, useMemo } from 'react';
import { LocalMediaContext } from './context';
/**
* This initializes Local Media for the Whereby SDK and adds some convenience
* functions for later use.
*/
export default function LocalMediaProvider({ children }: PropsWithChildren) {
// Run the base hook from the Whereby SDK
const { actions, state, ...rest } = useBaseLocalMedia();
// Keep some arbitrary state that we can change so that we can force a re-render
const [, setActionNo] = useState(0);
// Check whether both the audio and video are currently enabled. Since the
// SDK switches this directly using the mediaDevices API, we have no way of
// detecting when this changes. Hence, we use the above state to force state
// updates so that is connected.
const isAudioEnabled = state.localStream?.getAudioTracks().some((t) => t.enabled) || false;
const isVideoEnabled = state.localStream?.getVideoTracks().some((t) => t.enabled) || false;
const toggleCameraEnabled = useCallback((...args: Parameters<LocalMediaContext['actions']['toggleCameraEnabled']>) => {
setActionNo((n) => n + 1);
actions.toggleCameraEnabled(...args);
}, [actions]);
const toggleMicrophoneEnabled = useCallback((...args: Parameters<LocalMediaContext['actions']['toggleMicrophoneEnabled']>) => {
setActionNo((n) => n + 1);
actions.toggleMicrophoneEnabled(...args);
}, [actions]);
const context: LocalMediaContext = useMemo(() => ({
actions: {
...actions,
toggleCameraEnabled,
toggleMicrophoneEnabled,
},
state: {
...state,
isAudioEnabled,
isVideoEnabled,
},
...rest,
}), [actions, state, toggleCameraEnabled, toggleMicrophoneEnabled, rest, isAudioEnabled, isVideoEnabled]);
return (
<LocalMediaContext.Provider value={context}>
{children}
</LocalMediaContext.Provider>
);
}