2022-04-20 11:03:33 -04:00
|
|
|
/*
|
2024-09-09 14:57:16 +01:00
|
|
|
Copyright 2024 New Vector Ltd.
|
2022-04-20 11:03:33 -04:00
|
|
|
Copyright 2022 The Matrix.org Foundation C.I.C.
|
|
|
|
|
|
2025-01-06 11:18:54 +00:00
|
|
|
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
2024-09-09 14:57:16 +01:00
|
|
|
Please see LICENSE files in the repository root for full details.
|
2022-04-20 11:03:33 -04:00
|
|
|
*/
|
|
|
|
|
|
2025-02-05 13:25:06 +00:00
|
|
|
import React, { type FC, useContext, useEffect, type AriaRole, useCallback } from "react";
|
2022-04-20 11:03:33 -04:00
|
|
|
|
2023-08-04 08:36:16 +01:00
|
|
|
import type { Room } from "matrix-js-sdk/src/matrix";
|
2025-03-05 15:41:26 -05:00
|
|
|
import { type Call, CallEvent } from "../../../models/Call";
|
2022-09-27 07:54:51 -04:00
|
|
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
|
|
|
|
import AppTile from "../elements/AppTile";
|
2022-08-30 15:13:39 -04:00
|
|
|
import { CallStore } from "../../../stores/CallStore";
|
2024-01-29 17:06:12 +01:00
|
|
|
import { SdkContextClass } from "../../../contexts/SDKContext";
|
2025-03-05 15:41:26 -05:00
|
|
|
import { useTypedEventEmitter } from "../../../hooks/useEventEmitter";
|
|
|
|
|
import { useCall } from "../../../hooks/useCall";
|
2022-09-27 07:54:51 -04:00
|
|
|
|
|
|
|
|
interface JoinCallViewProps {
|
|
|
|
|
room: Room;
|
|
|
|
|
resizing: boolean;
|
|
|
|
|
call: Call;
|
2024-01-29 17:06:12 +01:00
|
|
|
skipLobby?: boolean;
|
2023-12-20 15:32:24 +00:00
|
|
|
role?: AriaRole;
|
2025-03-05 15:41:26 -05:00
|
|
|
onClose: () => void;
|
2022-09-27 07:54:51 -04:00
|
|
|
}
|
|
|
|
|
|
2025-03-05 15:41:26 -05:00
|
|
|
const JoinCallView: FC<JoinCallViewProps> = ({ room, resizing, call, skipLobby, role, onClose }) => {
|
2022-09-27 07:54:51 -04:00
|
|
|
const cli = useContext(MatrixClientContext);
|
2025-03-05 15:41:26 -05:00
|
|
|
useTypedEventEmitter(call, CallEvent.Close, onClose);
|
2022-09-27 07:54:51 -04:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
2024-01-29 17:06:12 +01:00
|
|
|
// We'll take this opportunity to tidy up our room state
|
2022-09-27 07:54:51 -04:00
|
|
|
call.clean();
|
|
|
|
|
}, [call]);
|
|
|
|
|
|
2024-01-29 17:06:12 +01:00
|
|
|
useEffect(() => {
|
|
|
|
|
// Always update the widget data so that we don't ignore "skipLobby" accidentally.
|
|
|
|
|
call.widget.data ??= {};
|
|
|
|
|
call.widget.data.skipLobby = skipLobby;
|
|
|
|
|
}, [call.widget, skipLobby]);
|
2022-09-27 07:54:51 -04:00
|
|
|
|
2024-01-29 17:06:12 +01:00
|
|
|
const disconnectAllOtherCalls: () => Promise<void> = useCallback(async () => {
|
|
|
|
|
// The stickyPromise has to resolve before the widget actually becomes sticky.
|
|
|
|
|
// We only let the widget become sticky after disconnecting all other active calls.
|
2024-06-17 13:00:41 +02:00
|
|
|
const calls = [...CallStore.instance.connectedCalls].filter(
|
2024-01-29 17:06:12 +01:00
|
|
|
(call) => SdkContextClass.instance.roomViewStore.getRoomId() !== call.roomId,
|
2022-10-07 22:16:35 +02:00
|
|
|
);
|
2024-01-29 17:06:12 +01:00
|
|
|
await Promise.all(calls.map(async (call) => await call.disconnect()));
|
|
|
|
|
}, []);
|
2025-03-05 15:41:26 -05:00
|
|
|
|
2022-09-27 07:54:51 -04:00
|
|
|
return (
|
2025-02-11 15:28:29 +07:00
|
|
|
<div className="mx_CallView" role={role}>
|
2022-09-27 07:54:51 -04:00
|
|
|
<AppTile
|
|
|
|
|
app={call.widget}
|
|
|
|
|
room={room}
|
2023-02-16 09:38:44 +00:00
|
|
|
userId={cli.credentials.userId!}
|
2022-09-27 07:54:51 -04:00
|
|
|
creatorUserId={call.widget.creatorUserId}
|
|
|
|
|
waitForIframeLoad={call.widget.waitForIframeLoad}
|
|
|
|
|
showMenubar={false}
|
|
|
|
|
pointerEvents={resizing ? "none" : undefined}
|
2024-01-29 17:06:12 +01:00
|
|
|
stickyPromise={disconnectAllOtherCalls}
|
2022-09-27 07:54:51 -04:00
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
interface CallViewProps {
|
|
|
|
|
room: Room;
|
|
|
|
|
resizing: boolean;
|
2024-01-29 17:06:12 +01:00
|
|
|
skipLobby?: boolean;
|
2023-12-20 15:32:24 +00:00
|
|
|
role?: AriaRole;
|
2025-03-05 15:41:26 -05:00
|
|
|
/**
|
|
|
|
|
* Callback for when the user closes the call.
|
|
|
|
|
*/
|
|
|
|
|
onClose: () => void;
|
2022-09-27 07:54:51 -04:00
|
|
|
}
|
|
|
|
|
|
2025-03-05 15:41:26 -05:00
|
|
|
export const CallView: FC<CallViewProps> = ({ room, resizing, skipLobby, role, onClose }) => {
|
2022-09-27 07:54:51 -04:00
|
|
|
const call = useCall(room.roomId);
|
|
|
|
|
|
2025-03-05 15:41:26 -05:00
|
|
|
return (
|
|
|
|
|
call && (
|
|
|
|
|
<JoinCallView
|
|
|
|
|
room={room}
|
|
|
|
|
resizing={resizing}
|
|
|
|
|
call={call}
|
|
|
|
|
skipLobby={skipLobby}
|
|
|
|
|
role={role}
|
|
|
|
|
onClose={onClose}
|
|
|
|
|
/>
|
|
|
|
|
)
|
|
|
|
|
);
|
2022-09-27 07:54:51 -04:00
|
|
|
};
|