Lifted some logic up a level to clean up code.

master
Håvar Aambø Fosstveit 2019-10-23 11:29:32 +02:00
parent 223642a44f
commit 12dd85a99d
6 changed files with 350 additions and 209 deletions

View File

@ -0,0 +1,56 @@
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import Room from './Room';
import JoinDialog from './JoinDialog';
import Lobby from './Lobby';
const App = (props) =>
{
const {
room
} = props;
if (room.lockedOut)
{
return (
<Lobby />
);
}
else if (!room.joined)
{
return (
<JoinDialog />
);
}
else
{
return (
<Room />
);
}
}
App.propTypes =
{
room : PropTypes.object.isRequired
};
const mapStateToProps = (state) =>
({
room : state.room
});
export default connect(
mapStateToProps,
null,
null,
{
areStatesEqual : (next, prev) =>
{
return (
prev.room === next.room
);
}
}
)(App);

View File

@ -14,6 +14,15 @@ const styles = (theme) =>
({ ({
root : root :
{ {
display : 'flex',
width : '100%',
height : '100%',
backgroundColor : 'var(--background-color)',
backgroundImage : `url(${window.config.background})`,
backgroundAttachment : 'fixed',
backgroundPosition : 'center',
backgroundSize : 'cover',
backgroundRepeat : 'no-repeat'
}, },
dialogPaper : dialogPaper :
{ {
@ -50,52 +59,53 @@ const JoinDialog = ({
}) => }) =>
{ {
return ( return (
<Dialog <div className={classes.root}>
className={classes.root} <Dialog
open open
classes={{ classes={{
paper : classes.dialogPaper paper : classes.dialogPaper
}} }}
> >
{ window.config.logo ? { window.config.logo ?
<img alt='Logo' className={classes.logo} src={window.config.logo} /> <img alt='Logo' className={classes.logo} src={window.config.logo} />
:null :null
} }
<Typography variant='subtitle1'>You are about to join a meeting, how would you like to join?</Typography> <Typography variant='subtitle1'>You are about to join a meeting, how would you like to join?</Typography>
<DialogActions> <DialogActions>
<Button <Button
onClick={() => onClick={() =>
{ {
roomClient.join({ joinVideo: false }); roomClient.join({ joinVideo: false });
}} }}
variant='contained' variant='contained'
> >
Audio only Audio only
</Button> </Button>
<Button <Button
onClick={() => onClick={() =>
{ {
roomClient.join({ joinVideo: true }); roomClient.join({ joinVideo: true });
}} }}
variant='contained' variant='contained'
> >
Audio and Video Audio and Video
</Button> </Button>
<TextField <TextField
id='displayname' id='displayname'
label='Name' label='Name'
className={classes.textField} className={classes.textField}
value={displayName} value={displayName}
onChange={(event) => onChange={(event) =>
{ {
const { value } = event.target; const { value } = event.target;
changeDisplayName(value); changeDisplayName(value);
}} }}
margin='normal' margin='normal'
/> />
</DialogActions> </DialogActions>
</Dialog> </Dialog>
</div>
); );
}; };

View File

@ -0,0 +1,108 @@
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 Paper from '@material-ui/core/Paper';
import DialogActions from '@material-ui/core/DialogActions';
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
const styles = (theme) =>
({
root :
{
display : 'flex',
width : '100%',
height : '100%',
backgroundColor : 'var(--background-color)',
backgroundImage : `url(${window.config.background})`,
backgroundAttachment : 'fixed',
backgroundPosition : 'center',
backgroundSize : 'cover',
backgroundRepeat : 'no-repeat'
},
dialogPaper :
{
width : '20vw',
padding : theme.spacing(2),
[theme.breakpoints.down('lg')] :
{
width : '30vw'
},
[theme.breakpoints.down('md')] :
{
width : '40vw'
},
[theme.breakpoints.down('sm')] :
{
width : '60vw'
},
[theme.breakpoints.down('xs')] :
{
width : '80vw'
}
},
logo :
{
display : 'block'
}
});
const Lobby = ({
roomClient,
displayName,
changeDisplayName,
classes
}) =>
{
return (
<div className={classes.root}>
<Paper className={classes.message}>
<Typography variant='h2'>This room is locked at the moment, try again later.</Typography>
</Paper>
</div>
);
};
Lobby.propTypes =
{
roomClient : PropTypes.any.isRequired,
displayName : PropTypes.string.isRequired,
changeDisplayName : PropTypes.func.isRequired,
classes : PropTypes.object.isRequired
};
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)(Lobby)));

View File

@ -13,7 +13,6 @@ import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar'; import Toolbar from '@material-ui/core/Toolbar';
import SwipeableDrawer from '@material-ui/core/SwipeableDrawer'; import SwipeableDrawer from '@material-ui/core/SwipeableDrawer';
import Hidden from '@material-ui/core/Hidden'; import Hidden from '@material-ui/core/Hidden';
import Paper from '@material-ui/core/Paper';
import Typography from '@material-ui/core/Typography'; import Typography from '@material-ui/core/Typography';
import IconButton from '@material-ui/core/IconButton'; import IconButton from '@material-ui/core/IconButton';
import MenuIcon from '@material-ui/icons/Menu'; import MenuIcon from '@material-ui/icons/Menu';
@ -34,7 +33,6 @@ import LockIcon from '@material-ui/icons/Lock';
import LockOpenIcon from '@material-ui/icons/LockOpen'; import LockOpenIcon from '@material-ui/icons/LockOpen';
import Button from '@material-ui/core/Button'; import Button from '@material-ui/core/Button';
import Settings from './Settings/Settings'; import Settings from './Settings/Settings';
import JoinDialog from './JoinDialog';
const TIMEOUT = 10 * 1000; const TIMEOUT = 10 * 1000;
@ -277,172 +275,139 @@ class Room extends React.PureComponent
democratic : Democratic democratic : Democratic
}[room.mode]; }[room.mode];
if (room.lockedOut) return (
{ <div className={classes.root}>
return ( <CookieConsent>
<div className={classes.root}> This website uses cookies to enhance the user experience.
<Paper className={classes.message}> </CookieConsent>
<Typography variant='h2'>This room is locked at the moment, try again later.</Typography>
</Paper>
</div>
);
}
else if (!room.joined)
{
return (
<div className={classes.root}>
<JoinDialog />
</div>
);
}
else
{
return (
<div className={classes.root}>
<CookieConsent>
This website uses cookies to enhance the user experience.
</CookieConsent>
<FullScreenView advancedMode={advancedMode} /> <FullScreenView advancedMode={advancedMode} />
<VideoWindow advancedMode={advancedMode} /> <VideoWindow advancedMode={advancedMode} />
<AudioPeers /> <AudioPeers />
<Notifications /> <Notifications />
<CssBaseline /> <CssBaseline />
<AppBar <AppBar
position='fixed' position='fixed'
className={room.toolbarsVisible ? classes.show : classes.hide} className={room.toolbarsVisible ? classes.show : classes.hide}
> >
<Toolbar> <Toolbar>
<PulsingBadge <PulsingBadge
color='secondary' color='secondary'
badgeContent={unread} badgeContent={unread}
> >
<IconButton <IconButton
color='inherit'
aria-label='Open drawer'
onClick={() => toggleToolArea()}
className={classes.menuButton}
>
<MenuIcon />
</IconButton>
</PulsingBadge>
{ window.config.logo ?
<img alt='Logo' className={classes.logo} src={window.config.logo} />
:null
}
<Typography
className={classes.title}
variant='h6'
color='inherit' color='inherit'
noWrap aria-label='Open drawer'
onClick={() => toggleToolArea()}
className={classes.menuButton}
> >
{ window.config.title } <MenuIcon />
</Typography> </IconButton>
<div className={classes.grow} /> </PulsingBadge>
<div className={classes.actionButtons}> { window.config.logo && <img alt='Logo' className={classes.logo} src={window.config.logo} /> }
<IconButton <Typography
aria-label='Lock room' className={classes.title}
className={classes.actionButton} variant='h6'
color='inherit' color='inherit'
onClick={() => noWrap
{ >
if (room.locked) { window.config.title }
{ </Typography>
roomClient.unlockRoom(); <div className={classes.grow} />
} <div className={classes.actionButtons}>
else <IconButton
{ aria-label='Lock room'
roomClient.lockRoom(); className={classes.actionButton}
} color='inherit'
}} onClick={() =>
> {
{ room.locked ? room.locked ? roomClient.unlockRoom() : roomClient.lockRoom();
<LockIcon />
:
<LockOpenIcon />
}
</IconButton>
{ this.fullscreen.fullscreenEnabled ?
<IconButton
aria-label='Fullscreen'
className={classes.actionButton}
color='inherit'
onClick={this.handleToggleFullscreen}
>
{ this.state.fullscreen ?
<FullScreenExitIcon />
:
<FullScreenIcon />
}
</IconButton>
:null
}
<IconButton
aria-label='Settings'
className={classes.actionButton}
color='inherit'
onClick={() => setSettingsOpen(!room.settingsOpen)}
>
<SettingsIcon />
</IconButton>
{ loginEnabled ?
<IconButton
aria-label='Account'
className={classes.actionButton}
color='inherit'
onClick={() =>
{
loggedIn ? roomClient.logout() : roomClient.login();
}}
>
{ myPicture ?
<Avatar src={myPicture} />
:
<AccountCircle />
}
</IconButton>
:null
}
<Button
aria-label='Leave meeting'
className={classes.actionButton}
variant='contained'
color='secondary'
onClick={() => roomClient.close()}
>
Leave
</Button>
</div>
</Toolbar>
</AppBar>
<nav>
<Hidden implementation='css'>
<SwipeableDrawer
variant='temporary'
anchor={theme.direction === 'rtl' ? 'right' : 'left'}
open={toolAreaOpen}
onClose={() => toggleToolArea()}
onOpen={() => toggleToolArea()}
classes={{
paper : classes.drawerPaper
}} }}
> >
<MeetingDrawer closeDrawer={toggleToolArea} /> { room.locked ?
</SwipeableDrawer> <LockIcon />
</Hidden> :
</nav> <LockOpenIcon />
}
</IconButton>
{ this.fullscreen.fullscreenEnabled &&
<IconButton
aria-label='Fullscreen'
className={classes.actionButton}
color='inherit'
onClick={this.handleToggleFullscreen}
>
{ this.state.fullscreen ?
<FullScreenExitIcon />
:
<FullScreenIcon />
}
</IconButton>
}
<IconButton
aria-label='Settings'
className={classes.actionButton}
color='inherit'
onClick={() => setSettingsOpen(!room.settingsOpen)}
>
<SettingsIcon />
</IconButton>
{ loginEnabled &&
<IconButton
aria-label='Account'
className={classes.actionButton}
color='inherit'
onClick={() =>
{
loggedIn ? roomClient.logout() : roomClient.login();
}}
>
{ myPicture ?
<Avatar src={myPicture} />
:
<AccountCircle />
}
</IconButton>
}
<Button
aria-label='Leave meeting'
className={classes.actionButton}
variant='contained'
color='secondary'
onClick={() => roomClient.close()}
>
Leave
</Button>
</div>
</Toolbar>
</AppBar>
<nav>
<Hidden implementation='css'>
<SwipeableDrawer
variant='temporary'
anchor={theme.direction === 'rtl' ? 'right' : 'left'}
open={toolAreaOpen}
onClose={() => toggleToolArea()}
onOpen={() => toggleToolArea()}
classes={{
paper : classes.drawerPaper
}}
>
<MeetingDrawer closeDrawer={toggleToolArea} />
</SwipeableDrawer>
</Hidden>
</nav>
<View advancedMode={advancedMode} /> <View advancedMode={advancedMode} />
<Settings /> <Settings />
</div> </div>
); );
}
} }
} }

