Moved Me window into view with other Peer containers.

master
Håvar Aambø Fosstveit 2019-04-01 15:08:25 +02:00
parent 9b78a81ef0
commit 49ebf5330b
6 changed files with 444 additions and 516 deletions

View File

@ -9,10 +9,6 @@ import { getDeviceInfo } from 'mediasoup-client';
import * as appPropTypes from '../appPropTypes';
import PeerView from '../VideoContainers/PeerView';
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 = () =>
({
@ -36,53 +32,6 @@ const styles = () =>
{
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 {
roomClient,
connected,
me,
style,
advancedMode,
micProducer,
webcamProducer,
@ -133,26 +82,6 @@ class Me extends React.PureComponent
classes
} = 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 = (
Boolean(webcamProducer) &&
!webcamProducer.locallyPaused &&
@ -180,57 +109,7 @@ class Me extends React.PureComponent
onMouseOver={this.handleMouseOver}
onMouseOut={this.handleMouseOut}
>
<div className={classnames(classes.viewContainer, 'webcam')}>
{ connected ?
<div className={classnames(classes.controls, 'visible')}>
<div
data-tip='keyboard shortcut: &lsquo;m&lsquo;'
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
}
<div className={classnames(classes.viewContainer, 'webcam')} style={style}>
<PeerView
isMe
advancedMode={advancedMode}
@ -249,7 +128,7 @@ class Me extends React.PureComponent
</div>
{ screenProducer ?
<div className={classnames(classes.viewContainer, 'screen')}>
<div className={classnames(classes.viewContainer, 'screen')} style={style}>
<ScreenView
isMe
advancedMode={advancedMode}
@ -304,6 +183,7 @@ Me.propTypes =
micProducer : appPropTypes.Producer,
webcamProducer : appPropTypes.Producer,
screenProducer : appPropTypes.Producer,
style : PropTypes.object,
classes : PropTypes.object.isRequired
};

View File

@ -5,15 +5,17 @@ import classnames from 'classnames';
import * as appPropTypes from '../appPropTypes';
import { withRoomContext } from '../../RoomContext';
import { withStyles } from '@material-ui/core/styles';
import { unstable_useMediaQuery as useMediaQuery } from '@material-ui/core/useMediaQuery';
import * as stateActions from '../../actions/stateActions';
import PeerView from '../VideoContainers/PeerView';
import ScreenView from '../VideoContainers/ScreenView';
import Fab from '@material-ui/core/Fab';
import MicIcon from '@material-ui/icons/Mic';
import MicOffIcon from '@material-ui/icons/MicOff';
import NewWindowIcon from '@material-ui/icons/OpenInNew';
import FullScreenIcon from '@material-ui/icons/Fullscreen';
const styles = () =>
const styles = (theme) =>
({
root :
{
@ -24,6 +26,10 @@ const styles = () =>
flex : '100 100 auto',
position : 'relative'
},
fab :
{
margin : theme.spacing.unit
},
viewContainer :
{
position : 'relative',
@ -40,56 +46,23 @@ const styles = () =>
},
controls :
{
position : 'absolute',
right : 0,
top : 0,
display : 'flex',
flexDirection : 'row',
justifyContent : 'flex-start',
alignItems : 'center',
padding : '0.4vmin',
zIndex : 20,
opacity : 0,
transition : 'opacity 0.3s',
'&.visible' :
position : 'absolute',
width : '100%',
height : '100%',
backgroundColor : 'rgba(0, 0, 0, 0.3)',
display : 'flex',
flexDirection : 'row',
justifyContent : 'center',
alignItems : 'center',
padding : '0.4vmin',
zIndex : 20,
opacity : 0,
transition : 'opacity 0.3s',
'&:hover' :
{
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 :
{
position : 'absolute',
@ -136,207 +109,186 @@ const styles = () =>
}
});
class Peer extends React.PureComponent
const Peer = (props) =>
{
state = {
controlsVisible : false
};
const {
roomClient,
advancedMode,
peer,
micConsumer,
webcamConsumer,
screenConsumer,
toggleConsumerFullscreen,
toggleConsumerWindow,
style,
windowConsumer,
classes,
theme
} = props;
handleMouseOver = () =>
{
this.setState({
controlsVisible : true
});
};
const micEnabled = (
Boolean(micConsumer) &&
!micConsumer.locallyPaused &&
!micConsumer.remotelyPaused
);
handleMouseOut = () =>
{
this.setState({
controlsVisible : false
});
};
const videoVisible = (
Boolean(webcamConsumer) &&
!webcamConsumer.locallyPaused &&
!webcamConsumer.remotelyPaused
);
render()
{
const {
roomClient,
advancedMode,
peer,
micConsumer,
webcamConsumer,
screenConsumer,
toggleConsumerFullscreen,
toggleConsumerWindow,
style,
windowConsumer,
classes
} = this.props;
const screenVisible = (
Boolean(screenConsumer) &&
!screenConsumer.locallyPaused &&
!screenConsumer.remotelyPaused
);
const micEnabled = (
Boolean(micConsumer) &&
!micConsumer.locallyPaused &&
!micConsumer.remotelyPaused
);
let videoProfile;
const videoVisible = (
Boolean(webcamConsumer) &&
!webcamConsumer.locallyPaused &&
!webcamConsumer.remotelyPaused
);
if (webcamConsumer)
videoProfile = webcamConsumer.profile;
const screenVisible = (
Boolean(screenConsumer) &&
!screenConsumer.locallyPaused &&
!screenConsumer.remotelyPaused
);
let screenProfile;
let videoProfile;
if (screenConsumer)
screenProfile = screenConsumer.profile;
if (webcamConsumer)
videoProfile = webcamConsumer.profile;
const smallScreen = useMediaQuery(theme.breakpoints.down('sm'));
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)
screenProfile = screenConsumer.profile;
{ !videoVisible ?
<div className={classes.pausedVideo}>
<p>this video is paused</p>
</div>
:null
}
return (
<div
className={classnames(classes.root, {
screen : screenConsumer
})}
onMouseOver={this.handleMouseOver}
onMouseOut={this.handleMouseOut}
>
{ videoVisible && !webcamConsumer.supported ?
<div className={classes.incompatibleVideo}>
<p>incompatible video</p>
</div>
:null
}
{ !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 className={classnames(classes.viewContainer, 'webcam')} style={style}>
<div
className={classes.controls}
>
<Fab
aria-label='Mute mic'
className={classes.fab}
color={micEnabled ? 'default' : 'secondary'}
onClick={() =>
{
micEnabled ?
roomClient.modifyPeerConsumer(peer.name, 'mic', true) :
roomClient.modifyPeerConsumer(peer.name, 'mic', false);
}}
>
<div
className={classnames(classes.button, {
on : micEnabled,
off : !micEnabled,
disabled : peer.peerAudioInProgress
})}
onClick={(e) =>
{
e.stopPropagation();
micEnabled ?
roomClient.modifyPeerConsumer(peer.name, 'mic', true) :
roomClient.modifyPeerConsumer(peer.name, 'mic', false);
}}
>
{ micEnabled ?
<MicIcon />
:
<MicOffIcon />
}
</div>
{ micEnabled ?
<MicIcon />
:
<MicOffIcon />
}
</Fab>
<div
className={classnames(classes.button, {
disabled : !videoVisible ||
(windowConsumer === webcamConsumer.id)
})}
onClick={(e) =>
{ !smallScreen ?
<Fab
aria-label='New window'
className={classes.fab}
disabled={
!videoVisible ||
(windowConsumer === webcamConsumer.id)
}
onClick={() =>
{
e.stopPropagation();
toggleConsumerWindow(webcamConsumer);
}}
>
<NewWindowIcon />
</div>
</Fab>
:null
}
<div
className={classnames(classes.button, 'fullscreen', {
disabled : !videoVisible
})}
onClick={(e) =>
{
e.stopPropagation();
toggleConsumerFullscreen(webcamConsumer);
}}
>
<FullScreenIcon />
</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}
/>
<Fab
aria-label='Fullscreen'
className={classes.fab}
disabled={!videoVisible}
onClick={() =>
{
toggleConsumerFullscreen(webcamConsumer);
}}
>
<FullScreenIcon />
</Fab>
</div>
{ screenConsumer ?
<div className={classnames(classes.viewContainer, 'screen')} style={style}>
<div
className={classnames(classes.controls, {
visible : this.state.controlsVisible
})}
>
<div
className={classnames(classes.button, 'newwindow', {
disabled : !screenVisible ||
(windowConsumer === screenConsumer.id)
})}
onClick={(e) =>
<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>
{ 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);
}}
>
<NewWindowIcon />
</div>
</Fab>
:null
}
<div
className={classnames(classes.button, 'fullscreen', {
disabled : !screenVisible
})}
onClick={(e) =>
{
e.stopPropagation();
toggleConsumerFullscreen(screenConsumer);
}}
>
<FullScreenIcon />
</div>
</div>
<ScreenView
advancedMode={advancedMode}
screenTrack={screenConsumer ? screenConsumer.track : null}
screenVisible={screenVisible}
screenProfile={screenProfile}
screenCodec={screenConsumer ? screenConsumer.codec : null}
/>
<Fab
aria-label='Fullscreen'
className={classes.fab}
disabled={!screenVisible}
onClick={() =>
{
toggleConsumerFullscreen(screenConsumer);
}}
>
<FullScreenIcon />
</Fab>
</div>
:null
}
</div>
);
}
}
<ScreenView
advancedMode={advancedMode}
screenTrack={screenConsumer ? screenConsumer.track : null}
screenVisible={screenVisible}
screenProfile={screenProfile}
screenCodec={screenConsumer ? screenConsumer.codec : null}
/>
</div>
:null
}
</div>
);
};
Peer.propTypes =
{
@ -351,7 +303,8 @@ Peer.propTypes =
style : PropTypes.object,
toggleConsumerFullscreen : PropTypes.func.isRequired,
toggleConsumerWindow : PropTypes.func.isRequired,
classes : PropTypes.object
classes : PropTypes.object.isRequired,
theme : PropTypes.object.isRequired
};
const mapStateToProps = (state, { name }) =>
@ -394,4 +347,4 @@ const mapDispatchToProps = (dispatch) =>
export default withRoomContext(connect(
mapStateToProps,
mapDispatchToProps
)(withStyles(styles)(Peer)));
)(withStyles(styles, { withTheme: true })(Peer)));

