diff --git a/src/room/InCallView.tsx b/src/room/InCallView.tsx index 1c8b41e9..3d7ce8db 100644 --- a/src/room/InCallView.tsx +++ b/src/room/InCallView.tsx @@ -60,7 +60,7 @@ import { useRageshakeRequestModal } from "../settings/submit-rageshake"; import { RageshakeRequestModal } from "./RageshakeRequestModal"; import { useWakeLock } from "../useWakeLock"; import { useMergedRefs } from "../useMergedRefs"; -import { type MuteStates } from "./MuteStates"; +import { type MuteStates } from "../state/MuteStates"; import { type MatrixInfo } from "./VideoPreview"; import { InviteButton } from "../button/InviteButton"; import { LayoutToggle } from "./LayoutToggle"; @@ -143,6 +143,7 @@ export const ActiveCall: FC = (props) => { props.rtcSession, props.matrixRoom, mediaDevices, + props.muteStates, { encryptionSystem: props.e2eeSystem, autoLeaveWhenOthersLeft, @@ -161,6 +162,7 @@ export const ActiveCall: FC = (props) => { props.rtcSession, props.matrixRoom, mediaDevices, + props.muteStates, props.e2eeSystem, autoLeaveWhenOthersLeft, sendNotificationType, @@ -265,22 +267,19 @@ export const InCallView: FC = ({ ], ); - const toggleMicrophone = useCallback( - () => muteStates.audio.setEnabled?.((e) => !e), - [muteStates], - ); - const toggleCamera = useCallback( - () => muteStates.video.setEnabled?.((e) => !e), - [muteStates], - ); + const audioEnabled = useBehavior(muteStates.audio.enabled$); + const videoEnabled = useBehavior(muteStates.video.enabled$); + const toggleAudio = useBehavior(muteStates.audio.toggle$); + const toggleVideo = useBehavior(muteStates.video.toggle$); + const setAudioEnabled = useBehavior(muteStates.audio.setEnabled$); // This function incorrectly assumes that there is a camera and microphone, which is not always the case. // TODO: Make sure that this module is resilient when it comes to camera/microphone availability! useCallViewKeyboardShortcuts( containerRef1, - toggleMicrophone, - toggleCamera, - (muted) => muteStates.audio.setEnabled?.(!muted), + toggleAudio, + toggleVideo, + setAudioEnabled, (reaction) => void sendReaction(reaction), () => void toggleRaisedHand(), ); @@ -764,18 +763,18 @@ export const InCallView: FC = ({ buttons.push( , , ); diff --git a/src/room/LobbyView.tsx b/src/room/LobbyView.tsx index 391cb391..057c1206 100644 --- a/src/room/LobbyView.tsx +++ b/src/room/LobbyView.tsx @@ -31,7 +31,7 @@ import inCallStyles from "./InCallView.module.css"; import styles from "./LobbyView.module.css"; import { Header, LeftNav, RightNav, RoomHeaderInfo } from "../Header"; import { type MatrixInfo, VideoPreview } from "./VideoPreview"; -import { type MuteStates } from "./MuteStates"; +import { type MuteStates } from "../state/MuteStates"; import { InviteButton } from "../button/InviteButton"; import { EndCallButton, @@ -50,8 +50,8 @@ import { useTrackProcessorSync, } from "../livekit/TrackProcessorContext"; import { usePageTitle } from "../usePageTitle"; -import { useLatest } from "../useLatest"; import { getValue } from "../utils/observable"; +import { useBehavior } from "../useBehavior"; interface Props { client: MatrixClient; @@ -88,14 +88,10 @@ export const LobbyView: FC = ({ const { t } = useTranslation(); usePageTitle(matrixInfo.roomName); - const onAudioPress = useCallback( - () => muteStates.audio.setEnabled?.((e) => !e), - [muteStates], - ); - const onVideoPress = useCallback( - () => muteStates.video.setEnabled?.((e) => !e), - [muteStates], - ); + const audioEnabled = useBehavior(muteStates.audio.enabled$); + const videoEnabled = useBehavior(muteStates.video.enabled$); + const toggleAudio = useBehavior(muteStates.audio.toggle$); + const toggleVideo = useBehavior(muteStates.video.toggle$); const [settingsModalOpen, setSettingsModalOpen] = useState(false); const [settingsTab, setSettingsTab] = useState(defaultSettingsTab); @@ -133,7 +129,7 @@ export const LobbyView: FC = ({ // re-open the devices when they change (see below). const initialAudioOptions = useInitial( () => - muteStates.audio.enabled && { + audioEnabled && { deviceId: getValue(devices.audioInput.selected$)?.id, }, ); @@ -150,27 +146,21 @@ export const LobbyView: FC = ({ // We also pass in a clone because livekit mutates the object passed in, // which would cause the devices to be re-opened on the next render. audio: Object.assign({}, initialAudioOptions), - video: muteStates.video.enabled && { + video: videoEnabled && { deviceId: videoInputId, processor: initialProcessor, }, }), - [ - initialAudioOptions, - muteStates.video.enabled, - videoInputId, - initialProcessor, - ], + [initialAudioOptions, videoEnabled, videoInputId, initialProcessor], ); - const latestMuteStates = useLatest(muteStates); const onError = useCallback( (error: Error) => { logger.error("Error while creating preview Tracks:", error); - latestMuteStates.current.audio.setEnabled?.(false); - latestMuteStates.current.video.setEnabled?.(false); + muteStates.audio.setEnabled$.value?.(false); + muteStates.video.setEnabled$.value?.(false); }, - [latestMuteStates], + [muteStates], ); const tracks = usePreviewTracks(localTrackOptions, onError); @@ -217,7 +207,7 @@ export const LobbyView: FC = ({