From 513f0efa0ba059c91540417f2d3a2bae438e1f2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5var=20Aamb=C3=B8=20Fosstveit?= Date: Wed, 16 Oct 2019 14:09:29 +0200 Subject: [PATCH] First working version of lobby. --- app/src/RoomClient.js | 45 ++++++- app/src/actions/stateActions.js | 8 ++ app/src/components/JoinDialog.js | 55 +++++++- .../ParticipantList/ListLobbyPeer.js | 117 ++---------------- .../ParticipantList/ParticipantList.js | 5 +- app/src/reducers/lobbyPeers.js | 9 +- app/src/reducers/rootReducer.js | 2 + server/lib/Lobby.js | 55 +++++++- server/lib/Room.js | 29 +++++ 9 files changed, 207 insertions(+), 118 deletions(-) diff --git a/app/src/RoomClient.js b/app/src/RoomClient.js index 0f77197..1435dc1 100644 --- a/app/src/RoomClient.js +++ b/app/src/RoomClient.js @@ -934,6 +934,26 @@ export default class RoomClient stateActions.setSelectedPeer(peerId)); } + async promoteLobbyPeer(peerId) + { + logger.debug('promoteLobbyPeer() [peerId:"%s"]', peerId); + + store.dispatch( + stateActions.setLobbyPeerPromotionInProgress(peerId, true)); + + try + { + await this.sendRequest('promotePeer', { peerId }); + } + catch (error) + { + logger.error('promoteLobbyPeer() failed: %o', error); + } + + store.dispatch( + stateActions.setLobbyPeerPromotionInProgress(peerId, false)); + } + // type: mic/webcam/screen // mute: true/false async modifyPeerConsumer(peerId, type, mute) @@ -1243,6 +1263,14 @@ export default class RoomClient switch (notification.method) { + case 'enteredLobby': + { + const { displayName } = store.getState().settings; + + await this.sendRequest('changeDisplayName', { displayName }); + break; + } + case 'roomReady': { await this._joinRoom({ joinVideo }); @@ -1298,6 +1326,21 @@ export default class RoomClient break; } + case 'lobbyPeerClosed': + { + const { peerId } = notification.data; + + store.dispatch( + stateActions.removeLobbyPeer(peerId)); + + store.dispatch(requestActions.notify( + { + text : 'Participant in lobby left.' + })); + + break; + } + case 'promotedPeer': { const { peerId } = notification.data; @@ -1308,7 +1351,7 @@ export default class RoomClient break; } - case 'parkedPeerDisplayName': + case 'lobbyPeerDisplayNameChanged': { const { peerId, displayName } = notification.data; diff --git a/app/src/actions/stateActions.js b/app/src/actions/stateActions.js index 7908b99..24f6870 100644 --- a/app/src/actions/stateActions.js +++ b/app/src/actions/stateActions.js @@ -415,6 +415,14 @@ export const setLobbyPeerDisplayName = (displayName, peerId) => }; }; +export const setLobbyPeerPromotionInProgress = (peerId, flag) => +{ + return { + type : 'SET_LOBBY_PEER_PROMOTION_IN_PROGRESS', + payload : { peerId, flag } + }; +}; + export const addNotification = (notification) => { return { diff --git a/app/src/components/JoinDialog.js b/app/src/components/JoinDialog.js index ae11771..c5bca93 100644 --- a/app/src/components/JoinDialog.js +++ b/app/src/components/JoinDialog.js @@ -1,11 +1,14 @@ import React from 'react'; +import { connect } from 'react-redux'; import { withStyles } from '@material-ui/core/styles'; import { withRoomContext } from '../RoomContext'; +import * as stateActions from '../actions/stateActions'; import PropTypes from 'prop-types'; import Dialog from '@material-ui/core/Dialog'; import Typography from '@material-ui/core/Typography'; import DialogActions from '@material-ui/core/DialogActions'; import Button from '@material-ui/core/Button'; +import TextField from '@material-ui/core/TextField'; const styles = (theme) => ({ @@ -41,6 +44,8 @@ const styles = (theme) => const JoinDialog = ({ roomClient, + displayName, + changeDisplayName, classes }) => { @@ -76,6 +81,19 @@ const JoinDialog = ({ > Audio and Video + + { + const { value } = event.target; + + changeDisplayName(value); + }} + margin='normal' + /> ); @@ -83,8 +101,39 @@ const JoinDialog = ({ JoinDialog.propTypes = { - roomClient : PropTypes.any.isRequired, - classes : PropTypes.object.isRequired + roomClient : PropTypes.any.isRequired, + displayName : PropTypes.string.isRequired, + changeDisplayName : PropTypes.func.isRequired, + classes : PropTypes.object.isRequired }; -export default withRoomContext(withStyles(styles)(JoinDialog)); \ No newline at end of file +const mapStateToProps = (state) => +{ + return { + displayName : state.settings.displayName + }; +}; + +const mapDispatchToProps = (dispatch) => +{ + return { + changeDisplayName : (displayName) => + { + dispatch(stateActions.setDisplayName(displayName)); + } + }; +}; + +export default withRoomContext(connect( + mapStateToProps, + mapDispatchToProps, + null, + { + areStatesEqual : (next, prev) => + { + return ( + prev.settings.displayName === next.settings.displayName + ); + } + } +)(withStyles(styles)(JoinDialog))); \ No newline at end of file diff --git a/app/src/components/MeetingDrawer/ParticipantList/ListLobbyPeer.js b/app/src/components/MeetingDrawer/ParticipantList/ListLobbyPeer.js index 7bc6178..85b0136 100644 --- a/app/src/components/MeetingDrawer/ParticipantList/ListLobbyPeer.js +++ b/app/src/components/MeetingDrawer/ParticipantList/ListLobbyPeer.js @@ -3,10 +3,9 @@ import { connect } from 'react-redux'; import { withStyles } from '@material-ui/core/styles'; import PropTypes from 'prop-types'; import classnames from 'classnames'; -import * as appPropTypes from '../../appPropTypes'; import { withRoomContext } from '../../../RoomContext'; import EmptyAvatar from '../../../images/avatar-empty.jpeg'; -import HandIcon from '../../../images/icon-hand-white.svg'; +import PromoteIcon from '@material-ui/icons/OpenInBrowser'; const styles = (theme) => ({ @@ -18,10 +17,6 @@ const styles = (theme) => cursor : 'auto', display : 'flex' }, - listPeer : - { - display : 'flex' - }, avatar : { borderRadius : '50%', @@ -36,47 +31,6 @@ const styles = (theme) => flexGrow : 1, alignItems : 'center' }, - indicators : - { - left : 0, - top : 0, - display : 'flex', - flexDirection : 'row', - justifyContent : 'flex-start', - alignItems : 'center', - transition : 'opacity 0.3s' - }, - icon : - { - flex : '0 0 auto', - margin : '0.3rem', - borderRadius : 2, - backgroundPosition : 'center', - backgroundSize : '75%', - backgroundRepeat : 'no-repeat', - backgroundColor : 'rgba(0, 0, 0, 0.5)', - transitionProperty : 'opacity, background-color', - transitionDuration : '0.15s', - width : 'var(--media-control-button-size)', - height : 'var(--media-control-button-size)', - opacity : 0.85, - '&:hover' : - { - opacity : 1 - }, - '&.on' : - { - opacity : 1 - }, - '&.off' : - { - opacity : 0.2 - }, - '&.raise-hand' : - { - backgroundImage : `url(${HandIcon})` - } - }, controls : { float : 'right', @@ -101,22 +55,14 @@ const styles = (theme) => { opacity : 1 }, - '&.unsupported' : - { - pointerEvents : 'none' - }, '&.disabled' : { pointerEvents : 'none', backgroundColor : 'var(--media-control-botton-disabled)' }, - '&.on' : + '&.promote' : { backgroundColor : 'var(--media-control-botton-on)' - }, - '&.off' : - { - backgroundColor : 'var(--media-control-botton-off)' } } }); @@ -124,7 +70,7 @@ const styles = (theme) => const ListLobbyPeer = (props) => { const { - // roomClient, + roomClient, peer, classes } = props; @@ -138,64 +84,19 @@ const ListLobbyPeer = (props) =>
{peer.displayName}
-
- { /* peer.raiseHandState ? -
- :null - */ } -
- {/* { screenConsumer ? -
- { - e.stopPropagation(); - screenVisible ? - roomClient.modifyPeerConsumer(peer.id, 'screen', true) : - roomClient.modifyPeerConsumer(peer.id, 'screen', false); - }} - > - { screenVisible ? - - : - - } -
- :null - }
{ e.stopPropagation(); - micEnabled ? - roomClient.modifyPeerConsumer(peer.id, 'mic', true) : - roomClient.modifyPeerConsumer(peer.id, 'mic', false); + roomClient.promoteLobbyPeer(peer.id); }} > - { micEnabled ? - - : - - } -
*/} + +
); @@ -205,7 +106,7 @@ ListLobbyPeer.propTypes = { roomClient : PropTypes.any.isRequired, advancedMode : PropTypes.bool, - peer : appPropTypes.Peer.isRequired, + peer : PropTypes.object.isRequired, classes : PropTypes.object.isRequired }; diff --git a/app/src/components/MeetingDrawer/ParticipantList/ParticipantList.js b/app/src/components/MeetingDrawer/ParticipantList/ParticipantList.js index f8c98e4..38f2aea 100644 --- a/app/src/components/MeetingDrawer/ParticipantList/ParticipantList.js +++ b/app/src/components/MeetingDrawer/ParticipantList/ParticipantList.js @@ -92,9 +92,9 @@ class ParticipantList extends React.PureComponent
- { lobbyPeers ? + { lobbyPeers.length > 0 ?