View File

@ -2,34 +2,49 @@ import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
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 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 ScreenOffIcon from '@material-ui/icons/StopScreenShare';
import ExtensionIcon from '@material-ui/icons/Extension';
import LockIcon from '@material-ui/icons/Lock';
import LockOpenIcon from '@material-ui/icons/LockOpen';
import HandOff from '../../images/icon-hand-black.svg';
import HandOn from '../../images/icon-hand-white.svg';
// import HandOff from '../../images/icon-hand-black.svg';
// import HandOn from '../../images/icon-hand-white.svg';
import LeaveIcon from '@material-ui/icons/Cancel';
const styles = (theme) =>
({
root :
{
position : 'fixed',
zIndex : 500,
top : '50%',
transform : 'translate(0%, -50%)',
display : 'flex',
flexDirection : 'column',
justifyContent : 'center',
alignItems : 'center',
left : '1.0em',
width : '2.6em'
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 :
{
@ -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 {
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>
);
screenState = 'need-extension';
}
}
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 =
{
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
classes : PropTypes.object.isRequired,
theme : PropTypes.object.isRequired
};
const mapStateToProps = (state) =>
({
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'),
me : state.me,
locked : state.room.locked
@ -198,4 +281,4 @@ const mapStateToProps = (state) =>
export default withRoomContext(connect(
mapStateToProps
)(withStyles(styles)(Sidebar)));
)(withStyles(styles, { withTheme: true })(Sidebar)));

View File

@ -5,11 +5,12 @@ import classnames from 'classnames';
import debounce from 'lodash/debounce';
import { withStyles } from '@material-ui/core/styles';
import Peer from '../Containers/Peer';
import Me from '../Containers/Me';
import HiddenPeers from '../Containers/HiddenPeers';
import ResizeObserver from 'resize-observer-polyfill';
const RATIO = 1.334;
const PADDING = 100;
const PADDING = 60;
const styles = () =>
({
@ -23,7 +24,7 @@ const styles = () =>
justifyContent : 'center',
alignItems : 'center',
alignContent : 'center',
paddingTop : 70,
paddingTop : 30,
paddingBottom : 30
},
peerContainer :
@ -126,6 +127,7 @@ class Democratic extends React.PureComponent
const {
advancedMode,
activeSpeakerName,
amActiveSpeaker,
peers,
spotlights,
spotlightsLength,
@ -140,6 +142,16 @@ class Democratic extends React.PureComponent
return (
<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) =>
{
if (spotlights.find((spotlightsElement) => spotlightsElement === peerName))
@ -181,6 +193,7 @@ Democratic.propTypes =
advancedMode : PropTypes.bool,
peers : PropTypes.object.isRequired,
boxes : PropTypes.number,
amActiveSpeaker : PropTypes.bool.isRequired,
activeSpeakerName : PropTypes.string,
selectedPeerName : PropTypes.string,
spotlightsLength : PropTypes.number,
@ -193,13 +206,15 @@ const mapStateToProps = (state) =>
const spotlights = state.room.spotlights;
const spotlightsLength = spotlights ? state.room.spotlights.length : 0;
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 {
peers : state.peers,
boxes,
activeSpeakerName : state.room.activeSpeakerName,
selectedPeerName : state.room.selectedPeerName,
amActiveSpeaker : state.me.name === state.room.activeSpeakerName,
spotlights,
spotlightsLength
};

View File

@ -2,11 +2,11 @@ import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import * as appPropTypes from './appPropTypes';
import classnames from 'classnames';
// import classnames from 'classnames';
import { withRoomContext } from '../RoomContext';
import { withStyles } from '@material-ui/core/styles';
import * as stateActions from '../actions/stateActions';
import Draggable from 'react-draggable';
// import Draggable from 'react-draggable';
import { idle } from '../utils';
import FullScreen from './FullScreen';
import CookieConsent from 'react-cookie-consent';
@ -26,7 +26,7 @@ import Notifications from './Notifications/Notifications';
import MeetingDrawer from './MeetingDrawer/MeetingDrawer';
import Democratic from './MeetingViews/Democratic';
import Filmstrip from './MeetingViews/Filmstrip';
import Me from './Containers/Me';
// import Me from './Containers/Me';
import AudioPeers from './PeerAudio/AudioPeers';
import FullScreenView from './VideoContainers/FullScreenView';
import VideoWindow from './VideoWindow/VideoWindow';
@ -68,7 +68,12 @@ const styles = (theme) =>
},
logo :
{
marginLeft : 20
display : 'none',
marginLeft : 20,
[theme.breakpoints.up('sm')] :
{
display : 'block'
}
},
show :
{
@ -126,8 +131,8 @@ const styles = (theme) =>
boxShadow : 'var(--me-shadow)',
transitionProperty : 'border-color',
transitionDuration : '0.15s',
top : '8%',
left : '1%',
top : '5em',
left : '1em',
border : 'var(--me-border)',
'&.active-speaker' :
{
@ -215,7 +220,7 @@ class Room extends React.PureComponent
roomClient,
room,
me,
amActiveSpeaker,
// amActiveSpeaker,
setSettingsOpen,
toolAreaOpen,
toggleToolArea,
@ -337,7 +342,8 @@ class Room extends React.PureComponent
<IconButton
aria-label='Account'
color='inherit'
onClick={() => {
onClick={() =>
{
me.loggedIn ? roomClient.logout() : roomClient.login();
}}
>
@ -367,6 +373,7 @@ class Room extends React.PureComponent
<View advancedMode={room.advancedMode} />
{ /*
<Draggable handle='.me-handle' bounds='body' cancel='.display-name'>
<div
className={classnames(classes.meContainer, 'me-handle', {
@ -378,6 +385,7 @@ class Room extends React.PureComponent
/>
</div>
</Draggable>
*/ }
<Sidebar />
@ -393,7 +401,7 @@ Room.propTypes =
roomClient : PropTypes.object.isRequired,
room : appPropTypes.Room.isRequired,
me : appPropTypes.Me.isRequired,
amActiveSpeaker : PropTypes.bool.isRequired,
// amActiveSpeaker : PropTypes.bool.isRequired,
toolAreaOpen : PropTypes.bool.isRequired,
screenProducer : appPropTypes.Producer,
setToolbarsVisible : PropTypes.func.isRequired,
@ -411,13 +419,13 @@ const mapStateToProps = (state) =>
producersArray.find((producer) => producer.source === 'screen');
return {
room : state.room,
me : state.me,
amActiveSpeaker : state.me.name === state.room.activeSpeakerName,
screenProducer : screenProducer,
toolAreaOpen : state.toolarea.toolAreaOpen,
unread : state.toolarea.unreadMessages +
room : state.room,
me : state.me,
screenProducer : screenProducer,
toolAreaOpen : state.toolarea.toolAreaOpen,
unread : state.toolarea.unreadMessages +
state.toolarea.unreadFiles
// amActiveSpeaker : state.me.name === state.room.activeSpeakerName,
};
};

View File

@ -1,17 +1,6 @@
:root {
--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-border: 1px solid rgba(255, 255, 255, 0.15);
--peer-empty-avatar: url('./images/buddy.svg');