Film strip view almost working again.
parent
1eb115f547
commit
c530876d0d
|
|
@ -568,10 +568,10 @@ export const loggedIn = () =>
|
||||||
type : 'LOGGED_IN'
|
type : 'LOGGED_IN'
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setSelectedPeer = (selectedpeerId) =>
|
export const setSelectedPeer = (selectedPeerId) =>
|
||||||
({
|
({
|
||||||
type : 'SET_SELECTED_PEER',
|
type : 'SET_SELECTED_PEER',
|
||||||
payload : { selectedpeerId }
|
payload : { selectedPeerId }
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setSpotlights = (spotlights) =>
|
export const setSpotlights = (spotlights) =>
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ const styles = () =>
|
||||||
root :
|
root :
|
||||||
{
|
{
|
||||||
flexDirection : 'row',
|
flexDirection : 'row',
|
||||||
margin : 6,
|
|
||||||
flex : '0 0 auto',
|
flex : '0 0 auto',
|
||||||
boxShadow : 'var(--peer-shadow)',
|
boxShadow : 'var(--peer-shadow)',
|
||||||
border : 'var(--peer-border)',
|
border : 'var(--peer-border)',
|
||||||
|
|
@ -49,6 +48,7 @@ const Me = (props) =>
|
||||||
me,
|
me,
|
||||||
settings,
|
settings,
|
||||||
activeSpeaker,
|
activeSpeaker,
|
||||||
|
spacing,
|
||||||
style,
|
style,
|
||||||
advancedMode,
|
advancedMode,
|
||||||
micProducer,
|
micProducer,
|
||||||
|
|
@ -69,6 +69,11 @@ const Me = (props) =>
|
||||||
!screenProducer.remotelyPaused
|
!screenProducer.remotelyPaused
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const spacingStyle =
|
||||||
|
{
|
||||||
|
'margin' : spacing
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<div
|
<div
|
||||||
|
|
@ -78,6 +83,7 @@ const Me = (props) =>
|
||||||
activeSpeaker ? 'active-speaker' : null
|
activeSpeaker ? 'active-speaker' : null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
style={spacingStyle}
|
||||||
>
|
>
|
||||||
<div className={classnames(classes.viewContainer, 'webcam')} style={style}>
|
<div className={classnames(classes.viewContainer, 'webcam')} style={style}>
|
||||||
<VideoView
|
<VideoView
|
||||||
|
|
@ -128,6 +134,7 @@ Me.propTypes =
|
||||||
micProducer : appPropTypes.Producer,
|
micProducer : appPropTypes.Producer,
|
||||||
webcamProducer : appPropTypes.Producer,
|
webcamProducer : appPropTypes.Producer,
|
||||||
screenProducer : appPropTypes.Producer,
|
screenProducer : appPropTypes.Producer,
|
||||||
|
spacing : PropTypes.number,
|
||||||
style : PropTypes.object,
|
style : PropTypes.object,
|
||||||
classes : PropTypes.object.isRequired
|
classes : PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ const styles = (theme) =>
|
||||||
root :
|
root :
|
||||||
{
|
{
|
||||||
flex : '0 0 auto',
|
flex : '0 0 auto',
|
||||||
margin : 6,
|
|
||||||
boxShadow : 'var(--peer-shadow)',
|
boxShadow : 'var(--peer-shadow)',
|
||||||
border : 'var(--peer-border)',
|
border : 'var(--peer-border)',
|
||||||
touchAction : 'none',
|
touchAction : 'none',
|
||||||
|
|
@ -128,6 +127,7 @@ const Peer = (props) =>
|
||||||
screenConsumer,
|
screenConsumer,
|
||||||
toggleConsumerFullscreen,
|
toggleConsumerFullscreen,
|
||||||
toggleConsumerWindow,
|
toggleConsumerWindow,
|
||||||
|
spacing,
|
||||||
style,
|
style,
|
||||||
windowConsumer,
|
windowConsumer,
|
||||||
classes,
|
classes,
|
||||||
|
|
@ -164,6 +164,11 @@ const Peer = (props) =>
|
||||||
|
|
||||||
const smallScreen = useMediaQuery(theme.breakpoints.down('sm'));
|
const smallScreen = useMediaQuery(theme.breakpoints.down('sm'));
|
||||||
|
|
||||||
|
const spacingStyle =
|
||||||
|
{
|
||||||
|
'margin' : spacing
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<div
|
<div
|
||||||
|
|
@ -194,6 +199,7 @@ const Peer = (props) =>
|
||||||
setHover(false);
|
setHover(false);
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}}
|
}}
|
||||||
|
style={spacingStyle}
|
||||||
>
|
>
|
||||||
<div className={classnames(classes.viewContainer)} style={style}>
|
<div className={classnames(classes.viewContainer)} style={style}>
|
||||||
{ !videoVisible ?
|
{ !videoVisible ?
|
||||||
|
|
@ -406,6 +412,7 @@ Peer.propTypes =
|
||||||
screenConsumer : appPropTypes.Consumer,
|
screenConsumer : appPropTypes.Consumer,
|
||||||
windowConsumer : PropTypes.string,
|
windowConsumer : PropTypes.string,
|
||||||
activeSpeaker : PropTypes.bool,
|
activeSpeaker : PropTypes.bool,
|
||||||
|
spacing : PropTypes.number,
|
||||||
style : PropTypes.object,
|
style : PropTypes.object,
|
||||||
toggleConsumerFullscreen : PropTypes.func.isRequired,
|
toggleConsumerFullscreen : PropTypes.func.isRequired,
|
||||||
toggleConsumerWindow : PropTypes.func.isRequired,
|
toggleConsumerWindow : PropTypes.func.isRequired,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,210 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { makePeerConsumerSelector } from '../Selectors';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
import * as appPropTypes from '../appPropTypes';
|
||||||
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
|
import VideoView from '../VideoContainers/VideoView';
|
||||||
|
import Volume from './Volume';
|
||||||
|
|
||||||
|
const styles = () =>
|
||||||
|
({
|
||||||
|
root :
|
||||||
|
{
|
||||||
|
flex : '0 0 auto',
|
||||||
|
boxShadow : 'var(--peer-shadow)',
|
||||||
|
border : 'var(--peer-border)',
|
||||||
|
touchAction : 'none',
|
||||||
|
backgroundColor : 'var(--peer-bg-color)',
|
||||||
|
backgroundImage : 'var(--peer-empty-avatar)',
|
||||||
|
backgroundPosition : 'bottom',
|
||||||
|
backgroundSize : 'auto 85%',
|
||||||
|
backgroundRepeat : 'no-repeat',
|
||||||
|
'&.webcam' :
|
||||||
|
{
|
||||||
|
order : 2
|
||||||
|
},
|
||||||
|
'&.screen' :
|
||||||
|
{
|
||||||
|
order : 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
viewContainer :
|
||||||
|
{
|
||||||
|
position : 'relative',
|
||||||
|
'&.webcam' :
|
||||||
|
{
|
||||||
|
order : 2
|
||||||
|
},
|
||||||
|
'&.screen' :
|
||||||
|
{
|
||||||
|
order : 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
videoInfo :
|
||||||
|
{
|
||||||
|
position : 'absolute',
|
||||||
|
width : '100%',
|
||||||
|
height : '100%',
|
||||||
|
backgroundColor : 'rgba(0, 0, 0, 0.3)',
|
||||||
|
display : 'flex',
|
||||||
|
justifyContent : 'center',
|
||||||
|
alignItems : 'center',
|
||||||
|
padding : '0.4vmin',
|
||||||
|
zIndex : 21,
|
||||||
|
'& p' :
|
||||||
|
{
|
||||||
|
padding : '6px 12px',
|
||||||
|
borderRadius : 6,
|
||||||
|
userSelect : 'none',
|
||||||
|
pointerEvents : 'none',
|
||||||
|
fontSize : 20,
|
||||||
|
color : 'rgba(255, 255, 255, 0.55)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const SpeakerPeer = (props) =>
|
||||||
|
{
|
||||||
|
const {
|
||||||
|
advancedMode,
|
||||||
|
peer,
|
||||||
|
micConsumer,
|
||||||
|
webcamConsumer,
|
||||||
|
screenConsumer,
|
||||||
|
spacing,
|
||||||
|
style,
|
||||||
|
classes
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
const videoVisible = (
|
||||||
|
Boolean(webcamConsumer) &&
|
||||||
|
!webcamConsumer.locallyPaused &&
|
||||||
|
!webcamConsumer.remotelyPaused
|
||||||
|
);
|
||||||
|
|
||||||
|
const screenVisible = (
|
||||||
|
Boolean(screenConsumer) &&
|
||||||
|
!screenConsumer.locallyPaused &&
|
||||||
|
!screenConsumer.remotelyPaused
|
||||||
|
);
|
||||||
|
|
||||||
|
let videoProfile;
|
||||||
|
|
||||||
|
if (webcamConsumer)
|
||||||
|
videoProfile = webcamConsumer.profile;
|
||||||
|
|
||||||
|
let screenProfile;
|
||||||
|
|
||||||
|
if (screenConsumer)
|
||||||
|
screenProfile = screenConsumer.profile;
|
||||||
|
|
||||||
|
const spacingStyle =
|
||||||
|
{
|
||||||
|
'margin' : spacing
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
classnames(
|
||||||
|
classes.root,
|
||||||
|
'webcam'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
style={spacingStyle}
|
||||||
|
>
|
||||||
|
<div className={classnames(classes.viewContainer)} style={style}>
|
||||||
|
{ !videoVisible ?
|
||||||
|
<div className={classes.videoInfo}>
|
||||||
|
<p>this video is paused</p>
|
||||||
|
</div>
|
||||||
|
:null
|
||||||
|
}
|
||||||
|
|
||||||
|
<VideoView
|
||||||
|
advancedMode={advancedMode}
|
||||||
|
peer={peer}
|
||||||
|
displayName={peer.displayName}
|
||||||
|
showPeerInfo
|
||||||
|
videoTrack={webcamConsumer ? webcamConsumer.track : null}
|
||||||
|
videoVisible={videoVisible}
|
||||||
|
videoProfile={videoProfile}
|
||||||
|
audioCodec={micConsumer ? micConsumer.codec : null}
|
||||||
|
videoCodec={webcamConsumer ? webcamConsumer.codec : null}
|
||||||
|
>
|
||||||
|
<Volume id={peer.id} />
|
||||||
|
</VideoView>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{ screenConsumer ?
|
||||||
|
<div
|
||||||
|
className={classnames(classes.root, 'screen')}
|
||||||
|
>
|
||||||
|
{ !screenVisible ?
|
||||||
|
<div className={classes.videoInfo} style={style}>
|
||||||
|
<p>this video is paused</p>
|
||||||
|
</div>
|
||||||
|
:null
|
||||||
|
}
|
||||||
|
|
||||||
|
{ screenVisible ?
|
||||||
|
<div className={classnames(classes.viewContainer)} style={style}>
|
||||||
|
<VideoView
|
||||||
|
advancedMode={advancedMode}
|
||||||
|
videoContain
|
||||||
|
videoTrack={screenConsumer ? screenConsumer.track : null}
|
||||||
|
videoVisible={screenVisible}
|
||||||
|
videoProfile={screenProfile}
|
||||||
|
videoCodec={screenConsumer ? screenConsumer.codec : null}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
:null
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
:null
|
||||||
|
}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
SpeakerPeer.propTypes =
|
||||||
|
{
|
||||||
|
advancedMode : PropTypes.bool,
|
||||||
|
peer : appPropTypes.Peer,
|
||||||
|
micConsumer : appPropTypes.Consumer,
|
||||||
|
webcamConsumer : appPropTypes.Consumer,
|
||||||
|
screenConsumer : appPropTypes.Consumer,
|
||||||
|
spacing : PropTypes.number,
|
||||||
|
style : PropTypes.object,
|
||||||
|
classes : PropTypes.object.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapStateToProps = (state, props) =>
|
||||||
|
{
|
||||||
|
const getPeerConsumers = makePeerConsumerSelector();
|
||||||
|
|
||||||
|
return {
|
||||||
|
peer : state.peers[props.id],
|
||||||
|
...getPeerConsumers(state, props)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
areStatesEqual : (next, prev) =>
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
prev.peers === next.peers &&
|
||||||
|
prev.consumers === next.consumers &&
|
||||||
|
prev.room.activeSpeakerId === next.room.activeSpeakerId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)(withStyles(styles, { withTheme: true })(SpeakerPeer));
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import * as appPropTypes from '../../appPropTypes';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { withRoomContext } from '../../../RoomContext';
|
import { withRoomContext } from '../../../RoomContext';
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,10 @@ import {
|
||||||
spotlightsLengthSelector
|
spotlightsLengthSelector
|
||||||
} from '../Selectors';
|
} from '../Selectors';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import debounce from 'lodash/debounce';
|
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
import Peer from '../Containers/Peer';
|
import Peer from '../Containers/Peer';
|
||||||
import Me from '../Containers/Me';
|
import Me from '../Containers/Me';
|
||||||
import HiddenPeers from '../Containers/HiddenPeers';
|
import HiddenPeers from '../Containers/HiddenPeers';
|
||||||
import ResizeObserver from 'resize-observer-polyfill';
|
|
||||||
|
|
||||||
const RATIO = 1.334;
|
const RATIO = 1.334;
|
||||||
const PADDING_V = 50;
|
const PADDING_V = 50;
|
||||||
|
|
@ -43,16 +41,17 @@ class Democratic extends React.PureComponent
|
||||||
{
|
{
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {};
|
||||||
peerWidth : 400,
|
|
||||||
peerHeight : 300
|
this.resizeTimeout = null;
|
||||||
};
|
|
||||||
|
|
||||||
this.peersRef = React.createRef();
|
this.peersRef = React.createRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDimensions = debounce(() =>
|
updateDimensions = () =>
|
||||||
{
|
{
|
||||||
|
console.log('updateDimensions');
|
||||||
|
|
||||||
if (!this.peersRef.current)
|
if (!this.peersRef.current)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
@ -93,14 +92,21 @@ class Democratic extends React.PureComponent
|
||||||
peerHeight : 0.9 * y
|
peerHeight : 0.9 * y
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, 200);
|
};
|
||||||
|
|
||||||
componentDidMount()
|
componentDidMount()
|
||||||
{
|
{
|
||||||
window.addEventListener('resize', this.updateDimensions);
|
// window.resize event listener
|
||||||
const observer = new ResizeObserver(this.updateDimensions);
|
window.addEventListener('resize', () =>
|
||||||
|
{
|
||||||
|
// clear the timeout
|
||||||
|
clearTimeout(this.resizeTimeout);
|
||||||
|
|
||||||
observer.observe(this.peersRef.current);
|
// start timing for event "completion"
|
||||||
|
this.resizeTimeout = setTimeout(() => this.updateDimensions(), 250);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.updateDimensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount()
|
componentWillUnmount()
|
||||||
|
|
@ -108,8 +114,9 @@ class Democratic extends React.PureComponent
|
||||||
window.removeEventListener('resize', this.updateDimensions);
|
window.removeEventListener('resize', this.updateDimensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate()
|
componentDidUpdate(prevProps)
|
||||||
{
|
{
|
||||||
|
if (prevProps !== this.props)
|
||||||
this.updateDimensions();
|
this.updateDimensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -125,14 +132,15 @@ class Democratic extends React.PureComponent
|
||||||
|
|
||||||
const style =
|
const style =
|
||||||
{
|
{
|
||||||
'width' : this.state.peerWidth,
|
'width' : this.state.peerWidth ? this.state.peerWidth : 0,
|
||||||
'height' : this.state.peerHeight
|
'height' : this.state.peerHeight ? this.state.peerHeight : 0
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.root} ref={this.peersRef}>
|
<div className={classes.root} ref={this.peersRef}>
|
||||||
<Me
|
<Me
|
||||||
advancedMode={advancedMode}
|
advancedMode={advancedMode}
|
||||||
|
spacing={6}
|
||||||
style={style}
|
style={style}
|
||||||
/>
|
/>
|
||||||
{ spotlightsPeers.map((peer) =>
|
{ spotlightsPeers.map((peer) =>
|
||||||
|
|
@ -142,6 +150,7 @@ class Democratic extends React.PureComponent
|
||||||
key={peer.id}
|
key={peer.id}
|
||||||
advancedMode={advancedMode}
|
advancedMode={advancedMode}
|
||||||
id={peer.id}
|
id={peer.id}
|
||||||
|
spacing={6}
|
||||||
style={style}
|
style={style}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,89 +1,53 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ResizeObserver from 'resize-observer-polyfill';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import debounce from 'lodash/debounce';
|
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
import {
|
||||||
|
spotlightsLengthSelector
|
||||||
|
} from '../Selectors';
|
||||||
import { withRoomContext } from '../../RoomContext';
|
import { withRoomContext } from '../../RoomContext';
|
||||||
|
import Me from '../Containers/Me';
|
||||||
import Peer from '../Containers/Peer';
|
import Peer from '../Containers/Peer';
|
||||||
|
import SpeakerPeer from '../Containers/SpeakerPeer';
|
||||||
import HiddenPeers from '../Containers/HiddenPeers';
|
import HiddenPeers from '../Containers/HiddenPeers';
|
||||||
|
import Grid from '@material-ui/core/Grid';
|
||||||
|
|
||||||
const styles = () =>
|
const styles = () =>
|
||||||
({
|
({
|
||||||
root :
|
root :
|
||||||
{
|
{
|
||||||
display : 'flex',
|
|
||||||
flexDirection : 'column',
|
|
||||||
alignItems : 'center',
|
|
||||||
height : '100%',
|
height : '100%',
|
||||||
width : '100%'
|
|
||||||
},
|
|
||||||
activePeerContainer :
|
|
||||||
{
|
|
||||||
width : '100%',
|
width : '100%',
|
||||||
height : '80vh',
|
display : 'grid',
|
||||||
|
gridTemplateColumns : '1fr',
|
||||||
|
gridTemplateRows : '1.6fr minmax(0, 0.4fr)'
|
||||||
|
},
|
||||||
|
speaker :
|
||||||
|
{
|
||||||
|
gridArea : '1 / 1 / 2 / 2',
|
||||||
display : 'flex',
|
display : 'flex',
|
||||||
justifyContent : 'center',
|
justifyContent : 'center',
|
||||||
alignItems : 'center'
|
alignItems : 'center',
|
||||||
},
|
paddingTop : 40
|
||||||
activePeer :
|
|
||||||
{
|
|
||||||
width : '100%',
|
|
||||||
border : '5px solid rgba(255, 255, 255, 0.15)',
|
|
||||||
boxShadow : '0px 5px 12px 2px rgba(17, 17, 17, 0.5)',
|
|
||||||
marginTop : 60
|
|
||||||
},
|
},
|
||||||
filmStrip :
|
filmStrip :
|
||||||
|
{
|
||||||
|
gridArea : '2 / 1 / 3 / 2'
|
||||||
|
},
|
||||||
|
filmItem :
|
||||||
{
|
{
|
||||||
display : 'flex',
|
display : 'flex',
|
||||||
background : 'rgba(0, 0, 0 , 0.5)',
|
marginLeft : '6px',
|
||||||
width : '100%',
|
border : 'var(--peer-border)',
|
||||||
overflowX : 'auto',
|
|
||||||
height : '20vh',
|
|
||||||
alignItems : 'center'
|
|
||||||
},
|
|
||||||
filmStripContent :
|
|
||||||
{
|
|
||||||
margin : '0 auto',
|
|
||||||
display : 'flex',
|
|
||||||
height : '100%',
|
|
||||||
alignItems : 'center'
|
|
||||||
},
|
|
||||||
film :
|
|
||||||
{
|
|
||||||
height : '18vh',
|
|
||||||
flexShrink : 0,
|
|
||||||
paddingLeft : '1vh',
|
|
||||||
'& .active' :
|
|
||||||
{
|
|
||||||
borderColor : 'var(--active-speaker-border-color)'
|
|
||||||
},
|
|
||||||
'&.selected' :
|
'&.selected' :
|
||||||
{
|
{
|
||||||
borderColor : 'var(--selected-peer-border-color)'
|
borderColor : 'var(--selected-peer-border-color)'
|
||||||
},
|
},
|
||||||
'&:last-child' :
|
'&.active' :
|
||||||
{
|
{
|
||||||
paddingRight : '1vh'
|
opacity : '0.6'
|
||||||
}
|
}
|
||||||
},
|
|
||||||
filmContent :
|
|
||||||
{
|
|
||||||
height : '100%',
|
|
||||||
width : '100%',
|
|
||||||
border : '1px solid rgba(255,255,255,0.15)',
|
|
||||||
maxWidth : 'calc(18vh * (4 / 3))',
|
|
||||||
cursor : 'pointer',
|
|
||||||
'& .screen' :
|
|
||||||
{
|
|
||||||
maxWidth : 'calc(18vh * (2 * 4 / 3))',
|
|
||||||
border : 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hiddenPeers :
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -93,12 +57,13 @@ class Filmstrip extends React.PureComponent
|
||||||
{
|
{
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
this.resizeTimeout = null;
|
||||||
|
|
||||||
this.activePeerContainer = React.createRef();
|
this.activePeerContainer = React.createRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
lastSpeaker : null,
|
lastSpeaker : null
|
||||||
width : 400
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Find the name of the peer which is currently speaking. This is either
|
// Find the name of the peer which is currently speaking. This is either
|
||||||
|
|
@ -106,17 +71,24 @@ class Filmstrip extends React.PureComponent
|
||||||
// person has spoken yet, the first peer in the list of peers.
|
// person has spoken yet, the first peer in the list of peers.
|
||||||
getActivePeerId = () =>
|
getActivePeerId = () =>
|
||||||
{
|
{
|
||||||
if (this.props.selectedPeerId)
|
const {
|
||||||
|
selectedPeerId,
|
||||||
|
peers
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const { lastSpeaker } = this.state;
|
||||||
|
|
||||||
|
if (selectedPeerId && peers[selectedPeerId])
|
||||||
{
|
{
|
||||||
return this.props.selectedPeerId;
|
return this.props.selectedPeerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.state.lastSpeaker)
|
if (lastSpeaker && peers[lastSpeaker])
|
||||||
{
|
{
|
||||||
return this.state.lastSpeaker;
|
return this.state.lastSpeaker;
|
||||||
}
|
}
|
||||||
|
|
||||||
const peerIds = Object.keys(this.props.peers);
|
const peerIds = Object.keys(peers);
|
||||||
|
|
||||||
if (peerIds.length > 0)
|
if (peerIds.length > 0)
|
||||||
{
|
{
|
||||||
|
|
@ -128,45 +100,47 @@ class Filmstrip extends React.PureComponent
|
||||||
this.props.peers[peerId].consumers.some((consumer) =>
|
this.props.peers[peerId].consumers.some((consumer) =>
|
||||||
this.props.consumers[consumer].source === 'screen');
|
this.props.consumers[consumer].source === 'screen');
|
||||||
|
|
||||||
getRatio = () =>
|
updateDimensions = () =>
|
||||||
{
|
|
||||||
let ratio = 4 / 3;
|
|
||||||
|
|
||||||
if (this.isSharingCamera(this.getActivePeerId()))
|
|
||||||
{
|
|
||||||
ratio *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ratio;
|
|
||||||
};
|
|
||||||
|
|
||||||
updateDimensions = debounce(() =>
|
|
||||||
{
|
{
|
||||||
const container = this.activePeerContainer.current;
|
const container = this.activePeerContainer.current;
|
||||||
|
|
||||||
if (container)
|
if (container)
|
||||||
{
|
{
|
||||||
const ratio = this.getRatio();
|
let width = (container.clientWidth - 100);
|
||||||
|
|
||||||
let width = container.clientWidth;
|
let height = (width / 4) * 3;
|
||||||
|
|
||||||
if (width / ratio > (container.clientHeight - 100))
|
if (this.isSharingCamera(this.getActivePeerId()))
|
||||||
{
|
{
|
||||||
width = (container.clientHeight - 100) * ratio;
|
width /= 2;
|
||||||
|
height = (width / 4) * 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (height > (container.clientHeight - 60))
|
||||||
|
{
|
||||||
|
height = (container.clientHeight - 60);
|
||||||
|
width = (height / 3) * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
width
|
width,
|
||||||
|
height
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, 200);
|
};
|
||||||
|
|
||||||
componentDidMount()
|
componentDidMount()
|
||||||
{
|
{
|
||||||
window.addEventListener('resize', this.updateDimensions);
|
// window.resize event listener
|
||||||
const observer = new ResizeObserver(this.updateDimensions);
|
window.addEventListener('resize', () =>
|
||||||
|
{
|
||||||
|
// clear the timeout
|
||||||
|
clearTimeout(this.resizeTimeout);
|
||||||
|
|
||||||
|
// start timing for event "completion"
|
||||||
|
this.resizeTimeout = setTimeout(() => this.updateDimensions(), 250);
|
||||||
|
});
|
||||||
|
|
||||||
observer.observe(this.activePeerContainer.current);
|
|
||||||
this.updateDimensions();
|
this.updateDimensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -175,19 +149,28 @@ class Filmstrip extends React.PureComponent
|
||||||
window.removeEventListener('resize', this.updateDimensions);
|
window.removeEventListener('resize', this.updateDimensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillUpdate(nextProps)
|
||||||
|
{
|
||||||
|
if (nextProps !== this.props)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
nextProps.activeSpeakerId != null &&
|
||||||
|
nextProps.activeSpeakerId !== this.props.myId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// eslint-disable-next-line react/no-did-update-set-state
|
||||||
|
this.setState({
|
||||||
|
lastSpeaker : nextProps.activeSpeakerId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps)
|
componentDidUpdate(prevProps)
|
||||||
{
|
{
|
||||||
if (prevProps !== this.props)
|
if (prevProps !== this.props)
|
||||||
{
|
{
|
||||||
this.updateDimensions();
|
this.updateDimensions();
|
||||||
|
|
||||||
if (this.props.activeSpeakerName !== this.props.myName)
|
|
||||||
{
|
|
||||||
// eslint-disable-next-line react/no-did-update-set-state
|
|
||||||
this.setState({
|
|
||||||
lastSpeaker : this.props.activeSpeakerName
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,6 +179,7 @@ class Filmstrip extends React.PureComponent
|
||||||
const {
|
const {
|
||||||
roomClient,
|
roomClient,
|
||||||
peers,
|
peers,
|
||||||
|
myId,
|
||||||
advancedMode,
|
advancedMode,
|
||||||
spotlights,
|
spotlights,
|
||||||
spotlightsLength,
|
spotlightsLength,
|
||||||
|
|
@ -204,48 +188,67 @@ class Filmstrip extends React.PureComponent
|
||||||
|
|
||||||
const activePeerId = this.getActivePeerId();
|
const activePeerId = this.getActivePeerId();
|
||||||
|
|
||||||
|
const speakerStyle =
|
||||||
|
{
|
||||||
|
width : this.state.width,
|
||||||
|
height : this.state.height
|
||||||
|
};
|
||||||
|
|
||||||
|
const peerStyle =
|
||||||
|
{
|
||||||
|
'width' : '24vmin',
|
||||||
|
'height' : '18vmin'
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
<div className={classes.activePeerContainer} ref={this.activePeerContainer}>
|
<div className={classes.speaker} ref={this.activePeerContainer}>
|
||||||
{ peers[activePeerId] ?
|
{ peers[activePeerId] ?
|
||||||
<div
|
<SpeakerPeer
|
||||||
className={classes.activePeer}
|
|
||||||
style={{
|
|
||||||
width : this.state.width,
|
|
||||||
height : this.state.width / this.getRatio()
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Peer
|
|
||||||
advancedMode={advancedMode}
|
advancedMode={advancedMode}
|
||||||
name={activePeerId}
|
id={activePeerId}
|
||||||
|
style={speakerStyle}
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
:null
|
:null
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={classes.filmStrip}>
|
<div className={classes.filmStrip}>
|
||||||
<div className={classes.filmStripContent}>
|
<Grid container justify='center' spacing={0}>
|
||||||
|
<Grid item>
|
||||||
|
<div
|
||||||
|
className={classnames(classes.filmItem, {
|
||||||
|
active : myId === activePeerId
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<Me
|
||||||
|
advancedMode={advancedMode}
|
||||||
|
style={peerStyle}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
{ Object.keys(peers).map((peerId) =>
|
{ Object.keys(peers).map((peerId) =>
|
||||||
{
|
{
|
||||||
if (spotlights.find((spotlightsElement) => spotlightsElement === peerId))
|
if (spotlights.find((spotlightsElement) => spotlightsElement === peerId))
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
|
<Grid key={peerId} item>
|
||||||
<div
|
<div
|
||||||
key={peerId}
|
key={peerId}
|
||||||
onClick={() => roomClient.setSelectedPeer(peerId)}
|
onClick={() => roomClient.setSelectedPeer(peerId)}
|
||||||
className={classnames(classes.film, {
|
className={classnames(classes.filmItem, {
|
||||||
selected : this.props.selectedPeerId === peerId,
|
selected : this.props.selectedPeerId === peerId,
|
||||||
active : this.state.lastSpeaker === peerId
|
active : peerId === activePeerId
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<div className={classes.filmContent}>
|
|
||||||
<Peer
|
<Peer
|
||||||
advancedMode={advancedMode}
|
advancedMode={advancedMode}
|
||||||
name={peerId}
|
id={peerId}
|
||||||
|
style={peerStyle}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Grid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -253,7 +256,7 @@ class Filmstrip extends React.PureComponent
|
||||||
return ('');
|
return ('');
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
</div>
|
</Grid>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.hiddenPeers}>
|
<div className={classes.hiddenPeers}>
|
||||||
{ spotlightsLength<Object.keys(peers).length ?
|
{ spotlightsLength<Object.keys(peers).length ?
|
||||||
|
|
@ -263,7 +266,6 @@ class Filmstrip extends React.PureComponent
|
||||||
:null
|
:null
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -271,11 +273,11 @@ class Filmstrip extends React.PureComponent
|
||||||
|
|
||||||
Filmstrip.propTypes = {
|
Filmstrip.propTypes = {
|
||||||
roomClient : PropTypes.any.isRequired,
|
roomClient : PropTypes.any.isRequired,
|
||||||
activeSpeakerName : PropTypes.string,
|
activeSpeakerId : PropTypes.string,
|
||||||
advancedMode : PropTypes.bool,
|
advancedMode : PropTypes.bool,
|
||||||
peers : PropTypes.object.isRequired,
|
peers : PropTypes.object.isRequired,
|
||||||
consumers : PropTypes.object.isRequired,
|
consumers : PropTypes.object.isRequired,
|
||||||
myName : PropTypes.string.isRequired,
|
myId : PropTypes.string.isRequired,
|
||||||
selectedPeerId : PropTypes.string,
|
selectedPeerId : PropTypes.string,
|
||||||
spotlightsLength : PropTypes.number,
|
spotlightsLength : PropTypes.number,
|
||||||
spotlights : PropTypes.array.isRequired,
|
spotlights : PropTypes.array.isRequired,
|
||||||
|
|
@ -284,20 +286,32 @@ Filmstrip.propTypes = {
|
||||||
|
|
||||||
const mapStateToProps = (state) =>
|
const mapStateToProps = (state) =>
|
||||||
{
|
{
|
||||||
const spotlightsLength = state.room.spotlights ? state.room.spotlights.length : 0;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
activeSpeakerName : state.room.activeSpeakerName,
|
activeSpeakerId : state.room.activeSpeakerId,
|
||||||
selectedPeerId : state.room.selectedPeerId,
|
selectedPeerId : state.room.selectedPeerId,
|
||||||
peers : state.peers,
|
peers : state.peers,
|
||||||
consumers : state.consumers,
|
consumers : state.consumers,
|
||||||
myName : state.me.name,
|
myId : state.me.id,
|
||||||
spotlights : state.room.spotlights,
|
spotlights : state.room.spotlights,
|
||||||
spotlightsLength
|
spotlightsLength : spotlightsLengthSelector(state)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withRoomContext(connect(
|
export default withRoomContext(connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
undefined
|
null,
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
areStatesEqual : (next, prev) =>
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
prev.room.activeSpeakerId === next.room.activeSpeakerId &&
|
||||||
|
prev.room.selectedPeerId === next.room.selectedPeerId &&
|
||||||
|
prev.peers === next.peers &&
|
||||||
|
prev.consumers === next.consumers &&
|
||||||
|
prev.room.spotlights === next.room.spotlights &&
|
||||||
|
prev.me.id === next.me.id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
)(withStyles(styles)(Filmstrip)));
|
)(withStyles(styles)(Filmstrip)));
|
||||||
Loading…
Reference in New Issue