mirror of
https://github.com/vector-im/element-call.git
synced 2026-09-22 22:29:30 +00:00
Let the component own its mute state
ElementCallView took muteStates as a prop, which would have meant an embedder building one before it could show a call. It could not simply make its own: RoomPage created one on mount whichever branch it went on to render, and two would both report the user's mute state to the host, talking over each other. Move the construction into a useMuteStates hook, and give the lobby shown while waiting to be let into a room its own component. Each lobby now holds mute state only while it is on screen, so there is never a second one, and the component can own the call's. KnockLobbyView also takes the room summary and label handling that RoomPage was assembling on its behalf, leaving the page with arriving at a call rather than being in one.
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
Copyright 2026 Element Creations Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import { MuteStates } from "./MuteStates";
|
||||
import { ObservableScope } from "./ObservableScope";
|
||||
import { calculateInitialMuteState } from "./initialMuteState";
|
||||
import { useMediaDevices } from "../MediaDevicesContext";
|
||||
import { useHostBridge } from "../HostBridge";
|
||||
import { useUrlParams } from "../UrlParams";
|
||||
|
||||
/**
|
||||
* Audio and video mute state, kept in step with the host.
|
||||
*
|
||||
* `null` until the media devices have been looked at, since what the user
|
||||
* starts muted depends on what they have.
|
||||
*
|
||||
* Whoever shows the user their own camera owns one of these. Note there should
|
||||
* only ever be one alive at a time: each reports the user's mute state to the
|
||||
* host, so two would have them talking over each other.
|
||||
*/
|
||||
export function useMuteStates(): MuteStates | null {
|
||||
const urlParams = useUrlParams();
|
||||
const hostBridge = useHostBridge();
|
||||
const devices = useMediaDevices();
|
||||
const [muteStates, setMuteStates] = useState<MuteStates | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const scope = new ObservableScope();
|
||||
setMuteStates(
|
||||
new MuteStates(
|
||||
scope,
|
||||
devices,
|
||||
calculateInitialMuteState(
|
||||
urlParams.skipLobby,
|
||||
urlParams.callIntent,
|
||||
urlParams.isWidget,
|
||||
),
|
||||
hostBridge,
|
||||
),
|
||||
);
|
||||
return (): void => scope.end();
|
||||
}, [devices, urlParams, hostBridge]);
|
||||
|
||||
return muteStates;
|
||||
}
|
||||
Reference in New Issue
Block a user