View File

@ -9,7 +9,7 @@ import RoomClient from './RoomClient';
import RoomContext from './RoomContext'; import RoomContext from './RoomContext';
import deviceInfo from './deviceInfo'; import deviceInfo from './deviceInfo';
import * as stateActions from './actions/stateActions'; import * as stateActions from './actions/stateActions';
import Room from './components/Room'; import App from './components/App';
import LoadingView from './components/LoadingView'; import LoadingView from './components/LoadingView';
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles'; import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import { PersistGate } from 'redux-persist/lib/integration/react'; import { PersistGate } from 'redux-persist/lib/integration/react';
@ -94,7 +94,7 @@ function run()
<PersistGate loading={<LoadingView />} persistor={persistor}> <PersistGate loading={<LoadingView />} persistor={persistor}>
<RoomContext.Provider value={roomClient}> <RoomContext.Provider value={roomClient}>
<SnackbarProvider> <SnackbarProvider>
<Room /> <App />
</SnackbarProvider> </SnackbarProvider>
</RoomContext.Provider> </RoomContext.Provider>
</PersistGate> </PersistGate>

View File

@ -19,12 +19,7 @@ const base64 = require('base-64');
// auth // auth
const passport = require('passport'); const passport = require('passport');
const { Issuer, Strategy } = require('openid-client'); const { Issuer, Strategy } = require('openid-client');
const session = require('express-session')({ const expressSession = require('express-session');
secret : config.cookieSecret,
resave : true,
saveUninitialized : true,
cookie : { secure: true }
});
const sharedSession = require('express-socket.io-session'); const sharedSession = require('express-socket.io-session');
/* eslint-disable no-console */ /* eslint-disable no-console */
@ -57,6 +52,13 @@ const tls =
const app = express(); const app = express();
const session = expressSession({
secret : config.cookieSecret,
resave : true,
saveUninitialized : true,
cookie : { secure: true }
})
app.use(session); app.use(session);
let httpsServer; let httpsServer;