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 * 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: &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
}
<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
}; };

View File

@ -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',
@ -41,53 +47,20 @@ const styles = () =>
controls : controls :
{ {
position : 'absolute', position : 'absolute',
right : 0, width : '100%',
top : 0, height : '100%',
backgroundColor : 'rgba(0, 0, 0, 0.3)',
display : 'flex', display : 'flex',
flexDirection : 'row', flexDirection : 'row',
justifyContent : 'flex-start', justifyContent : 'center',
alignItems : 'center', alignItems : 'center',
padding : '0.4vmin', padding : '0.4vmin',
zIndex : 20, zIndex : 20,
opacity : 0, opacity : 0,
transition : 'opacity 0.3s', 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)',
cursor : 'pointer',
transitionProperty : 'opacity, background-color',
transitionDuration : '0.15s',
'&:hover' : '&:hover' :
{ {
opacity : 1 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 :
@ -136,27 +109,7 @@ const styles = () =>
} }
}); });
class Peer extends React.PureComponent const Peer = (props) =>
{
state = {
controlsVisible : false
};
handleMouseOver = () =>
{
this.setState({
controlsVisible : true
});
};
handleMouseOut = () =>
{
this.setState({
controlsVisible : false
});
};
render()
{ {
const { const {
roomClient, roomClient,
@ -169,8 +122,9 @@ class Peer extends React.PureComponent
toggleConsumerWindow, toggleConsumerWindow,
style, style,
windowConsumer, windowConsumer,
classes classes,
} = this.props; theme
} = props;
const micEnabled = ( const micEnabled = (
Boolean(micConsumer) && Boolean(micConsumer) &&
@ -200,13 +154,13 @@ class Peer extends React.PureComponent
if (screenConsumer) if (screenConsumer)
screenProfile = screenConsumer.profile; screenProfile = screenConsumer.profile;
const smallScreen = useMediaQuery(theme.breakpoints.down('sm'));
return ( return (
<div <div
className={classnames(classes.root, { className={classnames(classes.root, {
screen : screenConsumer screen : screenConsumer
})} })}
onMouseOver={this.handleMouseOver}
onMouseOut={this.handleMouseOut}
> >
{ videoVisible && !webcamConsumer.supported ? { videoVisible && !webcamConsumer.supported ?
<div className={classes.incompatibleVideo}> <div className={classes.incompatibleVideo}>
@ -224,19 +178,14 @@ class Peer extends React.PureComponent
<div className={classnames(classes.viewContainer, 'webcam')} style={style}> <div className={classnames(classes.viewContainer, 'webcam')} style={style}>
<div <div
className={classnames(classes.controls, { className={classes.controls}
visible : this.state.controlsVisible
})}
> >
<div <Fab
className={classnames(classes.button, { aria-label='Mute mic'
on : micEnabled, className={classes.fab}
off : !micEnabled, color={micEnabled ? 'default' : 'secondary'}
disabled : peer.peerAudioInProgress onClick={() =>
})}
onClick={(e) =>
{ {
e.stopPropagation();
micEnabled ? micEnabled ?
roomClient.modifyPeerConsumer(peer.name, 'mic', true) : roomClient.modifyPeerConsumer(peer.name, 'mic', true) :
roomClient.modifyPeerConsumer(peer.name, 'mic', false); roomClient.modifyPeerConsumer(peer.name, 'mic', false);
@ -247,34 +196,37 @@ class Peer extends React.PureComponent
: :
<MicOffIcon /> <MicOffIcon />
} }
</div> </Fab>
<div { !smallScreen ?
className={classnames(classes.button, { <Fab
disabled : !videoVisible || aria-label='New window'
className={classes.fab}
disabled={
!videoVisible ||
(windowConsumer === webcamConsumer.id) (windowConsumer === webcamConsumer.id)
})} }
onClick={(e) => 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 />
</div> </Fab>
</div> </div>
<PeerView <PeerView
@ -292,36 +244,37 @@ class Peer extends React.PureComponent
{ screenConsumer ? { screenConsumer ?
<div className={classnames(classes.viewContainer, 'screen')} style={style}> <div className={classnames(classes.viewContainer, 'screen')} style={style}>
<div <div
className={classnames(classes.controls, { className={classes.controls}
visible : this.state.controlsVisible
})}
> >
<div { !smallScreen ?
className={classnames(classes.button, 'newwindow', { <Fab
disabled : !screenVisible || aria-label='New window'
className={classes.fab}
disabled={
!screenVisible ||
(windowConsumer === screenConsumer.id) (windowConsumer === screenConsumer.id)
})} }
onClick={(e) => 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 />
</div> </Fab>
</div> </div>
<ScreenView <ScreenView
advancedMode={advancedMode} advancedMode={advancedMode}
@ -335,8 +288,7 @@ class Peer extends React.PureComponent
} }
</div> </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)));

View File

@ -2,18 +2,23 @@ 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) =>
@ -22,15 +27,25 @@ const styles = (theme) =>
{ {
position : 'fixed', position : 'fixed',
zIndex : 500, zIndex : 500,
display : 'flex',
[theme.breakpoints.up('md')] :
{
top : '50%', top : '50%',
transform : 'translate(0%, -50%)', transform : 'translate(0%, -50%)',
display : 'flex',
flexDirection : 'column', flexDirection : 'column',
justifyContent : 'center', justifyContent : 'center',
alignItems : 'center', alignItems : 'center',
left : '1.0em', left : '1.0em',
width : '2.6em' width : '2.6em'
}, },
[theme.breakpoints.down('sm')] :
{
flexDirection : 'row',
bottom : '0.5em',
left : '50%',
transform : 'translate(-50%, -0%)'
}
},
fab : fab :
{ {
margin : theme.spacing.unit margin : theme.spacing.unit
@ -47,18 +62,39 @@ const styles = (theme) =>
} }
}); });
class Sidebar extends React.PureComponent const Sidebar = (props) =>
{
render()
{ {
const { const {
roomClient, roomClient,
toolbarsVisible, toolbarsVisible,
me, me,
micProducer,
webcamProducer,
screenProducer, screenProducer,
locked, locked,
classes classes,
} = this.props; 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; let screenState;
@ -79,18 +115,56 @@ class Sidebar extends React.PureComponent
screenState = 'off'; screenState = 'off';
} }
const smallScreen = useMediaQuery(theme.breakpoints.down('sm'));
return ( return (
<div <div
className={ className={
classnames(classes.root, toolbarsVisible ? classes.show : classes.hide) 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 <Fab
aria-label='Share screen' aria-label='Share screen'
className={classes.fab} className={classes.fab}
disabled={!me.canShareScreen || me.screenShareInProgress} disabled={!me.canShareScreen || me.screenShareInProgress}
color={screenState === 'on' ? 'primary' : 'default'} color={screenState === 'on' ? 'primary' : 'default'}
size={smallScreen ? 'large' : 'medium'}
onClick={() => onClick={() =>
{ {
switch (screenState) switch (screenState)
@ -135,6 +209,7 @@ class Sidebar extends React.PureComponent
aria-label='Room lock' aria-label='Room lock'
className={classes.fab} className={classes.fab}
color={locked ? 'primary' : 'default'} color={locked ? 'primary' : 'default'}
size={smallScreen ? 'large' : 'medium'}
onClick={() => onClick={() =>
{ {
if (locked) if (locked)
@ -154,42 +229,50 @@ class Sidebar extends React.PureComponent
} }
</Fab> </Fab>
<Fab { /* <Fab
aria-label='Raise hand' aria-label='Raise hand'
className={classes.fab} className={classes.fab}
disabled={me.raiseHandInProgress} disabled={me.raiseHandInProgress}
color={me.raiseHand ? 'primary' : 'default'} color={me.raiseHand ? 'primary' : 'default'}
size='large'
onClick={() => roomClient.sendRaiseHandState(!me.raiseHand)} onClick={() => roomClient.sendRaiseHandState(!me.raiseHand)}
> >
<Avatar alt='Hand' src={me.raiseHand ? HandOn : HandOff} /> <Avatar alt='Hand' src={me.raiseHand ? HandOn : HandOff} />
</Fab> </Fab> */ }
<Fab <Fab
aria-label='Leave meeting' aria-label='Leave meeting'
className={classes.fab} className={classes.fab}
color='secondary' color='secondary'
size={smallScreen ? 'large' : 'medium'}
onClick={() => roomClient.close()} onClick={() => roomClient.close()}
> >
<LeaveIcon /> <LeaveIcon />
</Fab> </Fab>
</div> </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,
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) screenProducer : Object.values(state.producers)
.find((producer) => producer.source === 'screen'), .find((producer) => producer.source === 'screen'),
me : state.me, me : state.me,
@ -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)));

View File

@ -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
}; };

View File

@ -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,
@ -413,11 +421,11 @@ const mapStateToProps = (state) =>
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,
}; };
}; };

View File

@ -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');