Added redux selectors to improve performance. Fixed drawer. Cleaned up code and removed some unused code.

master
Håvar Aambø Fosstveit 2019-04-03 00:09:27 +02:00
parent 0478a44b74
commit fd1e512a80
14 changed files with 271 additions and 344 deletions

View File

@ -29,6 +29,7 @@
"redux-logger": "^3.0.6", "redux-logger": "^3.0.6",
"redux-persist": "^5.10.0", "redux-persist": "^5.10.0",
"redux-thunk": "^2.3.0", "redux-thunk": "^2.3.0",
"reselect": "^4.0.0",
"resize-observer-polyfill": "^1.5.1", "resize-observer-polyfill": "^1.5.1",
"riek": "^1.1.0", "riek": "^1.1.0",
"socket.io-client": "^2.2.0", "socket.io-client": "^2.2.0",
@ -168,7 +169,7 @@
"no-case-declarations": 2, "no-case-declarations": 2,
"no-catch-shadow": 2, "no-catch-shadow": 2,
"no-class-assign": 2, "no-class-assign": 2,
"no-confusing-arrow": 2, "no-confusing-arrow": ["error", {"allowParens": true}],
"no-console": 2, "no-console": 2,
"no-const-assign": 2, "no-const-assign": 2,
"no-debugger": 2, "no-debugger": 2,

View File

@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
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 PropTypes from 'prop-types'; import PropTypes from 'prop-types';
@ -133,21 +134,11 @@ Me.propTypes =
const mapStateToProps = (state) => const mapStateToProps = (state) =>
{ {
const producersArray = Object.values(state.producers);
const micProducer =
producersArray.find((producer) => producer.source === 'mic');
const webcamProducer =
producersArray.find((producer) => producer.source === 'webcam');
const screenProducer =
producersArray.find((producer) => producer.source === 'screen');
return { return {
connected : state.room.state === 'connected', connected : state.room.state === 'connected',
me : state.me, me : state.me,
micProducer : micProducer, ...meProducersSelector(state),
webcamProducer : webcamProducer, activeSpeaker : state.me.name === state.room.activeSpeakerName
screenProducer : screenProducer,
activeSpeaker : state.me.name === state.room.activeSpeakerName
}; };
}; };

View File

@ -1,5 +1,6 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { makePeerConsumerSelector } from '../Selectors';
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';
@ -423,26 +424,21 @@ Peer.propTypes =
theme : PropTypes.object.isRequired theme : PropTypes.object.isRequired
}; };
const mapStateToProps = (state, { name }) => const makeMapStateToProps = () =>
{ {
const peer = state.peers[name]; const getPeerConsumers = makePeerConsumerSelector();
const consumersArray = peer.consumers
.map((consumerId) => state.consumers[consumerId]);
const micConsumer =
consumersArray.find((consumer) => consumer.source === 'mic');
const webcamConsumer =
consumersArray.find((consumer) => consumer.source === 'webcam');
const screenConsumer =
consumersArray.find((consumer) => consumer.source === 'screen');
return { const mapStateToProps = (state, props) =>
peer, {
micConsumer, return {
webcamConsumer, peer : state.peers[props.name],
screenConsumer, ...getPeerConsumers(state, props),
windowConsumer : state.room.windowConsumer, windowConsumer : state.room.windowConsumer,
activeSpeaker : name === state.room.activeSpeakerName activeSpeaker : props.name === state.room.activeSpeakerName
};
}; };
return mapStateToProps;
}; };
const mapDispatchToProps = (dispatch) => const mapDispatchToProps = (dispatch) =>
@ -462,6 +458,6 @@ const mapDispatchToProps = (dispatch) =>
}; };
export default withRoomContext(connect( export default withRoomContext(connect(
mapStateToProps, makeMapStateToProps,
mapDispatchToProps mapDispatchToProps
)(withStyles(styles, { withTheme: true })(Peer))); )(withStyles(styles, { withTheme: true })(Peer)));

View File

