Remove static chooseRoom file, and use react-router instead.

master
Håvar Aambø Fosstveit 2019-11-10 00:01:01 +01:00
parent 37bac2f650
commit daf661889d
9 changed files with 326 additions and 94 deletions

View File

@ -23,6 +23,7 @@
"react-dom": "^16.10.2",
"react-intl": "^3.4.0",
"react-redux": "^7.1.1",
"react-router-dom": "^5.1.2",
"react-scripts": "3.2.0",
"redux": "^4.0.4",
"redux-logger": "^3.0.6",

View File

@ -1,86 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Multiparty Meeting</title>
</head>
<style>
body
{
margin:auto;
padding:0.5vmin;
text-align:center;
position: fixed;
left: 50%;
top: 40%;
width: 90%;
transform: translate(-50%, 0%);
background-image: url('/images/background.jpg');
background-attachment: fixed;
background-position: center;
background-size: cover;
background-repeat: repeat;
}
input:hover { opacity:0.9; }
input[type=text]
{
font-size: 1.5em;
padding: 1.5vmin;
background-color: rgba(0,0,0,0.3);
border: 0;
color: #fff;
margin: 0.8vmin;
width: 50%;
}
button:hover { background-color: #f5f5f5; }
button
{
font-size: 1.5em;
padding: 1.5vmin;
margin: 0.8vmin;
background-color: #fafafa;
border-radius: 1.8vmin;
color: #000;
border: 0;
}
img
{
height: 15vmin;
}
</style>
<body>
<a>
<img src='/images/logo.svg'></img><br />
</a>
<input id='room' type='text' onkeypress='checkEnter(event)' value='' placeholder='your room name' />
<button onclick = 'start(location.href)'>Go to room</button>
</body>
<script>
let room = document.getElementById('room');
let stateObj = { foo: 'bar' };
room.addEventListener('input', (e) =>
{
console.log(e.charCode);
history.replaceState(stateObj, 'Multiparty Meeting', '/'+room.value);
}, true);
room.focus();
function start(target)
{
location.href;history.replaceState(stateObj, 'Multiparty Meeting', '/');
window.location = target;
}
function checkEnter(event)
{
let x = event.charCode || event.keyCode;
if (x == 13 )
{
start(location.href);
}
}
</script>
</html>

View File

@ -0,0 +1,299 @@
import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import { withStyles } from '@material-ui/core/styles';
import { withRoomContext } from '../RoomContext';
import * as roomActions from '../actions/roomActions';
import PropTypes from 'prop-types';
import { useIntl, FormattedMessage } from 'react-intl';
import randomString from 'random-string';
import Dialog from '@material-ui/core/Dialog';
import DialogContentText from '@material-ui/core/DialogContentText';
import IconButton from '@material-ui/core/IconButton';
import AccountCircle from '@material-ui/icons/AccountCircle';
import Avatar from '@material-ui/core/Avatar';
import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
import Tooltip from '@material-ui/core/Tooltip';
import CookieConsent from 'react-cookie-consent';
import MuiDialogTitle from '@material-ui/core/DialogTitle';
import MuiDialogContent from '@material-ui/core/DialogContent';
import MuiDialogActions from '@material-ui/core/DialogActions';
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'
},
dialogTitle :
{
},
dialogPaper :
{
width : '30vw',
padding : theme.spacing(2),
[theme.breakpoints.down('lg')] :
{
width : '40vw'
},
[theme.breakpoints.down('md')] :
{
width : '50vw'
},
[theme.breakpoints.down('sm')] :
{
width : '70vw'
},
[theme.breakpoints.down('xs')] :
{
width : '90vw'
}
},
logo :
{
display : 'block',
paddingBottom : '1vh'
},
loginButton :
{
position : 'absolute',
right : theme.spacing(2),
top : theme.spacing(2),
padding : 0
},
largeIcon :
{
fontSize : '2em'
},
largeAvatar :
{
width : 50,
height : 50
},
green :
{
color : 'rgba(0, 153, 0, 1)'
}
});
const DialogTitle = withStyles(styles)((props) =>
{
const [ open, setOpen ] = useState(false);
const intl = useIntl();
useEffect(() =>
{
const openTimer = setTimeout(() => setOpen(true), 1000);
const closeTimer = setTimeout(() => setOpen(false), 4000);
return () =>
{
clearTimeout(openTimer);
clearTimeout(closeTimer);
};
}, []);
const { children, classes, myPicture, onLogin, ...other } = props;
const handleTooltipClose = () =>
{
setOpen(false);
};
const handleTooltipOpen = () =>
{
setOpen(true);
};
return (
<MuiDialogTitle disableTypography className={classes.dialogTitle} {...other}>
{ window.config.logo && <img alt='Logo' className={classes.logo} src={window.config.logo} /> }
<Typography variant='h5'>{children}</Typography>
{ window.config.loginEnabled &&
<Tooltip
onClose={handleTooltipClose}
onOpen={handleTooltipOpen}
open={open}
title={intl.formatMessage({
id : 'tooltip.login',
defaultMessage : 'Click to log in'
})}
placement='left'
>
<IconButton
aria-label='Account'
className={classes.loginButton}
color='inherit'
onClick={onLogin}
>
{ myPicture ?
<Avatar src={myPicture} className={classes.largeAvatar} />
:
<AccountCircle className={classes.largeIcon} />
}
</IconButton>
</Tooltip>
}
</MuiDialogTitle>
);
});
const DialogContent = withStyles((theme) => ({
root :
{
padding : theme.spacing(2)
}
}))(MuiDialogContent);
const DialogActions = withStyles((theme) => ({
root :
{
margin : 0,
padding : theme.spacing(1)
}
}))(MuiDialogActions);
const ChooseRoom = ({
roomClient,
roomId,
loggedIn,
myPicture,
changeRoomId,
classes
}) =>
{
const intl = useIntl();
return (
<div className={classes.root}>
<Dialog
open
classes={{
paper : classes.dialogPaper
}}
>
<DialogTitle
myPicture={myPicture}
onLogin={() =>
{
loggedIn ? roomClient.logout() : roomClient.login();
}}
>
{ window.config.title }
<hr />
</DialogTitle>
<DialogContent>
<DialogContentText gutterBottom>
<FormattedMessage
id='room.chooseRoom'
defaultMessage='Choose the name of the room you would like to join'
/>
</DialogContentText>
<TextField
id='roomId'
label={intl.formatMessage({
id : 'label.roomName',
defaultMessage : 'Room name'
})}
value={roomId}
variant='outlined'
margin='normal'
onChange={(event) =>
{
const { value } = event.target;
changeRoomId(value);
}}
onBlur={() =>
{
if (roomId === '')
changeRoomId(randomString({ length: 8 }).toLowerCase());
}}
fullWidth
/>
</DialogContent>
<DialogActions>
<Button
component={Link}
to={roomId}
variant='contained'
color='secondary'
>
<FormattedMessage
id='label.chooseRoomButton'
defaultMessage='Continue'
/>
</Button>
</DialogActions>
<CookieConsent>
<FormattedMessage
id='room.cookieConsent'
defaultMessage='This website uses cookies to enhance the user experience'
/>
</CookieConsent>
</Dialog>
</div>
);
};
ChooseRoom.propTypes =
{
roomClient : PropTypes.any.isRequired,
roomId : PropTypes.string,
loginEnabled : PropTypes.bool.isRequired,
loggedIn : PropTypes.bool.isRequired,
myPicture : PropTypes.string,
changeRoomId : PropTypes.func.isRequired,
classes : PropTypes.object.isRequired
};
const mapStateToProps = (state) =>
{
return {
roomId : state.room.name,
loginEnabled : state.me.loginEnabled,
loggedIn : state.me.loggedIn,
myPicture : state.me.picture
};
};
const mapDispatchToProps = (dispatch) =>
{
return {
changeRoomId : (roomId) =>
{
dispatch(roomActions.setRoomName(roomId));
}
};
};
export default withRoomContext(connect(
mapStateToProps,
mapDispatchToProps,
null,
{
areStatesEqual : (next, prev) =>
{
return (
prev.room.name === next.room.name &&
prev.me.loginEnabled === next.me.loginEnabled &&
prev.me.loggedIn === next.me.loggedIn &&
prev.me.picture === next.me.picture
);
}
}
)(withStyles(styles)(ChooseRoom)));

View File

@ -1,8 +1,9 @@
import domready from 'domready';
import React from 'react';
import React, { Suspense } from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { createIntl, createIntlCache, RawIntlProvider } from 'react-intl';
import { Route, BrowserRouter as Router } from 'react-router-dom'
import randomString from 'random-string';
import Logger from './Logger';
import debug from 'debug';
@ -11,13 +12,14 @@ import RoomContext from './RoomContext';
import deviceInfo from './deviceInfo';
import * as roomActions from './actions/roomActions';
import * as meActions from './actions/meActions';
import App from './components/App';
import ChooseRoom from './components/ChooseRoom';
import LoadingView from './components/LoadingView';
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import { PersistGate } from 'redux-persist/lib/integration/react';
import { persistor, store } from './store';
import { SnackbarProvider } from 'notistack';
import * as serviceWorker from './serviceWorker';
import { ReactLazyPreload } from './components/ReactLazyPreload';
import messagesEnglish from './translations/en';
import messagesNorwegian from './translations/nb';
@ -26,6 +28,8 @@ import messagesHungarian from './translations/hu';
import './index.css';
const App = ReactLazyPreload(() => import(/* webpackChunkName: "app" */ './components/App'));
const cache = createIntlCache();
const messages =
@ -118,7 +122,14 @@ function run()
<PersistGate loading={<LoadingView />} persistor={persistor}>
<RoomContext.Provider value={roomClient}>
<SnackbarProvider>
<App />
<Router>
<Suspense fallback={<LoadingView />}>
<React.Fragment>
<Route exact path='/' component={ChooseRoom} />
<Route path='/:id' component={App} />
</React.Fragment>
</Suspense>
</Router>
</SnackbarProvider>
</RoomContext.Provider>
</PersistGate>

View File

@ -4,6 +4,7 @@
"socket.reconnected": "Verbindung wieder hergestellt",
"socket.requestError": "Fehler bei Serveranfrage",
"room.chooseRoom": "Choose the name of the room you would like to join",
"room.cookieConsent": "Diese Seite verwendet Cookies, um die Benutzerfreundlichkeit zu erhöhen",
"room.joined": "Konferenzraum betreten",
"room.cantJoin": "Betreten des Raumes nicht möglich",
@ -58,6 +59,8 @@
"tooltip.lobby": "Warteraum",
"tooltip.settings": "Einstellungen",
"label.roomName": "Room name",
"label.chooseRoomButton": "Continue",
"label.yourName": "Dein Name",
"label.newWindow": "In separatem Fenster öffnen",
"label.fullscreen": "Vollbild",

View File

@ -4,6 +4,7 @@
"socket.reconnected": "You are reconnected",
"socket.requestError": "Error on server request",
"room.chooseRoom": "Choose the name of the room you would like to join",
"room.cookieConsent": "This website uses cookies to enhance the user experience",
"room.joined": "You have joined the room",
"room.cantJoin": "Unable to join the room",
@ -58,6 +59,8 @@
"tooltip.lobby": "Show lobby",
"tooltip.settings": "Show settings",
"label.roomName": "Room name",
"label.chooseRoomButton": "Continue",
"label.yourName": "Your name",
"label.newWindow": "New window",
"label.fullscreen": "Fullscreen",

View File

@ -4,6 +4,7 @@
"socket.reconnected": "Sikeres újarkapcsolódás",
"socket.requestError": "Sikertelen szerver lekérés",
"room.chooseRoom": "Choose the name of the room you would like to join",
"room.cookieConsent": "Ez a weblap a felhasználói élmény fokozása miatt sütiket használ",
"room.joined": "Csatlakozátál a konferenciaszobához",
"room.cantJoin": "Sikertelen csatlakozás a konferenciaszobához",
@ -58,6 +59,8 @@
"tooltip.lobby": "Az előszobában várakozók listája",
"tooltip.settings": "Beállítások",
"label.roomName": "Room name",
"label.chooseRoomButton": "Continue",
"label.yourName": "A neved",
"label.newWindow": "Új ablak",
"label.fullscreen": "Teljes képernyős mód",

View File

@ -4,6 +4,7 @@
"socket.reconnected": "Du er koblet til igjen",
"socket.requestError": "Feil på server melding",
"room.chooseRoom": "Velg navn på møtet du vil bli med i eller starte",
"room.cookieConsent": "Denne siden bruker cookies for å forbedre brukeropplevelsen",
"room.joined": "Du ble med i møtet",
"room.cantJoin": "Kunne ikke bli med i møtet",
@ -58,6 +59,8 @@
"tooltip.lobby": "Vis lobby",
"tooltip.settings": "Vis innstillinger",
"label.roomName": "Møtenavn",
"label.chooseRoomButton": "Fortsett",
"label.yourName": "Ditt navn",
"label.newWindow": "Flytt til separat vindu",
"label.fullscreen": "Fullskjerm",

View File

@ -328,11 +328,6 @@ async function runHttpsServer()
res.redirect(`https://${req.hostname}${req.url}`);
});
app.get('/', (req, res) =>
{
res.sendFile(`${__dirname}/public/chooseRoom.html`);
});
// Serve all files in the public folder as static files.
app.use(express.static('public'));