lock Dialog

This commit is contained in:
Stefan Otto
2019-10-23 11:47:41 +02:00
parent 223642a44f
commit e5ddaa458a
9 changed files with 445 additions and 66 deletions
@@ -0,0 +1,140 @@
import React from 'react';
import { connect } from 'react-redux';
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';
const styles = (theme) =>
({
root :
{
padding : theme.spacing(1),
width : '100%',
overflow : 'hidden',
cursor : 'auto',
display : 'flex'
},
avatar :
{
borderRadius : '50%',
height : '2rem'
},
peerInfo :
{
fontSize : '1rem',
border : 'none',
display : 'flex',
paddingLeft : theme.spacing(1),
flexGrow : 1,
alignItems : 'center'
},
controls :
{
float : 'right',
display : 'flex',
flexDirection : 'row',
justifyContent : 'flex-start',
alignItems : 'center'
},
button :
{
flex : '0 0 auto',
margin : '0.3rem',
borderRadius : 2,
backgroundColor : 'rgba(0, 0, 0, 0.5)',
cursor : 'pointer',
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
},
'&.disabled' :
{
pointerEvents : 'none',
backgroundColor : 'var(--media-control-botton-disabled)'
},
'&.promote' :
{
backgroundColor : 'var(--media-control-botton-on)'
}
}
});
const ListLobbyPeer = (props) =>
{
const {
roomClient,
peer,
classes
} = props;
const picture = peer.picture || EmptyAvatar;
return (
<ListItem
key={peer.peerId}
button
alignItems="flex-start"
>
<ListItemAvatar>
<Avatar alt='Peer avatar' src={picture} />
</ListItemAvatar>
<ListItemText
primary={peer.displayName}
/>
<ListItemIcon
className={classnames(classes.button, 'promote', {
disabled : peer.promotionInProgress
})}
onClick={(e) =>
{
e.stopPropagation();
roomClient.promoteLobbyPeer(peer.id);
}}
>
<PromoteIcon />
</ListItemIcon>
</ListItem>
);
};
ListLobbyPeer.propTypes =
{
roomClient : PropTypes.any.isRequired,
advancedMode : PropTypes.bool,
peer : PropTypes.object.isRequired,
classes : PropTypes.object.isRequired
};
const mapStateToProps = (state, { id }) =>
{
return {
peer : state.lobbyPeers[id]
};
};
export default withRoomContext(connect(
mapStateToProps,
null,
null,
{
areStatesEqual : (next, prev) =>
{
return (
prev.lobbyPeers === next.lobbyPeers
);
}
}
)(withStyles(styles)(ListLobbyPeer)));
@@ -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 (
<Dialog
className={classes.root}
open={room.lockDialogOpen}
onClose={() => handleCloseLockDialog({ lockDialogOpen: false })}
classes={{
paper : classes.dialogPaper
}}
>
<DialogTitle id='form-dialog-title'>Room access control</DialogTitle>
<form className={classes.lock} autoComplete='off'>
<FormControl component='fieldset' className={classes.formControl}>
<FormLabel component='legend'>Room lock</FormLabel>
<FormGroup>
<FormControlLabel
control={
<Switch checked={room.locked} onChange={() =>
{
if (room.locked)
{
roomClient.unlockRoom();
}
else
{
roomClient.lockRoom();
}
}}
/>}
label='Lock'
/>
{/* TODO: access code
<FormControlLabel disabled={ room.locked ? false : true }
control={
<Checkbox checked={room.joinByAccessCode}
onChange={
(event) => roomClient.setJoinByAccessCode(event.target.checked)
}
/>}
label='Join by Access code'
/>
<InputLabel htmlFor='access-code-input' />
<OutlinedInput
disabled={ room.locked ? false : true }
id='acces-code-input'
label='Access code'
labelWidth={0}
variant='outlined'
value={room.accessCode}
onChange={(event) => handleAccessCode(event.target.value)}
>
</OutlinedInput>
<Button onClick={() => roomClient.setAccessCode(room.accessCode)} color='primary'>
save
</Button>
*/}
</FormGroup>
</FormControl>
{ lobbyPeers.length > 0 ?
<List subheader={
<ListSubheader component="div">
Participants in Lobby
</ListSubheader>
}>
{
lobbyPeers.map((peerId) => { return (<ListLobbyPeer id={peerId} />); })
}
</List>
: null
}
</form>
<DialogActions>
<Button onClick={() => handleCloseLockDialog({ lockDialogOpen: false })} color='primary'>
Close
</Button>
</DialogActions>
</Dialog>
);
};
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)));