From 1548a5673ff83cbcb25b6ea2c0b2fb2f69d1ef73 Mon Sep 17 00:00:00 2001 From: Enrico Schwendig Date: Wed, 15 Feb 2023 16:04:05 +0100 Subject: [PATCH] Extend developer view with media debug information (#909) * interceptor: add MediaStream feed debug interceptor - interceptor displays nick name for default and nick name + user id if user gast - interceptor displays track id + media stream ids --- public/locales/en-GB/app.json | 4 +- src/inspectors/MediaInspector.module.css | 53 +++++++++ src/inspectors/MediaInspector.tsx | 134 +++++++++++++++++++++++ src/room/GroupCallInspector.tsx | 10 ++ src/settings/SettingsModal.tsx | 15 --- src/settings/useSetting.ts | 2 - src/video-grid/VideoTile.tsx | 6 +- 7 files changed, 203 insertions(+), 21 deletions(-) create mode 100644 src/inspectors/MediaInspector.module.css create mode 100644 src/inspectors/MediaInspector.tsx diff --git a/public/locales/en-GB/app.json b/public/locales/en-GB/app.json index 21af889..882fd17 100644 --- a/public/locales/en-GB/app.json +++ b/public/locales/en-GB/app.json @@ -68,6 +68,7 @@ "Logging in…": "Logging in…", "Login": "Login", "Login to your account": "Login to your account", + "Media Feeds": "Media Feeds", "Microphone": "Microphone", "Microphone {{n}}": "Microphone {{n}}", "Microphone permissions needed to join the call.": "Microphone permissions needed to join the call.", @@ -75,6 +76,7 @@ "More menu": "More menu", "Mute microphone": "Mute microphone", "No": "No", + "No Feeds…": "No Feeds…", "Not now, return to home screen": "Not now, return to home screen", "Not registered yet? <2>Create an account": "Not registered yet? <2>Create an account", "Other users are trying to join this call from incompatible versions. These users should ensure that they have refreshed their browsers:<1>{userLis}": "Other users are trying to join this call from incompatible versions. These users should ensure that they have refreshed their browsers:<1>{userLis}", @@ -95,13 +97,13 @@ "Return to home screen": "Return to home screen", "Save": "Save", "Saving…": "Saving…", + "Screen Share Feeds": "Screen Share Feeds", "Select an option": "Select an option", "Send debug logs": "Send debug logs", "Sending debug logs…": "Sending debug logs…", "Sending…": "Sending…", "Settings": "Settings", "Share screen": "Share screen", - "Show call feed debug info": "Show call feed debug info", "Show call inspector": "Show call inspector", "Sign in": "Sign in", "Sign out": "Sign out", diff --git a/src/inspectors/MediaInspector.module.css b/src/inspectors/MediaInspector.module.css new file mode 100644 index 0000000..d37638d --- /dev/null +++ b/src/inspectors/MediaInspector.module.css @@ -0,0 +1,53 @@ +/* +Copyright 2023 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +element { + --table-header: #1976d2; + --table-header-border: #1565c0; + --table-border: #d9d9d9; + --row-bg: #ffffff; +} + +.scrollContainer { + height: 100%; + overflow-y: auto; +} + +.voIPInspectorViewer { + display: flex; + flex-direction: column; + align-items: center; + padding: 20px; +} + +.voIPInspectorViewer :global(.messageText) { + font-size: var(--font-size-caption); + fill: var(--primary-content) !important; + stroke: var(--primary-content) !important; +} + +.section { + display: table; + width: 100%; +} + +.section > * { + display: table-row; +} + +.section .col { + display: table-cell; +} diff --git a/src/inspectors/MediaInspector.tsx b/src/inspectors/MediaInspector.tsx new file mode 100644 index 0000000..3a48265 --- /dev/null +++ b/src/inspectors/MediaInspector.tsx @@ -0,0 +1,134 @@ +/* +Copyright 2023 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { MatrixClient } from "matrix-js-sdk/src/client"; +import { GroupCall } from "matrix-js-sdk/src/webrtc/groupCall"; +import { CallFeed } from "matrix-js-sdk/src/webrtc/callFeed"; +import React from "react"; +import { t } from "i18next"; + +import styles from "./MediaInspector.module.css"; + +interface MediaViewerProps { + client: MatrixClient; + groupCall: GroupCall; + userMediaFeeds: CallFeed[]; + screenshareFeeds: CallFeed[]; +} + +export function MediaViewer({ + client, + groupCall, + userMediaFeeds, + screenshareFeeds, +}: MediaViewerProps) { + return ( +
+
+ +
+ + + ); +} + +// View Items ########################################################################################################## + +interface TableProp { + name: string; + feeds: CallFeed[]; +} + +function Table({ name, feeds }: TableProp): JSX.Element { + // Catch case if feeds is empty + if (feeds.length === 0) { + const noFeed = t("No Feeds…"); + return ( +
+

