diff --git a/app/src/components/Controls/TopBar.js b/app/src/components/Controls/TopBar.js new file mode 100644 index 0000000..d597387 --- /dev/null +++ b/app/src/components/Controls/TopBar.js @@ -0,0 +1,329 @@ +import React from 'react'; +import { connect } from 'react-redux'; +import PropTypes from 'prop-types'; +import { + lobbyPeersKeySelector +} from '../Selectors'; +import * as appPropTypes from '../appPropTypes'; +import { withRoomContext } from '../../RoomContext'; +import { withStyles } from '@material-ui/core/styles'; +import * as roomActions from '../../actions/roomActions'; +import * as toolareaActions from '../../actions/toolareaActions'; +import AppBar from '@material-ui/core/AppBar'; +import Toolbar from '@material-ui/core/Toolbar'; +import Typography from '@material-ui/core/Typography'; +import IconButton from '@material-ui/core/IconButton'; +import MenuIcon from '@material-ui/icons/Menu'; +import Avatar from '@material-ui/core/Avatar'; +import Badge from '@material-ui/core/Badge'; +import AccountCircle from '@material-ui/icons/AccountCircle'; +import FullScreenIcon from '@material-ui/icons/Fullscreen'; +import FullScreenExitIcon from '@material-ui/icons/FullscreenExit'; +import SettingsIcon from '@material-ui/icons/Settings'; +import SecurityIcon from '@material-ui/icons/Security'; +import LockIcon from '@material-ui/icons/Lock'; +import LockOpenIcon from '@material-ui/icons/LockOpen'; +import Button from '@material-ui/core/Button'; +import Tooltip from '@material-ui/core/Tooltip'; + +const styles = (theme) => + ({ + menuButton : + { + margin : 0, + padding : 0 + }, + logo : + { + display : 'none', + marginLeft : 20, + [theme.breakpoints.up('sm')] : + { + display : 'block' + } + }, + show : + { + opacity : 1, + transition : 'opacity .5s' + }, + hide : + { + opacity : 0, + transition : 'opacity .5s' + }, + grow : + { + flexGrow : 1 + }, + title : + { + display : 'none', + marginLeft : 20, + [theme.breakpoints.up('sm')] : + { + display : 'block' + } + }, + actionButtons : + { + display : 'flex' + }, + actionButton : + { + margin : theme.spacing(1), + padding : 0 + } + }); + +const PulsingBadge = withStyles((theme) => + ({ + badge : + { + backgroundColor : theme.palette.secondary.main, + '&::after' : + { + position : 'absolute', + width : '100%', + height : '100%', + borderRadius : '50%', + animation : '$ripple 1.2s infinite ease-in-out', + border : `3px solid ${theme.palette.secondary.main}`, + content : '""' + } + }, + '@keyframes ripple' : + { + '0%' : + { + transform : 'scale(.8)', + opacity : 1 + }, + '100%' : + { + transform : 'scale(2.4)', + opacity : 0 + } + } + }))(Badge); + +const TopBar = (props) => +{ + const { + roomClient, + room, + lobbyPeers, + myPicture, + loggedIn, + loginEnabled, + fullscreenEnabled, + fullscreen, + onFullscreen, + setSettingsOpen, + setLockDialogOpen, + toggleToolArea, + unread, + classes + } = props; + + return ( + + + + toggleToolArea()} + className={classes.menuButton} + > + + + + { window.config.logo && Logo } + + { window.config.title } + +
+
+ + + { + if (room.locked) + { + roomClient.unlockRoom(); + } + else + { + roomClient.lockRoom(); + } + }} + > + { room.locked ? + + : + + } + + + { lobbyPeers.length > 0 && + + setLockDialogOpen(!room.lockDialogOpen)} + > + + + + + + } + { fullscreenEnabled && + + + { fullscreen ? + + : + + } + + + } + + setSettingsOpen(!room.settingsOpen)} + > + + + + { loginEnabled && + + + { + loggedIn ? roomClient.logout() : roomClient.login(); + }} + > + { myPicture ? + + : + + } + + + } + +
+ + + ); +}; + +TopBar.propTypes = +{ + roomClient : PropTypes.object.isRequired, + room : appPropTypes.Room.isRequired, + lobbyPeers : PropTypes.array, + myPicture : PropTypes.string, + loggedIn : PropTypes.bool.isRequired, + loginEnabled : PropTypes.bool.isRequired, + fullscreenEnabled : PropTypes.bool, + fullscreen : PropTypes.bool, + onFullscreen : PropTypes.func.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, + theme : PropTypes.object.isRequired +}; + +const mapStateToProps = (state) => + ({ + room : state.room, + lobbyPeers : lobbyPeersKeySelector(state), + advancedMode : state.settings.advancedMode, + loggedIn : state.me.loggedIn, + loginEnabled : state.me.loginEnabled, + myPicture : state.me.picture, + unread : state.toolarea.unreadMessages + + state.toolarea.unreadFiles + }); + +const mapDispatchToProps = (dispatch) => + ({ + setToolbarsVisible : (visible) => + { + dispatch(roomActions.setToolbarsVisible(visible)); + }, + setSettingsOpen : (settingsOpen) => + { + dispatch(roomActions.setSettingsOpen({ settingsOpen })); + }, + setLockDialogOpen : (lockDialogOpen) => + { + dispatch(roomActions.setLockDialogOpen({ lockDialogOpen })); + }, + toggleToolArea : () => + { + dispatch(toolareaActions.toggleToolArea()); + } + }); + +export default withRoomContext(connect( + mapStateToProps, + mapDispatchToProps, + null, + { + areStatesEqual : (next, prev) => + { + return ( + prev.room === next.room && + prev.lobbyPeers === next.lobbyPeers && + prev.me.loggedIn === next.me.loggedIn && + prev.me.loginEnabled === next.me.loginEnabled && + prev.me.picture === next.me.picture && + prev.toolarea.unreadMessages === next.toolarea.unreadMessages && + prev.toolarea.unreadFiles === next.toolarea.unreadFiles + ); + } + } +)(withStyles(styles, { withTheme: true })(TopBar))); \ No newline at end of file diff --git a/app/src/components/Room.js b/app/src/components/Room.js index f7eb661..275bf75 100644 --- a/app/src/components/Room.js +++ b/app/src/components/Room.js @@ -1,11 +1,7 @@ import React from 'react'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; -import { - lobbyPeersKeySelector -} from './Selectors'; import * as appPropTypes from './appPropTypes'; -import { withRoomContext } from '../RoomContext'; import { withStyles } from '@material-ui/core/styles'; import * as roomActions from '../actions/roomActions'; import * as toolareaActions from '../actions/toolareaActions'; @@ -13,16 +9,8 @@ import { idle } from '../utils'; import FullScreen from './FullScreen'; import CookieConsent from 'react-cookie-consent'; import CssBaseline from '@material-ui/core/CssBaseline'; -import AppBar from '@material-ui/core/AppBar'; -import Toolbar from '@material-ui/core/Toolbar'; import SwipeableDrawer from '@material-ui/core/SwipeableDrawer'; import Hidden from '@material-ui/core/Hidden'; -import Typography from '@material-ui/core/Typography'; -import IconButton from '@material-ui/core/IconButton'; -import MenuIcon from '@material-ui/icons/Menu'; -import Avatar from '@material-ui/core/Avatar'; -import Badge from '@material-ui/core/Badge'; -import AccountCircle from '@material-ui/icons/AccountCircle'; import Notifications from './Notifications/Notifications'; import MeetingDrawer from './MeetingDrawer/MeetingDrawer'; import Democratic from './MeetingViews/Democratic'; @@ -30,18 +18,11 @@ import Filmstrip from './MeetingViews/Filmstrip'; import AudioPeers from './PeerAudio/AudioPeers'; import FullScreenView from './VideoContainers/FullScreenView'; import VideoWindow from './VideoWindow/VideoWindow'; -import FullScreenIcon from '@material-ui/icons/Fullscreen'; -import FullScreenExitIcon from '@material-ui/icons/FullscreenExit'; -import SettingsIcon from '@material-ui/icons/Settings'; -import SecurityIcon from '@material-ui/icons/Security'; import LockDialog from './AccessControl/LockDialog/LockDialog'; -import LockIcon from '@material-ui/icons/Lock'; -import LockOpenIcon from '@material-ui/icons/LockOpen'; -import Button from '@material-ui/core/Button'; import Settings from './Settings/Settings'; -import Tooltip from '@material-ui/core/Tooltip'; +import TopBar from './Controls/TopBar'; -const TIMEOUT = 10 * 1000; +const TIMEOUT = 5 * 1000; const styles = (theme) => ({ @@ -57,44 +38,6 @@ const styles = (theme) => backgroundSize : 'cover', backgroundRepeat : 'no-repeat' }, - message : - { - position : 'absolute', - display : 'flex', - top : '50%', - left : '50%', - transform : 'translateX(-50%) translateY(-50%)', - width : '30vw', - padding : theme.spacing(2), - flexDirection : 'column', - justifyContent : 'center', - alignItems : 'center' - }, - menuButton : - { - margin : 0, - padding : 0 - }, - logo : - { - display : 'none', - marginLeft : 20, - [theme.breakpoints.up('sm')] : - { - display : 'block' - } - }, - show : - { - opacity : 1, - transition : 'opacity .5s' - }, - hide : - { - opacity : 0, - transition : 'opacity .5s' - }, - toolbar : theme.mixins.toolbar, drawerPaper : { width : '30vw', @@ -114,79 +57,9 @@ const styles = (theme) => { width : '90vw' } - }, - grow : - { - flexGrow : 1 - }, - title : - { - display : 'none', - marginLeft : 20, - [theme.breakpoints.up('sm')] : - { - display : 'block' - } - }, - actionButtons : - { - display : 'flex' - }, - actionButton : - { - margin : theme.spacing(1), - padding : 0 - }, - meContainer : - { - position : 'fixed', - zIndex : 110, - overflow : 'hidden', - boxShadow : 'var(--me-shadow)', - transitionProperty : 'border-color', - transitionDuration : '0.15s', - top : '5em', - left : '1em', - border : 'var(--me-border)', - '&.active-speaker' : - { - borderColor : 'var(--active-speaker-border-color)' - } } }); -const PulsingBadge = withStyles((theme) => - ({ - badge : - { - backgroundColor : theme.palette.secondary.main, - // boxShadow : `0 0 0 2px ${theme.palette.secondary.main}`, - '&::after' : - { - position : 'absolute', - width : '100%', - height : '100%', - borderRadius : '50%', - animation : '$ripple 1.2s infinite ease-in-out', - border : `3px solid ${theme.palette.secondary.main}`, - content : '""' - } - }, - '@keyframes ripple' : - { - '0%' : - { - transform : 'scale(.8)', - opacity : 1 - }, - '100%' : - { - transform : 'scale(2.4)', - opacity : 0 - } - } - }))(Badge); - class Room extends React.PureComponent { constructor(props) @@ -262,18 +135,10 @@ class Room extends React.PureComponent render() { const { - roomClient, room, - lobbyPeers, advancedMode, - myPicture, - loggedIn, - loginEnabled, - setSettingsOpen, - setLockDialogOpen, toolAreaOpen, toggleToolArea, - unread, classes, theme } = this.props; @@ -300,132 +165,12 @@ class Room extends React.PureComponent - - - - toggleToolArea()} - className={classes.menuButton} - > - - - - { window.config.logo && Logo } - - { window.config.title } - -
-
- - - { - if (room.locked) - { - roomClient.unlockRoom(); - } - else - { - roomClient.lockRoom(); - } - }} - > - { room.locked ? - - : - - } - - - { lobbyPeers.length > 0 && - - setLockDialogOpen(!room.lockDialogOpen)} - > - - - - - - } - { this.fullscreen.fullscreenEnabled && - - - { this.state.fullscreen ? - - : - - } - - - } - - setSettingsOpen(!room.settingsOpen)} - > - - - - { loginEnabled && - - - { - loggedIn ? roomClient.logout() : roomClient.login(); - }} - > - { myPicture ? - - : - - } - - - } - -
- - + +