import React, { useCallback, useMemo, useState } from 'react'; import { useMeasure } from 'react-use'; import { selectAudioTrackByPeerID, selectHasPeerHandRaised, selectIsPeerAudioEnabled, selectLocalPeerID, selectPeerMetadata, selectPeerNameByID, selectVideoTrackByID, selectVideoTrackByPeerID, useHMSStore, } from '@100mslive/react-sdk'; import { BrbTileIcon, HandIcon, MicOffIcon } from '@100mslive/react-icons'; import TileConnection from './Connection/TileConnection'; import TileMenu, { isSameTile } from './TileMenu/TileMenu'; import { AudioLevel } from '../../AudioLevel'; import { Avatar } from '../../Avatar'; import { VideoTileStats } from '../../Stats'; import { CSS } from '../../Theme'; import { Video } from '../../Video'; import { StyledVideoTile } from '../../VideoTile'; import { getVideoTileLabel } from './peerTileUtils'; // @ts-ignore: No implicit Any import { useSetAppDataByKey, useUISettings } from './AppData/useUISettings'; // @ts-ignore: No implicit Any import { calculateAvatarAndAttribBoxSize } from '../common/utils'; import { APP_DATA, UI_SETTINGS } from '../common/constants'; const PeerMetadata = ({ peerId, size }: { peerId: string; size?: 'medium' | 'small' }) => { const metaData = useHMSStore(selectPeerMetadata(peerId)); const isBRB = metaData?.isBRBOn || false; const isHandRaised = useHMSStore(selectHasPeerHandRaised(peerId)); return ( <> {isHandRaised ? ( ) : null} {isBRB ? ( ) : null} ); }; const Tile = ({ peerId = '', trackId = '', width, height, objectFit = 'cover', canMinimise = false, isDragabble = false, rootCSS = {}, containerCSS = {}, enableSpotlightingPeer = true, hideParticipantNameOnTile = false, roundedVideoTile = true, hideAudioMuteOnTile = false, hideMetadataOnTile = false, }: { peerId?: string; trackId?: string; width?: string | number; height?: string | number; objectFit?: string; canMinimise?: boolean; isDragabble?: boolean; rootCSS?: CSS; containerCSS?: CSS; enableSpotlightingPeer?: boolean; hideParticipantNameOnTile?: boolean; roundedVideoTile?: boolean; hideAudioMuteOnTile?: boolean; hideMetadataOnTile?: boolean; }) => { const trackSelector = trackId ? selectVideoTrackByID(trackId) : selectVideoTrackByPeerID(peerId); const track = useHMSStore(trackSelector); const peerName = useHMSStore(selectPeerNameByID(peerId)); const audioTrack = useHMSStore(selectAudioTrackByPeerID(peerId)); const localPeerID = useHMSStore(selectLocalPeerID); const isAudioOnly = useUISettings(UI_SETTINGS.isAudioOnly); const mirrorLocalVideo = useUISettings(UI_SETTINGS.mirrorLocalVideo); const showStatsOnTiles = useUISettings(UI_SETTINGS.showStatsOnTiles); const isAudioMuted = !useHMSStore(selectIsPeerAudioEnabled(peerId)); const isVideoMuted = !track?.enabled; const [isMouseHovered, setIsMouseHovered] = useState(false); const isVideoDegraded = track?.degraded; const isLocal = localPeerID === peerId; const [pinnedTrackId] = useSetAppDataByKey(APP_DATA.pinnedTrackId); const pinned = isSameTile({ trackId: pinnedTrackId, videoTrackID: track?.id, audioTrackID: audioTrack?.id, }); const label = getVideoTileLabel({ peerName, isLocal, videoTrack: track, audioTrack, }); const onHoverHandler = useCallback((event: React.MouseEvent) => { setIsMouseHovered(event.type === 'mouseenter'); }, []); const [ref, { width: calculatedWidth, height: calculatedHeight }] = useMeasure(); const isTileBigEnoughToShowStats = calculatedHeight >= 180 && calculatedWidth >= 180; const [avatarSize, attribBoxSize] = useMemo( () => calculateAvatarAndAttribBoxSize(calculatedWidth, calculatedHeight), [calculatedWidth, calculatedHeight], ); return ( {peerName !== undefined ? ( {showStatsOnTiles && isTileBigEnoughToShowStats ? ( ) : null} ) : null} ); }; const VideoTile = React.memo(Tile); export default VideoTile;