import React, { Component } from 'react'; import { connect } from 'react-redux'; // @ts-expect-error import Filmstrip from '../../../../../modules/UI/videolayout/Filmstrip'; import { IReduxState } from '../../../app/types'; import { FakeParticipant } from '../../../base/participants/types'; import { getVerticalViewMaxWidth } from '../../../filmstrip/functions.web'; import { getLargeVideoParticipant } from '../../../large-video/functions'; import { getToolboxHeight } from '../../../toolbox/functions.web'; import { VIDEO_SOURCE_TYPES } from '../../constants'; import { getVideoSourceType, isSharedVideoEnabled, isVideoPlaying } from '../../functions'; import EmbedVideoManager from './EmbedVideoManager'; import VideoManager from './VideoManager'; import YoutubeVideoManager from './YoutubeVideoManager'; const EMBED_VIDEO_TYPES = [ VIDEO_SOURCE_TYPES.VIMEO, VIDEO_SOURCE_TYPES.DAILYMOTION, VIDEO_SOURCE_TYPES.TWITCH ]; interface IProps { /** * The available client width. */ clientHeight: number; /** * The available client width. */ clientWidth: number; /** * Whether the (vertical) filmstrip is visible or not. */ filmstripVisible: boolean; /** * The width of the vertical filmstrip. */ filmstripWidth: number; /** * Whether the shared video is enabled or not. */ isEnabled: boolean; /** * Whether the user is actively resizing the filmstrip. */ isResizing: boolean; /** * Whether the shared video is currently playing. */ isVideoShared: boolean; /** * Whether the shared video should be shown on stage. */ onStage: boolean; /** * The shared video url. */ videoUrl?: string; } /** . * Implements a React {@link Component} which represents the large video (a.k.a. * The conference participant who is on the local stage) on Web/React. * * @augments Component */ class SharedVideo extends Component { /** * Computes the width and the height of the component. * * @returns {{ * height: number, * width: number * }} */ getDimensions() { const { clientHeight, clientWidth, filmstripVisible, filmstripWidth } = this.props; let width; let height; if (interfaceConfig.VERTICAL_FILMSTRIP) { if (filmstripVisible) { width = `${clientWidth - filmstripWidth}px`; } else { width = `${clientWidth}px`; } height = `${clientHeight - getToolboxHeight()}px`; } else { if (filmstripVisible) { height = `${clientHeight - Filmstrip.getFilmstripHeight()}px`; } else { height = `${clientHeight}px`; } width = `${clientWidth}px`; } return { width, height }; } /** * Retrieves the manager to be used for playing the shared video. * * @returns {Component} */ getManager() { const { videoUrl } = this.props; if (!videoUrl) { return null; } const sourceType = getVideoSourceType(videoUrl); if (sourceType === VIDEO_SOURCE_TYPES.YOUTUBE) { return ; } if (EMBED_VIDEO_TYPES.includes(sourceType as any)) { return ( ); } return ; } /** * Implements React's {@link Component#render()}. * * @inheritdoc * @returns {React$Element} */ override render() { const { isEnabled, isResizing, isVideoShared, onStage } = this.props; if (!isEnabled || !isVideoShared || !onStage) { return null; } const style: any = this.getDimensions(); return (
{this.getManager()}
); } } /** * Maps (parts of) the Redux state to the associated LargeVideo props. * * @param {Object} state - The Redux state. * @private * @returns {IProps} */ function _mapStateToProps(state: IReduxState) { const { videoUrl } = state['features/shared-video']; const { clientHeight, videoSpaceWidth } = state['features/base/responsive-ui']; const { visible, isResizing } = state['features/filmstrip']; const { isResizing: isChatResizing } = state['features/chat']; const onStage = getLargeVideoParticipant(state)?.fakeParticipant === FakeParticipant.SharedVideo; const isVideoShared = isVideoPlaying(state); return { clientHeight, clientWidth: videoSpaceWidth, filmstripVisible: visible, filmstripWidth: getVerticalViewMaxWidth(state), isEnabled: isSharedVideoEnabled(state), isResizing: isResizing || isChatResizing, isVideoShared, onStage, videoUrl }; } export default connect(_mapStateToProps)(SharedVideo);