diff --git a/src/room/GridLayoutMenu.tsx b/src/room/GridLayoutMenu.tsx index 6c9fa5a..6b00c44 100644 --- a/src/room/GridLayoutMenu.tsx +++ b/src/room/GridLayoutMenu.tsx @@ -26,7 +26,7 @@ import menuStyles from "../Menu.module.css"; import { Menu } from "../Menu"; import { TooltipTrigger } from "../Tooltip"; -type Layout = "freedom" | "spotlight"; +export type Layout = "freedom" | "spotlight"; interface Props { layout: Layout; setLayout: (layout: Layout) => void; diff --git a/src/room/InCallView.tsx b/src/room/InCallView.tsx index 7037765..84c00d2 100644 --- a/src/room/InCallView.tsx +++ b/src/room/InCallView.tsx @@ -16,7 +16,7 @@ limitations under the License. import React, { useCallback, useMemo, useRef } from "react"; import { usePreventScroll } from "@react-aria/overlays"; -import { GroupCall, MatrixClient } from "matrix-js-sdk"; +import { GroupCall, MatrixClient, RoomMember } from "matrix-js-sdk"; import { CallFeed } from "matrix-js-sdk/src/webrtc/callFeed"; import classNames from "classnames"; @@ -79,10 +79,10 @@ interface Props { export interface Participant { id: string; - callFeed: CallFeed; focused: boolean; - isLocal: boolean; presenter: boolean; + callFeed?: CallFeed; + isLocal?: boolean; } export function InCallView({ @@ -106,7 +106,7 @@ export function InCallView({ }: Props) { usePreventScroll(); const elementRef = useRef(); - const [layout, setLayout] = useVideoGridLayout(screenshareFeeds.length > 0); + const { layout, setLayout } = useVideoGridLayout(screenshareFeeds.length > 0); const { toggleFullscreen, fullscreenParticipant } = useFullscreen(elementRef); const [spatialAudio] = useSpatialAudio(); @@ -157,20 +157,23 @@ export function InCallView({ return participants; }, [userMediaFeeds, activeSpeaker, screenshareFeeds, layout]); - const renderAvatar = useCallback((roomMember, width, height) => { - const avatarUrl = roomMember.user?.avatarUrl; - const size = Math.round(Math.min(width, height) / 2); + const renderAvatar = useCallback( + (roomMember: RoomMember, width: number, height: number) => { + const avatarUrl = roomMember.user?.avatarUrl; + const size = Math.round(Math.min(width, height) / 2); - return ( - - ); - }, []); + return ( + + ); + }, + [] + ); const renderContent = useCallback((): JSX.Element => { if (items.length === 0) { @@ -189,7 +192,7 @@ export function InCallView({ audioContext={audioContext} audioDestination={audioDestination} disableSpeakingIndicator={true} - isFullscreen={fullscreenParticipant} + isFullscreen={!!fullscreenParticipant} onFullscreen={toggleFullscreen} /> ); @@ -202,11 +205,11 @@ export function InCallView({ key={item.id} item={item} getAvatar={renderAvatar} - showName={items.length > 2 || item.focused} + audioOutputDevice={audioOutput} audioContext={audioContext} audioDestination={audioDestination} disableSpeakingIndicator={items.length < 3} - isFullscreen={fullscreenParticipant} + isFullscreen={!!fullscreenParticipant} onFullscreen={toggleFullscreen} {...rest} /> @@ -221,6 +224,7 @@ export function InCallView({ layout, renderAvatar, toggleFullscreen, + audioOutput, ]); const { diff --git a/src/video-grid/AudioContainer.tsx b/src/video-grid/AudioContainer.tsx index d756d00..a60e195 100644 --- a/src/video-grid/AudioContainer.tsx +++ b/src/video-grid/AudioContainer.tsx @@ -39,7 +39,7 @@ export function AudioForParticipant({ const sourceRef = useRef(); useEffect(() => { - if (!item.isLocal && stream.getAudioTracks().length > 0 && audioContext) { + if (!item.isLocal && audioContext) { if (!gainNodeRef.current) { gainNodeRef.current = new GainNode(audioContext, { gain: localVolume, diff --git a/src/video-grid/VideoGrid.stories.jsx b/src/video-grid/VideoGrid.stories.tsx similarity index 90% rename from src/video-grid/VideoGrid.stories.jsx rename to src/video-grid/VideoGrid.stories.tsx index 3a62440..916ba68 100644 --- a/src/video-grid/VideoGrid.stories.jsx +++ b/src/video-grid/VideoGrid.stories.tsx @@ -15,10 +15,12 @@ limitations under the License. */ import React, { useState } from "react"; +import { useMemo } from "react"; + import { VideoGrid, useVideoGridLayout } from "./VideoGrid"; import { VideoTile } from "./VideoTile"; -import { useMemo } from "react"; import { Button } from "../button"; +import { Participant } from "../room/InCallView"; export default { title: "VideoGrid", @@ -28,10 +30,10 @@ export default { }; export const ParticipantsTest = () => { - const [layout, setLayout] = useVideoGridLayout(false); + const { layout, setLayout } = useVideoGridLayout(false); const [participantCount, setParticipantCount] = useState(1); - const items = useMemo( + const items: Participant[] = useMemo( () => new Array(participantCount).fill(undefined).map((_, i) => ({ id: (i + 1).toString(), @@ -46,9 +48,7 @@ export const ParticipantsTest = () => {
)} - {(videoMuted || noVideo) && ( + {videoMuted && ( <>
{avatar} @@ -86,15 +105,12 @@ export const VideoTile = forwardRef( {`${name} is presenting`}
) : ( - (showName || audioMuted || (videoMuted && !noVideo)) && ( -
- {audioMuted && !(videoMuted && !noVideo) && } - {videoMuted && !noVideo && } - {showName && {name}} -
- ) +
+ {audioMuted && !videoMuted && } + {videoMuted && } + {name} +
)} -