Removed sidebar. Moved buttons to me-view and top-bar. Added text hint on me-view.
parent
66b922d0b3
commit
9acf0056ac
|
|
@ -1,19 +1,27 @@
|
||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { meProducersSelector } from '../Selectors';
|
import { meProducersSelector } from '../Selectors';
|
||||||
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 PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import * as appPropTypes from '../appPropTypes';
|
import * as appPropTypes from '../appPropTypes';
|
||||||
import VideoView from '../VideoContainers/VideoView';
|
import VideoView from '../VideoContainers/VideoView';
|
||||||
import Volume from './Volume';
|
import Volume from './Volume';
|
||||||
|
import Fab from '@material-ui/core/Fab';
|
||||||
|
import Tooltip from '@material-ui/core/Tooltip';
|
||||||
|
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 ScreenOffIcon from '@material-ui/icons/StopScreenShare';
|
||||||
|
|
||||||
const styles = () =>
|
const styles = (theme) =>
|
||||||
({
|
({
|
||||||
root :
|
root :
|
||||||
{
|
{
|
||||||
flexDirection : 'row',
|
|
||||||
flex : '0 0 auto',
|
flex : '0 0 auto',
|
||||||
boxShadow : 'var(--peer-shadow)',
|
boxShadow : 'var(--peer-shadow)',
|
||||||
border : 'var(--peer-border)',
|
border : 'var(--peer-border)',
|
||||||
|
|
@ -22,27 +30,78 @@ const styles = () =>
|
||||||
backgroundPosition : 'bottom',
|
backgroundPosition : 'bottom',
|
||||||
backgroundSize : 'auto 85%',
|
backgroundSize : 'auto 85%',
|
||||||
backgroundRepeat : 'no-repeat',
|
backgroundRepeat : 'no-repeat',
|
||||||
|
'&.webcam' :
|
||||||
|
{
|
||||||
|
order : 1
|
||||||
|
},
|
||||||
|
'&.screen' :
|
||||||
|
{
|
||||||
|
order : 2
|
||||||
|
},
|
||||||
|
'&.hover' :
|
||||||
|
{
|
||||||
|
boxShadow : '0px 1px 3px rgba(0, 0, 0, 0.05) inset, 0px 0px 8px rgba(82, 168, 236, 0.9)'
|
||||||
|
},
|
||||||
'&.active-speaker' :
|
'&.active-speaker' :
|
||||||
{
|
{
|
||||||
borderColor : 'var(--active-speaker-border-color)'
|
borderColor : 'var(--active-speaker-border-color)'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
fab :
|
||||||
|
{
|
||||||
|
margin : theme.spacing.unit
|
||||||
|
},
|
||||||
viewContainer :
|
viewContainer :
|
||||||
{
|
{
|
||||||
position : 'relative',
|
position : 'relative',
|
||||||
'&.webcam' :
|
width : '100%',
|
||||||
|
height : '100%'
|
||||||
|
},
|
||||||
|
controls :
|
||||||
|
{
|
||||||
|
position : 'absolute',
|
||||||
|
width : '100%',
|
||||||
|
height : '100%',
|
||||||
|
backgroundColor : 'rgba(0, 0, 0, 0.3)',
|
||||||
|
display : 'flex',
|
||||||
|
flexDirection : 'column',
|
||||||
|
justifyContent : 'center',
|
||||||
|
alignItems : 'flex-end',
|
||||||
|
padding : '0.4vmin',
|
||||||
|
zIndex : 21,
|
||||||
|
opacity : 0,
|
||||||
|
transition : 'opacity 0.3s',
|
||||||
|
touchAction : 'none',
|
||||||
|
'&.hover' :
|
||||||
{
|
{
|
||||||
order : 2
|
opacity : 1
|
||||||
},
|
},
|
||||||
'&.screen' :
|
'& p' :
|
||||||
{
|
{
|
||||||
order : 1
|
position : 'absolute',
|
||||||
|
float : 'left',
|
||||||
|
top : '50%',
|
||||||
|
left : '50%',
|
||||||
|
transform : 'translate(-50%, -50%)',
|
||||||
|
color : 'rgba(255, 255, 255, 1)',
|
||||||
|
fontSize : '7em',
|
||||||
|
margin : 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const Me = (props) =>
|
const Me = (props) =>
|
||||||
{
|
{
|
||||||
|
const [ hover, setHover ] = useState(false);
|
||||||
|
const [ webcamHover, setWebcamHover ] = useState(false);
|
||||||
|
const [ screenHover, setScreenHover ] = useState(false);
|
||||||
|
|
||||||
|
let touchTimeout = null;
|
||||||
|
|
||||||
|
let touchWebcamTimeout = null;
|
||||||
|
|
||||||
|
let touchScreenTimeout = null;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
roomClient,
|
roomClient,
|
||||||
me,
|
me,
|
||||||
|
|
@ -54,7 +113,8 @@ const Me = (props) =>
|
||||||
micProducer,
|
micProducer,
|
||||||
webcamProducer,
|
webcamProducer,
|
||||||
screenProducer,
|
screenProducer,
|
||||||
classes
|
classes,
|
||||||
|
theme
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const videoVisible = (
|
const videoVisible = (
|
||||||
|
|
@ -69,23 +129,222 @@ const Me = (props) =>
|
||||||
!screenProducer.remotelyPaused
|
!screenProducer.remotelyPaused
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let micState;
|
||||||
|
|
||||||
|
let micTip;
|
||||||
|
|
||||||
|
if (!me.canSendMic)
|
||||||
|
{
|
||||||
|
micState = 'unsupported';
|
||||||
|
micTip = 'Audio unsupported';
|
||||||
|
}
|
||||||
|
else if (!micProducer)
|
||||||
|
{
|
||||||
|
micState = 'off';
|
||||||
|
micTip = 'Activate audio';
|
||||||
|
}
|
||||||
|
else if (!micProducer.locallyPaused && !micProducer.remotelyPaused)
|
||||||
|
{
|
||||||
|
micState = 'on';
|
||||||
|
micTip = 'Mute audio';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
micState = 'muted';
|
||||||
|
micTip = 'Unmute audio';
|
||||||
|
}
|
||||||
|
|
||||||
|
let webcamState;
|
||||||
|
|
||||||
|
let webcamTip;
|
||||||
|
|
||||||
|
if (!me.canSendWebcam)
|
||||||
|
{
|
||||||
|
webcamState = 'unsupported';
|
||||||
|
webcamTip = 'Video unsupported';
|
||||||
|
}
|
||||||
|
else if (webcamProducer)
|
||||||
|
{
|
||||||
|
webcamState = 'on';
|
||||||
|
webcamTip = 'Stop video';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
webcamState = 'off';
|
||||||
|
webcamTip = 'Start video';
|
||||||
|
}
|
||||||
|
|
||||||
|
let screenState;
|
||||||
|
|
||||||
|
let screenTip;
|
||||||
|
|
||||||
|
if (!me.canShareScreen)
|
||||||
|
{
|
||||||
|
screenState = 'unsupported';
|
||||||
|
screenTip = 'Screen sharing not supported';
|
||||||
|
}
|
||||||
|
else if (screenProducer)
|
||||||
|
{
|
||||||
|
screenState = 'on';
|
||||||
|
screenTip = 'Stop screen sharing';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
screenState = 'off';
|
||||||
|
screenTip = 'Start screen sharing';
|
||||||
|
}
|
||||||
|
|
||||||
const spacingStyle =
|
const spacingStyle =
|
||||||
{
|
{
|
||||||
'margin' : spacing
|
'margin' : spacing
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const smallScreen = useMediaQuery(theme.breakpoints.down('sm'));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
classnames(
|
classnames(
|
||||||
classes.root,
|
classes.root,
|
||||||
|
'webcam',
|
||||||
|
hover ? 'hover' : null,
|
||||||
activeSpeaker ? 'active-speaker' : null
|
activeSpeaker ? 'active-speaker' : null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
onMouseOver={() => setHover(true)}
|
||||||
|
onMouseOut={() => setHover(false)}
|
||||||
|
onTouchStart={() =>
|
||||||
|
{
|
||||||
|
if (touchTimeout)
|
||||||
|
clearTimeout(touchTimeout);
|
||||||
|
|
||||||
|
setHover(true);
|
||||||
|
}}
|
||||||
|
onTouchEnd={() =>
|
||||||
|
{
|
||||||
|
if (touchTimeout)
|
||||||
|
clearTimeout(touchTimeout);
|
||||||
|
|
||||||
|
touchTimeout = setTimeout(() =>
|
||||||
|
{
|
||||||
|
setHover(false);
|
||||||
|
}, 2000);
|
||||||
|
}}
|
||||||
style={spacingStyle}
|
style={spacingStyle}
|
||||||
>
|
>
|
||||||
<div className={classnames(classes.viewContainer, 'webcam')} style={style}>
|
<div className={classnames(classes.viewContainer)} style={style}>
|
||||||
|
<div
|
||||||
|
className={classnames(classes.controls, webcamHover ? 'hover' : null)}
|
||||||
|
onMouseOver={() => setWebcamHover(true)}
|
||||||
|
onMouseOut={() => setWebcamHover(false)}
|
||||||
|
onTouchStart={() =>
|
||||||
|
{
|
||||||
|
if (touchWebcamTimeout)
|
||||||
|
clearTimeout(touchWebcamTimeout);
|
||||||
|
|
||||||
|
setWebcamHover(true);
|
||||||
|
}}
|
||||||
|
onTouchEnd={() =>
|
||||||
|
{
|
||||||
|
if (touchWebcamTimeout)
|
||||||
|
clearTimeout(touchWebcamTimeout);
|
||||||
|
|
||||||
|
touchWebcamTimeout = setTimeout(() =>
|
||||||
|
{
|
||||||
|
setWebcamHover(false);
|
||||||
|
}, 2000);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p>ME</p>
|
||||||
|
<Tooltip title={micTip} placement={smallScreen ? 'top' : 'right'}>
|
||||||
|
<div>
|
||||||
|
<Fab
|
||||||
|
aria-label='Mute mic'
|
||||||
|
className={classes.fab}
|
||||||
|
disabled={!me.canSendMic || me.audioInProgress}
|
||||||
|
color={micState === 'on' ? 'default' : 'secondary'}
|
||||||
|
onClick={() =>
|
||||||
|
{
|
||||||
|
if (micState === 'off')
|
||||||
|
roomClient.enableMic();
|
||||||
|
else if (micState === 'on')
|
||||||
|
roomClient.muteMic();
|
||||||
|
else
|
||||||
|
roomClient.unmuteMic();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ micState === 'on' ?
|
||||||
|
<MicIcon />
|
||||||
|
:
|
||||||
|
<MicOffIcon />
|
||||||
|
}
|
||||||
|
</Fab>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip title={webcamTip} placement={smallScreen ? 'top' : 'right'}>
|
||||||
|
<div>
|
||||||
|
<Fab
|
||||||
|
aria-label='Mute video'
|
||||||
|
className={classes.fab}
|
||||||
|
disabled={!me.canSendWebcam || me.webcamInProgress}
|
||||||
|
color={webcamState === 'on' ? 'default' : 'secondary'}
|
||||||
|
onClick={() =>
|
||||||
|
{
|
||||||
|
webcamState === 'on' ?
|
||||||
|
roomClient.disableWebcam() :
|
||||||
|
roomClient.enableWebcam();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ webcamState === 'on' ?
|
||||||
|
<VideoIcon />
|
||||||
|
:
|
||||||
|
<VideoOffIcon />
|
||||||
|
}
|
||||||
|
</Fab>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip title={screenTip} placement={smallScreen ? 'top' : 'right'}>
|
||||||
|
<div>
|
||||||
|
<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;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ screenState === 'on' || screenState === 'unsupported' ?
|
||||||
|
<ScreenOffIcon/>
|
||||||
|
:null
|
||||||
|
}
|
||||||
|
{ screenState === 'off' ?
|
||||||
|
<ScreenIcon/>
|
||||||
|
:null
|
||||||
|
}
|
||||||
|
</Fab>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
|
||||||
<VideoView
|
<VideoView
|
||||||
isMe
|
isMe
|
||||||
advancedMode={advancedMode}
|
advancedMode={advancedMode}
|
||||||
|
|
@ -106,8 +365,56 @@ const Me = (props) =>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{ screenProducer ?
|
{ screenProducer ?
|
||||||
<div className={classes.root}>
|
<div
|
||||||
<div className={classnames(classes.viewContainer, 'screen')} style={style}>
|
className={classnames(classes.root, 'screen', hover ? 'hover' : null)}
|
||||||
|
onMouseOver={() => setHover(true)}
|
||||||
|
onMouseOut={() => setHover(false)}
|
||||||
|
onTouchStart={() =>
|
||||||
|
{
|
||||||
|
if (touchTimeout)
|
||||||
|
clearTimeout(touchTimeout);
|
||||||
|
|
||||||
|
setHover(true);
|
||||||
|
}}
|
||||||
|
onTouchEnd={() =>
|
||||||
|
{
|
||||||
|
if (touchTimeout)
|
||||||
|
clearTimeout(touchTimeout);
|
||||||
|
|
||||||
|
touchTimeout = setTimeout(() =>
|
||||||
|
{
|
||||||
|
setHover(false);
|
||||||
|
}, 2000);
|
||||||
|
}}
|
||||||
|
style={spacingStyle}
|
||||||
|
>
|
||||||
|
<div className={classnames(classes.viewContainer)} style={style}>
|
||||||
|
<div
|
||||||
|
className={classnames(classes.controls, screenHover ? 'hover' : null)}
|
||||||
|
onMouseOver={() => setScreenHover(true)}
|
||||||
|
onMouseOut={() => setScreenHover(false)}
|
||||||
|
onTouchStart={() =>
|
||||||
|
{
|
||||||
|
if (touchScreenTimeout)
|
||||||
|
clearTimeout(touchScreenTimeout);
|
||||||
|
|
||||||
|
setScreenHover(true);
|
||||||
|
}}
|
||||||
|
onTouchEnd={() =>
|
||||||
|
{
|
||||||
|
|
||||||
|
if (touchScreenTimeout)
|
||||||
|
clearTimeout(touchScreenTimeout);
|
||||||
|
|
||||||
|
touchScreenTimeout = setTimeout(() =>
|
||||||
|
{
|
||||||
|
setScreenHover(false);
|
||||||
|
}, 2000);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p>ME</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<VideoView
|
<VideoView
|
||||||
isMe
|
isMe
|
||||||
advancedMode={advancedMode}
|
advancedMode={advancedMode}
|
||||||
|
|
@ -136,7 +443,8 @@ Me.propTypes =
|
||||||
screenProducer : appPropTypes.Producer,
|
screenProducer : appPropTypes.Producer,
|
||||||
spacing : PropTypes.number,
|
spacing : PropTypes.number,
|
||||||
style : PropTypes.object,
|
style : PropTypes.object,
|
||||||
classes : PropTypes.object.isRequired
|
classes : PropTypes.object.isRequired,
|
||||||
|
theme : PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = (state) =>
|
const mapStateToProps = (state) =>
|
||||||
|
|
@ -164,4 +472,4 @@ export default withRoomContext(connect(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)(withStyles(styles)(Me)));
|
)(withStyles(styles, { withTheme: true })(Me)));
|
||||||
|
|
|
||||||
|
|
@ -31,11 +31,11 @@ const styles = (theme) =>
|
||||||
backgroundRepeat : 'no-repeat',
|
backgroundRepeat : 'no-repeat',
|
||||||
'&.webcam' :
|
'&.webcam' :
|
||||||
{
|
{
|
||||||
order : 2
|
order : 4
|
||||||
},
|
},
|
||||||
'&.screen' :
|
'&.screen' :
|
||||||
{
|
{
|
||||||
order : 1
|
order : 3
|
||||||
},
|
},
|
||||||
'&.hover' :
|
'&.hover' :
|
||||||
{
|
{
|
||||||
|
|
@ -52,17 +52,9 @@ const styles = (theme) =>
|
||||||
},
|
},
|
||||||
viewContainer :
|
viewContainer :
|
||||||
{
|
{
|
||||||
position : 'relative',
|
position : 'relative',
|
||||||
width : '100%',
|
width : '100%',
|
||||||
height : '100%',
|
height : '100%'
|
||||||
'&.webcam' :
|
|
||||||
{
|
|
||||||
order : 2
|
|
||||||
},
|
|
||||||
'&.screen' :
|
|
||||||
{
|
|
||||||
order : 1
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
controls :
|
controls :
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,331 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { meProducersSelector } from '../Selectors';
|
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
|
||||||
import { unstable_useMediaQuery as useMediaQuery } from '@material-ui/core/useMediaQuery';
|
|
||||||
import classnames from 'classnames';
|
|
||||||
import * as appPropTypes from '../appPropTypes';
|
|
||||||
import { withRoomContext } from '../../RoomContext';
|
|
||||||
import Fab from '@material-ui/core/Fab';
|
|
||||||
import Tooltip from '@material-ui/core/Tooltip';
|
|
||||||
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 ScreenOffIcon from '@material-ui/icons/StopScreenShare';
|
|
||||||
import LockIcon from '@material-ui/icons/Lock';
|
|
||||||
import LockOpenIcon from '@material-ui/icons/LockOpen';
|
|
||||||
import LeaveIcon from '@material-ui/icons/Cancel';
|
|
||||||
|
|
||||||
const styles = (theme) =>
|
|
||||||
({
|
|
||||||
root :
|
|
||||||
{
|
|
||||||
position : 'fixed',
|
|
||||||
zIndex : 500,
|
|
||||||
display : 'flex',
|
|
||||||
[theme.breakpoints.up('md')] :
|
|
||||||
{
|
|
||||||
top : '50%',
|
|
||||||
transform : 'translate(0%, -50%)',
|
|
||||||
flexDirection : 'column',
|
|
||||||
justifyContent : 'center',
|
|
||||||
alignItems : 'center',
|
|
||||||
left : '1.0em',
|
|
||||||
width : '2.6em'
|
|
||||||
},
|
|
||||||
[theme.breakpoints.down('sm')] :
|
|
||||||
{
|
|
||||||
flexDirection : 'row',
|
|
||||||
bottom : '0.5em',
|
|
||||||
left : '50%',
|
|
||||||
transform : 'translate(-50%, -0%)'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fab :
|
|
||||||
{
|
|
||||||
margin : theme.spacing.unit
|
|
||||||
},
|
|
||||||
show :
|
|
||||||
{
|
|
||||||
opacity : 1,
|
|
||||||
transition : 'opacity .5s'
|
|
||||||
},
|
|
||||||
hide :
|
|
||||||
{
|
|
||||||
opacity : 0,
|
|
||||||
transition : 'opacity .5s'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const Sidebar = (props) =>
|
|
||||||
{
|
|
||||||
const {
|
|
||||||
roomClient,
|
|
||||||
toolbarsVisible,
|
|
||||||
me,
|
|
||||||
micProducer,
|
|
||||||
webcamProducer,
|
|
||||||
screenProducer,
|
|
||||||
locked,
|
|
||||||
classes,
|
|
||||||
theme
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
let micState;
|
|
||||||
|
|
||||||
let micTip;
|
|
||||||
|
|
||||||
if (!me.canSendMic)
|
|
||||||
{
|
|
||||||
micState = 'unsupported';
|
|
||||||
micTip = 'Audio unsupported';
|
|
||||||
}
|
|
||||||
else if (!micProducer)
|
|
||||||
{
|
|
||||||
micState = 'off';
|
|
||||||
micTip = 'Activate audio';
|
|
||||||
}
|
|
||||||
else if (!micProducer.locallyPaused && !micProducer.remotelyPaused)
|
|
||||||
{
|
|
||||||
micState = 'on';
|
|
||||||
micTip = 'Mute audio';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
micState = 'muted';
|
|
||||||
micTip = 'Unmute audio';
|
|
||||||
}
|
|
||||||
|
|
||||||
let webcamState;
|
|
||||||
|
|
||||||
let webcamTip;
|
|
||||||
|
|
||||||
if (!me.canSendWebcam)
|
|
||||||
{
|
|
||||||
webcamState = 'unsupported';
|
|
||||||
webcamTip = 'Video unsupported';
|
|
||||||
}
|
|
||||||
else if (webcamProducer)
|
|
||||||
{
|
|
||||||
webcamState = 'on';
|
|
||||||
webcamTip = 'Stop video';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
webcamState = 'off';
|
|
||||||
webcamTip = 'Start video';
|
|
||||||
}
|
|
||||||
|
|
||||||
let screenState;
|
|
||||||
|
|
||||||
let screenTip;
|
|
||||||
|
|
||||||
if (!me.canShareScreen)
|
|
||||||
{
|
|
||||||
screenState = 'unsupported';
|
|
||||||
screenTip = 'Screen sharing not supported';
|
|
||||||
}
|
|
||||||
else if (screenProducer)
|
|
||||||
{
|
|
||||||
screenState = 'on';
|
|
||||||
screenTip = 'Stop screen sharing';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
screenState = 'off';
|
|
||||||
screenTip = 'Start screen sharing';
|
|
||||||
}
|
|
||||||
|
|
||||||
const smallScreen = useMediaQuery(theme.breakpoints.down('sm'));
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
classnames(classes.root, toolbarsVisible ? classes.show : classes.hide)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Tooltip title={micTip} placement={smallScreen ? 'top' : 'right'}>
|
|
||||||
<div>
|
|
||||||
<Fab
|
|
||||||
aria-label='Mute mic'
|
|
||||||
className={classes.fab}
|
|
||||||
disabled={!me.canSendMic || me.audioInProgress}
|
|
||||||
color={micState === 'on' ? 'default' : 'secondary'}
|
|
||||||
size={smallScreen ? 'large' : 'medium'}
|
|
||||||
onClick={() =>
|
|
||||||
{
|
|
||||||
if (micState === 'off')
|
|
||||||
roomClient.enableMic();
|
|
||||||
else if (micState === 'on')
|
|
||||||
roomClient.muteMic();
|
|
||||||
else
|
|
||||||
roomClient.unmuteMic();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{ micState === 'on' ?
|
|
||||||
<MicIcon />
|
|
||||||
:
|
|
||||||
<MicOffIcon />
|
|
||||||
}
|
|
||||||
</Fab>
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip title={webcamTip} placement={smallScreen ? 'top' : 'right'}>
|
|
||||||
<div>
|
|
||||||
<Fab
|
|
||||||
aria-label='Mute video'
|
|
||||||
className={classes.fab}
|
|
||||||
disabled={!me.canSendWebcam || me.webcamInProgress}
|
|
||||||
color={webcamState === 'on' ? 'default' : 'secondary'}
|
|
||||||
size={smallScreen ? 'large' : 'medium'}
|
|
||||||
onClick={() =>
|
|
||||||
{
|
|
||||||
webcamState === 'on' ?
|
|
||||||
roomClient.disableWebcam() :
|
|
||||||
roomClient.enableWebcam();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{ webcamState === 'on' ?
|
|
||||||
<VideoIcon />
|
|
||||||
:
|
|
||||||
<VideoOffIcon />
|
|
||||||
}
|
|
||||||
</Fab>
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip title={screenTip} placement={smallScreen ? 'top' : 'right'}>
|
|
||||||
<div>
|
|
||||||
<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;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{ screenState === 'on' || screenState === 'unsupported' ?
|
|
||||||
<ScreenOffIcon/>
|
|
||||||
:null
|
|
||||||
}
|
|
||||||
{ screenState === 'off' ?
|
|
||||||
<ScreenIcon/>
|
|
||||||
:null
|
|
||||||
}
|
|
||||||
</Fab>
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
|
|
||||||
<Tooltip
|
|
||||||
title={locked ? 'Unlock room' : 'Lock room'}
|
|
||||||
placement={smallScreen ? 'top' : 'right'}
|
|
||||||
>
|
|
||||||
<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>
|
|
||||||
</Tooltip>
|
|
||||||
|
|
||||||
{ /* <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> */ }
|
|
||||||
|
|
||||||
<Tooltip title='Leave meeting' placement={smallScreen ? 'top' : 'right'}>
|
|
||||||
<Fab
|
|
||||||
aria-label='Leave meeting'
|
|
||||||
className={classes.fab}
|
|
||||||
color='secondary'
|
|
||||||
size={smallScreen ? 'large' : 'medium'}
|
|
||||||
onClick={() => roomClient.close()}
|
|
||||||
>
|
|
||||||
<LeaveIcon />
|
|
||||||
</Fab>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
Sidebar.propTypes =
|
|
||||||
{
|
|
||||||
roomClient : PropTypes.any.isRequired,
|
|
||||||
toolbarsVisible : PropTypes.bool.isRequired,
|
|
||||||
me : appPropTypes.Me.isRequired,
|
|
||||||
micProducer : appPropTypes.Producer,
|
|
||||||
webcamProducer : appPropTypes.Producer,
|
|
||||||
screenProducer : appPropTypes.Producer,
|
|
||||||
locked : PropTypes.bool.isRequired,
|
|
||||||
classes : PropTypes.object.isRequired,
|
|
||||||
theme : PropTypes.object.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapStateToProps = (state) =>
|
|
||||||
({
|
|
||||||
toolbarsVisible : state.room.toolbarsVisible,
|
|
||||||
...meProducersSelector(state),
|
|
||||||
me : state.me,
|
|
||||||
locked : state.room.locked
|
|
||||||
});
|
|
||||||
|
|
||||||
export default withRoomContext(connect(
|
|
||||||
mapStateToProps,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
{
|
|
||||||
areStatesEqual : (next, prev) =>
|
|
||||||
{
|
|
||||||
return (
|
|
||||||
prev.room.toolbarsVisible === next.room.toolbarsVisible &&
|
|
||||||
prev.room.locked === next.room.locked &&
|
|
||||||
prev.producers === next.producers &&
|
|
||||||
prev.me === next.me
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)(withStyles(styles, { withTheme: true })(Sidebar)));
|
|
||||||
|
|
@ -27,10 +27,12 @@ import Filmstrip from './MeetingViews/Filmstrip';
|
||||||
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';
|
||||||
import Sidebar from './Controls/Sidebar';
|
|
||||||
import FullScreenIcon from '@material-ui/icons/Fullscreen';
|
import FullScreenIcon from '@material-ui/icons/Fullscreen';
|
||||||
import FullScreenExitIcon from '@material-ui/icons/FullscreenExit';
|
import FullScreenExitIcon from '@material-ui/icons/FullscreenExit';
|
||||||
import SettingsIcon from '@material-ui/icons/Settings';
|
import SettingsIcon from '@material-ui/icons/Settings';
|
||||||
|
import LockIcon from '@material-ui/icons/Lock';
|
||||||
|
import LockOpenIcon from '@material-ui/icons/LockOpen';
|
||||||
|
import LeaveIcon from '@material-ui/icons/Cancel';
|
||||||
import Settings from './Settings/Settings';
|
import Settings from './Settings/Settings';
|
||||||
import JoinDialog from './JoinDialog';
|
import JoinDialog from './JoinDialog';
|
||||||
|
|
||||||
|
|
@ -306,6 +308,34 @@ class Room extends React.PureComponent
|
||||||
</Typography>
|
</Typography>
|
||||||
<div className={classes.grow} />
|
<div className={classes.grow} />
|
||||||
<div className={classes.actionButtons}>
|
<div className={classes.actionButtons}>
|
||||||
|
<IconButton
|
||||||
|
aria-label='Leave meeting'
|
||||||
|
color='secondary'
|
||||||
|
onClick={() => roomClient.close()}
|
||||||
|
>
|
||||||
|
<LeaveIcon />
|
||||||
|
</IconButton>
|
||||||
|
<IconButton
|
||||||
|
aria-label='Lock room'
|
||||||
|
color='inherit'
|
||||||
|
onClick={() =>
|
||||||
|
{
|
||||||
|
if (room.locked)
|
||||||
|
{
|
||||||
|
roomClient.unlockRoom();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
roomClient.lockRoom();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ room.locked ?
|
||||||
|
<LockIcon />
|
||||||
|
:
|
||||||
|
<LockOpenIcon />
|
||||||
|
}
|
||||||
|
</IconButton>
|
||||||
{ this.fullscreen.fullscreenEnabled ?
|
{ this.fullscreen.fullscreenEnabled ?
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label='Fullscreen'
|
aria-label='Fullscreen'
|
||||||
|
|
@ -366,8 +396,6 @@ class Room extends React.PureComponent
|
||||||
|
|
||||||
<View advancedMode={advancedMode} />
|
<View advancedMode={advancedMode} />
|
||||||
|
|
||||||
<Sidebar />
|
|
||||||
|
|
||||||
<Settings />
|
<Settings />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue