Added redux selectors to improve performance. Fixed drawer. Cleaned up code and removed some unused code.
parent
0478a44b74
commit
fd1e512a80
|
|
@ -29,6 +29,7 @@
|
|||
"redux-logger": "^3.0.6",
|
||||
"redux-persist": "^5.10.0",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"reselect": "^4.0.0",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"riek": "^1.1.0",
|
||||
"socket.io-client": "^2.2.0",
|
||||
|
|
@ -168,7 +169,7 @@
|
|||
"no-case-declarations": 2,
|
||||
"no-catch-shadow": 2,
|
||||
"no-class-assign": 2,
|
||||
"no-confusing-arrow": 2,
|
||||
"no-confusing-arrow": ["error", {"allowParens": true}],
|
||||
"no-console": 2,
|
||||
"no-const-assign": 2,
|
||||
"no-debugger": 2,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { meProducersSelector } from '../Selectors';
|
||||
import { withRoomContext } from '../../RoomContext';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import PropTypes from 'prop-types';
|
||||
|
|
@ -133,20 +134,10 @@ Me.propTypes =
|
|||
|
||||
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 {
|
||||
connected : state.room.state === 'connected',
|
||||
me : state.me,
|
||||
micProducer : micProducer,
|
||||
webcamProducer : webcamProducer,
|
||||
screenProducer : screenProducer,
|
||||
...meProducersSelector(state),
|
||||
activeSpeaker : state.me.name === state.room.activeSpeakerName
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React, { useState } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { makePeerConsumerSelector } from '../Selectors';
|
||||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
import * as appPropTypes from '../appPropTypes';
|
||||
|
|
@ -423,28 +424,23 @@ Peer.propTypes =
|
|||
theme : PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state, { name }) =>
|
||||
const makeMapStateToProps = () =>
|
||||
{
|
||||
const peer = state.peers[name];
|
||||
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');
|
||||
const getPeerConsumers = makePeerConsumerSelector();
|
||||
|
||||
const mapStateToProps = (state, props) =>
|
||||
{
|
||||
return {
|
||||
peer,
|
||||
micConsumer,
|
||||
webcamConsumer,
|
||||
screenConsumer,
|
||||
peer : state.peers[props.name],
|
||||
...getPeerConsumers(state, props),
|
||||
windowConsumer : state.room.windowConsumer,
|
||||
activeSpeaker : name === state.room.activeSpeakerName
|
||||
activeSpeaker : props.name === state.room.activeSpeakerName
|
||||
};
|
||||
};
|
||||
|
||||
return mapStateToProps;
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) =>
|
||||
{
|
||||
return {
|
||||
|
|
@ -462,6 +458,6 @@ const mapDispatchToProps = (dispatch) =>
|
|||
};
|
||||
|
||||
export default withRoomContext(connect(
|
||||
mapStateToProps,
|
||||
makeMapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(withStyles(styles, { withTheme: true })(Peer)));
|
||||
|
|
|
|||
|
|
@ -30,33 +30,41 @@ const styles = (theme) =>
|
|||
width : '100%',
|
||||
height : '100%',
|
||||
backgroundColor : theme.palette.background.paper
|
||||
},
|
||||
appBar :
|
||||
{
|
||||
display : 'flex',
|
||||
flexDirection : 'row'
|
||||
},
|
||||
tabsHeader :
|
||||
{
|
||||
flexGrow : 1
|
||||
}
|
||||
});
|
||||
|
||||
class MeetingDrawer extends React.PureComponent
|
||||
{
|
||||
handleChange = (event, value) =>
|
||||
{
|
||||
this.props.setToolTab(tabs[value]);
|
||||
};
|
||||
|
||||
render()
|
||||
const MeetingDrawer = (props) =>
|
||||
{
|
||||
const {
|
||||
currentToolTab,
|
||||
unreadMessages,
|
||||
unreadFiles,
|
||||
closeDrawer,
|
||||
setToolTab,
|
||||
classes,
|
||||
theme
|
||||
} = this.props;
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<AppBar position='static' color='default'>
|
||||
<AppBar
|
||||
position='static'
|
||||
color='default'
|
||||
className={classes.appBar}
|
||||
>
|
||||
<Tabs
|
||||
className={classes.tabsHeader}
|
||||
value={tabs.indexOf(currentToolTab)}
|
||||
onChange={this.handleChange}
|
||||
onChange={(event, value) => setToolTab(tabs[value])}
|
||||
indicatorColor='primary'
|
||||
textColor='primary'
|
||||
variant='fullWidth'
|
||||
|
|
@ -76,18 +84,17 @@ class MeetingDrawer extends React.PureComponent
|
|||
}
|
||||
/>
|
||||
<Tab label='Participants' />
|
||||
</Tabs>
|
||||
<IconButton onClick={closeDrawer}>
|
||||
{theme.direction === 'ltr' ? <ChevronLeftIcon /> : <ChevronRightIcon />}
|
||||
</IconButton>
|
||||
</Tabs>
|
||||
</AppBar>
|
||||
{currentToolTab === 'chat' && <Chat />}
|
||||
{currentToolTab === 'files' && <FileSharing />}
|
||||
{currentToolTab === 'users' && <ParticipantList />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
MeetingDrawer.propTypes =
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { makePeerConsumerSelector } from '../../Selectors';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
|
|
@ -269,26 +270,21 @@ ListPeer.propTypes =
|
|||
classes : PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state, { name }) =>
|
||||
const makeMapStateToProps = () =>
|
||||
{
|
||||
const peer = state.peers[name];
|
||||
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');
|
||||
const getPeerConsumers = makePeerConsumerSelector();
|
||||
|
||||
const mapStateToProps = (state, props) =>
|
||||
{
|
||||
return {
|
||||
peer,
|
||||
micConsumer,
|
||||
webcamConsumer,
|
||||
screenConsumer
|
||||
peer : state.peers[props.name],
|
||||
...getPeerConsumers(state, props)
|
||||
};
|
||||
};
|
||||
|
||||
return mapStateToProps;
|
||||
};
|
||||
|
||||
export default withRoomContext(connect(
|
||||
mapStateToProps
|
||||
makeMapStateToProps
|
||||
)(withStyles(styles)(ListPeer)));
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import {
|
||||
peersSelector,
|
||||
videoBoxesSelector,
|
||||
spotlightsSelector,
|
||||
spotlightsLengthSelector
|
||||
} from '../Selectors';
|
||||
import PropTypes from 'prop-types';
|
||||
import debounce from 'lodash/debounce';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
|
|
@ -170,17 +176,11 @@ Democratic.propTypes =
|
|||
|
||||
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 {
|
||||
peers : state.peers,
|
||||
boxes,
|
||||
spotlights,
|
||||
spotlightsLength
|
||||
peers : peersSelector(state),
|
||||
boxes : videoBoxesSelector(state),
|
||||
spotlights : spotlightsSelector(state),
|
||||
spotlightsLength : spotlightsLengthSelector(state)
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -1,19 +1,24 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { micConsumerSelector } from '../Selectors';
|
||||
import PropTypes from 'prop-types';
|
||||
import AudioPeer from './AudioPeer';
|
||||
import PeerAudio from './PeerAudio';
|
||||
|
||||
const AudioPeers = ({ peers }) =>
|
||||
const AudioPeers = (props) =>
|
||||
{
|
||||
const {
|
||||
micConsumers
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<div data-component='AudioPeers'>
|
||||
{
|
||||
Object.values(peers).map((peer) =>
|
||||
micConsumers.map((micConsumer) =>
|
||||
{
|
||||
return (
|
||||
<AudioPeer
|
||||
key={peer.name}
|
||||
name={peer.name}
|
||||
<PeerAudio
|
||||
key={micConsumer.id}
|
||||
audioTrack={micConsumer.track}
|
||||
/>
|
||||
);
|
||||
})
|
||||
|
|
@ -24,12 +29,12 @@ const AudioPeers = ({ peers }) =>
|
|||
|
||||
AudioPeers.propTypes =
|
||||
{
|
||||
peers : PropTypes.object
|
||||
micConsumers : PropTypes.array
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
({
|
||||
peers : state.peers
|
||||
micConsumers : micConsumerSelector(state)
|
||||
});
|
||||
|
||||
const AudioPeersContainer = connect(
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import Typography from '@material-ui/core/Typography';
|
|||
import Button from '@material-ui/core/Button';
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
import MenuIcon from '@material-ui/icons/Menu';
|
||||
import Avatar from '@material-ui/core/Avatar';
|
||||
import Badge from '@material-ui/core/Badge';
|
||||
import AccountCircle from '@material-ui/icons/AccountCircle';
|
||||
import Notifications from './Notifications/Notifications';
|
||||
|
|
@ -152,7 +153,6 @@ class Room extends React.PureComponent
|
|||
|
||||
this.state =
|
||||
{
|
||||
drawerOpen : false,
|
||||
fullscreen : false
|
||||
};
|
||||
}
|
||||
|
|
@ -220,7 +220,9 @@ class Room extends React.PureComponent
|
|||
const {
|
||||
roomClient,
|
||||
room,
|
||||
me,
|
||||
myPicture,
|
||||
loggedIn,
|
||||
loginEnabled,
|
||||
setSettingsOpen,
|
||||
toolAreaOpen,
|
||||
toggleToolArea,
|
||||
|
|
@ -338,16 +340,20 @@ class Room extends React.PureComponent
|
|||
>
|
||||
<SettingsIcon />
|
||||
</IconButton>
|
||||
{ me.loginEnabled ?
|
||||
{ loginEnabled ?
|
||||
<IconButton
|
||||
aria-label='Account'
|
||||
color='inherit'
|
||||
onClick={() =>
|
||||
{
|
||||
me.loggedIn ? roomClient.logout() : roomClient.login();
|
||||
loggedIn ? roomClient.logout() : roomClient.login();
|
||||
}}
|
||||
>
|
||||
{ myPicture ?
|
||||
<Avatar src={myPicture} />
|
||||
:
|
||||
<AccountCircle />
|
||||
}
|
||||
</IconButton>
|
||||
:null
|
||||
}
|
||||
|
|
@ -373,20 +379,6 @@ 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', {
|
||||
'active-speaker' : amActiveSpeaker
|
||||
})}
|
||||
>
|
||||
<Me
|
||||
advancedMode={room.advancedMode}
|
||||
/>
|
||||
</div>
|
||||
</Draggable>
|
||||
*/ }
|
||||
|
||||
<Sidebar />
|
||||
|
||||
<Settings />
|
||||
|
|
@ -400,10 +392,10 @@ Room.propTypes =
|
|||
{
|
||||
roomClient : PropTypes.object.isRequired,
|
||||
room : appPropTypes.Room.isRequired,
|
||||
me : appPropTypes.Me.isRequired,
|
||||
// amActiveSpeaker : PropTypes.bool.isRequired,
|
||||
myPicture : PropTypes.string,
|
||||
loggedIn : PropTypes.bool.isRequired,
|
||||
loginEnabled : PropTypes.bool.isRequired,
|
||||
toolAreaOpen : PropTypes.bool.isRequired,
|
||||
screenProducer : appPropTypes.Producer,
|
||||
setToolbarsVisible : PropTypes.func.isRequired,
|
||||
setSettingsOpen : PropTypes.func.isRequired,
|
||||
toggleToolArea : PropTypes.func.isRequired,
|
||||
|
|
@ -413,25 +405,18 @@ Room.propTypes =
|
|||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
{
|
||||
const producersArray = Object.values(state.producers);
|
||||
const screenProducer =
|
||||
producersArray.find((producer) => producer.source === 'screen');
|
||||
|
||||
return {
|
||||
({
|
||||
room : state.room,
|
||||
me : state.me,
|
||||
screenProducer : screenProducer,
|
||||
loggedIn : state.me.loggedIn,
|
||||
loginEnabled : state.me.loginEnabled,
|
||||
myPicture : state.me.picture,
|
||||
toolAreaOpen : state.toolarea.toolAreaOpen,
|
||||
unread : state.toolarea.unreadMessages +
|
||||
state.toolarea.unreadFiles
|
||||
// amActiveSpeaker : state.me.name === state.room.activeSpeakerName,
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) =>
|
||||
{
|
||||
return {
|
||||
({
|
||||
setToolbarsVisible : (visible) =>
|
||||
{
|
||||
dispatch(stateActions.setToolbarsVisible(visible));
|
||||
|
|
@ -444,8 +429,7 @@ const mapDispatchToProps = (dispatch) =>
|
|||
{
|
||||
dispatch(stateActions.toggleToolArea());
|
||||
}
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
export default withRoomContext(connect(
|
||||
mapStateToProps,
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
}
|
||||
);
|
||||
};
|
||||
|
|
@ -5,8 +5,8 @@ import classnames from 'classnames';
|
|||
import { withStyles } from '@material-ui/core/styles';
|
||||
import * as appPropTypes from '../appPropTypes';
|
||||
import * as stateActions from '../../actions/stateActions';
|
||||
import FullView from './FullView';
|
||||
import FullScreenExitIcon from '@material-ui/icons/FullscreenExit';
|
||||
import VideoView from './VideoView';
|
||||
|
||||
const styles = () =>
|
||||
({
|
||||
|
|
@ -41,7 +41,12 @@ const styles = () =>
|
|||
transitionProperty : 'opacity, background-color',
|
||||
transitionDuration : '0.15s',
|
||||
width : '5vmin',
|
||||
height : '5vmin'
|
||||
height : '5vmin',
|
||||
opacity : 0,
|
||||
'&.visible' :
|
||||
{
|
||||
opacity : 1
|
||||
}
|
||||
},
|
||||
icon :
|
||||
{
|
||||
|
|
@ -106,7 +111,7 @@ const FullScreenView = (props) =>
|
|||
|
||||
<div className={classes.controls}>
|
||||
<div
|
||||
className={classnames(classes.button, 'room-controls', {
|
||||
className={classnames(classes.button, {
|
||||
visible : toolbarsVisible
|
||||
})}
|
||||
onClick={(e) =>
|
||||
|
|
@ -119,8 +124,9 @@ const FullScreenView = (props) =>
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<FullView
|
||||
<VideoView
|
||||
advancedMode={advancedMode}
|
||||
videoContain
|
||||
videoTrack={consumer ? consumer.track : null}
|
||||
videoVisible={consumerVisible}
|
||||
videoProfile={consumerProfile}
|
||||
|
|
@ -139,23 +145,19 @@ FullScreenView.propTypes =
|
|||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
{
|
||||
return {
|
||||
({
|
||||
consumer : state.consumers[state.room.fullScreenConsumer],
|
||||
toolbarsVisible : state.room.toolbarsVisible
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) =>
|
||||
{
|
||||
return {
|
||||
({
|
||||
toggleConsumerFullscreen : (consumer) =>
|
||||
{
|
||||
if (consumer)
|
||||
dispatch(stateActions.toggleConsumerFullscreen(consumer.id));
|
||||
}
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -42,7 +42,8 @@ const styles = () =>
|
|||
},
|
||||
'&.contain' :
|
||||
{
|
||||
objectFit : 'contain'
|
||||
objectFit : 'contain',
|
||||
backgroundColor : 'rgba(0, 0, 0, 1)'
|
||||
}
|
||||
},
|
||||
info :
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import NewWindow from './NewWindow';
|
|||
import PropTypes from 'prop-types';
|
||||
import * as appPropTypes from '../appPropTypes';
|
||||
import * as stateActions from '../../actions/stateActions';
|
||||
import FullView from '../VideoContainers/FullView';
|
||||
import VideoView from '../VideoContainers/VideoView';
|
||||
|
||||
const VideoWindow = (props) =>
|
||||
{
|
||||
|
|
@ -30,8 +30,9 @@ const VideoWindow = (props) =>
|
|||
|
||||
return (
|
||||
<NewWindow onUnload={toggleConsumerWindow}>
|
||||
<FullView
|
||||
<VideoView
|
||||
advancedMode={advancedMode}
|
||||
videoContain
|
||||
videoTrack={consumer ? consumer.track : null}
|
||||
videoVisible={consumerVisible}
|
||||
videoProfile={consumerProfile}
|
||||
|
|
|
|||
Loading…
Reference in New Issue