@ -30,64 +30,71 @@ const styles = (theme) =>
width : '100%', width : '100%',
height : '100%', height : '100%',
backgroundColor : theme.palette.background.paper backgroundColor : theme.palette.background.paper
},
appBar :
{
display : 'flex',
flexDirection : 'row'
},
tabsHeader :
{
flexGrow : 1
} }
}); });
class MeetingDrawer extends React.PureComponent const MeetingDrawer = (props) =>
{ {
handleChange = (event, value) => const {
{ currentToolTab,
this.props.setToolTab(tabs[value]); unreadMessages,
}; unreadFiles,
closeDrawer,
setToolTab,
classes,
theme
} = props;
render() return (
{ <div className={classes.root}>
const { <AppBar
currentToolTab, position='static'
unreadMessages, color='default'
unreadFiles, className={classes.appBar}
closeDrawer, >
classes, <Tabs
theme className={classes.tabsHeader}
} = this.props; value={tabs.indexOf(currentToolTab)}
onChange={(event, value) => setToolTab(tabs[value])}
return ( indicatorColor='primary'
<div className={classes.root}> textColor='primary'
<AppBar position='static' color='default'> variant='fullWidth'
<Tabs >
value={tabs.indexOf(currentToolTab)} <Tab
onChange={this.handleChange} label={
indicatorColor='primary' <Badge color='secondary' badgeContent={unreadMessages}>
textColor='primary' Chat
variant='fullWidth' </Badge>
> }
<Tab />
label={ <Tab
<Badge color='secondary' badgeContent={unreadMessages}> label={
Chat <Badge color='secondary' badgeContent={unreadFiles}>
</Badge> File sharing
} </Badge>
/> }
<Tab />
label={ <Tab label='Participants' />
<Badge color='secondary' badgeContent={unreadFiles}> </Tabs>
File sharing <IconButton onClick={closeDrawer}>
</Badge> {theme.direction === 'ltr' ? <ChevronLeftIcon /> : <ChevronRightIcon />}
} </IconButton>
/> </AppBar>
<Tab label='Participants' /> {currentToolTab === 'chat' && <Chat />}
<IconButton onClick={closeDrawer}> {currentToolTab === 'files' && <FileSharing />}
{theme.direction === 'ltr' ? <ChevronLeftIcon /> : <ChevronRightIcon />} {currentToolTab === 'users' && <ParticipantList />}
</IconButton> </div>
</Tabs> );
</AppBar> };
{currentToolTab === 'chat' && <Chat />}
{currentToolTab === 'files' && <FileSharing />}
{currentToolTab === 'users' && <ParticipantList />}
</div>
);
}
}
MeetingDrawer.propTypes = MeetingDrawer.propTypes =
{ {

View File

@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { makePeerConsumerSelector } from '../../Selectors';
import { withStyles } from '@material-ui/core/styles'; import { withStyles } from '@material-ui/core/styles';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classnames from 'classnames'; import classnames from 'classnames';
@ -269,26 +270,21 @@ ListPeer.propTypes =
classes : PropTypes.object.isRequired classes : PropTypes.object.isRequired
}; };
const mapStateToProps = (state, { name }) => const makeMapStateToProps = () =>
{ {
const peer = state.peers[name]; const getPeerConsumers = makePeerConsumerSelector();
const consumersArray = peer.consumers
.map((consumerId) => state.consumers[consumerId]);
const micConsumer =
consumersArray.find((consumer) => consumer.source === 'mic');
const webcamConsumer =
consumersArray.find((consumer) => consumer.source === 'webcam');
const screenConsumer =
consumersArray.find((consumer) => consumer.source === 'screen');
return { const mapStateToProps = (state, props) =>
peer, {
micConsumer, return {
webcamConsumer, peer : state.peers[props.name],
screenConsumer ...getPeerConsumers(state, props)
};
}; };
return mapStateToProps;
}; };
export default withRoomContext(connect( export default withRoomContext(connect(
mapStateToProps makeMapStateToProps
)(withStyles(styles)(ListPeer))); )(withStyles(styles)(ListPeer)));

View File

