import React, { useState, useEffect, useRef } from 'react'; import useVideoTrack from '@dailyjs/shared/hooks/useVideoTrack'; import { ReactComponent as IconMicMute } from '@dailyjs/shared/icons/mic-off-sm.svg'; import classNames from 'classnames'; import PropTypes from 'prop-types'; import { DEFAULT_ASPECT_RATIO } from '../../constants'; import { Video } from './Video'; import { ReactComponent as Avatar } from './avatar.svg'; export const Tile = React.memo( ({ participant, mirrored = true, showName = true, showAvatar = true, showActiveSpeaker = true, aspectRatio = DEFAULT_ASPECT_RATIO, onVideoResize, videoFit = 'contain', ...props }) => { const videoTrack = useVideoTrack(participant); const videoEl = useRef(null); const [tileAspectRatio, setTileAspectRatio] = useState(aspectRatio); const [layer, setLayer] = useState(); /** * Add optional event listener for resize event so the parent component * can know the video's native aspect ratio. */ useEffect(() => { const video = videoEl.current; if (!onVideoResize || !video) return false; const handleResize = () => { if (!video) return; const width = video?.videoWidth; const height = video?.videoHeight; if (width && height) { // Return the video's aspect ratio to the parent's handler onVideoResize(width / height); } }; handleResize(); video?.addEventListener('resize', handleResize); return () => video?.removeEventListener('resize', handleResize); }, [onVideoResize, videoEl, participant]); useEffect(() => { if (aspectRatio === tileAspectRatio) return; setTileAspectRatio(aspectRatio); }, [aspectRatio, tileAspectRatio]); useEffect(() => { if ( typeof rtcpeers === 'undefined' || rtcpeers?.getCurrentType() !== 'sfu' ) return false; const i = setInterval(() => { setLayer( rtcpeers.sfu.consumers[`${participant.id}/cam-video`]?._preferredLayer ); }, 1500); return () => clearInterval(i); }, [participant]); const cx = classNames('tile', videoFit, { mirrored, avatar: showAvatar && !videoTrack, active: showActiveSpeaker && participant.isActiveSpeaker, }); return (
{showName && (
{participant.isMicMuted && } {participant.name} - {layer}
)} {videoTrack ? (
); } ); Tile.propTypes = { participant: PropTypes.object.isRequired, mirrored: PropTypes.bool, showName: PropTypes.bool, showAvatar: PropTypes.bool, aspectRatio: PropTypes.number, onVideoResize: PropTypes.func, videoFit: PropTypes.string, showActiveSpeaker: PropTypes.bool, }; export default Tile;