diff --git a/app/src/RoomClient.js b/app/src/RoomClient.js index 243ce57..7c586ef 100644 --- a/app/src/RoomClient.js +++ b/app/src/RoomClient.js @@ -77,7 +77,7 @@ export default class RoomClient } constructor( - { roomId, peerId, device, useSimulcast, produce, consume, forceTcp }) + { roomId, peerId, accessCode, device, useSimulcast, produce, consume, forceTcp }) { logger.debug( 'constructor() [roomId: "%s", peerId: "%s", device: "%s", useSimulcast: "%s", produce: "%s", consume: "%s", forceTcp: "%s"]', @@ -112,6 +112,9 @@ export default class RoomClient // My peer name. this._peerId = peerId; + // Access code + this._accessCode = accessCode; + // Alert sound this._soundAlert = new Audio('/sounds/notify.mp3'); @@ -609,7 +612,8 @@ export default class RoomClient fileHistory, lastN, locked, - lobbyPeers + lobbyPeers, + accessCode } = await this.sendRequest('serverHistory'); if (chatHistory.length > 0) @@ -654,6 +658,13 @@ export default class RoomClient stateActions.setLobbyPeerDisplayName(peer.displayName)); }); } + + if (accessCode != null) + { + logger.debug('Got accessCode'); + + store.dispatch(stateActions.setAccessCode(accessCode)) + } } catch (error) { @@ -1385,6 +1396,46 @@ export default class RoomClient break; } + case 'setAccessCode': + { + const { accessCode } = notification.data; + + store.dispatch( + stateActions.setAccessCode(accessCode)); + + store.dispatch(requestActions.notify( + { + text : 'Access code for room updated' + })); + + break; + } + + case 'setJoinByAccessCode': + { + const { joinByAccessCode } = notification.data; + + store.dispatch( + stateActions.setJoinByAccessCode(joinByAccessCode)); + + if (joinByAccessCode) + { + store.dispatch(requestActions.notify( + { + text : 'Access code for room is now activated' + })); + } + else + { + store.dispatch(requestActions.notify( + { + text : 'Access code for room is now deactivated' + })); + } + + break; + } + case 'activeSpeaker': { const { peerId } = notification.data; @@ -1843,6 +1894,60 @@ export default class RoomClient } } + async setAccessCode(code) + { + logger.debug('setAccessCode()'); + + try + { + await this.sendRequest('setAccessCode', { accessCode: code }); + + store.dispatch( + stateActions.setAccessCode(code)); + + store.dispatch(requestActions.notify( + { + text : 'Access code saved.' + })); + } + catch (error) + { + logger.error('setAccessCode() | failed: %o', error); + store.dispatch(requestActions.notify( + { + type : 'error', + text : 'Unable to set access code.' + })); + } + } + + async setJoinByAccessCode(value) + { + logger.debug('setJoinByAccessCode()'); + + try + { + await this.sendRequest('setJoinByAccessCode', { joinByAccessCode: value }); + + store.dispatch( + stateActions.setJoinByAccessCode(value)); + + store.dispatch(requestActions.notify( + { + text : `You switched Join by access-code to ${value}` + })); + } + catch (error) + { + logger.error('setAccessCode() | failed: %o', error); + store.dispatch(requestActions.notify( + { + type : 'error', + text : 'Unable to set join by access code.' + })); + } + } + async enableMic() { if (this._micProducer) diff --git a/app/src/actions/stateActions.js b/app/src/actions/stateActions.js index 24f6870..1e72125 100644 --- a/app/src/actions/stateActions.js +++ b/app/src/actions/stateActions.js @@ -43,12 +43,35 @@ export const setRoomLockedOut = () => }; }; +export const setAccessCode = (accessCode) => +{ + return { + type : 'SET_ACCESS_CODE', + payload : { accessCode } + }; +}; + +export const setJoinByAccessCode = (joinByAccessCode) => +{ + return { + type : 'SET_JOIN_BY_ACCESS_CODE', + payload : { joinByAccessCode } + }; +}; + + export const setSettingsOpen = ({ settingsOpen }) => ({ type : 'SET_SETTINGS_OPEN', payload : { settingsOpen } }); +export const setLockDialogOpen = ({ lockDialogOpen }) => + ({ + type : 'SET_LOCK_DIALOG_OPEN', + payload : { lockDialogOpen } + }); + export const setMe = ({ peerId, device, loginEnabled }) => { return { @@ -178,6 +201,13 @@ export const toggleSettings = () => }; }; +export const toggleLockDialog = () => +{ + return { + type : 'TOGGLE_LOCK_DIALOG' + }; +}; + export const toggleToolArea = () => { return { diff --git a/app/src/components/MeetingDrawer/ParticipantList/ListLobbyPeer.js b/app/src/components/AccessControl/LockDialog/ListLobbyPeer.js similarity index 76% rename from app/src/components/MeetingDrawer/ParticipantList/ListLobbyPeer.js rename to app/src/components/AccessControl/LockDialog/ListLobbyPeer.js index 85b0136..665561d 100644 --- a/app/src/components/MeetingDrawer/ParticipantList/ListLobbyPeer.js +++ b/app/src/components/AccessControl/LockDialog/ListLobbyPeer.js @@ -4,6 +4,11 @@ import { withStyles } from '@material-ui/core/styles'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import { withRoomContext } from '../../../RoomContext'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemText from '@material-ui/core/ListItemText'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemAvatar from '@material-ui/core/ListItemAvatar'; +import Avatar from '@material-ui/core/Avatar'; import EmptyAvatar from '../../../images/avatar-empty.jpeg'; import PromoteIcon from '@material-ui/icons/OpenInBrowser'; @@ -78,27 +83,30 @@ const ListLobbyPeer = (props) => const picture = peer.picture || EmptyAvatar; return ( -
- Peer avatar - -
- {peer.displayName} -
-
-
+ + + + + + { e.stopPropagation(); roomClient.promoteLobbyPeer(peer.id); }} - > - -
-
-
+ > + + + ); }; diff --git a/app/src/components/AccessControl/LockDialog/LockDialog.js b/app/src/components/AccessControl/LockDialog/LockDialog.js new file mode 100644 index 0000000..021cf20 --- /dev/null +++ b/app/src/components/AccessControl/LockDialog/LockDialog.js @@ -0,0 +1,191 @@ +import React from 'react'; +import { connect } from 'react-redux'; +import { + lobbyPeersKeySelector +} from '../../Selectors'; +import * as appPropTypes from '../../appPropTypes'; +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 DialogTitle from '@material-ui/core/DialogTitle'; +import DialogActions from '@material-ui/core/DialogActions'; +import Button from '@material-ui/core/Button'; +import FormLabel from '@material-ui/core/FormLabel'; +import FormControl from '@material-ui/core/FormControl'; +import FormGroup from '@material-ui/core/FormGroup'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import Checkbox from '@material-ui/core/Checkbox'; +import InputLabel from '@material-ui/core/InputLabel'; +import OutlinedInput from '@material-ui/core/OutlinedInput'; +import Switch from '@material-ui/core/Switch'; +import List from '@material-ui/core/List'; +import ListSubheader from '@material-ui/core/ListSubheader'; +import ListLobbyPeer from './ListLobbyPeer'; + + +const styles = (theme) => + ({ + root : + { + }, + dialogPaper : + { + width : '30vw', + [theme.breakpoints.down('lg')] : + { + width : '40vw' + }, + [theme.breakpoints.down('md')] : + { + width : '50vw' + }, + [theme.breakpoints.down('sm')] : + { + width : '70vw' + }, + [theme.breakpoints.down('xs')] : + { + width : '90vw' + } + }, + lock : + { + padding : theme.spacing.unit * 2 + } + }); + +const LockDialog = ({ + roomClient, + room, + handleCloseLockDialog, + handleAccessCode, + lobbyPeers, + classes +}) => +{ + return ( + handleCloseLockDialog({ lockDialogOpen: false })} + classes={{ + paper : classes.dialogPaper + }} + > + Room access control +
+ + Room lock + + + { + if (room.locked) + { + roomClient.unlockRoom(); + } + else + { + roomClient.lockRoom(); + } + }} + />} + label='Lock' + /> + {/* TODO: access code + roomClient.setJoinByAccessCode(event.target.checked) + } + />} + label='Join by Access code' + /> + + handleAccessCode(event.target.value)} + > + + + */} + + + + { lobbyPeers.length > 0 ? + + Participants in Lobby + + }> + { + lobbyPeers.map((peerId) => { return (); }) + } + + : null + } +
+ + + + +
+ ); +}; + +LockDialog.propTypes = +{ + roomClient : PropTypes.any.isRequired, + room : appPropTypes.Room.isRequired, + handleCloseLockDialog : PropTypes.func.isRequired, + handleAccessCode : PropTypes.func.isRequired, + lobbyPeers : PropTypes.array, + classes : PropTypes.object.isRequired +}; + +const mapStateToProps = (state) => +{ + return { + room : state.room, + lobbyPeers : lobbyPeersKeySelector(state) + + }; +}; + +const mapDispatchToProps = { + handleCloseLockDialog : stateActions.setLockDialogOpen, + handleAccessCode : stateActions.setAccessCode +}; + +export default withRoomContext(connect( + mapStateToProps, + mapDispatchToProps, + null, + { + areStatesEqual : (next, prev) => + { + return ( + prev.room.locked === next.room.locked && + prev.room.joinByAccessCode === next.room.joinByAccessCode && + prev.room.accessCode === next.room.accessCode && + prev.room.code === next.room.code && + prev.room.lockDialogOpen === next.room.lockDialogOpen && + prev.room.codeHidden === next.room.codeHidden && + prev.lobbyPeers === next.lobbyPeers + ); + } + } +)(withStyles(styles)(LockDialog))); \ No newline at end of file diff --git a/app/src/components/MeetingDrawer/ParticipantList/ParticipantList.js b/app/src/components/MeetingDrawer/ParticipantList/ParticipantList.js index 85a71cb..484c7ba 100644 --- a/app/src/components/MeetingDrawer/ParticipantList/ParticipantList.js +++ b/app/src/components/MeetingDrawer/ParticipantList/ParticipantList.js @@ -2,15 +2,13 @@ import React from 'react'; import { connect } from 'react-redux'; import { passivePeersSelector, - spotlightPeersSelector, - lobbyPeersKeySelector + spotlightPeersSelector } from '../../Selectors'; import classNames from 'classnames'; import { withStyles } from '@material-ui/core/styles'; import { withRoomContext } from '../../../RoomContext'; import PropTypes from 'prop-types'; import ListPeer from './ListPeer'; -import ListLobbyPeer from './ListLobbyPeer'; import ListMe from './ListMe'; import Volume from '../../Containers/Volume'; @@ -80,7 +78,6 @@ class ParticipantList extends React.PureComponent passivePeers, selectedPeerId, spotlightPeers, - lobbyPeers, classes } = this.props; @@ -90,20 +87,6 @@ class ParticipantList extends React.PureComponent
  • Me:
  • - { lobbyPeers.length > 0 ? - - :null - }