@ -1,5 +1,11 @@
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import {
peersSelector,
videoBoxesSelector,
spotlightsSelector,
spotlightsLengthSelector
} from '../Selectors';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import debounce from 'lodash/debounce'; import debounce from 'lodash/debounce';
import { withStyles } from '@material-ui/core/styles'; import { withStyles } from '@material-ui/core/styles';
@ -159,28 +165,22 @@ class Democratic extends React.PureComponent
} }
Democratic.propTypes = Democratic.propTypes =
{ {
advancedMode : PropTypes.bool, advancedMode : PropTypes.bool,
peers : PropTypes.object.isRequired, peers : PropTypes.object.isRequired,
boxes : PropTypes.number, boxes : PropTypes.number,
spotlightsLength : PropTypes.number, spotlightsLength : PropTypes.number,
spotlights : PropTypes.array.isRequired, spotlights : PropTypes.array.isRequired,
classes : PropTypes.object.isRequired classes : PropTypes.object.isRequired
}; };
const mapStateToProps = (state) => 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 + Object.values(state.producers)
.filter((producer) => producer.source === 'screen').length + 1;
return { return {
peers : state.peers, peers : peersSelector(state),
boxes, boxes : videoBoxesSelector(state),
spotlights, spotlights : spotlightsSelector(state),
spotlightsLength spotlightsLength : spotlightsLengthSelector(state)
}; };
}; };

View File

@ -1,39 +0,0 @@
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import * as appPropTypes from '../appPropTypes';
import PeerAudio from './PeerAudio';
const AudioPeer = ({ micConsumer }) =>
{
return (
<PeerAudio
audioTrack={micConsumer ? micConsumer.track : null}
/>
);
};
AudioPeer.propTypes =
{
micConsumer : appPropTypes.Consumer,
name : PropTypes.string
};
const mapStateToProps = (state, { name }) =>
{
const peer = state.peers[name];
const consumersArray = peer.consumers
.map((consumerId) => state.consumers[consumerId]);
const micConsumer =
consumersArray.find((consumer) => consumer.source === 'mic');
return {
micConsumer
};
};
const AudioPeerContainer = connect(
mapStateToProps
)(AudioPeer);
export default AudioPeerContainer;

View File