{name}

+ +
+

{noFeed}

+
+
+ ); + } + + // Render Table + return ( +
+

{name}

+
+
Feed
+
User
+
StreamID
+
Tracks
+
+ {feeds.map((feed, i) => { + const user = feed.isLocal() + ? "local" + : feed.getMember() !== null + ? feed.getMember()?.name + : feed.userId; + return ( + + ); + })} +
+ ); +} + +interface TableRowProp { + index: number; + user: string; + stream: MediaStream | undefined; +} + +function TableRow({ index, user, stream }: TableRowProp): JSX.Element { + return ( +
+
{index}
+
{user}
+
{stream?.id}
+
+ {stream?.getTracks().map( + (track): JSX.Element => ( + + ) + )} +
+
+ ); +} + +interface TrackColumnProp { + kind: string; + trackId: string; +} + +function TrackColumn({ kind, trackId }: TrackColumnProp): JSX.Element { + return ( +
+
{kind}  
+
{trackId}
+
+ ); +} diff --git a/src/room/GroupCallInspector.tsx b/src/room/GroupCallInspector.tsx index 73b2a00..feefe33 100644 --- a/src/room/GroupCallInspector.tsx +++ b/src/room/GroupCallInspector.tsx @@ -36,6 +36,7 @@ import { CallEvent } from "matrix-js-sdk/src/webrtc/call"; import styles from "./GroupCallInspector.module.css"; import { SelectInput } from "../input/SelectInput"; import { PosthogAnalytics } from "../PosthogAnalytics"; +import { MediaViewer } from "../inspectors/MediaInspector"; interface InspectorContextState { eventsByUserId?: { [userId: string]: SequenceDiagramMatrixEvent[] }; @@ -464,6 +465,7 @@ export function GroupCallInspector({ Sequence Diagrams + {currentTab === "sequence-diagrams" && ( )} + {currentTab === "voip" && ( + + )} ); } diff --git a/src/settings/SettingsModal.tsx b/src/settings/SettingsModal.tsx index ccff126..106ef9e 100644 --- a/src/settings/SettingsModal.tsx +++ b/src/settings/SettingsModal.tsx @@ -33,7 +33,6 @@ import { useShowInspector, useOptInAnalytics, canEnableSpatialAudio, - useShowCallFeedDebugInfo, } from "./useSetting"; import { FieldRow, InputField } from "../input/Input"; import { Button } from "../button"; @@ -61,8 +60,6 @@ export const SettingsModal = (props: Props) => { const [spatialAudio, setSpatialAudio] = useSpatialAudio(); const [showInspector, setShowInspector] = useShowInspector(); - const [showCallFeedDebugInfo, setShowCallFeedDebugInfo] = - useShowCallFeedDebugInfo(); const [optInAnalytics, setOptInAnalytics] = useOptInAnalytics(); const [keyboardShortcuts, setKeyboardShortcuts] = useKeyboardShortcuts(); @@ -219,18 +216,6 @@ export const SettingsModal = (props: Props) => { } /> - - ) => - setShowCallFeedDebugInfo(e.target.checked) - } - /> -