Add new GroupCallInspector

This commit is contained in:
Robert Long 2021-10-15 16:41:23 -07:00
commit f5142ba93e
4 changed files with 284 additions and 1 deletions

143
src/GroupCallInspector.jsx Normal file
View file

@ -0,0 +1,143 @@
import React, { useEffect, useState, useMemo } from "react";
import { useCallback } from "react";
import ReactJson from "react-json-view";
function getCallUserId(call) {
return call.getOpponentMember()?.userId || call.invitee || null;
}
function getCallState(call) {
return {
opponentMemberId: getCallUserId(call),
state: call.state,
direction: call.direction,
};
}
function getHangupCallState(call) {
return {
...getCallState(call),
hangupReason: call.hangupReason,
};
}
export function GroupCallInspector({ client, groupCall, show }) {
const [roomStateEvents, setRoomStateEvents] = useState([]);
const [toDeviceEvents, setToDeviceEvents] = useState([]);
const [state, setState] = useState({
userId: client.getUserId(),
});
const updateState = useCallback(
(next) => setState((prev) => ({ ...prev, ...next })),
[]
);
useEffect(() => {
function onUpdateRoomState(event) {
if (event) {
setRoomStateEvents((prev) => [
...prev,
{
eventType: event.getType(),
stateKey: event.getStateKey(),
content: event.getContent(),
},
]);
}
const roomEvent = groupCall.room.currentState
.getStateEvents("org.matrix.msc3401.call", groupCall.groupCallId)
.getContent();
const memberEvents = Object.fromEntries(
groupCall.room.currentState
.getStateEvents("org.matrix.msc3401.call.member")
.map((event) => [event.getStateKey(), event.getContent()])
);
updateState({
["org.matrix.msc3401.call"]: roomEvent,
["org.matrix.msc3401.call.member"]: memberEvents,
});
}
function onCallsChanged() {
const calls = groupCall.calls.map(getCallState);
updateState({ calls });
}
function onCallHangup(call) {
setState(({ hangupCalls, ...rest }) => ({
...rest,
hangupCalls: hangupCalls
? [...hangupCalls, getHangupCallState(call)]
: [getHangupCallState(call)],
}));
}
function onToDeviceEvent(event) {
const eventType = event.getType();
if (
!(
eventType.startsWith("m.call.") ||
eventType.startsWith("org.matrix.call.")
)
) {
return;
}
const content = event.getContent();
if (content.conf_id && content.conf_id !== groupCall.groupCallId) {
return;
}
setToDeviceEvents((prev) => [...prev, { eventType, content }]);
}
client.on("RoomState.events", onUpdateRoomState);
groupCall.on("calls_changed", onCallsChanged);
client.on("state", onCallsChanged);
client.on("hangup", onCallHangup);
client.on("toDeviceEvent", onToDeviceEvent);
onUpdateRoomState();
}, [client, groupCall]);
const toDeviceEventsByCall = useMemo(() => {
const result = {};
for (const event of toDeviceEvents) {
const callId = event.content.call_id;
result[callId] = result[callId] || [];
result[callId].push(event);
}
return result;
}, [toDeviceEvents]);
return (
<div style={{ maxHeight: "25%", overflowY: "auto" }}>
{show && (
<ReactJson
theme="monokai"
src={{
state,
roomStateEvents,
toDeviceEvents,
toDeviceEventsByCall,
}}
name={null}
indentWidth={2}
collapsed={1}
displayDataTypes={false}
displayObjectSize={false}
enableClipboard={false}
/>
)}
</div>
);
}

View file

@ -24,6 +24,7 @@ import {
LayoutToggleButton,
ScreenshareButton,
DropdownButton,
SettingsButton,
} from "./RoomButton";
import { Header, LeftNav, RightNav, CenterNav } from "./Header";
import { Button } from "./Input";
@ -37,6 +38,7 @@ import { useCallFeed } from "matrix-react-sdk/src/hooks/useCallFeed";
import { useMediaStream } from "matrix-react-sdk/src/hooks/useMediaStream";
import { fetchGroupCall } from "./ConferenceCallManagerHooks";
import { ErrorModal } from "./ErrorModal";
import { GroupCallInspector } from "./GroupCallInspector";
function useLoadGroupCall(client, roomId) {
const [state, setState] = useState({
@ -109,6 +111,7 @@ export function GroupCallView({ client, groupCall }) {
} else if (state === GroupCallState.Entered) {
return (
<InRoomView
groupCall={groupCall}
client={client}
roomName={groupCall.room.name}
microphoneMuted={microphoneMuted}
@ -290,6 +293,7 @@ function useMediaHandler(client) {
function InRoomView({
client,
groupCall,
roomName,
microphoneMuted,
localVideoMuted,
@ -302,6 +306,8 @@ function InRoomView({
isScreensharing,
screenshareFeeds,
}) {
const [showInspector, setShowInspector] = useState(false);
const [layout, toggleLayout] = useVideoGridLayout();
const {
@ -377,6 +383,11 @@ function InRoomView({
<h3>{roomName}</h3>
</CenterNav>
<RightNav>
<SettingsButton
title={showInspector ? "Hide Inspector" : "Show Inspector"}
on={showInspector}
onClick={() => setShowInspector((prev) => !prev)}
/>
<LayoutToggleButton
title={layout === "spotlight" ? "Spotlight" : "Gallery"}
layout={layout}
@ -421,6 +432,11 @@ function InRoomView({
/>
<HangupButton onClick={onLeave} />
</div>
<GroupCallInspector
client={client}
groupCall={groupCall}
show={showInspector}
/>
</>
);
}