@ -1,19 +1,24 @@
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { micConsumerSelector } from '../Selectors';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import AudioPeer from './AudioPeer'; import PeerAudio from './PeerAudio';
const AudioPeers = ({ peers }) => const AudioPeers = (props) =>
{ {
const {
micConsumers
} = props;
return ( return (
<div data-component='AudioPeers'> <div data-component='AudioPeers'>
{ {
Object.values(peers).map((peer) => micConsumers.map((micConsumer) =>
{ {
return ( return (
<AudioPeer <PeerAudio
key={peer.name} key={micConsumer.id}
name={peer.name} audioTrack={micConsumer.track}
/> />
); );
}) })
@ -24,12 +29,12 @@ const AudioPeers = ({ peers }) =>
AudioPeers.propTypes = AudioPeers.propTypes =
{ {
peers : PropTypes.object micConsumers : PropTypes.array
}; };
const mapStateToProps = (state) => const mapStateToProps = (state) =>
({ ({
peers : state.peers micConsumers : micConsumerSelector(state)
}); });
const AudioPeersContainer = connect( const AudioPeersContainer = connect(

View File

@ -18,6 +18,7 @@ import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button'; import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton'; import IconButton from '@material-ui/core/IconButton';
import MenuIcon from '@material-ui/icons/Menu'; import MenuIcon from '@material-ui/icons/Menu';
import Avatar from '@material-ui/core/Avatar';
import Badge from '@material-ui/core/Badge'; import Badge from '@material-ui/core/Badge';
import AccountCircle from '@material-ui/icons/AccountCircle'; import AccountCircle from '@material-ui/icons/AccountCircle';
import Notifications from './Notifications/Notifications'; import Notifications from './Notifications/Notifications';
@ -152,7 +153,6 @@ class Room extends React.PureComponent
this.state = this.state =
{ {
drawerOpen : false,
fullscreen : false fullscreen : false
}; };
} }
@ -220,7 +220,9 @@ class Room extends React.PureComponent
const { const {
roomClient, roomClient,
room, room,
me, myPicture,
loggedIn,
loginEnabled,
setSettingsOpen, setSettingsOpen,
toolAreaOpen, toolAreaOpen,
toggleToolArea, toggleToolArea,
@ -338,16 +340,20 @@ class Room extends React.PureComponent
> >
<SettingsIcon /> <SettingsIcon />
</IconButton> </IconButton>
{ me.loginEnabled ? { loginEnabled ?
<IconButton <IconButton
aria-label='Account' aria-label='Account'
color='inherit' color='inherit'
onClick={() => onClick={() =>
{ {
me.loggedIn ? roomClient.logout() : roomClient.login(); loggedIn ? roomClient.logout() : roomClient.login();
}} }}
> >
<AccountCircle /> { myPicture ?
<Avatar src={myPicture} />
:
<AccountCircle />
}
</IconButton> </IconButton>
:null :null
} }
@ -373,20 +379,6 @@ class Room extends React.PureComponent
<View advancedMode={room.advancedMode} /> <View advancedMode={room.advancedMode} />
{ /*
<Draggable handle='.me-handle' bounds='body' cancel='.display-name'>
<div
className={classnames(classes.meContainer, 'me-handle', {
'active-speaker' : amActiveSpeaker
})}
>
<Me
advancedMode={room.advancedMode}
/>
</div>
</Draggable>
*/ }
<Sidebar /> <Sidebar />
<Settings /> <Settings />
@ -400,10 +392,10 @@ Room.propTypes =
{ {
roomClient : PropTypes.object.isRequired, roomClient : PropTypes.object.isRequired,
room : appPropTypes.Room.isRequired, room : appPropTypes.Room.isRequired,
me : appPropTypes.Me.isRequired, myPicture : PropTypes.string,
// amActiveSpeaker : PropTypes.bool.isRequired, loggedIn : PropTypes.bool.isRequired,
loginEnabled : PropTypes.bool.isRequired,
toolAreaOpen : PropTypes.bool.isRequired, toolAreaOpen : PropTypes.bool.isRequired,
screenProducer : appPropTypes.Producer,
setToolbarsVisible : PropTypes.func.isRequired, setToolbarsVisible : PropTypes.func.isRequired,
setSettingsOpen : PropTypes.func.isRequired, setSettingsOpen : PropTypes.func.isRequired,
toggleToolArea : PropTypes.func.isRequired, toggleToolArea : PropTypes.func.isRequired,
@ -413,25 +405,18 @@ Room.propTypes =
}; };
const mapStateToProps = (state) => const mapStateToProps = (state) =>
{ ({
const producersArray = Object.values(state.producers); room : state.room,
const screenProducer = loggedIn : state.me.loggedIn,
producersArray.find((producer) => producer.source === 'screen'); loginEnabled : state.me.loginEnabled,
myPicture : state.me.picture,
return { toolAreaOpen : state.toolarea.toolAreaOpen,
room : state.room, unread : state.toolarea.unreadMessages +
me : state.me,
screenProducer : screenProducer,
toolAreaOpen : state.toolarea.toolAreaOpen,
unread : state.toolarea.unreadMessages +
state.toolarea.unreadFiles state.toolarea.unreadFiles
// amActiveSpeaker : state.me.name === state.room.activeSpeakerName, });
};
};
const mapDispatchToProps = (dispatch) => const mapDispatchToProps = (dispatch) =>
{ ({
return {
setToolbarsVisible : (visible) => setToolbarsVisible : (visible) =>
{ {
dispatch(stateActions.setToolbarsVisible(visible)); dispatch(stateActions.setToolbarsVisible(visible));
@ -444,8 +429,7 @@ const mapDispatchToProps = (dispatch) =>
{ {
dispatch(stateActions.toggleToolArea()); dispatch(stateActions.toggleToolArea());
} }
}; });
};
export default withRoomContext(connect( export default withRoomContext(connect(
mapStateToProps, mapStateToProps,

View File

@ -0,0 +1,104 @@
import { createSelector } from 'reselect';
const producersSelect = (state) => state.producers;
const consumersSelect = (state) => state.consumers;
export const spotlightsSelector = (state) => state.room.spotlights;
export const peersSelector = (state) => state.peers;
export const micProducersSelector = createSelector(
producersSelect,
(producers) => Object.values(producers).filter((producer) => producer.source === 'mic')
);
export const webcamProducersSelector = createSelector(
producersSelect,
(producers) => Object.values(producers).filter((producer) => producer.source === 'webcam')
);
export const screenProducersSelector = createSelector(
producersSelect,
(producers) => Object.values(producers).filter((producer) => producer.source === 'screen')
);
export const micProducerSelector = createSelector(
producersSelect,
(producers) => Object.values(producers).find((producer) => producer.source === 'mic')
);
export const webcamProducerSelector = createSelector(
producersSelect,
(producers) => Object.values(producers).find((producer) => producer.source === 'webcam')
);
export const screenProducerSelector = createSelector(
producersSelect,
(producers) => Object.values(producers).find((producer) => producer.source === 'screen')
);
export const micConsumerSelector = createSelector(
consumersSelect,
(consumers) => Object.values(consumers).filter((consumer) => consumer.source === 'mic')
);
export const webcamConsumerSelector = createSelector(
consumersSelect,
(consumers) => Object.values(consumers).filter((consumer) => consumer.source === 'webcam')
);
export const screenConsumerSelector = createSelector(
consumersSelect,
(consumers) => Object.values(consumers).filter((consumer) => consumer.source === 'screen')
);
export const spotlightsLengthSelector = createSelector(
spotlightsSelector,
(spotlights) => (spotlights ? spotlights.length : 0)
);
export const videoBoxesSelector = createSelector(
spotlightsLengthSelector,
screenProducersSelector,
screenConsumerSelector,
(spotlightsLength, screenProducers, screenConsumers) =>
spotlightsLength + 1 + screenProducers.length + screenConsumers.length
);
export const meProducersSelector = createSelector(
micProducerSelector,
webcamProducerSelector,
screenProducerSelector,
(micProducer, webcamProducer, screenProducer) =>
{
return {
micProducer,
webcamProducer,
screenProducer
};
}
);
const getPeerConsumers = (state, props) => state.peers[props.name].consumers;
const getAllConsumers = (state) => state.consumers;
export const makePeerConsumerSelector = () =>
{
return createSelector(
getPeerConsumers,
getAllConsumers,
(consumers, allConsumers) =>
{
const consumersArray = consumers
.map((consumerId) => allConsumers[consumerId]);
const micConsumer =
consumersArray.find((consumer) => consumer.source === 'mic');
const webcamConsumer =
consumersArray.find((consumer) => consumer.source === 'webcam');
const screenConsumer =
consumersArray.find((consumer) => consumer.source === 'screen');
return { micConsumer, webcamConsumer, screenConsumer };
}
);
};

View File

@ -5,8 +5,8 @@ import classnames from 'classnames';
import { withStyles } from '@material-ui/core/styles'; import { withStyles } from '@material-ui/core/styles';
import * as appPropTypes from '../appPropTypes'; import * as appPropTypes from '../appPropTypes';
import * as stateActions from '../../actions/stateActions'; import * as stateActions from '../../actions/stateActions';
import FullView from './FullView';
import FullScreenExitIcon from '@material-ui/icons/FullscreenExit'; import FullScreenExitIcon from '@material-ui/icons/FullscreenExit';
import VideoView from './VideoView';
const styles = () => const styles = () =>
({ ({
@ -41,7 +41,12 @@ const styles = () =>
transitionProperty : 'opacity, background-color', transitionProperty : 'opacity, background-color',
transitionDuration : '0.15s', transitionDuration : '0.15s',
width : '5vmin', width : '5vmin',
height : '5vmin' height : '5vmin',
opacity : 0,
'&.visible' :
{
opacity : 1
}
}, },
icon : icon :
{ {
@ -106,7 +111,7 @@ const FullScreenView = (props) =>
<div className={classes.controls}> <div className={classes.controls}>
<div <div
className={classnames(classes.button, 'room-controls', { className={classnames(classes.button, {
visible : toolbarsVisible visible : toolbarsVisible
})} })}
onClick={(e) => onClick={(e) =>
@ -119,8 +124,9 @@ const FullScreenView = (props) =>
</div> </div>
</div> </div>
<FullView <VideoView
advancedMode={advancedMode} advancedMode={advancedMode}
videoContain
videoTrack={consumer ? consumer.track : null} videoTrack={consumer ? consumer.track : null}
videoVisible={consumerVisible} videoVisible={consumerVisible}
videoProfile={consumerProfile} videoProfile={consumerProfile}
@ -139,23 +145,19 @@ FullScreenView.propTypes =
}; };
const mapStateToProps = (state) => const mapStateToProps = (state) =>
{ ({
return {
consumer : state.consumers[state.room.fullScreenConsumer], consumer : state.consumers[state.room.fullScreenConsumer],
toolbarsVisible : state.room.toolbarsVisible toolbarsVisible : state.room.toolbarsVisible
}; });
};
const mapDispatchToProps = (dispatch) => const mapDispatchToProps = (dispatch) =>
{ ({
return {
toggleConsumerFullscreen : (consumer) => toggleConsumerFullscreen : (consumer) =>
{ {
if (consumer) if (consumer)
dispatch(stateActions.toggleConsumerFullscreen(consumer.id)); dispatch(stateActions.toggleConsumerFullscreen(consumer.id));
} }
}; });
};
export default connect( export default connect(
mapStateToProps, mapStateToProps,

View File

@ -1,122 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { withStyles } from '@material-ui/core/styles';
const styles = () =>
({
root :
{
position : 'relative',
flex : '100 100 auto',
height : '100%',
width : '100%',
display : 'flex',
flexDirection : 'column',
overflow : 'hidden'
},
video :
{
flex : '100 100 auto',
height : '100%',
width : '100%',
objectFit : 'contain',
userSelect : 'none',
transitionProperty : 'opacity',
transitionDuration : '.15s',
backgroundColor : 'rgba(0, 0, 0, 1)',
'&.hidden' :
{
opacity : 0,
transitionDuration : '0s'
},
'&.loading' :
{
filter : 'blur(5px)'
}
}
});
class FullView extends React.PureComponent
{
constructor(props)
{
super(props);
// Latest received video track.
// @type {MediaStreamTrack}
this._videoTrack = null;
this.video = React.createRef();
}
render()
{
const {
videoVisible,
videoProfile,
classes
} = this.props;
return (
<div className={classes.root}>
<video
ref={this.video}
className={classnames(classes.video, {
hidden : !videoVisible,
loading : videoProfile === 'none'
})}
autoPlay
playsInline
muted={Boolean(true)}
/>
</div>
);
}
componentDidMount()
{
const { videoTrack } = this.props;
this._setTracks(videoTrack);
}
componentDidUpdate()
{
const { videoTrack } = this.props;
this._setTracks(videoTrack);
}
_setTracks(videoTrack)
{
if (this._videoTrack === videoTrack)
return;
this._videoTrack = videoTrack;
const video = this.video.current;
if (videoTrack)
{
const stream = new MediaStream();
stream.addTrack(videoTrack);
video.srcObject = stream;
}
else
{
video.srcObject = null;
}
}
}
FullView.propTypes =
{
videoTrack : PropTypes.any,
videoVisible : PropTypes.bool,
videoProfile : PropTypes.string,
classes : PropTypes.object.isRequired
};
export default withStyles(styles)(FullView);

View File

@ -42,7 +42,8 @@ const styles = () =>
}, },
'&.contain' : '&.contain' :
{ {
objectFit : 'contain' objectFit : 'contain',
backgroundColor : 'rgba(0, 0, 0, 1)'
} }
}, },
info : info :

View File

@ -4,7 +4,7 @@ import NewWindow from './NewWindow';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import * as appPropTypes from '../appPropTypes'; import * as appPropTypes from '../appPropTypes';
import * as stateActions from '../../actions/stateActions'; import * as stateActions from '../../actions/stateActions';
import FullView from '../VideoContainers/FullView'; import VideoView from '../VideoContainers/VideoView';
const VideoWindow = (props) => const VideoWindow = (props) =>
{ {
@ -30,8 +30,9 @@ const VideoWindow = (props) =>
return ( return (
<NewWindow onUnload={toggleConsumerWindow}> <NewWindow onUnload={toggleConsumerWindow}>
<FullView <VideoView
advancedMode={advancedMode} advancedMode={advancedMode}
videoContain
videoTrack={consumer ? consumer.track : null} videoTrack={consumer ? consumer.track : null}
videoVisible={consumerVisible} videoVisible={consumerVisible}
videoProfile={consumerProfile} videoProfile={consumerProfile}