import React, { useEffect, useMemo, useState } from 'react';
import { GridVideoTileLayout } from '@100mslive/types-prebuilt/elements/video_tile_layout';
import {
selectLocalPeerID,
selectLocalPeerRoleName,
selectPeers,
selectPeerScreenSharing,
selectWhiteboard,
useHMSStore,
useHMSVanillaStore,
} from '@100mslive/react-sdk';
import { EqualProminence } from './EqualProminence';
import { RoleProminence } from './RoleProminence';
import { ScreenshareLayout } from './ScreenshareLayout';
import { WhiteboardLayout } from './WhiteboardLayout';
// @ts-ignore: No implicit Any
import { usePinnedTrack, useSetAppDataByKey } from '../AppData/useUISettings';
import { VideoTileContext } from '../hooks/useVideoTileLayout';
import PeersSorter from '../../common/PeersSorter';
import { APP_DATA } from '../../common/constants';
export type TileCustomisationProps = {
hide_participant_name_on_tile: boolean;
rounded_video_tile: boolean;
hide_audio_mute_on_tile: boolean;
video_object_fit: 'contain' | 'cover';
edge_to_edge: boolean;
hide_metadata_on_tile: boolean;
};
export type GridLayoutProps = GridVideoTileLayout & TileCustomisationProps;
export const GridLayout = ({
enable_local_tile_inset: isInsetEnabled = false,
prominent_roles: prominentRoles = [],
enable_spotlighting_peer = false,
hide_participant_name_on_tile = false,
rounded_video_tile = true,
hide_audio_mute_on_tile = false,
video_object_fit = 'contain',
edge_to_edge = false,
hide_metadata_on_tile = false,
}: GridLayoutProps) => {
const peerSharing = useHMSStore(selectPeerScreenSharing);
const whiteboard = useHMSStore(selectWhiteboard);
const pinnedTrack = usePinnedTrack();
const peers = useHMSStore(selectPeers);
const localPeerRole = useHMSStore(selectLocalPeerRoleName);
const localPeerID = useHMSStore(selectLocalPeerID);
const [activeScreensharePeerId] = useSetAppDataByKey(APP_DATA.activeScreensharePeerId);
const isRoleProminence =
(prominentRoles.length &&
peers.some(
peer => peer.roleName && prominentRoles.includes(peer.roleName) && (peer.videoTrack || peer.audioTrack),
)) ||
pinnedTrack;
const updatedPeers = useMemo(() => {
// remove screenshare/whiteboard peer from active speaker sorting
if (activeScreensharePeerId || whiteboard?.open) {
return peers.filter(peer => peer.id !== activeScreensharePeerId || peer.customerUserId !== whiteboard?.owner);
}
if (isInsetEnabled) {
const isLocalPeerPinned = localPeerID === pinnedTrack?.peerId;
// if localPeer role is prominent role, it shows up in the center or local peer is pinned, so allow it in active speaker sorting
if ((localPeerRole && prominentRoles.includes(localPeerRole)) || isLocalPeerPinned) {
return peers;
} else {
return peers.filter(peer => !peer.isLocal);
}
}
return peers;
}, [
isInsetEnabled,
whiteboard,
activeScreensharePeerId,
localPeerRole,
localPeerID,
prominentRoles,
peers,
pinnedTrack,
]);
const vanillaStore = useHMSVanillaStore();
const [sortedPeers, setSortedPeers] = useState(updatedPeers);
const peersSorter = useMemo(() => new PeersSorter(vanillaStore), [vanillaStore]);
const [pageSize, setPageSize] = useState(0);
const [mainPage, setMainPage] = useState(0);
const tileLayout = {
enableSpotlightingPeer: enable_spotlighting_peer,
hideParticipantNameOnTile: hide_participant_name_on_tile,
roundedVideoTile: rounded_video_tile,
hideAudioMuteOnTile: hide_audio_mute_on_tile,
hideMetadataOnTile: hide_metadata_on_tile,
objectFit: video_object_fit,
};
useEffect(() => {
if (mainPage !== 0) {
return;
}
peersSorter.setPeersAndTilesPerPage({
peers: updatedPeers,
tilesPerPage: pageSize,
});
peersSorter.onUpdate(setSortedPeers);
}, [mainPage, peersSorter, updatedPeers, pageSize]);
if (peerSharing) {
return (
);
} else if (whiteboard?.open) {
return (
);
} else if (isRoleProminence) {
return (
);
}
return (
);
};