mirror of
https://github.com/vector-im/element-call.git
synced 2026-03-31 07:00:26 +00:00
Switch to new group call if the call in a room changes
This PR comes with a lot of caveats currently: * It removes the leaveCall() from when the useGroupCall() hook is torn down. I can't see another way of maintaining the correct joined state (because switching group calls will cause the effects to re-run) but this does mean that if the user somehow navigates within the app without using the hangup button, they won't leave the call. * The state of the call will be reset on switch, including the state of the screenshare, what devices are being used and even the mute states. Unsure if it's better to try & fix these up by moving state around or whether to refactor more in js-sdk so the group call can be switched more transparently.
This commit is contained in:
@@ -94,6 +94,8 @@ interface State {
|
||||
requestingScreenshare: boolean;
|
||||
participants: Map<RoomMember, Map<string, ParticipantInfo>>;
|
||||
hasLocalParticipant: boolean;
|
||||
// whether we think we should be joined to the call (irrespective of whether or not we actually are)
|
||||
joined: boolean;
|
||||
}
|
||||
|
||||
// This is a bit of a hack, but we keep the opentelemetry tracker object at the file
|
||||
@@ -161,6 +163,7 @@ export function useGroupCall(
|
||||
participants,
|
||||
hasLocalParticipant,
|
||||
requestingScreenshare,
|
||||
joined,
|
||||
},
|
||||
setState,
|
||||
] = useState<State>({
|
||||
@@ -173,6 +176,7 @@ export function useGroupCall(
|
||||
requestingScreenshare: false,
|
||||
participants: getParticipants(groupCall),
|
||||
hasLocalParticipant: false,
|
||||
joined: false,
|
||||
});
|
||||
|
||||
if (groupCallOTelMembershipGroupCallId !== groupCall.groupCallId) {
|
||||
@@ -208,7 +212,8 @@ export function useGroupCall(
|
||||
const leaveCall = useCallback(() => {
|
||||
groupCallOTelMembership?.onLeaveCall();
|
||||
groupCall.leave();
|
||||
}, [groupCall]);
|
||||
updateState({ joined: false });
|
||||
}, [groupCall, updateState]);
|
||||
|
||||
useEffect(() => {
|
||||
// disable the media action keys, otherwise audio elements get paused when
|
||||
@@ -238,6 +243,15 @@ export function useGroupCall(
|
||||
}, [doNothingMediaActionCallback]);
|
||||
|
||||
useEffect(() => {
|
||||
if (joined && groupCall.state !== GroupCallState.Entered) {
|
||||
groupCall.enter().catch((error) => {
|
||||
console.error(error);
|
||||
updateState({ error });
|
||||
});
|
||||
} else if (!joined && groupCall.state === GroupCallState.Entered) {
|
||||
groupCall.leave();
|
||||
}
|
||||
|
||||
function onGroupCallStateChanged() {
|
||||
updateState({
|
||||
state: groupCall.state,
|
||||
@@ -462,9 +476,8 @@ export function useGroupCall(
|
||||
RoomStateEvent.Update,
|
||||
checkForParallelCalls
|
||||
);
|
||||
leaveCall();
|
||||
};
|
||||
}, [groupCall, updateState, leaveCall]);
|
||||
}, [groupCall, updateState, leaveCall, joined]);
|
||||
|
||||
usePageUnload(() => {
|
||||
leaveCall();
|
||||
@@ -490,10 +503,7 @@ export function useGroupCall(
|
||||
// have started tracking by the time calls start getting created.
|
||||
groupCallOTelMembership?.onJoinCall();
|
||||
|
||||
await groupCall.enter().catch((error) => {
|
||||
console.error(error);
|
||||
updateState({ error });
|
||||
});
|
||||
updateState({ joined: true });
|
||||
}, [groupCall, updateState]);
|
||||
|
||||
const toggleLocalVideoMuted = useCallback(() => {
|
||||
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||
import {
|
||||
GroupCallType,
|
||||
@@ -31,6 +31,7 @@ import type { GroupCall } from "matrix-js-sdk/src/webrtc/groupCall";
|
||||
import { isLocalRoomId, createRoom, roomNameFromRoomId } from "../matrix-utils";
|
||||
import { translatedError } from "../TranslatedError";
|
||||
import { widget } from "../widget";
|
||||
import { useTypedEventEmitter } from "../useEvents";
|
||||
|
||||
const STATS_COLLECT_INTERVAL_TIME_MS = 10000;
|
||||
|
||||
@@ -67,6 +68,17 @@ export const useLoadGroupCall = (
|
||||
const { t } = useTranslation();
|
||||
const [state, setState] = useState<GroupCallStatus>({ kind: "loading" });
|
||||
|
||||
const onGroupCallIncoming = useCallback((groupCall: GroupCall) => {
|
||||
// update if a new group call arrives for this room
|
||||
setState({ kind: "loaded", groupCall });
|
||||
}, []);
|
||||
|
||||
useTypedEventEmitter(
|
||||
client,
|
||||
GroupCallEventHandlerEvent.Incoming,
|
||||
onGroupCallIncoming
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchOrCreateRoom = async (): Promise<Room> => {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user