import React, { useCallback, useMemo } from "react"; import styles from "./InCallView.module.css"; import { HangupButton, MicButton, VideoButton, ScreenshareButton, } from "../button"; import { Header, LeftNav, RightNav, RoomHeaderInfo } from "../Header"; import VideoGrid, { useVideoGridLayout, } from "matrix-react-sdk/src/components/views/voip/GroupCallView/VideoGrid"; import { VideoTileContainer } from "matrix-react-sdk/src/components/views/voip/GroupCallView/VideoTileContainer"; import SimpleVideoGrid from "matrix-react-sdk/src/components/views/voip/GroupCallView/SimpleVideoGrid"; import "matrix-react-sdk/res/css/views/voip/GroupCallView/_VideoGrid.scss"; import { getAvatarUrl } from "../matrix-utils"; import { GroupCallInspector } from "./GroupCallInspector"; import { OverflowMenu } from "./OverflowMenu"; import { GridLayoutMenu } from "./GridLayoutMenu"; import { Avatar } from "../Avatar"; import { UserMenuContainer } from "../UserMenuContainer"; const canScreenshare = "getDisplayMedia" in navigator.mediaDevices; // There is currently a bug in Safari our our code with cloning and sending MediaStreams // or with getUsermedia and getDisplaymedia being used within the same session. // For now we can disable screensharing in Safari. const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); export function InCallView({ client, groupCall, roomName, microphoneMuted, localVideoMuted, toggleLocalVideoMuted, toggleMicrophoneMuted, userMediaFeeds, activeSpeaker, onLeave, toggleScreensharing, isScreensharing, screenshareFeeds, simpleGrid, setShowInspector, showInspector, roomId, }) { const [layout, setLayout] = useVideoGridLayout(); const items = useMemo(() => { const participants = []; for (const callFeed of userMediaFeeds) { participants.push({ id: callFeed.stream.id, callFeed, isActiveSpeaker: screenshareFeeds.length === 0 ? callFeed.userId === activeSpeaker : false, }); } for (const callFeed of screenshareFeeds) { const userMediaItem = participants.find( (item) => item.callFeed.userId === callFeed.userId ); if (userMediaItem) { userMediaItem.presenter = true; } participants.push({ id: callFeed.stream.id, callFeed, focused: true, }); } return participants; }, [userMediaFeeds, activeSpeaker, screenshareFeeds]); const onFocusTile = useCallback( (tiles, focusedTile) => { if (layout === "freedom") { return tiles.map((tile) => { if (tile === focusedTile) { return { ...tile, presenter: !tile.presenter }; } return tile; }); } else { return tiles; } }, [layout, setLayout] ); const renderAvatar = useCallback( (roomMember, width, height) => { const avatarUrl = roomMember.user?.avatarUrl; const size = Math.round(Math.min(width, height) / 2); return ( ); }, [client] ); return (
{items.length === 0 ? (

Waiting for other participants...

) : simpleGrid ? ( ) : ( {({ item, ...rest }) => ( )} )}
{canScreenshare && !isSafari && ( )}
); }