Major cleanup
This commit is contained in:
@@ -1,17 +1,28 @@
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as stateActions from '../../redux/stateActions';
|
||||
import * as requestActions from '../../redux/requestActions';
|
||||
import { withRoomContext } from '../../RoomContext';
|
||||
import MessageList from './MessageList';
|
||||
|
||||
class Chat extends Component
|
||||
{
|
||||
createNewMessage(text, sender, name, picture)
|
||||
{
|
||||
return {
|
||||
type : 'message',
|
||||
text,
|
||||
time : Date.now(),
|
||||
name,
|
||||
sender,
|
||||
picture
|
||||
};
|
||||
}
|
||||
|
||||
render()
|
||||
{
|
||||
const {
|
||||
roomClient,
|
||||
senderPlaceHolder,
|
||||
onSendMessage,
|
||||
disabledInput,
|
||||
autofocus,
|
||||
displayName,
|
||||
@@ -23,7 +34,19 @@ class Chat extends Component
|
||||
<MessageList />
|
||||
<form
|
||||
data-component='Sender'
|
||||
onSubmit={(e) => { onSendMessage(e, displayName, picture); }}
|
||||
onSubmit={(e) =>
|
||||
{
|
||||
e.preventDefault();
|
||||
const userInput = e.target.message.value;
|
||||
|
||||
if (userInput)
|
||||
{
|
||||
const message = this.createNewMessage(userInput, 'response', displayName, picture);
|
||||
|
||||
roomClient.sendChatMessage(message);
|
||||
}
|
||||
e.target.message.value = '';
|
||||
}}
|
||||
>
|
||||
<input
|
||||
type='text'
|
||||
@@ -47,8 +70,8 @@ class Chat extends Component
|
||||
|
||||
Chat.propTypes =
|
||||
{
|
||||
roomClient : PropTypes.any.isRequired,
|
||||
senderPlaceHolder : PropTypes.string,
|
||||
onSendMessage : PropTypes.func,
|
||||
disabledInput : PropTypes.bool,
|
||||
autofocus : PropTypes.bool,
|
||||
displayName : PropTypes.string,
|
||||
@@ -71,27 +94,8 @@ const mapStateToProps = (state) =>
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) =>
|
||||
{
|
||||
return {
|
||||
onSendMessage : (event, displayName, picture) =>
|
||||
{
|
||||
event.preventDefault();
|
||||
const userInput = event.target.message.value;
|
||||
|
||||
if (userInput)
|
||||
{
|
||||
dispatch(stateActions.addUserMessage(userInput));
|
||||
dispatch(requestActions.sendChatMessage(userInput, displayName, picture));
|
||||
}
|
||||
event.target.message.value = '';
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const ChatContainer = connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Chat);
|
||||
const ChatContainer = withRoomContext(connect(
|
||||
mapStateToProps
|
||||
)(Chat));
|
||||
|
||||
export default ChatContainer;
|
||||
|
||||
@@ -30,41 +30,47 @@ class MessageList extends Component
|
||||
|
||||
return (
|
||||
<div data-component='MessageList' id='messages'>
|
||||
{ chatmessages.length > 0 ?
|
||||
chatmessages.map((message, i) =>
|
||||
{
|
||||
const messageTime = new Date(message.time);
|
||||
<Choose>
|
||||
<When condition={chatmessages.length > 0}>
|
||||
{
|
||||
chatmessages.map((message, i) =>
|
||||
{
|
||||
const messageTime = new Date(message.time);
|
||||
|
||||
const picture = (message.sender === 'response' ?
|
||||
message.picture : this.props.myPicture) || 'resources/images/avatar-empty.jpeg';
|
||||
const picture = (message.sender === 'response' ?
|
||||
message.picture : this.props.myPicture) || 'resources/images/avatar-empty.jpeg';
|
||||
|
||||
return (
|
||||
<div className='message' key={i}>
|
||||
<div className={message.sender}>
|
||||
<img className='message-avatar' src={picture} />
|
||||
return (
|
||||
<div className='message' key={i}>
|
||||
<div className={message.sender}>
|
||||
<img className='message-avatar' src={picture} />
|
||||
|
||||
<div className='message-content'>
|
||||
<div
|
||||
className='message-text'
|
||||
// eslint-disable-next-line react/no-danger
|
||||
dangerouslySetInnerHTML={{ __html : marked.parse(
|
||||
message.text,
|
||||
{ sanitize: true, renderer: linkRenderer }
|
||||
) }}
|
||||
/>
|
||||
<div className='message-content'>
|
||||
<div
|
||||
className='message-text'
|
||||
// eslint-disable-next-line react/no-danger
|
||||
dangerouslySetInnerHTML={{ __html : marked.parse(
|
||||
message.text,
|
||||
{ sanitize: true, renderer: linkRenderer }
|
||||
) }}
|
||||
/>
|
||||
|
||||
<span className='message-time'>
|
||||
{message.name} - {this.getTimeString(messageTime)}
|
||||
</span>
|
||||
<span className='message-time'>
|
||||
{message.name} - {this.getTimeString(messageTime)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
:<div className='empty'>
|
||||
<p>No one has said anything yet...</p>
|
||||
</div>
|
||||
}
|
||||
);
|
||||
})
|
||||
}
|
||||
</When>
|
||||
<Otherwise>
|
||||
<div className='empty'>
|
||||
<p>No one has said anything yet...</p>
|
||||
</div>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -110,29 +110,34 @@ class FileEntry extends Component
|
||||
<img className='file-avatar' src={this.props.data.picture || DEFAULT_PICTURE} />
|
||||
|
||||
<div className='file-content'>
|
||||
{this.props.data.me ? (
|
||||
<p>You shared a file.</p>
|
||||
) : (
|
||||
<p>{this.props.data.name} shared a file.</p>
|
||||
)}
|
||||
<Choose>
|
||||
<When condition={this.props.data.me}>
|
||||
<p>You shared a file.</p>
|
||||
</When>
|
||||
<Otherwise>
|
||||
<p>{this.props.data.name} shared a file.</p>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
|
||||
{!this.state.active && !this.state.files && (
|
||||
<If condition={!this.state.active && !this.state.files}>
|
||||
<div className='file-info'>
|
||||
{WebTorrent.WEBRTC_SUPPORT ? (
|
||||
<span className='button' onClick={this.handleDownload}>
|
||||
<img src='resources/images/download-icon.svg' />
|
||||
</span>
|
||||
) : (
|
||||
<p>
|
||||
Your browser does not support downloading files using WebTorrent.
|
||||
</p>
|
||||
)}
|
||||
|
||||
<Choose>
|
||||
<When condition={WebTorrent.WEBRTC_SUPPORT}>
|
||||
<span className='button' onClick={this.handleDownload}>
|
||||
<img src='resources/images/download-icon.svg' />
|
||||
</span>
|
||||
</When>
|
||||
<Otherwise>
|
||||
<p>
|
||||
Your browser does not support downloading files using WebTorrent.
|
||||
</p>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
<p>{magnet.decode(this.props.data.file.magnet).dn}</p>
|
||||
</div>
|
||||
)}
|
||||
</If>
|
||||
|
||||
{this.state.active && this.state.numPeers === 0 && (
|
||||
<If condition={this.state.active && this.state.numPeers === 0}>
|
||||
<Fragment>
|
||||
<p>
|
||||
Locating peers
|
||||
@@ -145,13 +150,13 @@ class FileEntry extends Component
|
||||
</p>
|
||||
)}
|
||||
</Fragment>
|
||||
)}
|
||||
</If>
|
||||
|
||||
{this.state.active && this.state.numPeers > 0 && (
|
||||
<If condition={this.state.active && this.state.numPeers > 0}>
|
||||
<progress value={this.state.progress} />
|
||||
)}
|
||||
</If>
|
||||
|
||||
{this.state.files && (
|
||||
<If condition={this.state.files}>
|
||||
<Fragment>
|
||||
<p>Torrent finished downloading.</p>
|
||||
|
||||
@@ -165,7 +170,7 @@ class FileEntry extends Component
|
||||
</div>
|
||||
))}
|
||||
</Fragment>
|
||||
)}
|
||||
</If>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -17,17 +17,23 @@ class SharedFilesList extends Component
|
||||
|
||||
return (
|
||||
<div className='shared-files'>
|
||||
{ sharing.length > 0 ?
|
||||
sharing.map((entry, i) => (
|
||||
<FileEntry
|
||||
data={entry}
|
||||
key={i}
|
||||
/>
|
||||
))
|
||||
:<div className='empty'>
|
||||
<p>No one has shared files yet...</p>
|
||||
</div>
|
||||
}
|
||||
<Choose>
|
||||
<When condition={sharing.length > 0}>
|
||||
{
|
||||
sharing.map((entry, i) => (
|
||||
<FileEntry
|
||||
data={entry}
|
||||
key={i}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</When>
|
||||
<Otherwise>
|
||||
<div className='empty'>
|
||||
<p>No one has shared files yet...</p>
|
||||
</div>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import ResizeObserver from 'resize-observer-polyfill';
|
||||
import { connect } from 'react-redux';
|
||||
import debounce from 'lodash/debounce';
|
||||
import classnames from 'classnames';
|
||||
import * as requestActions from '../redux/requestActions';
|
||||
import { withRoomContext } from '../RoomContext';
|
||||
import Peer from './Peer';
|
||||
import HiddenPeers from './HiddenPeers';
|
||||
|
||||
@@ -114,14 +114,20 @@ class Filmstrip extends Component
|
||||
|
||||
render()
|
||||
{
|
||||
const { peers, advancedMode, spotlights, spotlightsLength } = this.props;
|
||||
const {
|
||||
roomClient,
|
||||
peers,
|
||||
advancedMode,
|
||||
spotlights,
|
||||
spotlightsLength
|
||||
} = this.props;
|
||||
|
||||
const activePeerName = this.getActivePeerName();
|
||||
|
||||
return (
|
||||
<div data-component='Filmstrip'>
|
||||
<div className='active-peer-container' ref={this.activePeerContainer}>
|
||||
{peers[activePeerName] && (
|
||||
<If condition={peers[activePeerName]}>
|
||||
<div
|
||||
className='active-peer'
|
||||
style={{
|
||||
@@ -134,7 +140,7 @@ class Filmstrip extends Component
|
||||
name={activePeerName}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</If>
|
||||
</div>
|
||||
|
||||
<div className='filmstrip'>
|
||||
@@ -142,35 +148,37 @@ class Filmstrip extends Component
|
||||
{
|
||||
Object.keys(peers).map((peerName) =>
|
||||
{
|
||||
return (
|
||||
spotlights.find((spotlightsElement) => spotlightsElement === peerName)?
|
||||
<div
|
||||
key={peerName}
|
||||
onClick={() => this.props.setSelectedPeer(peerName)}
|
||||
className={classnames('film', {
|
||||
selected : this.props.selectedPeerName === peerName,
|
||||
active : this.state.lastSpeaker === peerName
|
||||
})}
|
||||
>
|
||||
<div className='film-content'>
|
||||
<Peer
|
||||
advancedMode={advancedMode}
|
||||
name={peerName}
|
||||
/>
|
||||
</div>
|
||||
<If
|
||||
condition={
|
||||
spotlights.find((spotlightsElement) => spotlightsElement === peerName)
|
||||
}
|
||||
>
|
||||
<div
|
||||
key={peerName}
|
||||
onClick={() => roomClient.setSelectedPeer(peerName)}
|
||||
className={classnames('film', {
|
||||
selected : this.props.selectedPeerName === peerName,
|
||||
active : this.state.lastSpeaker === peerName
|
||||
})}
|
||||
>
|
||||
<div className='film-content'>
|
||||
<Peer
|
||||
advancedMode={advancedMode}
|
||||
name={peerName}
|
||||
/>
|
||||
</div>
|
||||
:null
|
||||
);
|
||||
</div>
|
||||
</If>;
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div className='hidden-peer-container'>
|
||||
{ (spotlightsLength<Object.keys(peers).length)?
|
||||
<If condition={(spotlightsLength<Object.keys(peers).length)}>
|
||||
<HiddenPeers
|
||||
hiddenPeersCount={Object.keys(peers).length-spotlightsLength}
|
||||
/>:null
|
||||
}
|
||||
/>
|
||||
</If>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -179,13 +187,13 @@ class Filmstrip extends Component
|
||||
}
|
||||
|
||||
Filmstrip.propTypes = {
|
||||
roomClient : PropTypes.any.isRequired,
|
||||
activeSpeakerName : PropTypes.string,
|
||||
advancedMode : PropTypes.bool,
|
||||
peers : PropTypes.object.isRequired,
|
||||
consumers : PropTypes.object.isRequired,
|
||||
myName : PropTypes.string.isRequired,
|
||||
selectedPeerName : PropTypes.string,
|
||||
setSelectedPeer : PropTypes.func.isRequired,
|
||||
spotlightsLength : PropTypes.number,
|
||||
spotlights : PropTypes.array.isRequired
|
||||
};
|
||||
@@ -205,11 +213,7 @@ const mapStateToProps = (state) =>
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = {
|
||||
setSelectedPeer : requestActions.setSelectedPeer
|
||||
};
|
||||
|
||||
export default connect(
|
||||
export default withRoomContext(connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Filmstrip);
|
||||
undefined
|
||||
)(Filmstrip));
|
||||
|
||||
@@ -31,12 +31,11 @@ const FullScreenView = (props) =>
|
||||
|
||||
return (
|
||||
<div data-component='FullScreenView'>
|
||||
{consumerVisible && !consumer.supported ?
|
||||
<If condition={consumerVisible && !consumer.supported}>
|
||||
<div className='incompatible-video'>
|
||||
<p>incompatible video</p>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
|
||||
<div className='controls'>
|
||||
<div
|
||||
|
||||
@@ -35,12 +35,11 @@ export default class FullView extends React.Component
|
||||
muted={Boolean(true)}
|
||||
/>
|
||||
|
||||
{videoProfile === 'none' ?
|
||||
<If condition={videoProfile === 'none'}>
|
||||
<div className='spinner-container'>
|
||||
<Spinner />
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
+27
-45
@@ -5,7 +5,7 @@ import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
import { getDeviceInfo } from 'mediasoup-client';
|
||||
import * as appPropTypes from './appPropTypes';
|
||||
import * as requestActions from '../redux/requestActions';
|
||||
import { withRoomContext } from '../RoomContext';
|
||||
import PeerView from './PeerView';
|
||||
import ScreenView from './ScreenView';
|
||||
|
||||
@@ -46,17 +46,13 @@ class Me extends React.Component
|
||||
render()
|
||||
{
|
||||
const {
|
||||
roomClient,
|
||||
connected,
|
||||
me,
|
||||
advancedMode,
|
||||
micProducer,
|
||||
webcamProducer,
|
||||
screenProducer,
|
||||
onChangeDisplayName,
|
||||
onMuteMic,
|
||||
onUnmuteMic,
|
||||
onEnableWebcam,
|
||||
onDisableWebcam
|
||||
screenProducer
|
||||
} = this.props;
|
||||
|
||||
let micState;
|
||||
@@ -107,7 +103,7 @@ class Me extends React.Component
|
||||
onMouseOut={this.handleMouseOut}
|
||||
>
|
||||
<div className={classnames('view-container', 'webcam')}>
|
||||
{connected ?
|
||||
<If condition={connected}>
|
||||
<div className={classnames('controls', 'visible')}>
|
||||
<div
|
||||
data-tip='keyboard shortcut: ‘m‘'
|
||||
@@ -120,7 +116,9 @@ class Me extends React.Component
|
||||
})}
|
||||
onClick={() =>
|
||||
{
|
||||
micState === 'on' ? onMuteMic() : onUnmuteMic();
|
||||
micState === 'on' ?
|
||||
roomClient.muteMic() :
|
||||
roomClient.unmuteMic();
|
||||
}}
|
||||
/>
|
||||
<ReactTooltip
|
||||
@@ -134,12 +132,13 @@ class Me extends React.Component
|
||||
})}
|
||||
onClick={() =>
|
||||
{
|
||||
webcamState === 'on' ? onDisableWebcam() : onEnableWebcam();
|
||||
webcamState === 'on' ?
|
||||
roomClient.disableWebcam() :
|
||||
roomClient.enableWebcam();
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
|
||||
<PeerView
|
||||
isMe
|
||||
@@ -151,11 +150,14 @@ class Me extends React.Component
|
||||
videoVisible={videoVisible}
|
||||
audioCodec={micProducer ? micProducer.codec : null}
|
||||
videoCodec={webcamProducer ? webcamProducer.codec : null}
|
||||
onChangeDisplayName={(displayName) => onChangeDisplayName(displayName)}
|
||||
onChangeDisplayName={(displayName) =>
|
||||
{
|
||||
roomClient.changeDisplayName(displayName);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{screenProducer ?
|
||||
<If condition={screenProducer}>
|
||||
<div className={classnames('view-container', 'screen')}>
|
||||
<ScreenView
|
||||
isMe
|
||||
@@ -165,8 +167,7 @@ class Me extends React.Component
|
||||
screenCodec={screenProducer ? screenProducer.codec : null}
|
||||
/>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -204,17 +205,13 @@ class Me extends React.Component
|
||||
|
||||
Me.propTypes =
|
||||
{
|
||||
connected : PropTypes.bool.isRequired,
|
||||
advancedMode : PropTypes.bool,
|
||||
me : appPropTypes.Me.isRequired,
|
||||
micProducer : appPropTypes.Producer,
|
||||
webcamProducer : appPropTypes.Producer,
|
||||
screenProducer : appPropTypes.Producer,
|
||||
onChangeDisplayName : PropTypes.func.isRequired,
|
||||
onMuteMic : PropTypes.func.isRequired,
|
||||
onUnmuteMic : PropTypes.func.isRequired,
|
||||
onEnableWebcam : PropTypes.func.isRequired,
|
||||
onDisableWebcam : PropTypes.func.isRequired
|
||||
roomClient : PropTypes.any.isRequired,
|
||||
connected : PropTypes.bool.isRequired,
|
||||
advancedMode : PropTypes.bool,
|
||||
me : appPropTypes.Me.isRequired,
|
||||
micProducer : appPropTypes.Producer,
|
||||
webcamProducer : appPropTypes.Producer,
|
||||
screenProducer : appPropTypes.Producer
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
@@ -236,23 +233,8 @@ const mapStateToProps = (state) =>
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) =>
|
||||
{
|
||||
return {
|
||||
onChangeDisplayName : (displayName) =>
|
||||
{
|
||||
dispatch(requestActions.changeDisplayName(displayName));
|
||||
},
|
||||
onMuteMic : () => dispatch(requestActions.muteMic()),
|
||||
onUnmuteMic : () => dispatch(requestActions.unmuteMic()),
|
||||
onEnableWebcam : () => dispatch(requestActions.enableWebcam()),
|
||||
onDisableWebcam : () => dispatch(requestActions.disableWebcam())
|
||||
};
|
||||
};
|
||||
|
||||
const MeContainer = connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Me);
|
||||
const MeContainer = withRoomContext(connect(
|
||||
mapStateToProps
|
||||
)(Me));
|
||||
|
||||
export default MeContainer;
|
||||
|
||||
@@ -3,18 +3,15 @@ import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
import * as appPropTypes from '../appPropTypes';
|
||||
import * as requestActions from '../../redux/requestActions';
|
||||
import { withRoomContext } from '../../RoomContext';
|
||||
|
||||
const ListPeer = (props) =>
|
||||
{
|
||||
const {
|
||||
roomClient,
|
||||
peer,
|
||||
micConsumer,
|
||||
screenConsumer,
|
||||
onMuteMic,
|
||||
onUnmuteMic,
|
||||
onDisableScreen,
|
||||
onEnableScreen
|
||||
screenConsumer
|
||||
} = props;
|
||||
|
||||
const micEnabled = (
|
||||
@@ -39,7 +36,7 @@ const ListPeer = (props) =>
|
||||
{peer.displayName}
|
||||
</div>
|
||||
<div className='indicators'>
|
||||
{peer.raiseHandState ?
|
||||
<If condition={peer.raiseHandState}>
|
||||
<div className={
|
||||
classnames(
|
||||
'icon', 'raise-hand', {
|
||||
@@ -49,14 +46,13 @@ const ListPeer = (props) =>
|
||||
)
|
||||
}
|
||||
/>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
<div className='volume-container'>
|
||||
<div className={classnames('bar', `level${micEnabled && micConsumer ? micConsumer.volume:0}`)} />
|
||||
</div>
|
||||
<div className='controls'>
|
||||
{ screenConsumer ?
|
||||
<If condition={screenConsumer}>
|
||||
<div
|
||||
className={classnames('button', 'screen', {
|
||||
on : screenVisible,
|
||||
@@ -67,11 +63,11 @@ const ListPeer = (props) =>
|
||||
{
|
||||
e.stopPropagation();
|
||||
screenVisible ?
|
||||
onDisableScreen(peer.name) : onEnableScreen(peer.name);
|
||||
roomClient.pausePeerScreen(peer.name) :
|
||||
roomClient.resumePeerScreen(peer.name);
|
||||
}}
|
||||
/>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
<div
|
||||
className={classnames('button', 'mic', {
|
||||
on : micEnabled,
|
||||
@@ -81,7 +77,9 @@ const ListPeer = (props) =>
|
||||
onClick={(e) =>
|
||||
{
|
||||
e.stopPropagation();
|
||||
micEnabled ? onMuteMic(peer.name) : onUnmuteMic(peer.name);
|
||||
micEnabled ?
|
||||
roomClient.mutePeerAudio(peer.name) :
|
||||
roomClient.unmutePeerAudio(peer.name);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@@ -91,17 +89,12 @@ const ListPeer = (props) =>
|
||||
|
||||
ListPeer.propTypes =
|
||||
{
|
||||
advancedMode : PropTypes.bool,
|
||||
peer : appPropTypes.Peer.isRequired,
|
||||
micConsumer : appPropTypes.Consumer,
|
||||
webcamConsumer : appPropTypes.Consumer,
|
||||
screenConsumer : appPropTypes.Consumer,
|
||||
onMuteMic : PropTypes.func.isRequired,
|
||||
onUnmuteMic : PropTypes.func.isRequired,
|
||||
onEnableWebcam : PropTypes.func.isRequired,
|
||||
onDisableWebcam : PropTypes.func.isRequired,
|
||||
onEnableScreen : PropTypes.func.isRequired,
|
||||
onDisableScreen : PropTypes.func.isRequired
|
||||
roomClient : PropTypes.any.isRequired,
|
||||
advancedMode : PropTypes.bool,
|
||||
peer : appPropTypes.Peer.isRequired,
|
||||
micConsumer : appPropTypes.Consumer,
|
||||
webcamConsumer : appPropTypes.Consumer,
|
||||
screenConsumer : appPropTypes.Consumer
|
||||
};
|
||||
|
||||
const mapStateToProps = (state, { name }) =>
|
||||
@@ -124,40 +117,8 @@ const mapStateToProps = (state, { name }) =>
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) =>
|
||||
{
|
||||
return {
|
||||
onMuteMic : (peerName) =>
|
||||
{
|
||||
dispatch(requestActions.mutePeerAudio(peerName));
|
||||
},
|
||||
onUnmuteMic : (peerName) =>
|
||||
{
|
||||
dispatch(requestActions.unmutePeerAudio(peerName));
|
||||
},
|
||||
onEnableWebcam : (peerName) =>
|
||||
{
|
||||
|
||||
dispatch(requestActions.resumePeerVideo(peerName));
|
||||
},
|
||||
onDisableWebcam : (peerName) =>
|
||||
{
|
||||
dispatch(requestActions.pausePeerVideo(peerName));
|
||||
},
|
||||
onEnableScreen : (peerName) =>
|
||||
{
|
||||
dispatch(requestActions.resumePeerScreen(peerName));
|
||||
},
|
||||
onDisableScreen : (peerName) =>
|
||||
{
|
||||
dispatch(requestActions.pausePeerScreen(peerName));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const ListPeerContainer = connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(ListPeer);
|
||||
const ListPeerContainer = withRoomContext(connect(
|
||||
mapStateToProps
|
||||
)(ListPeer));
|
||||
|
||||
export default ListPeerContainer;
|
||||
|
||||
@@ -2,16 +2,16 @@ import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import classNames from 'classnames';
|
||||
import * as appPropTypes from '../appPropTypes';
|
||||
import * as requestActions from '../../redux/requestActions';
|
||||
import { withRoomContext } from '../../RoomContext';
|
||||
import PropTypes from 'prop-types';
|
||||
import ListPeer from './ListPeer';
|
||||
import ListMe from './ListMe';
|
||||
|
||||
const ParticipantList =
|
||||
({
|
||||
roomClient,
|
||||
advancedMode,
|
||||
peers,
|
||||
setSelectedPeer,
|
||||
selectedPeerName,
|
||||
spotlights
|
||||
}) => (
|
||||
@@ -33,7 +33,7 @@ const ParticipantList =
|
||||
className={classNames('list-item', {
|
||||
selected : peer.name === selectedPeerName
|
||||
})}
|
||||
onClick={() => setSelectedPeer(peer.name)}
|
||||
onClick={() => roomClient.setSelectedPeer(peer.name)}
|
||||
>
|
||||
<ListPeer name={peer.name} advancedMode={advancedMode} />
|
||||
</li>
|
||||
@@ -52,7 +52,7 @@ const ParticipantList =
|
||||
className={classNames('list-item', {
|
||||
selected : peer.name === selectedPeerName
|
||||
})}
|
||||
onClick={() => setSelectedPeer(peer.name)}
|
||||
onClick={() => roomClient.setSelectedPeer(peer.name)}
|
||||
>
|
||||
<ListPeer name={peer.name} advancedMode={advancedMode} />
|
||||
</li>
|
||||
@@ -64,9 +64,9 @@ const ParticipantList =
|
||||
|
||||
ParticipantList.propTypes =
|
||||
{
|
||||
roomClient : PropTypes.any.isRequired,
|
||||
advancedMode : PropTypes.bool,
|
||||
peers : PropTypes.arrayOf(appPropTypes.Peer).isRequired,
|
||||
setSelectedPeer : PropTypes.func.isRequired,
|
||||
selectedPeerName : PropTypes.string,
|
||||
spotlights : PropTypes.array.isRequired
|
||||
};
|
||||
@@ -82,13 +82,8 @@ const mapStateToProps = (state) =>
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = {
|
||||
setSelectedPeer : requestActions.setSelectedPeer
|
||||
};
|
||||
|
||||
const ParticipantListContainer = connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(ParticipantList);
|
||||
const ParticipantListContainer = withRoomContext(connect(
|
||||
mapStateToProps
|
||||
)(ParticipantList));
|
||||
|
||||
export default ParticipantListContainer;
|
||||
|
||||
+16
-28
@@ -3,7 +3,7 @@ import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
import * as appPropTypes from './appPropTypes';
|
||||
import * as requestActions from '../redux/requestActions';
|
||||
import { withRoomContext } from '../RoomContext';
|
||||
import * as stateActions from '../redux/stateActions';
|
||||
import PeerView from './PeerView';
|
||||
import ScreenView from './ScreenView';
|
||||
@@ -31,13 +31,12 @@ class Peer extends Component
|
||||
render()
|
||||
{
|
||||
const {
|
||||
roomClient,
|
||||
advancedMode,
|
||||
peer,
|
||||
micConsumer,
|
||||
webcamConsumer,
|
||||
screenConsumer,
|
||||
onMuteMic,
|
||||
onUnmuteMic,
|
||||
toggleConsumerFullscreen,
|
||||
toggleConsumerWindow,
|
||||
style,
|
||||
@@ -81,23 +80,21 @@ class Peer extends Component
|
||||
onMouseOver={this.handleMouseOver}
|
||||
onMouseOut={this.handleMouseOut}
|
||||
>
|
||||
{videoVisible && !webcamConsumer.supported ?
|
||||
<If condition={videoVisible && !webcamConsumer.supported}>
|
||||
<div className='incompatible-video'>
|
||||
<p>incompatible video</p>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
|
||||
{!videoVisible ?
|
||||
<If condition={!videoVisible}>
|
||||
<div className='paused-video'>
|
||||
<p>this video is paused</p>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
|
||||
<div className={classnames('view-container', 'webcam')} style={style}>
|
||||
<div className='indicators'>
|
||||
{peer.raiseHandState ?
|
||||
<If condition={peer.raiseHandState}>
|
||||
<div className={
|
||||
classnames(
|
||||
'icon', 'raise-hand', {
|
||||
@@ -107,8 +104,7 @@ class Peer extends Component
|
||||
)
|
||||
}
|
||||
/>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
<div
|
||||
className={classnames('controls', {
|
||||
@@ -124,7 +120,9 @@ class Peer extends Component
|
||||
onClick={(e) =>
|
||||
{
|
||||
e.stopPropagation();
|
||||
micEnabled ? onMuteMic(peer.name) : onUnmuteMic(peer.name);
|
||||
micEnabled ?
|
||||
roomClient.mutePeerAudio(peer.name) :
|
||||
roomClient.unmutePeerAudio(peer.name);
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -162,7 +160,7 @@ class Peer extends Component
|
||||
/>
|
||||
</div>
|
||||
|
||||
{screenConsumer ?
|
||||
<If condition={screenConsumer}>
|
||||
<div className={classnames('view-container', 'screen')} style={style}>
|
||||
<div
|
||||
className={classnames('controls', {
|
||||
@@ -195,8 +193,7 @@ class Peer extends Component
|
||||
screenCodec={screenConsumer ? screenConsumer.codec : null}
|
||||
/>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -204,14 +201,13 @@ class Peer extends Component
|
||||
|
||||
Peer.propTypes =
|
||||
{
|
||||
roomClient : PropTypes.any.isRequired,
|
||||
advancedMode : PropTypes.bool,
|
||||
peer : appPropTypes.Peer.isRequired,
|
||||
micConsumer : appPropTypes.Consumer,
|
||||
webcamConsumer : appPropTypes.Consumer,
|
||||
screenConsumer : appPropTypes.Consumer,
|
||||
windowConsumer : PropTypes.number,
|
||||
onMuteMic : PropTypes.func.isRequired,
|
||||
onUnmuteMic : PropTypes.func.isRequired,
|
||||
streamDimensions : PropTypes.object,
|
||||
style : PropTypes.object,
|
||||
toggleConsumerFullscreen : PropTypes.func.isRequired,
|
||||
@@ -242,14 +238,6 @@ const mapStateToProps = (state, { name }) =>
|
||||
const mapDispatchToProps = (dispatch) =>
|
||||
{
|
||||
return {
|
||||
onMuteMic : (peerName) =>
|
||||
{
|
||||
dispatch(requestActions.mutePeerAudio(peerName));
|
||||
},
|
||||
onUnmuteMic : (peerName) =>
|
||||
{
|
||||
dispatch(requestActions.unmutePeerAudio(peerName));
|
||||
},
|
||||
toggleConsumerFullscreen : (consumer) =>
|
||||
{
|
||||
if (consumer)
|
||||
@@ -263,9 +251,9 @@ const mapDispatchToProps = (dispatch) =>
|
||||
};
|
||||
};
|
||||
|
||||
const PeerContainer = connect(
|
||||
const PeerContainer = withRoomContext(connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Peer);
|
||||
)(Peer));
|
||||
|
||||
export default PeerContainer;
|
||||
|
||||
@@ -52,51 +52,50 @@ export default class PeerView extends React.Component
|
||||
return (
|
||||
<div data-component='PeerView'>
|
||||
<div className='info'>
|
||||
{advancedMode ?
|
||||
<If condition={advancedMode}>
|
||||
<div className={classnames('media', { 'is-me': isMe })}>
|
||||
<div className='box'>
|
||||
{audioCodec ?
|
||||
<If condition={audioCodec}>
|
||||
<p className='codec'>{audioCodec}</p>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
|
||||
{videoCodec ?
|
||||
<If condition={videoCodec}>
|
||||
<p className='codec'>{videoCodec} {videoProfile}</p>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
|
||||
{(videoVisible && videoWidth !== null) ?
|
||||
<If condition={(videoVisible && videoWidth !== null)}>
|
||||
<p className='resolution'>{videoWidth}x{videoHeight}</p>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
|
||||
<div className={classnames('peer', { 'is-me': isMe })}>
|
||||
{isMe ?
|
||||
<EditableInput
|
||||
value={peer.displayName}
|
||||
propName='displayName'
|
||||
className='display-name editable'
|
||||
classLoading='loading'
|
||||
classInvalid='invalid'
|
||||
shouldBlockWhileLoading
|
||||
editProps={{
|
||||
maxLength : 20,
|
||||
autoCorrect : false,
|
||||
spellCheck : false
|
||||
}}
|
||||
onChange={({ displayName }) => onChangeDisplayName(displayName)}
|
||||
/>
|
||||
:
|
||||
<span className='display-name'>
|
||||
{peer.displayName}
|
||||
</span>
|
||||
}
|
||||
<Choose>
|
||||
<When condition={isMe}>
|
||||
<EditableInput
|
||||
value={peer.displayName}
|
||||
propName='displayName'
|
||||
className='display-name editable'
|
||||
classLoading='loading'
|
||||
classInvalid='invalid'
|
||||
shouldBlockWhileLoading
|
||||
editProps={{
|
||||
maxLength : 20,
|
||||
autoCorrect : false,
|
||||
spellCheck : false
|
||||
}}
|
||||
onChange={({ displayName }) => onChangeDisplayName(displayName)}
|
||||
/>
|
||||
</When>
|
||||
<Otherwise>
|
||||
<span className='display-name'>
|
||||
{peer.displayName}
|
||||
</span>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
|
||||
{advancedMode ?
|
||||
<If condition={advancedMode}>
|
||||
<div className='row'>
|
||||
<span
|
||||
className={classnames('device-icon', peer.device.flag)}
|
||||
@@ -105,8 +104,7 @@ export default class PeerView extends React.Component
|
||||
{peer.device.name} {Math.floor(peer.device.version) || null}
|
||||
</span>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -125,12 +123,11 @@ export default class PeerView extends React.Component
|
||||
<div className={classnames('bar', `level${volume}`)} />
|
||||
</div>
|
||||
|
||||
{videoProfile === 'none' ?
|
||||
<If condition={videoProfile === 'none'}>
|
||||
<div className='spinner-container'>
|
||||
<Spinner />
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -108,35 +108,36 @@ class Peers extends React.Component
|
||||
{
|
||||
peers.map((peer) =>
|
||||
{
|
||||
return (
|
||||
(spotlights.find(function(spotlightsElement)
|
||||
{ return spotlightsElement == peer.name; }))?
|
||||
<Appear key={peer.name} duration={1000}>
|
||||
<div
|
||||
className={classnames('peer-container', {
|
||||
'selected' : this.props.selectedPeerName === peer.name,
|
||||
'active-speaker' : peer.name === activeSpeakerName
|
||||
})}
|
||||
>
|
||||
<div className='peer-content'>
|
||||
<Peer
|
||||
advancedMode={advancedMode}
|
||||
name={peer.name}
|
||||
style={style}
|
||||
/>
|
||||
</div>
|
||||
<If
|
||||
condition={
|
||||
spotlights.find((spotlightsElement) => spotlightsElement === peer.name)
|
||||
}
|
||||
>
|
||||
<Appear key={peer.name} duration={1000}>
|
||||
<div
|
||||
className={classnames('peer-container', {
|
||||
'selected' : this.props.selectedPeerName === peer.name,
|
||||
'active-speaker' : peer.name === activeSpeakerName
|
||||
})}
|
||||
>
|
||||
<div className='peer-content'>
|
||||
<Peer
|
||||
advancedMode={advancedMode}
|
||||
name={peer.name}
|
||||
style={style}
|
||||
/>
|
||||
</div>
|
||||
</Appear>
|
||||
:null
|
||||
);
|
||||
</div>
|
||||
</Appear>
|
||||
</If>;
|
||||
})
|
||||
}
|
||||
<div className='hidden-peer-container'>
|
||||
{ (spotlightsLength<peers.length)?
|
||||
<If condition={spotlightsLength < peers.length}>
|
||||
<HiddenPeers
|
||||
hiddenPeersCount={peers.length-spotlightsLength}
|
||||
/>:null
|
||||
}
|
||||
/>
|
||||
</If>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -13,7 +13,6 @@ import Me from './Me';
|
||||
import Peers from './Peers';
|
||||
import AudioPeers from './PeerAudio/AudioPeers';
|
||||
import Notifications from './Notifications';
|
||||
// import ToolAreaButton from './ToolArea/ToolAreaButton';
|
||||
import ToolArea from './ToolArea/ToolArea';
|
||||
import FullScreenView from './FullScreenView';
|
||||
import VideoWindow from './VideoWindow/VideoWindow';
|
||||
@@ -97,13 +96,12 @@ class Room extends React.Component
|
||||
|
||||
<Notifications />
|
||||
|
||||
{room.advancedMode ?
|
||||
<If condition={room.advancedMode}>
|
||||
<div className='state' data-tip='Server status'>
|
||||
<div className={classnames('icon', room.state)} />
|
||||
<p className={classnames('text', room.state)}>{room.state}</p>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
|
||||
<div
|
||||
className={classnames('room-link-wrapper room-controls', {
|
||||
|
||||
@@ -41,25 +41,21 @@ export default class ScreenView extends React.Component
|
||||
return (
|
||||
<div data-component='ScreenView'>
|
||||
<div className='info'>
|
||||
{advancedMode ?
|
||||
<If condition={advancedMode}>
|
||||
<div className={classnames('media', { 'is-me': isMe })}>
|
||||
{screenVisible ?
|
||||
<If condition={screenVisible}>
|
||||
<div className='box'>
|
||||
{screenCodec ?
|
||||
<If condition={screenCodec}>
|
||||
<p className='codec'>{screenCodec} {screenProfile}</p>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
|
||||
{(screenVisible && screenWidth !== null) ?
|
||||
<If condition={(screenVisible && screenWidth !== null)}>
|
||||
<p className='resolution'>{screenWidth}x{screenHeight}</p>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
|
||||
<video
|
||||
@@ -73,12 +69,11 @@ export default class ScreenView extends React.Component
|
||||
muted={Boolean(true)}
|
||||
/>
|
||||
|
||||
{screenProfile === 'none' ?
|
||||
<If condition={screenProfile === 'none'}>
|
||||
<div className='spinner-container'>
|
||||
<Spinner />
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import * as appPropTypes from './appPropTypes';
|
||||
import * as requestActions from '../redux/requestActions';
|
||||
import { withRoomContext } from '../RoomContext';
|
||||
import * as stateActions from '../redux/stateActions';
|
||||
import PropTypes from 'prop-types';
|
||||
import Dropdown from 'react-dropdown';
|
||||
@@ -18,8 +18,11 @@ const modes = [ {
|
||||
const findOption = (options, value) => options.find((option) => option.value === value);
|
||||
|
||||
const Settings = ({
|
||||
room, me, onToggleAdvancedMode, handleChangeWebcam,
|
||||
handleChangeAudioDevice, handleChangeMode
|
||||
roomClient,
|
||||
room,
|
||||
me,
|
||||
onToggleAdvancedMode,
|
||||
handleChangeMode
|
||||
}) =>
|
||||
{
|
||||
let webcams;
|
||||
@@ -48,7 +51,7 @@ const Settings = ({
|
||||
<Dropdown
|
||||
options={webcams}
|
||||
value={findOption(webcams, me.selectedWebcam)}
|
||||
onChange={(webcam) => handleChangeWebcam(webcam.value)}
|
||||
onChange={(webcam) => roomClient.changeWebcam(webcam.value)}
|
||||
placeholder={'Select camera'}
|
||||
/>
|
||||
|
||||
@@ -56,7 +59,7 @@ const Settings = ({
|
||||
disabled={!me.canChangeAudioDevice}
|
||||
options={audioDevices}
|
||||
value={findOption(audioDevices, me.selectedAudioDevice)}
|
||||
onChange={(device) => handleChangeAudioDevice(device.value)}
|
||||
onChange={(device) => roomClient.changeAudioDevice(device.value)}
|
||||
placeholder={audioDevicesText}
|
||||
/>
|
||||
<ReactTooltip
|
||||
@@ -94,12 +97,11 @@ const Settings = ({
|
||||
|
||||
Settings.propTypes =
|
||||
{
|
||||
me : appPropTypes.Me.isRequired,
|
||||
room : appPropTypes.Room.isRequired,
|
||||
handleChangeWebcam : PropTypes.func.isRequired,
|
||||
handleChangeAudioDevice : PropTypes.func.isRequired,
|
||||
onToggleAdvancedMode : PropTypes.func.isRequired,
|
||||
handleChangeMode : PropTypes.func.isRequired
|
||||
roomClient : PropTypes.any.isRequired,
|
||||
me : appPropTypes.Me.isRequired,
|
||||
room : appPropTypes.Room.isRequired,
|
||||
onToggleAdvancedMode : PropTypes.func.isRequired,
|
||||
handleChangeMode : PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
@@ -111,15 +113,13 @@ const mapStateToProps = (state) =>
|
||||
};
|
||||
|
||||
const mapDispatchToProps = {
|
||||
handleChangeWebcam : requestActions.changeWebcam,
|
||||
handleChangeAudioDevice : requestActions.changeAudioDevice,
|
||||
onToggleAdvancedMode : stateActions.toggleAdvancedMode,
|
||||
handleChangeMode : stateActions.setDisplayMode
|
||||
onToggleAdvancedMode : stateActions.toggleAdvancedMode,
|
||||
handleChangeMode : stateActions.setDisplayMode
|
||||
};
|
||||
|
||||
const SettingsContainer = connect(
|
||||
const SettingsContainer = withRoomContext(connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Settings);
|
||||
)(Settings));
|
||||
|
||||
export default SettingsContainer;
|
||||
|
||||
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import classnames from 'classnames';
|
||||
import * as appPropTypes from './appPropTypes';
|
||||
import * as requestActions from '../redux/requestActions';
|
||||
import { withRoomContext } from '../RoomContext';
|
||||
import FullScreen from './FullScreen';
|
||||
|
||||
class Sidebar extends Component
|
||||
@@ -56,8 +56,10 @@ class Sidebar extends Component
|
||||
render()
|
||||
{
|
||||
const {
|
||||
toolbarsVisible, me, screenProducer, onLogin, onShareScreen,
|
||||
onUnShareScreen, onNeedExtension, onLeaveMeeting, onLogout, onToggleHand
|
||||
roomClient,
|
||||
toolbarsVisible,
|
||||
me,
|
||||
screenProducer
|
||||
} = this.props;
|
||||
|
||||
let screenState;
|
||||
@@ -91,7 +93,7 @@ class Sidebar extends Component
|
||||
})}
|
||||
data-component='Sidebar'
|
||||
>
|
||||
{this.fullscreen.fullscreenEnabled && (
|
||||
<If condition={this.fullscreen.fullscreenEnabled}>
|
||||
<div
|
||||
className={classnames('button', 'fullscreen', {
|
||||
on : this.state.fullscreen
|
||||
@@ -101,7 +103,7 @@ class Sidebar extends Component
|
||||
data-place='right'
|
||||
data-type='dark'
|
||||
/>
|
||||
)}
|
||||
</If>
|
||||
|
||||
<div
|
||||
className={classnames('button', 'screen', screenState)}
|
||||
@@ -114,17 +116,17 @@ class Sidebar extends Component
|
||||
{
|
||||
case 'on':
|
||||
{
|
||||
onUnShareScreen();
|
||||
roomClient.disableScreenSharing();
|
||||
break;
|
||||
}
|
||||
case 'off':
|
||||
{
|
||||
onShareScreen();
|
||||
roomClient.enableScreenSharing();
|
||||
break;
|
||||
}
|
||||
case 'need-extension':
|
||||
{
|
||||
onNeedExtension();
|
||||
roomClient.installExtension();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -135,25 +137,30 @@ class Sidebar extends Component
|
||||
}}
|
||||
/>
|
||||
|
||||
{me.loginEnabled && (me.loggedIn ? (
|
||||
<div
|
||||
className='button logout'
|
||||
data-tip='Logout'
|
||||
data-place='right'
|
||||
data-type='dark'
|
||||
onClick={onLogout}
|
||||
>
|
||||
<img src={me.picture || 'resources/images/avatar-empty.jpeg'} />
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
className='button login off'
|
||||
data-tip='Login'
|
||||
data-place='right'
|
||||
data-type='dark'
|
||||
onClick={onLogin}
|
||||
/>
|
||||
))}
|
||||
<If condition={me.loginEnabled}>
|
||||
<Choose>
|
||||
<When condition={me.loggedIn}>
|
||||
<div
|
||||
className='button logout'
|
||||
data-tip='Logout'
|
||||
data-place='right'
|
||||
data-type='dark'
|
||||
onClick={() => roomClient.logout()}
|
||||
>
|
||||
<img src={me.picture || 'resources/images/avatar-empty.jpeg'} />
|
||||
</div>
|
||||
</When>
|
||||
<Otherwise>
|
||||
<div
|
||||
className='button login off'
|
||||
data-tip='Login'
|
||||
data-place='right'
|
||||
data-type='dark'
|
||||
onClick={() => roomClient.login()}
|
||||
/>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
</If>
|
||||
<div
|
||||
className={classnames('button', 'raise-hand', {
|
||||
on : me.raiseHand,
|
||||
@@ -162,7 +169,7 @@ class Sidebar extends Component
|
||||
data-tip='Raise hand'
|
||||
data-place='right'
|
||||
data-type='dark'
|
||||
onClick={() => onToggleHand(!me.raiseHand)}
|
||||
onClick={() => roomClient.sendRaiseHandState(!me.raiseHand)}
|
||||
/>
|
||||
|
||||
<div
|
||||
@@ -170,7 +177,7 @@ class Sidebar extends Component
|
||||
data-tip='Leave meeting'
|
||||
data-place='right'
|
||||
data-type='dark'
|
||||
onClick={() => onLeaveMeeting()}
|
||||
onClick={() => roomClient.close()}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@@ -178,15 +185,9 @@ class Sidebar extends Component
|
||||
}
|
||||
|
||||
Sidebar.propTypes = {
|
||||
roomClient : PropTypes.any.isRequired,
|
||||
toolbarsVisible : PropTypes.bool.isRequired,
|
||||
me : appPropTypes.Me.isRequired,
|
||||
onShareScreen : PropTypes.func.isRequired,
|
||||
onUnShareScreen : PropTypes.func.isRequired,
|
||||
onNeedExtension : PropTypes.func.isRequired,
|
||||
onToggleHand : PropTypes.func.isRequired,
|
||||
onLeaveMeeting : PropTypes.func.isRequired,
|
||||
onLogin : PropTypes.func.isRequired,
|
||||
onLogout : PropTypes.func.isRequired,
|
||||
screenProducer : appPropTypes.Producer
|
||||
};
|
||||
|
||||
@@ -198,17 +199,6 @@ const mapStateToProps = (state) =>
|
||||
me : state.me
|
||||
});
|
||||
|
||||
const mapDispatchToProps = {
|
||||
onLeaveMeeting : requestActions.leaveRoom,
|
||||
onShareScreen : requestActions.enableScreenSharing,
|
||||
onUnShareScreen : requestActions.disableScreenSharing,
|
||||
onNeedExtension : requestActions.installExtension,
|
||||
onToggleHand : requestActions.toggleHand,
|
||||
onLogin : requestActions.userLogin,
|
||||
onLogout : requestActions.userLogout
|
||||
};
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Sidebar);
|
||||
export default withRoomContext(connect(
|
||||
mapStateToProps
|
||||
)(Sidebar));
|
||||
|
||||
Reference in New Issue
Block a user