theluyuan 38ba663466
Some checks failed
Close stale issues and PRs / stale (push) Has been cancelled
init
2025-09-02 14:49:16 +08:00

186 lines
4.7 KiB
TypeScript

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 { isSharedVideoEnabled, isVideoPlaying } from '../../functions';
import VideoManager from './VideoManager';
import YoutubeVideoManager from './YoutubeVideoManager';
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<IProps> {
/**
* 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;
}
if (videoUrl.match(/http/)) {
return <VideoManager videoId = { videoUrl } />;
}
return <YoutubeVideoManager videoId = { videoUrl } />;
}
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {React$Element}
*/
override render() {
const { isEnabled, isResizing, isVideoShared, onStage } = this.props;
if (!isEnabled || !isVideoShared) {
return null;
}
const style: any = this.getDimensions();
if (!onStage) {
style.display = 'none';
}
return (
<div
className = { (isResizing && 'disable-pointer') || '' }
id = 'sharedVideo'
style = { style }>
{this.getManager()}
</div>
);
}
}
/**
* 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);