Moved Me window into view with other Peer containers.
parent
9b78a81ef0
commit
49ebf5330b
|
|
@ -9,10 +9,6 @@ import { getDeviceInfo } from 'mediasoup-client';
|
||||||
import * as appPropTypes from '../appPropTypes';
|
import * as appPropTypes from '../appPropTypes';
|
||||||
import PeerView from '../VideoContainers/PeerView';
|
import PeerView from '../VideoContainers/PeerView';
|
||||||
import ScreenView from '../VideoContainers/ScreenView';
|
import ScreenView from '../VideoContainers/ScreenView';
|
||||||
import MicIcon from '@material-ui/icons/Mic';
|
|
||||||
import MicOffIcon from '@material-ui/icons/MicOff';
|
|
||||||
import VideoIcon from '@material-ui/icons/Videocam';
|
|
||||||
import VideoOffIcon from '@material-ui/icons/VideocamOff';
|
|
||||||
|
|
||||||
const styles = () =>
|
const styles = () =>
|
||||||
({
|
({
|
||||||
|
|
@ -36,53 +32,6 @@ const styles = () =>
|
||||||
{
|
{
|
||||||
order : 1
|
order : 1
|
||||||
}
|
}
|
||||||
},
|
|
||||||
controls :
|
|
||||||
{
|
|
||||||
position : 'absolute',
|
|
||||||
right : 0,
|
|
||||||
top : 0,
|
|
||||||
display : 'flex',
|
|
||||||
flexDirection : 'row',
|
|
||||||
padding : '0.4vmin',
|
|
||||||
zIndex : 20,
|
|
||||||
opacity : 0,
|
|
||||||
transition : 'opacity 0.3s',
|
|
||||||
'&.visible' :
|
|
||||||
{
|
|
||||||
opacity : 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
button :
|
|
||||||
{
|
|
||||||
flex : '0 0 auto',
|
|
||||||
margin : '0.2vmin',
|
|
||||||
borderRadius : 2,
|
|
||||||
opacity : 0.85,
|
|
||||||
width : 'var(--media-control-button-size)',
|
|
||||||
height : 'var(--media-control-button-size)',
|
|
||||||
backgroundColor : 'var(--media-control-button-color)',
|
|
||||||
'&:hover' :
|
|
||||||
{
|
|
||||||
opacity : 1
|
|
||||||
},
|
|
||||||
'&.unsupported' :
|
|
||||||
{
|
|
||||||
pointerEvents : 'none'
|
|
||||||
},
|
|
||||||
'&.disabled' :
|
|
||||||
{
|
|
||||||
pointerEvents : 'none',
|
|
||||||
backgroundColor : 'var(--media-control-botton-disabled)'
|
|
||||||
},
|
|
||||||
'&.on' :
|
|
||||||
{
|
|
||||||
backgroundColor : 'var(--media-control-botton-on)'
|
|
||||||
},
|
|
||||||
'&.off' :
|
|
||||||
{
|
|
||||||
backgroundColor : 'var(--media-control-botton-off)'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -124,8 +73,8 @@ class Me extends React.PureComponent
|
||||||
{
|
{
|
||||||
const {
|
const {
|
||||||
roomClient,
|
roomClient,
|
||||||
connected,
|
|
||||||
me,
|
me,
|
||||||
|
style,
|
||||||
advancedMode,
|
advancedMode,
|
||||||
micProducer,
|
micProducer,
|
||||||
webcamProducer,
|
webcamProducer,
|
||||||
|
|
@ -133,26 +82,6 @@ class Me extends React.PureComponent
|
||||||
classes
|
classes
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
let micState;
|
|
||||||
|
|
||||||
if (!me.canSendMic)
|
|
||||||
micState = 'unsupported';
|
|
||||||
else if (!micProducer)
|
|
||||||
micState = 'unsupported';
|
|
||||||
else if (!micProducer.locallyPaused && !micProducer.remotelyPaused)
|
|
||||||
micState = 'on';
|
|
||||||
else
|
|
||||||
micState = 'off';
|
|
||||||
|
|
||||||
let webcamState;
|
|
||||||
|
|
||||||
if (!me.canSendWebcam)
|
|
||||||
webcamState = 'unsupported';
|
|
||||||
else if (webcamProducer)
|
|
||||||
webcamState = 'on';
|
|
||||||
else
|
|
||||||
webcamState = 'off';
|
|
||||||
|
|
||||||
const videoVisible = (
|
const videoVisible = (
|
||||||
Boolean(webcamProducer) &&
|
Boolean(webcamProducer) &&
|
||||||
!webcamProducer.locallyPaused &&
|
!webcamProducer.locallyPaused &&
|
||||||
|
|
@ -180,57 +109,7 @@ class Me extends React.PureComponent
|
||||||
onMouseOver={this.handleMouseOver}
|
onMouseOver={this.handleMouseOver}
|
||||||
onMouseOut={this.handleMouseOut}
|
onMouseOut={this.handleMouseOut}
|
||||||
>
|
>
|
||||||
<div className={classnames(classes.viewContainer, 'webcam')}>
|
<div className={classnames(classes.viewContainer, 'webcam')} style={style}>
|
||||||
{ connected ?
|
|
||||||
<div className={classnames(classes.controls, 'visible')}>
|
|
||||||
<div
|
|
||||||
data-tip='keyboard shortcut: ‘m‘'
|
|
||||||
data-type='dark'
|
|
||||||
data-place='bottom'
|
|
||||||
data-for='me'
|
|
||||||
className={classnames(classes.button, 'mic', micState, {
|
|
||||||
disabled : me.audioInProgress,
|
|
||||||
visible : micState === 'off' || this.state.controlsVisible
|
|
||||||
})}
|
|
||||||
onClick={() =>
|
|
||||||
{
|
|
||||||
micState === 'on' ?
|
|
||||||
roomClient.muteMic() :
|
|
||||||
roomClient.unmuteMic();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{ micState === 'on' ?
|
|
||||||
<MicIcon />
|
|
||||||
:
|
|
||||||
<MicOffIcon />
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<ReactTooltip
|
|
||||||
id='me'
|
|
||||||
effect='solid'
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
className={classnames(classes.button, 'webcam', webcamState, {
|
|
||||||
disabled : me.webcamInProgress,
|
|
||||||
visible : webcamState === 'off' || this.state.controlsVisible
|
|
||||||
})}
|
|
||||||
onClick={() =>
|
|
||||||
{
|
|
||||||
webcamState === 'on' ?
|
|
||||||
roomClient.disableWebcam() :
|
|
||||||
roomClient.enableWebcam();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{ webcamState === 'on' ?
|
|
||||||
<VideoIcon />
|
|
||||||
:
|
|
||||||
<VideoOffIcon />
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
:null
|
|
||||||
}
|
|
||||||
|
|
||||||
<PeerView
|
<PeerView
|
||||||
isMe
|
isMe
|
||||||
advancedMode={advancedMode}
|
advancedMode={advancedMode}
|
||||||
|
|
@ -249,7 +128,7 @@ class Me extends React.PureComponent
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{ screenProducer ?
|
{ screenProducer ?
|
||||||
<div className={classnames(classes.viewContainer, 'screen')}>
|
<div className={classnames(classes.viewContainer, 'screen')} style={style}>
|
||||||
<ScreenView
|
<ScreenView
|
||||||
isMe
|
isMe
|
||||||
advancedMode={advancedMode}
|
advancedMode={advancedMode}
|
||||||
|
|
@ -304,6 +183,7 @@ Me.propTypes =
|
||||||
micProducer : appPropTypes.Producer,
|
micProducer : appPropTypes.Producer,
|
||||||
webcamProducer : appPropTypes.Producer,
|
webcamProducer : appPropTypes.Producer,
|
||||||
screenProducer : appPropTypes.Producer,
|
screenProducer : appPropTypes.Producer,
|
||||||
|
style : PropTypes.object,
|
||||||
classes : PropTypes.object.isRequired
|
classes : PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,17 @@ import classnames from 'classnames';
|
||||||
import * as appPropTypes from '../appPropTypes';
|
import * as appPropTypes from '../appPropTypes';
|
||||||
import { withRoomContext } from '../../RoomContext';
|
import { withRoomContext } from '../../RoomContext';
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
|
import { unstable_useMediaQuery as useMediaQuery } from '@material-ui/core/useMediaQuery';
|
||||||
import * as stateActions from '../../actions/stateActions';
|
import * as stateActions from '../../actions/stateActions';
|
||||||
import PeerView from '../VideoContainers/PeerView';
|
import PeerView from '../VideoContainers/PeerView';
|
||||||
import ScreenView from '../VideoContainers/ScreenView';
|
import ScreenView from '../VideoContainers/ScreenView';
|
||||||
|
import Fab from '@material-ui/core/Fab';
|
||||||
import MicIcon from '@material-ui/icons/Mic';
|
import MicIcon from '@material-ui/icons/Mic';
|
||||||
import MicOffIcon from '@material-ui/icons/MicOff';
|
import MicOffIcon from '@material-ui/icons/MicOff';
|
||||||
import NewWindowIcon from '@material-ui/icons/OpenInNew';
|
import NewWindowIcon from '@material-ui/icons/OpenInNew';
|
||||||
import FullScreenIcon from '@material-ui/icons/Fullscreen';
|
import FullScreenIcon from '@material-ui/icons/Fullscreen';
|
||||||
|
|
||||||
const styles = () =>
|
const styles = (theme) =>
|
||||||
({
|
({
|
||||||
root :
|
root :
|
||||||
{
|
{
|
||||||
|
|
@ -24,6 +26,10 @@ const styles = () =>
|
||||||
flex : '100 100 auto',
|
flex : '100 100 auto',
|
||||||
position : 'relative'
|
position : 'relative'
|
||||||
},
|
},
|
||||||
|
fab :
|
||||||
|
{
|
||||||
|
margin : theme.spacing.unit
|
||||||
|
},
|
||||||
viewContainer :
|
viewContainer :
|
||||||
{
|
{
|
||||||
position : 'relative',
|
position : 'relative',
|
||||||
|
|
@ -40,56 +46,23 @@ const styles = () =>
|
||||||
},
|
},
|
||||||
controls :
|
controls :
|
||||||
{
|
{
|
||||||
position : 'absolute',
|
position : 'absolute',
|
||||||
right : 0,
|
width : '100%',
|
||||||
top : 0,
|
height : '100%',
|
||||||
display : 'flex',
|
backgroundColor : 'rgba(0, 0, 0, 0.3)',
|
||||||
flexDirection : 'row',
|
display : 'flex',
|
||||||
justifyContent : 'flex-start',
|
flexDirection : 'row',
|
||||||
alignItems : 'center',
|
justifyContent : 'center',
|
||||||
padding : '0.4vmin',
|
alignItems : 'center',
|
||||||
zIndex : 20,
|
padding : '0.4vmin',
|
||||||
opacity : 0,
|
zIndex : 20,
|
||||||
transition : 'opacity 0.3s',
|
opacity : 0,
|
||||||
'&.visible' :
|
transition : 'opacity 0.3s',
|
||||||
|
'&:hover' :
|
||||||
{
|
{
|
||||||
opacity : 1
|
opacity : 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
button :
|
|
||||||
{
|
|
||||||
flex : '0 0 auto',
|
|
||||||
margin : '0.2vmin',
|
|
||||||
borderRadius : 2,
|
|
||||||
opacity : 0.85,
|
|
||||||
width : 'var(--media-control-button-size)',
|
|
||||||
height : 'var(--media-control-button-size)',
|
|
||||||
backgroundColor : 'var(--media-control-button-color)',
|
|
||||||
cursor : 'pointer',
|
|
||||||
transitionProperty : 'opacity, background-color',
|
|
||||||
transitionDuration : '0.15s',
|
|
||||||
'&:hover' :
|
|
||||||
{
|
|
||||||
opacity : 1
|
|
||||||
},
|
|
||||||
'&.unsupported' :
|
|
||||||
{
|
|
||||||
pointerEvents : 'none'
|
|
||||||
},
|
|
||||||
'&.disabled' :
|
|
||||||
{
|
|
||||||
pointerEvents : 'none',
|
|
||||||
backgroundColor : 'var(--media-control-botton-disabled)'
|
|
||||||
},
|
|
||||||
'&.on' :
|
|
||||||
{
|
|
||||||
backgroundColor : 'var(--media-control-botton-on)'
|
|
||||||
},
|
|
||||||
'&.off' :
|
|
||||||
{
|
|
||||||
backgroundColor : 'var(--media-control-botton-off)'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
pausedVideo :
|
pausedVideo :
|
||||||
{
|
{
|
||||||
position : 'absolute',
|
position : 'absolute',
|
||||||
|
|
@ -136,207 +109,186 @@ const styles = () =>
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
class Peer extends React.PureComponent
|
const Peer = (props) =>
|
||||||
{
|
{
|
||||||
state = {
|
const {
|
||||||
controlsVisible : false
|
roomClient,
|
||||||
};
|
advancedMode,
|
||||||
|
peer,
|
||||||
|
micConsumer,
|
||||||
|
webcamConsumer,
|
||||||
|
screenConsumer,
|
||||||
|
toggleConsumerFullscreen,
|
||||||
|
toggleConsumerWindow,
|
||||||
|
style,
|
||||||
|
windowConsumer,
|
||||||
|
classes,
|
||||||
|
theme
|
||||||
|
} = props;
|
||||||
|
|
||||||
handleMouseOver = () =>
|
const micEnabled = (
|
||||||
{
|
Boolean(micConsumer) &&
|
||||||
this.setState({
|
!micConsumer.locallyPaused &&
|
||||||
controlsVisible : true
|
!micConsumer.remotelyPaused
|
||||||
});
|
);
|
||||||
};
|
|
||||||
|
|
||||||
handleMouseOut = () =>
|
const videoVisible = (
|
||||||
{
|
Boolean(webcamConsumer) &&
|
||||||
this.setState({
|
!webcamConsumer.locallyPaused &&
|
||||||
controlsVisible : false
|
!webcamConsumer.remotelyPaused
|
||||||
});
|
);
|
||||||
};
|
|
||||||
|
|
||||||
render()
|
const screenVisible = (
|
||||||
{
|
Boolean(screenConsumer) &&
|
||||||
const {
|
!screenConsumer.locallyPaused &&
|
||||||
roomClient,
|
!screenConsumer.remotelyPaused
|
||||||
advancedMode,
|
);
|
||||||
peer,
|
|
||||||
micConsumer,
|
|
||||||
webcamConsumer,
|
|
||||||
screenConsumer,
|
|
||||||
toggleConsumerFullscreen,
|
|
||||||
toggleConsumerWindow,
|
|
||||||
style,
|
|
||||||
windowConsumer,
|
|
||||||
classes
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
const micEnabled = (
|
let videoProfile;
|
||||||
Boolean(micConsumer) &&
|
|
||||||
!micConsumer.locallyPaused &&
|
|
||||||
!micConsumer.remotelyPaused
|
|
||||||
);
|
|
||||||
|
|
||||||
const videoVisible = (
|
if (webcamConsumer)
|
||||||
Boolean(webcamConsumer) &&
|
videoProfile = webcamConsumer.profile;
|
||||||
!webcamConsumer.locallyPaused &&
|
|
||||||
!webcamConsumer.remotelyPaused
|
|
||||||
);
|
|
||||||
|
|
||||||
const screenVisible = (
|
let screenProfile;
|
||||||
Boolean(screenConsumer) &&
|
|
||||||
!screenConsumer.locallyPaused &&
|
|
||||||
!screenConsumer.remotelyPaused
|
|
||||||
);
|
|
||||||
|
|
||||||
let videoProfile;
|
if (screenConsumer)
|
||||||
|
screenProfile = screenConsumer.profile;
|
||||||
|
|
||||||
if (webcamConsumer)
|
const smallScreen = useMediaQuery(theme.breakpoints.down('sm'));
|
||||||
videoProfile = webcamConsumer.profile;
|
|
||||||
|
|
||||||
let screenProfile;
|
return (
|
||||||
|
<div
|
||||||
|
className={classnames(classes.root, {
|
||||||
|
screen : screenConsumer
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{ videoVisible && !webcamConsumer.supported ?
|
||||||
|
<div className={classes.incompatibleVideo}>
|
||||||
|
<p>incompatible video</p>
|
||||||
|
</div>
|
||||||
|
:null
|
||||||
|
}
|
||||||
|
|
||||||
if (screenConsumer)
|
{ !videoVisible ?
|
||||||
screenProfile = screenConsumer.profile;
|
<div className={classes.pausedVideo}>
|
||||||
|
<p>this video is paused</p>
|
||||||
|
</div>
|
||||||
|
:null
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
<div className={classnames(classes.viewContainer, 'webcam')} style={style}>
|
||||||
<div
|
<div
|
||||||
className={classnames(classes.root, {
|
className={classes.controls}
|
||||||
screen : screenConsumer
|
>
|
||||||
})}
|
<Fab
|
||||||
onMouseOver={this.handleMouseOver}
|
aria-label='Mute mic'
|
||||||
onMouseOut={this.handleMouseOut}
|
className={classes.fab}
|
||||||
>
|
color={micEnabled ? 'default' : 'secondary'}
|
||||||
{ videoVisible && !webcamConsumer.supported ?
|
onClick={() =>
|
||||||
<div className={classes.incompatibleVideo}>
|
{
|
||||||
<p>incompatible video</p>
|
micEnabled ?
|
||||||
</div>
|
roomClient.modifyPeerConsumer(peer.name, 'mic', true) :
|
||||||
:null
|
roomClient.modifyPeerConsumer(peer.name, 'mic', false);
|
||||||
}
|
}}
|
||||||
|
|
||||||
{ !videoVisible ?
|
|
||||||
<div className={classes.pausedVideo}>
|
|
||||||
<p>this video is paused</p>
|
|
||||||
</div>
|
|
||||||
:null
|
|
||||||
}
|
|
||||||
|
|
||||||
<div className={classnames(classes.viewContainer, 'webcam')} style={style}>
|
|
||||||
<div
|
|
||||||
className={classnames(classes.controls, {
|
|
||||||
visible : this.state.controlsVisible
|
|
||||||
})}
|
|
||||||
>
|
>
|
||||||
<div
|
{ micEnabled ?
|
||||||
className={classnames(classes.button, {
|
<MicIcon />
|
||||||
on : micEnabled,
|
:
|
||||||
off : !micEnabled,
|
<MicOffIcon />
|
||||||
disabled : peer.peerAudioInProgress
|
}
|
||||||
})}
|
</Fab>
|
||||||
onClick={(e) =>
|
|
||||||
{
|
|
||||||
e.stopPropagation();
|
|
||||||
micEnabled ?
|
|
||||||
roomClient.modifyPeerConsumer(peer.name, 'mic', true) :
|
|
||||||
roomClient.modifyPeerConsumer(peer.name, 'mic', false);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{ micEnabled ?
|
|
||||||
<MicIcon />
|
|
||||||
:
|
|
||||||
<MicOffIcon />
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
{ !smallScreen ?
|
||||||
className={classnames(classes.button, {
|
<Fab
|
||||||
disabled : !videoVisible ||
|
aria-label='New window'
|
||||||
(windowConsumer === webcamConsumer.id)
|
className={classes.fab}
|
||||||
})}
|
disabled={
|
||||||
onClick={(e) =>
|
!videoVisible ||
|
||||||
|
(windowConsumer === webcamConsumer.id)
|
||||||
|
}
|
||||||
|
onClick={() =>
|
||||||
{
|
{
|
||||||
e.stopPropagation();
|
|
||||||
toggleConsumerWindow(webcamConsumer);
|
toggleConsumerWindow(webcamConsumer);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<NewWindowIcon />
|
<NewWindowIcon />
|
||||||
</div>
|
</Fab>
|
||||||
|
:null
|
||||||
|
}
|
||||||
|
|
||||||
<div
|
<Fab
|
||||||
className={classnames(classes.button, 'fullscreen', {
|
aria-label='Fullscreen'
|
||||||
disabled : !videoVisible
|
className={classes.fab}
|
||||||
})}
|
disabled={!videoVisible}
|
||||||
onClick={(e) =>
|
onClick={() =>
|
||||||
{
|
{
|
||||||
e.stopPropagation();
|
toggleConsumerFullscreen(webcamConsumer);
|
||||||
toggleConsumerFullscreen(webcamConsumer);
|
}}
|
||||||
}}
|
>
|
||||||
>
|
<FullScreenIcon />
|
||||||
<FullScreenIcon />
|
</Fab>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<PeerView
|
|
||||||
advancedMode={advancedMode}
|
|
||||||
peer={peer}
|
|
||||||
volume={micConsumer ? micConsumer.volume : null}
|
|
||||||
videoTrack={webcamConsumer ? webcamConsumer.track : null}
|
|
||||||
videoVisible={videoVisible}
|
|
||||||
videoProfile={videoProfile}
|
|
||||||
audioCodec={micConsumer ? micConsumer.codec : null}
|
|
||||||
videoCodec={webcamConsumer ? webcamConsumer.codec : null}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{ screenConsumer ?
|
<PeerView
|
||||||
<div className={classnames(classes.viewContainer, 'screen')} style={style}>
|
advancedMode={advancedMode}
|
||||||
<div
|
peer={peer}
|
||||||
className={classnames(classes.controls, {
|
volume={micConsumer ? micConsumer.volume : null}
|
||||||
visible : this.state.controlsVisible
|
videoTrack={webcamConsumer ? webcamConsumer.track : null}
|
||||||
})}
|
videoVisible={videoVisible}
|
||||||
>
|
videoProfile={videoProfile}
|
||||||
<div
|
audioCodec={micConsumer ? micConsumer.codec : null}
|
||||||
className={classnames(classes.button, 'newwindow', {
|
videoCodec={webcamConsumer ? webcamConsumer.codec : null}
|
||||||
disabled : !screenVisible ||
|
/>
|
||||||
(windowConsumer === screenConsumer.id)
|
</div>
|
||||||
})}
|
|
||||||
onClick={(e) =>
|
{ screenConsumer ?
|
||||||
|
<div className={classnames(classes.viewContainer, 'screen')} style={style}>
|
||||||
|
<div
|
||||||
|
className={classes.controls}
|
||||||
|
>
|
||||||
|
{ !smallScreen ?
|
||||||
|
<Fab
|
||||||
|
aria-label='New window'
|
||||||
|
className={classes.fab}
|
||||||
|
disabled={
|
||||||
|
!screenVisible ||
|
||||||
|
(windowConsumer === screenConsumer.id)
|
||||||
|
}
|
||||||
|
onClick={() =>
|
||||||
{
|
{
|
||||||
e.stopPropagation();
|
|
||||||
toggleConsumerWindow(screenConsumer);
|
toggleConsumerWindow(screenConsumer);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<NewWindowIcon />
|
<NewWindowIcon />
|
||||||
</div>
|
</Fab>
|
||||||
|
:null
|
||||||
|
}
|
||||||
|
|
||||||
<div
|
<Fab
|
||||||
className={classnames(classes.button, 'fullscreen', {
|
aria-label='Fullscreen'
|
||||||
disabled : !screenVisible
|
className={classes.fab}
|
||||||
})}
|
disabled={!screenVisible}
|
||||||
onClick={(e) =>
|
onClick={() =>
|
||||||
{
|
{
|
||||||
e.stopPropagation();
|
toggleConsumerFullscreen(screenConsumer);
|
||||||
toggleConsumerFullscreen(screenConsumer);
|
}}
|
||||||
}}
|
>
|
||||||
>
|
<FullScreenIcon />
|
||||||
<FullScreenIcon />
|
</Fab>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<ScreenView
|
|
||||||
advancedMode={advancedMode}
|
|
||||||
screenTrack={screenConsumer ? screenConsumer.track : null}
|
|
||||||
screenVisible={screenVisible}
|
|
||||||
screenProfile={screenProfile}
|
|
||||||
screenCodec={screenConsumer ? screenConsumer.codec : null}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
:null
|
<ScreenView
|
||||||
}
|
advancedMode={advancedMode}
|
||||||
</div>
|
screenTrack={screenConsumer ? screenConsumer.track : null}
|
||||||
);
|
screenVisible={screenVisible}
|
||||||
}
|
screenProfile={screenProfile}
|
||||||
}
|
screenCodec={screenConsumer ? screenConsumer.codec : null}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
:null
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
Peer.propTypes =
|
Peer.propTypes =
|
||||||
{
|
{
|
||||||
|
|
@ -351,7 +303,8 @@ Peer.propTypes =
|
||||||
style : PropTypes.object,
|
style : PropTypes.object,
|
||||||
toggleConsumerFullscreen : PropTypes.func.isRequired,
|
toggleConsumerFullscreen : PropTypes.func.isRequired,
|
||||||
toggleConsumerWindow : PropTypes.func.isRequired,
|
toggleConsumerWindow : PropTypes.func.isRequired,
|
||||||
classes : PropTypes.object
|
classes : PropTypes.object.isRequired,
|
||||||
|
theme : PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = (state, { name }) =>
|
const mapStateToProps = (state, { name }) =>
|
||||||
|
|
@ -394,4 +347,4 @@ const mapDispatchToProps = (dispatch) =>
|
||||||
export default withRoomContext(connect(
|
export default withRoomContext(connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
mapDispatchToProps
|
mapDispatchToProps
|
||||||
)(withStyles(styles)(Peer)));
|
)(withStyles(styles, { withTheme: true })(Peer)));
|
||||||
|
|
|
||||||
|
|
@ -2,34 +2,49 @@ import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
|
import { unstable_useMediaQuery as useMediaQuery } from '@material-ui/core/useMediaQuery';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import * as appPropTypes from '../appPropTypes';
|
import * as appPropTypes from '../appPropTypes';
|
||||||
import { withRoomContext } from '../../RoomContext';
|
import { withRoomContext } from '../../RoomContext';
|
||||||
import Fab from '@material-ui/core/Fab';
|
import Fab from '@material-ui/core/Fab';
|
||||||
import Avatar from '@material-ui/core/Avatar';
|
// import Avatar from '@material-ui/core/Avatar';
|
||||||
|
import MicIcon from '@material-ui/icons/Mic';
|
||||||
|
import MicOffIcon from '@material-ui/icons/MicOff';
|
||||||
|
import VideoIcon from '@material-ui/icons/Videocam';
|
||||||
|
import VideoOffIcon from '@material-ui/icons/VideocamOff';
|
||||||
import ScreenIcon from '@material-ui/icons/ScreenShare';
|
import ScreenIcon from '@material-ui/icons/ScreenShare';
|
||||||
import ScreenOffIcon from '@material-ui/icons/StopScreenShare';
|
import ScreenOffIcon from '@material-ui/icons/StopScreenShare';
|
||||||
import ExtensionIcon from '@material-ui/icons/Extension';
|
import ExtensionIcon from '@material-ui/icons/Extension';
|
||||||
import LockIcon from '@material-ui/icons/Lock';
|
import LockIcon from '@material-ui/icons/Lock';
|
||||||
import LockOpenIcon from '@material-ui/icons/LockOpen';
|
import LockOpenIcon from '@material-ui/icons/LockOpen';
|
||||||
import HandOff from '../../images/icon-hand-black.svg';
|
// import HandOff from '../../images/icon-hand-black.svg';
|
||||||
import HandOn from '../../images/icon-hand-white.svg';
|
// import HandOn from '../../images/icon-hand-white.svg';
|
||||||
import LeaveIcon from '@material-ui/icons/Cancel';
|
import LeaveIcon from '@material-ui/icons/Cancel';
|
||||||
|
|
||||||
const styles = (theme) =>
|
const styles = (theme) =>
|
||||||
({
|
({
|
||||||
root :
|
root :
|
||||||
{
|
{
|
||||||
position : 'fixed',
|
position : 'fixed',
|
||||||
zIndex : 500,
|
zIndex : 500,
|
||||||
top : '50%',
|
display : 'flex',
|
||||||
transform : 'translate(0%, -50%)',
|
[theme.breakpoints.up('md')] :
|
||||||
display : 'flex',
|
{
|
||||||
flexDirection : 'column',
|
top : '50%',
|
||||||
justifyContent : 'center',
|
transform : 'translate(0%, -50%)',
|
||||||
alignItems : 'center',
|
flexDirection : 'column',
|
||||||
left : '1.0em',
|
justifyContent : 'center',
|
||||||
width : '2.6em'
|
alignItems : 'center',
|
||||||
|
left : '1.0em',
|
||||||
|
width : '2.6em'
|
||||||
|
},
|
||||||
|
[theme.breakpoints.down('sm')] :
|
||||||
|
{
|
||||||
|
flexDirection : 'row',
|
||||||
|
bottom : '0.5em',
|
||||||
|
left : '50%',
|
||||||
|
transform : 'translate(-50%, -0%)'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
fab :
|
fab :
|
||||||
{
|
{
|
||||||
|
|
@ -47,150 +62,218 @@ const styles = (theme) =>
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
class Sidebar extends React.PureComponent
|
const Sidebar = (props) =>
|
||||||
{
|
{
|
||||||
render()
|
const {
|
||||||
|
roomClient,
|
||||||
|
toolbarsVisible,
|
||||||
|
me,
|
||||||
|
micProducer,
|
||||||
|
webcamProducer,
|
||||||
|
screenProducer,
|
||||||
|
locked,
|
||||||
|
classes,
|
||||||
|
theme
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
let micState;
|
||||||
|
|
||||||
|
if (!me.canSendMic)
|
||||||
|
micState = 'unsupported';
|
||||||
|
else if (!micProducer)
|
||||||
|
micState = 'unsupported';
|
||||||
|
else if (!micProducer.locallyPaused && !micProducer.remotelyPaused)
|
||||||
|
micState = 'on';
|
||||||
|
else
|
||||||
|
micState = 'off';
|
||||||
|
|
||||||
|
let webcamState;
|
||||||
|
|
||||||
|
if (!me.canSendWebcam)
|
||||||
|
webcamState = 'unsupported';
|
||||||
|
else if (webcamProducer)
|
||||||
|
webcamState = 'on';
|
||||||
|
else
|
||||||
|
webcamState = 'off';
|
||||||
|
|
||||||
|
let screenState;
|
||||||
|
|
||||||
|
if (me.needExtension)
|
||||||
{
|
{
|
||||||
const {
|
screenState = 'need-extension';
|
||||||
roomClient,
|
|
||||||
toolbarsVisible,
|
|
||||||
me,
|
|
||||||
screenProducer,
|
|
||||||
locked,
|
|
||||||
classes
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
let screenState;
|
|
||||||
|
|
||||||
if (me.needExtension)
|
|
||||||
{
|
|
||||||
screenState = 'need-extension';
|
|
||||||
}
|
|
||||||
else if (!me.canShareScreen)
|
|
||||||
{
|
|
||||||
screenState = 'unsupported';
|
|
||||||
}
|
|
||||||
else if (screenProducer)
|
|
||||||
{
|
|
||||||
screenState = 'on';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
screenState = 'off';
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
classnames(classes.root, toolbarsVisible ? classes.show : classes.hide)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Fab
|
|
||||||
aria-label='Share screen'
|
|
||||||
className={classes.fab}
|
|
||||||
disabled={!me.canShareScreen || me.screenShareInProgress}
|
|
||||||
color={screenState === 'on' ? 'primary' : 'default'}
|
|
||||||
|
|
||||||
onClick={() =>
|
|
||||||
{
|
|
||||||
switch (screenState)
|
|
||||||
{
|
|
||||||
case 'on':
|
|
||||||
{
|
|
||||||
roomClient.disableScreenSharing();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'off':
|
|
||||||
{
|
|
||||||
roomClient.enableScreenSharing();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'need-extension':
|
|
||||||
{
|
|
||||||
roomClient.installExtension();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{ screenState === 'on' || screenState === 'unsupported' ?
|
|
||||||
<ScreenOffIcon/>
|
|
||||||
:null
|
|
||||||
}
|
|
||||||
{ screenState === 'off' ?
|
|
||||||
<ScreenIcon/>
|
|
||||||
:null
|
|
||||||
}
|
|
||||||
{ screenState === 'need-extension' ?
|
|
||||||
<ExtensionIcon/>
|
|
||||||
:null
|
|
||||||
}
|
|
||||||
</Fab>
|
|
||||||
|
|
||||||
<Fab
|
|
||||||
aria-label='Room lock'
|
|
||||||
className={classes.fab}
|
|
||||||
color={locked ? 'primary' : 'default'}
|
|
||||||
onClick={() =>
|
|
||||||
{
|
|
||||||
if (locked)
|
|
||||||
{
|
|
||||||
roomClient.unlockRoom();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
roomClient.lockRoom();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{ locked ?
|
|
||||||
<LockIcon />
|
|
||||||
:
|
|
||||||
<LockOpenIcon />
|
|
||||||
}
|
|
||||||
</Fab>
|
|
||||||
|
|
||||||
<Fab
|
|
||||||
aria-label='Raise hand'
|
|
||||||
className={classes.fab}
|
|
||||||
disabled={me.raiseHandInProgress}
|
|
||||||
color={me.raiseHand ? 'primary' : 'default'}
|
|
||||||
onClick={() => roomClient.sendRaiseHandState(!me.raiseHand)}
|
|
||||||
>
|
|
||||||
<Avatar alt='Hand' src={me.raiseHand ? HandOn : HandOff} />
|
|
||||||
</Fab>
|
|
||||||
|
|
||||||
<Fab
|
|
||||||
aria-label='Leave meeting'
|
|
||||||
className={classes.fab}
|
|
||||||
color='secondary'
|
|
||||||
onClick={() => roomClient.close()}
|
|
||||||
>
|
|
||||||
<LeaveIcon />
|
|
||||||
</Fab>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
else if (!me.canShareScreen)
|
||||||
|
{
|
||||||
|
screenState = 'unsupported';
|
||||||
|
}
|
||||||
|
else if (screenProducer)
|
||||||
|
{
|
||||||
|
screenState = 'on';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
screenState = 'off';
|
||||||
|
}
|
||||||
|
|
||||||
|
const smallScreen = useMediaQuery(theme.breakpoints.down('sm'));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
classnames(classes.root, toolbarsVisible ? classes.show : classes.hide)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Fab
|
||||||
|
aria-label='Mute mic'
|
||||||
|
className={classes.fab}
|
||||||
|
color={micState === 'on' ? 'default' : 'secondary'}
|
||||||
|
size={smallScreen ? 'large' : 'medium'}
|
||||||
|
onClick={() =>
|
||||||
|
{
|
||||||
|
micState === 'on' ?
|
||||||
|
roomClient.muteMic() :
|
||||||
|
roomClient.unmuteMic();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ micState === 'on' ?
|
||||||
|
<MicIcon />
|
||||||
|
:
|
||||||
|
<MicOffIcon />
|
||||||
|
}
|
||||||
|
</Fab>
|
||||||
|
<Fab
|
||||||
|
aria-label='Mute video'
|
||||||
|
className={classes.fab}
|
||||||
|
color={webcamState === 'on' ? 'default' : 'secondary'}
|
||||||
|
size={smallScreen ? 'large' : 'medium'}
|
||||||
|
onClick={() =>
|
||||||
|
{
|
||||||
|
webcamState === 'on' ?
|
||||||
|
roomClient.disableWebcam() :
|
||||||
|
roomClient.enableWebcam();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ webcamState === 'on' ?
|
||||||
|
<VideoIcon />
|
||||||
|
:
|
||||||
|
<VideoOffIcon />
|
||||||
|
}
|
||||||
|
</Fab>
|
||||||
|
<Fab
|
||||||
|
aria-label='Share screen'
|
||||||
|
className={classes.fab}
|
||||||
|
disabled={!me.canShareScreen || me.screenShareInProgress}
|
||||||
|
color={screenState === 'on' ? 'primary' : 'default'}
|
||||||
|
size={smallScreen ? 'large' : 'medium'}
|
||||||
|
onClick={() =>
|
||||||
|
{
|
||||||
|
switch (screenState)
|
||||||
|
{
|
||||||
|
case 'on':
|
||||||
|
{
|
||||||
|
roomClient.disableScreenSharing();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'off':
|
||||||
|
{
|
||||||
|
roomClient.enableScreenSharing();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'need-extension':
|
||||||
|
{
|
||||||
|
roomClient.installExtension();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ screenState === 'on' || screenState === 'unsupported' ?
|
||||||
|
<ScreenOffIcon/>
|
||||||
|
:null
|
||||||
|
}
|
||||||
|
{ screenState === 'off' ?
|
||||||
|
<ScreenIcon/>
|
||||||
|
:null
|
||||||
|
}
|
||||||
|
{ screenState === 'need-extension' ?
|
||||||
|
<ExtensionIcon/>
|
||||||
|
:null
|
||||||
|
}
|
||||||
|
</Fab>
|
||||||
|
|
||||||
|
<Fab
|
||||||
|
aria-label='Room lock'
|
||||||
|
className={classes.fab}
|
||||||
|
color={locked ? 'primary' : 'default'}
|
||||||
|
size={smallScreen ? 'large' : 'medium'}
|
||||||
|
onClick={() =>
|
||||||
|
{
|
||||||
|
if (locked)
|
||||||
|
{
|
||||||
|
roomClient.unlockRoom();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
roomClient.lockRoom();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ locked ?
|
||||||
|
<LockIcon />
|
||||||
|
:
|
||||||
|
<LockOpenIcon />
|
||||||
|
}
|
||||||
|
</Fab>
|
||||||
|
|
||||||
|
{ /* <Fab
|
||||||
|
aria-label='Raise hand'
|
||||||
|
className={classes.fab}
|
||||||
|
disabled={me.raiseHandInProgress}
|
||||||
|
color={me.raiseHand ? 'primary' : 'default'}
|
||||||
|
size='large'
|
||||||
|
onClick={() => roomClient.sendRaiseHandState(!me.raiseHand)}
|
||||||
|
>
|
||||||
|
<Avatar alt='Hand' src={me.raiseHand ? HandOn : HandOff} />
|
||||||
|
</Fab> */ }
|
||||||
|
|
||||||
|
<Fab
|
||||||
|
aria-label='Leave meeting'
|
||||||
|
className={classes.fab}
|
||||||
|
color='secondary'
|
||||||
|
size={smallScreen ? 'large' : 'medium'}
|
||||||
|
onClick={() => roomClient.close()}
|
||||||
|
>
|
||||||
|
<LeaveIcon />
|
||||||
|
</Fab>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
Sidebar.propTypes =
|
Sidebar.propTypes =
|
||||||
{
|
{
|
||||||
roomClient : PropTypes.any.isRequired,
|
roomClient : PropTypes.any.isRequired,
|
||||||
toolbarsVisible : PropTypes.bool.isRequired,
|
toolbarsVisible : PropTypes.bool.isRequired,
|
||||||
me : appPropTypes.Me.isRequired,
|
me : appPropTypes.Me.isRequired,
|
||||||
|
micProducer : appPropTypes.Producer,
|
||||||
|
webcamProducer : appPropTypes.Producer,
|
||||||
screenProducer : appPropTypes.Producer,
|
screenProducer : appPropTypes.Producer,
|
||||||
locked : PropTypes.bool.isRequired,
|
locked : PropTypes.bool.isRequired,
|
||||||
classes : PropTypes.object.isRequired
|
classes : PropTypes.object.isRequired,
|
||||||
|
theme : PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = (state) =>
|
const mapStateToProps = (state) =>
|
||||||
({
|
({
|
||||||
toolbarsVisible : state.room.toolbarsVisible,
|
toolbarsVisible : state.room.toolbarsVisible,
|
||||||
screenProducer : Object.values(state.producers)
|
micProducer : Object.values(state.producers)
|
||||||
|
.find((producer) => producer.source === 'mic'),
|
||||||
|
webcamProducer : Object.values(state.producers)
|
||||||
|
.find((producer) => producer.source === 'webcam'),
|
||||||
|
screenProducer : Object.values(state.producers)
|
||||||
.find((producer) => producer.source === 'screen'),
|
.find((producer) => producer.source === 'screen'),
|
||||||
me : state.me,
|
me : state.me,
|
||||||
locked : state.room.locked
|
locked : state.room.locked
|
||||||
|
|
@ -198,4 +281,4 @@ const mapStateToProps = (state) =>
|
||||||
|
|
||||||
export default withRoomContext(connect(
|
export default withRoomContext(connect(
|
||||||
mapStateToProps
|
mapStateToProps
|
||||||
)(withStyles(styles)(Sidebar)));
|
)(withStyles(styles, { withTheme: true })(Sidebar)));
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,12 @@ import classnames from 'classnames';
|
||||||
import debounce from 'lodash/debounce';
|
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 HiddenPeers from '../Containers/HiddenPeers';
|
import HiddenPeers from '../Containers/HiddenPeers';
|
||||||
import ResizeObserver from 'resize-observer-polyfill';
|
import ResizeObserver from 'resize-observer-polyfill';
|
||||||
|
|
||||||
const RATIO = 1.334;
|
const RATIO = 1.334;
|
||||||
const PADDING = 100;
|
const PADDING = 60;
|
||||||
|
|
||||||
const styles = () =>
|
const styles = () =>
|
||||||
({
|
({
|
||||||
|
|
@ -23,7 +24,7 @@ const styles = () =>
|
||||||
justifyContent : 'center',
|
justifyContent : 'center',
|
||||||
alignItems : 'center',
|
alignItems : 'center',
|
||||||
alignContent : 'center',
|
alignContent : 'center',
|
||||||
paddingTop : 70,
|
paddingTop : 30,
|
||||||
paddingBottom : 30
|
paddingBottom : 30
|
||||||
},
|
},
|
||||||
peerContainer :
|
peerContainer :
|
||||||
|
|
@ -126,6 +127,7 @@ class Democratic extends React.PureComponent
|
||||||
const {
|
const {
|
||||||
advancedMode,
|
advancedMode,
|
||||||
activeSpeakerName,
|
activeSpeakerName,
|
||||||
|
amActiveSpeaker,
|
||||||
peers,
|
peers,
|
||||||
spotlights,
|
spotlights,
|
||||||
spotlightsLength,
|
spotlightsLength,
|
||||||
|
|
@ -140,6 +142,16 @@ class Democratic extends React.PureComponent
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.root} ref={this.peersRef}>
|
<div className={classes.root} ref={this.peersRef}>
|
||||||
|
<div
|
||||||
|
className={classnames(classes.peerContainer, 'me-handle', {
|
||||||
|
'active-speaker' : amActiveSpeaker
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<Me
|
||||||
|
advancedMode={advancedMode}
|
||||||
|
style={style}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
{ Object.keys(peers).map((peerName) =>
|
{ Object.keys(peers).map((peerName) =>
|
||||||
{
|
{
|
||||||
if (spotlights.find((spotlightsElement) => spotlightsElement === peerName))
|
if (spotlights.find((spotlightsElement) => spotlightsElement === peerName))
|
||||||
|
|
@ -181,6 +193,7 @@ Democratic.propTypes =
|
||||||
advancedMode : PropTypes.bool,
|
advancedMode : PropTypes.bool,
|
||||||
peers : PropTypes.object.isRequired,
|
peers : PropTypes.object.isRequired,
|
||||||
boxes : PropTypes.number,
|
boxes : PropTypes.number,
|
||||||
|
amActiveSpeaker : PropTypes.bool.isRequired,
|
||||||
activeSpeakerName : PropTypes.string,
|
activeSpeakerName : PropTypes.string,
|
||||||
selectedPeerName : PropTypes.string,
|
selectedPeerName : PropTypes.string,
|
||||||
spotlightsLength : PropTypes.number,
|
spotlightsLength : PropTypes.number,
|
||||||
|
|
@ -193,13 +206,15 @@ const mapStateToProps = (state) =>
|
||||||
const spotlights = state.room.spotlights;
|
const spotlights = state.room.spotlights;
|
||||||
const spotlightsLength = spotlights ? state.room.spotlights.length : 0;
|
const spotlightsLength = spotlights ? state.room.spotlights.length : 0;
|
||||||
const boxes = spotlightsLength + Object.values(state.consumers)
|
const boxes = spotlightsLength + Object.values(state.consumers)
|
||||||
.filter((consumer) => consumer.source === 'screen').length;
|
.filter((consumer) => consumer.source === 'screen').length + Object.values(state.producers)
|
||||||
|
.filter((producer) => producer.source === 'screen').length + 1;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
peers : state.peers,
|
peers : state.peers,
|
||||||
boxes,
|
boxes,
|
||||||
activeSpeakerName : state.room.activeSpeakerName,
|
activeSpeakerName : state.room.activeSpeakerName,
|
||||||
selectedPeerName : state.room.selectedPeerName,
|
selectedPeerName : state.room.selectedPeerName,
|
||||||
|
amActiveSpeaker : state.me.name === state.room.activeSpeakerName,
|
||||||
spotlights,
|
spotlights,
|
||||||
spotlightsLength
|
spotlightsLength
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@ import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import * as appPropTypes from './appPropTypes';
|
import * as appPropTypes from './appPropTypes';
|
||||||
import classnames from 'classnames';
|
// import classnames from 'classnames';
|
||||||
import { withRoomContext } from '../RoomContext';
|
import { withRoomContext } from '../RoomContext';
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
import * as stateActions from '../actions/stateActions';
|
import * as stateActions from '../actions/stateActions';
|
||||||
import Draggable from 'react-draggable';
|
// import Draggable from 'react-draggable';
|
||||||
import { idle } from '../utils';
|
import { idle } from '../utils';
|
||||||
import FullScreen from './FullScreen';
|
import FullScreen from './FullScreen';
|
||||||
import CookieConsent from 'react-cookie-consent';
|
import CookieConsent from 'react-cookie-consent';
|
||||||
|
|
@ -26,7 +26,7 @@ import Notifications from './Notifications/Notifications';
|
||||||
import MeetingDrawer from './MeetingDrawer/MeetingDrawer';
|
import MeetingDrawer from './MeetingDrawer/MeetingDrawer';
|
||||||
import Democratic from './MeetingViews/Democratic';
|
import Democratic from './MeetingViews/Democratic';
|
||||||
import Filmstrip from './MeetingViews/Filmstrip';
|
import Filmstrip from './MeetingViews/Filmstrip';
|
||||||
import Me from './Containers/Me';
|
// import Me from './Containers/Me';
|
||||||
import AudioPeers from './PeerAudio/AudioPeers';
|
import AudioPeers from './PeerAudio/AudioPeers';
|
||||||
import FullScreenView from './VideoContainers/FullScreenView';
|
import FullScreenView from './VideoContainers/FullScreenView';
|
||||||
import VideoWindow from './VideoWindow/VideoWindow';
|
import VideoWindow from './VideoWindow/VideoWindow';
|
||||||
|
|
@ -68,7 +68,12 @@ const styles = (theme) =>
|
||||||
},
|
},
|
||||||
logo :
|
logo :
|
||||||
{
|
{
|
||||||
marginLeft : 20
|
display : 'none',
|
||||||
|
marginLeft : 20,
|
||||||
|
[theme.breakpoints.up('sm')] :
|
||||||
|
{
|
||||||
|
display : 'block'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
show :
|
show :
|
||||||
{
|
{
|
||||||
|
|
@ -126,8 +131,8 @@ const styles = (theme) =>
|
||||||
boxShadow : 'var(--me-shadow)',
|
boxShadow : 'var(--me-shadow)',
|
||||||
transitionProperty : 'border-color',
|
transitionProperty : 'border-color',
|
||||||
transitionDuration : '0.15s',
|
transitionDuration : '0.15s',
|
||||||
top : '8%',
|
top : '5em',
|
||||||
left : '1%',
|
left : '1em',
|
||||||
border : 'var(--me-border)',
|
border : 'var(--me-border)',
|
||||||
'&.active-speaker' :
|
'&.active-speaker' :
|
||||||
{
|
{
|
||||||
|
|
@ -215,7 +220,7 @@ class Room extends React.PureComponent
|
||||||
roomClient,
|
roomClient,
|
||||||
room,
|
room,
|
||||||
me,
|
me,
|
||||||
amActiveSpeaker,
|
// amActiveSpeaker,
|
||||||
setSettingsOpen,
|
setSettingsOpen,
|
||||||
toolAreaOpen,
|
toolAreaOpen,
|
||||||
toggleToolArea,
|
toggleToolArea,
|
||||||
|
|
@ -337,7 +342,8 @@ class Room extends React.PureComponent
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label='Account'
|
aria-label='Account'
|
||||||
color='inherit'
|
color='inherit'
|
||||||
onClick={() => {
|
onClick={() =>
|
||||||
|
{
|
||||||
me.loggedIn ? roomClient.logout() : roomClient.login();
|
me.loggedIn ? roomClient.logout() : roomClient.login();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
@ -367,6 +373,7 @@ class Room extends React.PureComponent
|
||||||
|
|
||||||
<View advancedMode={room.advancedMode} />
|
<View advancedMode={room.advancedMode} />
|
||||||
|
|
||||||
|
{ /*
|
||||||
<Draggable handle='.me-handle' bounds='body' cancel='.display-name'>
|
<Draggable handle='.me-handle' bounds='body' cancel='.display-name'>
|
||||||
<div
|
<div
|
||||||
className={classnames(classes.meContainer, 'me-handle', {
|
className={classnames(classes.meContainer, 'me-handle', {
|
||||||
|
|
@ -378,6 +385,7 @@ class Room extends React.PureComponent
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Draggable>
|
</Draggable>
|
||||||
|
*/ }
|
||||||
|
|
||||||
<Sidebar />
|
<Sidebar />
|
||||||
|
|
||||||
|
|
@ -393,7 +401,7 @@ Room.propTypes =
|
||||||
roomClient : PropTypes.object.isRequired,
|
roomClient : PropTypes.object.isRequired,
|
||||||
room : appPropTypes.Room.isRequired,
|
room : appPropTypes.Room.isRequired,
|
||||||
me : appPropTypes.Me.isRequired,
|
me : appPropTypes.Me.isRequired,
|
||||||
amActiveSpeaker : PropTypes.bool.isRequired,
|
// amActiveSpeaker : PropTypes.bool.isRequired,
|
||||||
toolAreaOpen : PropTypes.bool.isRequired,
|
toolAreaOpen : PropTypes.bool.isRequired,
|
||||||
screenProducer : appPropTypes.Producer,
|
screenProducer : appPropTypes.Producer,
|
||||||
setToolbarsVisible : PropTypes.func.isRequired,
|
setToolbarsVisible : PropTypes.func.isRequired,
|
||||||
|
|
@ -411,13 +419,13 @@ const mapStateToProps = (state) =>
|
||||||
producersArray.find((producer) => producer.source === 'screen');
|
producersArray.find((producer) => producer.source === 'screen');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
room : state.room,
|
room : state.room,
|
||||||
me : state.me,
|
me : state.me,
|
||||||
amActiveSpeaker : state.me.name === state.room.activeSpeakerName,
|
screenProducer : screenProducer,
|
||||||
screenProducer : screenProducer,
|
toolAreaOpen : state.toolarea.toolAreaOpen,
|
||||||
toolAreaOpen : state.toolarea.toolAreaOpen,
|
unread : state.toolarea.unreadMessages +
|
||||||
unread : state.toolarea.unreadMessages +
|
|
||||||
state.toolarea.unreadFiles
|
state.toolarea.unreadFiles
|
||||||
|
// amActiveSpeaker : state.me.name === state.room.activeSpeakerName,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,6 @@
|
||||||
:root {
|
:root {
|
||||||
--background-color: rgba(114, 119, 143, 1.0);
|
--background-color: rgba(114, 119, 143, 1.0);
|
||||||
|
|
||||||
--media-control-button-color: rgba(255, 255, 255, 0.85);
|
|
||||||
--media-control-botton-on: rgba(255, 255, 255, 0.7);
|
|
||||||
--media-control-botton-off: rgba(212, 34, 65, 0.7);
|
|
||||||
--media-control-botton-disabled: rgba(255, 255, 255, 0.5);
|
|
||||||
--media-control-button-size: 1.5em;
|
|
||||||
|
|
||||||
--me-shadow: 0px 1px 5px 0px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 3px 1px -2px rgba(0, 0, 0, 0.12);
|
|
||||||
--me-border: 1px solid rgba(255, 255, 255, 0.15);
|
|
||||||
--me-width: 20vmin;
|
|
||||||
--me-height: 15vmin;
|
|
||||||
|
|
||||||
--peer-shadow: 0px 1px 5px 0px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 3px 1px -2px rgba(0, 0, 0, 0.12);
|
--peer-shadow: 0px 1px 5px 0px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 3px 1px -2px rgba(0, 0, 0, 0.12);
|
||||||
--peer-border: 1px solid rgba(255, 255, 255, 0.15);
|
--peer-border: 1px solid rgba(255, 255, 255, 0.15);
|
||||||
--peer-empty-avatar: url('./images/buddy.svg');
|
--peer-empty-avatar: url('./images/buddy.svg');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue