diff --git a/app/package.json b/app/package.json index ac81f80..4716292 100644 --- a/app/package.json +++ b/app/package.json @@ -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", diff --git a/app/public/chooseRoom.html b/app/public/chooseRoom.html deleted file mode 100644 index ee10a2b..0000000 --- a/app/public/chooseRoom.html +++ /dev/null @@ -1,86 +0,0 @@ - - - - - Multiparty Meeting - - - - -
-
- - - - - diff --git a/app/src/components/ChooseRoom.js b/app/src/components/ChooseRoom.js new file mode 100644 index 0000000..3bd5738 --- /dev/null +++ b/app/src/components/ChooseRoom.js @@ -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 ( + + { window.config.logo && Logo } + {children} + { window.config.loginEnabled && + + + { myPicture ? + + : + + } + + + } + + ); +}); + +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 ( +
+ + + { + loggedIn ? roomClient.logout() : roomClient.login(); + }} + > + { window.config.title } +
+
+ + + + + + + { + const { value } = event.target; + + changeRoomId(value); + }} + onBlur={() => + { + if (roomId === '') + changeRoomId(randomString({ length: 8 }).toLowerCase()); + }} + fullWidth + /> + + + + + + + + + +
+
+ ); +}; + +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))); \ No newline at end of file diff --git a/app/src/index.js b/app/src/index.js index a2df5a4..1a29b79 100644 --- a/app/src/index.js +++ b/app/src/index.js @@ -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() } persistor={persistor}> - + + }> + + + + + + diff --git a/app/src/translations/de.json b/app/src/translations/de.json index a314574..476c048 100644 --- a/app/src/translations/de.json +++ b/app/src/translations/de.json @@ -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", diff --git a/app/src/translations/en.json b/app/src/translations/en.json index 1a7a12b..2df5c04 100644 --- a/app/src/translations/en.json +++ b/app/src/translations/en.json @@ -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", diff --git a/app/src/translations/hu.json b/app/src/translations/hu.json index 209ebb7..3eab945 100644 --- a/app/src/translations/hu.json +++ b/app/src/translations/hu.json @@ -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", diff --git a/app/src/translations/nb.json b/app/src/translations/nb.json index 0f1527d..3f017e0 100644 --- a/app/src/translations/nb.json +++ b/app/src/translations/nb.json @@ -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", diff --git a/server/server.js b/server/server.js index 0aa1e78..8638609 100755 --- a/server/server.js +++ b/server/server.js @@ -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'));