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.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 (
+
+ );
+};
+
+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 ?
-
- - Participants in Lobby:
- { lobbyPeers.map((peerId) => (
- -
-
-
- ))}
-
- :null
- }
- Participants in Spotlight:
{ spotlightPeers.map((peer) => (
@@ -146,7 +129,6 @@ ParticipantList.propTypes =
passivePeers : PropTypes.array,
selectedPeerId : PropTypes.string,
spotlightPeers : PropTypes.array,
- lobbyPeers : PropTypes.array,
classes : PropTypes.object.isRequired
};
@@ -155,8 +137,7 @@ const mapStateToProps = (state) =>
return {
passivePeers : passivePeersSelector(state),
selectedPeerId : state.room.selectedPeerId,
- spotlightPeers : spotlightPeersSelector(state),
- lobbyPeers : lobbyPeersKeySelector(state)
+ spotlightPeers : spotlightPeersSelector(state)
};
};
@@ -170,8 +151,7 @@ const ParticipantListContainer = withRoomContext(connect(
return (
prev.peers === next.peers &&
prev.room.spotlights === next.room.spotlights &&
- prev.room.selectedPeerId === next.room.selectedPeerId &&
- prev.lobbyPeers === next.lobbyPeers
+ prev.room.selectedPeerId === next.room.selectedPeerId
);
}
}
diff --git a/app/src/components/Room.js b/app/src/components/Room.js
index 3ebebeb..c002a94 100644
--- a/app/src/components/Room.js
+++ b/app/src/components/Room.js
@@ -35,6 +35,7 @@ import LockOpenIcon from '@material-ui/icons/LockOpen';
import Button from '@material-ui/core/Button';
import Settings from './Settings/Settings';
import JoinDialog from './JoinDialog';
+import LockDialog from './AccessControl/LockDialog/LockDialog';
const TIMEOUT = 10 * 1000;
@@ -264,6 +265,7 @@ class Room extends React.PureComponent
loggedIn,
loginEnabled,
setSettingsOpen,
+ setLockDialogOpen,
toolAreaOpen,
toggleToolArea,
unread,
@@ -345,28 +347,6 @@ class Room extends React.PureComponent
-
- {
- if (room.locked)
- {
- roomClient.unlockRoom();
- }
- else
- {
- roomClient.lockRoom();
- }
- }}
- >
- { room.locked ?
-
- :
-
- }
-
{ this.fullscreen.fullscreenEnabled ?
+ setLockDialogOpen(!room.lockDialogOpen)}
+ >
+ { room.locked ? : }
+
{ loginEnabled ?
+
+
);
@@ -457,6 +446,7 @@ Room.propTypes =
toolAreaOpen : PropTypes.bool.isRequired,
setToolbarsVisible : PropTypes.func.isRequired,
setSettingsOpen : PropTypes.func.isRequired,
+ setLockDialogOpen : PropTypes.func.isRequired,
toggleToolArea : PropTypes.func.isRequired,
unread : PropTypes.number.isRequired,
classes : PropTypes.object.isRequired,
@@ -485,6 +475,10 @@ const mapDispatchToProps = (dispatch) =>
{
dispatch(stateActions.setSettingsOpen({ settingsOpen }));
},
+ setLockDialogOpen : (lockDialogOpen) =>
+ {
+ dispatch(stateActions.setLockDialogOpen({ lockDialogOpen }));
+ },
toggleToolArea : () =>
{
dispatch(stateActions.toggleToolArea());
diff --git a/app/src/index.js b/app/src/index.js
index 8e30c9d..c85fa18 100644
--- a/app/src/index.js
+++ b/app/src/index.js
@@ -62,6 +62,7 @@ function run()
window.history.pushState('', '', urlParser.toString());
}
+ const accessCode = parameters.get('code');
const produce = parameters.get('produce') !== 'false';
const consume = parameters.get('consume') !== 'false';
const useSimulcast = parameters.get('simulcast') === 'true';
@@ -84,7 +85,7 @@ function run()
);
roomClient = new RoomClient(
- { roomId, peerId, device, useSimulcast, produce, consume, forceTcp });
+ { roomId, peerId, accessCode, device, useSimulcast, produce, consume, forceTcp });
global.CLIENT = roomClient;
diff --git a/app/src/reducers/room.js b/app/src/reducers/room.js
index e1444c3..20a6026 100644
--- a/app/src/reducers/room.js
+++ b/app/src/reducers/room.js
@@ -4,6 +4,8 @@ const initialState =
state : 'new', // new/connecting/connected/disconnected/closed,
locked : false,
lockedOut : false,
+ accessCode : '', // access code to the room if locked and joinByAccessCode == true
+ joinByAccessCode : true, // if true: accessCode is a possibility to open the room
activeSpeakerId : null,
torrentSupport : false,
showSettings : false,
@@ -14,6 +16,7 @@ const initialState =
selectedPeerId : null,
spotlights : [],
settingsOpen : false,
+ lockDialogOpen : false,
joined : false
};
@@ -53,6 +56,27 @@ const room = (state = initialState, action) =>
return { ...state, lockedOut: true };
}
+ case 'SET_ACCESS_CODE':
+ {
+ const { accessCode } = action.payload;
+
+ return { ...state, accessCode };
+ }
+
+ case 'SET_JOIN_BY_ACCESS_CODE':
+ {
+ const { joinByAccessCode } = action.payload;
+
+ return { ...state, joinByAccessCode };
+ }
+
+ case 'SET_LOCK_DIALOG_OPEN':
+ {
+ const { lockDialogOpen } = action.payload;
+
+ return { ...state, lockDialogOpen };
+ }
+
case 'SET_SETTINGS_OPEN':
{
const { settingsOpen } = action.payload;
diff --git a/server/lib/Room.js b/server/lib/Room.js
index ef9d941..f382880 100644
--- a/server/lib/Room.js
+++ b/server/lib/Room.js
@@ -55,6 +55,12 @@ class Room extends EventEmitter
// Locked flag.
this._locked = false;
+ // if true: accessCode is a possibility to open the room
+ this._joinByAccesCode = true;
+
+ // access code to the room, applicable if ( _locked == true and _joinByAccessCode == true )
+ this._accessCode = '';
+
this._lobby = new Lobby();
this._lobby.on('promotePeer', (peer) =>
@@ -815,7 +821,8 @@ class Room extends EventEmitter
fileHistory : this._fileHistory,
lastN : this._lastN,
locked : this._locked,
- lobbyPeers : lobbyPeers
+ lobbyPeers : lobbyPeers,
+ accessCode : this._accessCode
}
);
@@ -852,6 +859,45 @@ class Room extends EventEmitter
break;
}
+ case 'setAccessCode':
+ {
+ const { accessCode } = request.data;
+
+ this._accessCode = accessCode;
+
+ // Spread to others
+ // if (request.public) {
+ this._notification(peer.socket, 'setAccessCode', {
+ peerId : peer.id,
+ accessCode : accessCode
+ }, true);
+ //}
+
+ // Return no error
+ cb();
+
+ break;
+ }
+
+ case 'setJoinByAccessCode':
+ {
+ const { joinByAccessCode } = request.data;
+
+ this._joinByAccessCode = joinByAccessCode;
+
+ // Spread to others
+ this._notification(peer.socket, 'setJoinByAccessCode', {
+ peerId : peer.id,
+ joinByAccessCode : joinByAccessCode
+ }, true);
+
+ // Return no error
+ cb();
+
+ break;
+ }
+
+
case 'promotePeer':
{
const { peerId } = request.data;