diff --git a/app/public/config/config.example.js b/app/public/config/config.example.js index 4bbc13f..7909284 100644 --- a/app/public/config/config.example.js +++ b/app/public/config/config.example.js @@ -57,6 +57,9 @@ var config = // If true, will show media control buttons in separate // control bar, not in the ME container. buttonControlBar : false, + // If false, will push videos away to make room for side + // drawer. If true, will overlay side drawer over videos + drawerOverlayed : true, // Timeout for autohiding topbar and button control bar hideTimeout : 3000, lastN : 4, diff --git a/app/src/actions/settingsActions.js b/app/src/actions/settingsActions.js index 4b7dc6d..21ff2fd 100644 --- a/app/src/actions/settingsActions.js +++ b/app/src/actions/settingsActions.js @@ -43,6 +43,11 @@ export const toggleButtonControlBar = () => type : 'TOGGLE_BUTTON_CONTROL_BAR' }); +export const toggleDrawerOverlayed = () => + ({ + type : 'TOGGLE_DRAWER_OVERLAYED' + }); + export const toggleShowNotifications = () => ({ type : 'TOGGLE_SHOW_NOTIFICATIONS' diff --git a/app/src/components/Controls/TopBar.js b/app/src/components/Controls/TopBar.js index b880c36..52b06cd 100644 --- a/app/src/components/Controls/TopBar.js +++ b/app/src/components/Controls/TopBar.js @@ -14,6 +14,7 @@ import { withStyles } from '@material-ui/core/styles'; import * as roomActions from '../../actions/roomActions'; import * as toolareaActions from '../../actions/toolareaActions'; import { useIntl, FormattedMessage } from 'react-intl'; +import classnames from 'classnames'; import AppBar from '@material-ui/core/AppBar'; import Toolbar from '@material-ui/core/Toolbar'; import MenuItem from '@material-ui/core/MenuItem'; @@ -43,6 +44,31 @@ import InfoIcon from '@material-ui/icons/Info'; const styles = (theme) => ({ + persistentDrawerOpen : + { + width : 'calc(100% - 30vw)', + marginLeft : '30vw', + [theme.breakpoints.down('lg')] : + { + width : 'calc(100% - 40vw)', + marginLeft : '40vw' + }, + [theme.breakpoints.down('md')] : + { + width : 'calc(100% - 50vw)', + marginLeft : '50vw' + }, + [theme.breakpoints.down('sm')] : + { + width : 'calc(100% - 70vw)', + marginLeft : '70vw' + }, + [theme.breakpoints.down('xs')] : + { + width : 'calc(100% - 90vw)', + marginLeft : '90vw' + } + }, menuButton : { margin : 0, @@ -188,6 +214,9 @@ const TopBar = (props) => peersLength, lobbyPeers, permanentTopBar, + drawerOverlayed, + toolAreaOpen, + isMobile, myPicture, loggedIn, loginEnabled, @@ -248,7 +277,12 @@ const TopBar = (props) => const mapStateToProps = (state) => ({ room : state.room, + isMobile : state.me.browser.platform === 'mobile', peersLength : peersLengthSelector(state), lobbyPeers : lobbyPeersKeySelector(state), permanentTopBar : state.settings.permanentTopBar, + drawerOverlayed : state.settings.drawerOverlayed, + toolAreaOpen : state.toolarea.toolAreaOpen, loggedIn : state.me.loggedIn, loginEnabled : state.me.loginEnabled, myPicture : state.me.picture, @@ -832,12 +872,15 @@ export default withRoomContext(connect( prev.peers === next.peers && prev.lobbyPeers === next.lobbyPeers && prev.settings.permanentTopBar === next.settings.permanentTopBar && + prev.settings.drawerOverlayed === next.settings.drawerOverlayed && prev.me.loggedIn === next.me.loggedIn && + prev.me.browser === next.me.browser && prev.me.loginEnabled === next.me.loginEnabled && prev.me.picture === next.me.picture && prev.me.roles === next.me.roles && prev.toolarea.unreadMessages === next.toolarea.unreadMessages && - prev.toolarea.unreadFiles === next.toolarea.unreadFiles + prev.toolarea.unreadFiles === next.toolarea.unreadFiles && + prev.toolarea.toolAreaOpen === next.toolarea.toolAreaOpen ); } } diff --git a/app/src/components/MeetingViews/Democratic.js b/app/src/components/MeetingViews/Democratic.js index f2fff1a..e2e774c 100644 --- a/app/src/components/MeetingViews/Democratic.js +++ b/app/src/components/MeetingViews/Democratic.js @@ -22,6 +22,7 @@ const styles = (theme) => display : 'flex', flexDirection : 'row', flexWrap : 'wrap', + overflow : 'hidden', justifyContent : 'center', alignItems : 'center', alignContent : 'center' @@ -189,6 +190,7 @@ Democratic.propTypes = toolbarsVisible : PropTypes.bool.isRequired, permanentTopBar : PropTypes.bool.isRequired, buttonControlBar : PropTypes.bool.isRequired, + toolAreaOpen : PropTypes.bool.isRequired, classes : PropTypes.object.isRequired }; @@ -199,7 +201,8 @@ const mapStateToProps = (state) => spotlightsPeers : spotlightPeersSelector(state), toolbarsVisible : state.room.toolbarsVisible, permanentTopBar : state.settings.permanentTopBar, - buttonControlBar : state.settings.buttonControlBar + buttonControlBar : state.settings.buttonControlBar, + toolAreaOpen : state.toolarea.toolAreaOpen }; }; @@ -217,7 +220,8 @@ export default connect( prev.room.spotlights === next.room.spotlights && prev.room.toolbarsVisible === next.room.toolbarsVisible && prev.settings.permanentTopBar === next.settings.permanentTopBar && - prev.settings.buttonControlBar === next.settings.buttonControlBar + prev.settings.buttonControlBar === next.settings.buttonControlBar && + prev.toolarea.toolAreaOpen === next.toolarea.toolAreaOpen ); } } diff --git a/app/src/components/MeetingViews/Filmstrip.js b/app/src/components/MeetingViews/Filmstrip.js index d1cfba6..120e985 100644 --- a/app/src/components/MeetingViews/Filmstrip.js +++ b/app/src/components/MeetingViews/Filmstrip.js @@ -25,6 +25,7 @@ const styles = () => height : '100%', width : '100%', display : 'grid', + overflow : 'hidden', gridTemplateColumns : '1fr', gridTemplateRows : '1fr 0.25fr' }, @@ -334,6 +335,7 @@ Filmstrip.propTypes = { spotlights : PropTypes.array.isRequired, boxes : PropTypes.number, toolbarsVisible : PropTypes.bool.isRequired, + toolAreaOpen : PropTypes.bool.isRequired, permanentTopBar : PropTypes.bool, classes : PropTypes.object.isRequired }; @@ -349,6 +351,7 @@ const mapStateToProps = (state) => spotlights : state.room.spotlights, boxes : videoBoxesSelector(state), toolbarsVisible : state.room.toolbarsVisible, + toolAreaOpen : state.toolarea.toolAreaOpen, permanentTopBar : state.settings.permanentTopBar }; }; @@ -364,6 +367,7 @@ export default withRoomContext(connect( prev.room.activeSpeakerId === next.room.activeSpeakerId && prev.room.selectedPeerId === next.room.selectedPeerId && prev.room.toolbarsVisible === next.room.toolbarsVisible && + prev.toolarea.toolAreaOpen === next.toolarea.toolAreaOpen && prev.settings.permanentTopBar === next.settings.permanentTopBar && prev.peers === next.peers && prev.consumers === next.consumers && diff --git a/app/src/components/Room.js b/app/src/components/Room.js index d021132..4dee360 100644 --- a/app/src/components/Room.js +++ b/app/src/components/Room.js @@ -12,6 +12,7 @@ import { FormattedMessage } from 'react-intl'; import CookieConsent from 'react-cookie-consent'; import CssBaseline from '@material-ui/core/CssBaseline'; import SwipeableDrawer from '@material-ui/core/SwipeableDrawer'; +import Drawer from '@material-ui/core/Drawer'; import Hidden from '@material-ui/core/Hidden'; import Notifications from './Notifications/Notifications'; import MeetingDrawer from './MeetingDrawer/MeetingDrawer'; @@ -45,6 +46,27 @@ const styles = (theme) => backgroundSize : 'cover', backgroundRepeat : 'no-repeat' }, + drawer : + { + width : '30vw', + flexShrink : 0, + [theme.breakpoints.down('lg')] : + { + width : '40vw' + }, + [theme.breakpoints.down('md')] : + { + width : '50vw' + }, + [theme.breakpoints.down('sm')] : + { + width : '70vw' + }, + [theme.breakpoints.down('xs')] : + { + width : '90vw' + } + }, drawerPaper : { width : '30vw', @@ -147,6 +169,7 @@ class Room extends React.PureComponent advancedMode, showNotifications, buttonControlBar, + drawerOverlayed, toolAreaOpen, toggleToolArea, classes, @@ -159,6 +182,8 @@ class Room extends React.PureComponent democratic : Democratic }[room.mode]; + const container = window !== undefined ? window.document.body : undefined; + return (
{ !isElectron() && @@ -195,22 +220,45 @@ class Room extends React.PureComponent onFullscreen={this.handleToggleFullscreen} /> - + { (browser.platform === 'mobile' || drawerOverlayed) ? + + : + + } { browser.platform === 'mobile' && browser.os !== 'ios' && @@ -252,6 +300,7 @@ Room.propTypes = advancedMode : PropTypes.bool.isRequired, showNotifications : PropTypes.bool.isRequired, buttonControlBar : PropTypes.bool.isRequired, + drawerOverlayed : PropTypes.bool.isRequired, toolAreaOpen : PropTypes.bool.isRequired, setToolbarsVisible : PropTypes.func.isRequired, toggleToolArea : PropTypes.func.isRequired, @@ -266,6 +315,7 @@ const mapStateToProps = (state) => advancedMode : state.settings.advancedMode, showNotifications : state.settings.showNotifications, buttonControlBar : state.settings.buttonControlBar, + drawerOverlayed : state.settings.drawerOverlayed, toolAreaOpen : state.toolarea.toolAreaOpen }); @@ -294,6 +344,7 @@ export default connect( prev.settings.advancedMode === next.settings.advancedMode && prev.settings.showNotifications === next.settings.showNotifications && prev.settings.buttonControlBar === next.settings.buttonControlBar && + prev.settings.drawerOverlayed === next.settings.drawerOverlayed && prev.toolarea.toolAreaOpen === next.toolarea.toolAreaOpen ); } diff --git a/app/src/components/Settings/AppearenceSettings.js b/app/src/components/Settings/AppearenceSettings.js index a859ab4..46cc898 100644 --- a/app/src/components/Settings/AppearenceSettings.js +++ b/app/src/components/Settings/AppearenceSettings.js @@ -26,12 +26,14 @@ const styles = (theme) => }); const AppearenceSettings = ({ + isMobile, room, settings, onTogglePermanentTopBar, onToggleHiddenControls, onToggleButtonControlBar, onToggleShowNotifications, + onToggleDrawerOverlayed, handleChangeMode, classes }) => @@ -111,6 +113,16 @@ const AppearenceSettings = ({ defaultMessage : 'Separate media controls' })} /> + { !isMobile && + } + label={intl.formatMessage({ + id : 'settings.drawerOverlayed', + defaultMessage : 'Side drawer over content' + })} + /> + } } @@ -125,18 +137,21 @@ const AppearenceSettings = ({ AppearenceSettings.propTypes = { + isMobile : PropTypes.bool.isRequired, room : appPropTypes.Room.isRequired, settings : PropTypes.object.isRequired, onTogglePermanentTopBar : PropTypes.func.isRequired, onToggleHiddenControls : PropTypes.func.isRequired, onToggleButtonControlBar : PropTypes.func.isRequired, onToggleShowNotifications : PropTypes.func.isRequired, + onToggleDrawerOverlayed : PropTypes.func.isRequired, handleChangeMode : PropTypes.func.isRequired, classes : PropTypes.object.isRequired }; const mapStateToProps = (state) => ({ + isMobile : state.me.browser.platform === 'mobile', room : state.room, settings : state.settings }); @@ -146,6 +161,7 @@ const mapDispatchToProps = { onToggleHiddenControls : settingsActions.toggleHiddenControls, onToggleShowNotifications : settingsActions.toggleShowNotifications, onToggleButtonControlBar : settingsActions.toggleButtonControlBar, + onToggleDrawerOverlayed : settingsActions.toggleDrawerOverlayed, handleChangeMode : roomActions.setDisplayMode }; @@ -157,6 +173,7 @@ export default connect( areStatesEqual : (next, prev) => { return ( + prev.me.browser === next.me.browser && prev.room === next.room && prev.settings === next.settings ); diff --git a/app/src/reducers/settings.js b/app/src/reducers/settings.js index f306726..1c375bf 100644 --- a/app/src/reducers/settings.js +++ b/app/src/reducers/settings.js @@ -19,6 +19,7 @@ const initialState = showNotifications : true, notificationSounds : true, buttonControlBar : window.config.buttonControlBar || false, + drawerOverlayed : window.config.drawerOverlayed || true, ...window.config.defaultAudio }; @@ -153,6 +154,13 @@ const settings = (state = initialState, action) => return { ...state, buttonControlBar }; } + case 'TOGGLE_DRAWER_OVERLAYED': + { + const drawerOverlayed = !state.drawerOverlayed; + + return { ...state, drawerOverlayed }; + } + case 'TOGGLE_HIDDEN_CONTROLS': { const hiddenControls = !state.hiddenControls; diff --git a/app/src/translations/cn.json b/app/src/translations/cn.json index df97372..0ce5f5b 100644 --- a/app/src/translations/cn.json +++ b/app/src/translations/cn.json @@ -138,6 +138,7 @@ "settings.echoCancellation": null, "settings.autoGainControl": null, "settings.noiseSuppression": null, + "settings.drawerOverlayed": null, "filesharing.saveFileError": "无法保存文件", "filesharing.startingFileShare": "正在尝试共享文件", diff --git a/app/src/translations/cs.json b/app/src/translations/cs.json index f73144e..3eac16c 100644 --- a/app/src/translations/cs.json +++ b/app/src/translations/cs.json @@ -137,6 +137,7 @@ "settings.echoCancellation": null, "settings.autoGainControl": null, "settings.noiseSuppression": null, + "settings.drawerOverlayed": null, "filesharing.saveFileError": "Není možné uložit soubor", "filesharing.startingFileShare": "Pokouším se sdílet soubor", diff --git a/app/src/translations/de.json b/app/src/translations/de.json index d141ae9..402c4b3 100644 --- a/app/src/translations/de.json +++ b/app/src/translations/de.json @@ -138,6 +138,7 @@ "settings.echoCancellation": null, "settings.autoGainControl": null, "settings.noiseSuppression": null, + "settings.drawerOverlayed": null, "filesharing.saveFileError": "Fehler beim Speichern der Datei", "filesharing.startingFileShare": "Starte Teilen der Datei", diff --git a/app/src/translations/dk.json b/app/src/translations/dk.json index a0bc95f..c5c3a2d 100644 --- a/app/src/translations/dk.json +++ b/app/src/translations/dk.json @@ -138,6 +138,7 @@ "settings.echoCancellation": null, "settings.autoGainControl": null, "settings.noiseSuppression": null, + "settings.drawerOverlayed": null, "filesharing.saveFileError": "Kan ikke gemme fil", "filesharing.startingFileShare": "Forsøger at dele filen", diff --git a/app/src/translations/el.json b/app/src/translations/el.json index c21ef1d..d71764f 100644 --- a/app/src/translations/el.json +++ b/app/src/translations/el.json @@ -138,6 +138,7 @@ "settings.echoCancellation": null, "settings.autoGainControl": null, "settings.noiseSuppression": null, + "settings.drawerOverlayed": null, "filesharing.saveFileError": "Αδυναμία αποθήκευσης του αρχείου", "filesharing.startingFileShare": "Προσπάθεια διαμοιρασμού αρχείου", diff --git a/app/src/translations/en.json b/app/src/translations/en.json index 4b33dbd..344d660 100644 --- a/app/src/translations/en.json +++ b/app/src/translations/en.json @@ -138,6 +138,7 @@ "settings.echoCancellation": "Echo cancellation", "settings.autoGainControl": "Auto gain control", "settings.noiseSuppression": "Noise suppression", + "settings.drawerOverlayed": "Side drawer over content", "filesharing.saveFileError": "Unable to save file", "filesharing.startingFileShare": "Attempting to share file", diff --git a/app/src/translations/es.json b/app/src/translations/es.json index 9bf9744..758b0c8 100644 --- a/app/src/translations/es.json +++ b/app/src/translations/es.json @@ -138,6 +138,7 @@ "settings.echoCancellation": null, "settings.autoGainControl": null, "settings.noiseSuppression": null, + "settings.drawerOverlayed": null, "filesharing.saveFileError": "No ha sido posible guardar el fichero", "filesharing.startingFileShare": "Intentando compartir el fichero", diff --git a/app/src/translations/fr.json b/app/src/translations/fr.json index 2b74da9..2eb7edf 100644 --- a/app/src/translations/fr.json +++ b/app/src/translations/fr.json @@ -138,6 +138,7 @@ "settings.echoCancellation": null, "settings.autoGainControl": null, "settings.noiseSuppression": null, + "settings.drawerOverlayed": null, "filesharing.saveFileError": "Impossible d'enregistrer le fichier", "filesharing.startingFileShare": "Début du transfert de fichier", diff --git a/app/src/translations/hr.json b/app/src/translations/hr.json index 9d55c44..c0f8879 100644 --- a/app/src/translations/hr.json +++ b/app/src/translations/hr.json @@ -138,6 +138,7 @@ "settings.echoCancellation": null, "settings.autoGainControl": null, "settings.noiseSuppression": null, + "settings.drawerOverlayed": null, "filesharing.saveFileError": "Nije moguće spremiti datoteku", "filesharing.startingFileShare": "Pokušaj dijeljenja datoteke", diff --git a/app/src/translations/hu.json b/app/src/translations/hu.json index be0342d..cf65f1d 100644 --- a/app/src/translations/hu.json +++ b/app/src/translations/hu.json @@ -138,6 +138,7 @@ "settings.echoCancellation": "Visszhangelnyomás", "settings.autoGainControl": "Automatikus hangerő", "settings.noiseSuppression": "Zajelnyomás", + "settings.drawerOverlayed": null, "filesharing.saveFileError": "A file-t nem sikerült elmenteni", "filesharing.startingFileShare": "Fájl megosztása", diff --git a/app/src/translations/it.json b/app/src/translations/it.json index 8ce1764..5ce26b6 100644 --- a/app/src/translations/it.json +++ b/app/src/translations/it.json @@ -137,6 +137,7 @@ "settings.echoCancellation": null, "settings.autoGainControl": null, "settings.noiseSuppression": null, + "settings.drawerOverlayed": null, "filesharing.saveFileError": "Impossibile salvare file", "filesharing.startingFileShare": "Tentativo di condivisione file", diff --git a/app/src/translations/lv.json b/app/src/translations/lv.json index 5a39315..7bf0b24 100644 --- a/app/src/translations/lv.json +++ b/app/src/translations/lv.json @@ -132,6 +132,7 @@ "settings.echoCancellation": null, "settings.autoGainControl": null, "settings.noiseSuppression": null, + "settings.drawerOverlayed": null, "filesharing.saveFileError": "Nav iespējams saglabāt failu", "filesharing.startingFileShare": "Tiek mēģināts kopīgot failu", diff --git a/app/src/translations/nb.json b/app/src/translations/nb.json index 139341a..251858b 100644 --- a/app/src/translations/nb.json +++ b/app/src/translations/nb.json @@ -138,6 +138,7 @@ "settings.echoCancellation": "Echokansellering", "settings.autoGainControl": "Auto gain kontroll", "settings.noiseSuppression": "Støy reduksjon", + "settings.drawerOverlayed": "Sidemeny over innhold", "filesharing.saveFileError": "Klarte ikke å lagre fil", "filesharing.startingFileShare": "Starter fildeling", diff --git a/app/src/translations/pl.json b/app/src/translations/pl.json index 4c8f28a..705a6d7 100644 --- a/app/src/translations/pl.json +++ b/app/src/translations/pl.json @@ -138,6 +138,7 @@ "settings.echoCancellation": null, "settings.autoGainControl": null, "settings.noiseSuppression": null, + "settings.drawerOverlayed": null, "filesharing.saveFileError": "Nie można zapisać pliku", "filesharing.startingFileShare": "Próba udostępnienia pliku", diff --git a/app/src/translations/pt.json b/app/src/translations/pt.json index df2bf73..8250231 100644 --- a/app/src/translations/pt.json +++ b/app/src/translations/pt.json @@ -138,6 +138,7 @@ "settings.echoCancellation": null, "settings.autoGainControl": null, "settings.noiseSuppression": null, + "settings.drawerOverlayed": null, "filesharing.saveFileError": "Impossível de gravar o ficheiro", "filesharing.startingFileShare": "Tentando partilha de ficheiro", diff --git a/app/src/translations/ro.json b/app/src/translations/ro.json index fe7fb50..1ba455c 100644 --- a/app/src/translations/ro.json +++ b/app/src/translations/ro.json @@ -138,6 +138,7 @@ "settings.echoCancellation": null, "settings.autoGainControl": null, "settings.noiseSuppression": null, + "settings.drawerOverlayed": null, "filesharing.saveFileError": "Încercarea de a salva fișierul a eșuat", "filesharing.startingFileShare": "Partajarea fișierului", diff --git a/app/src/translations/tr.json b/app/src/translations/tr.json index 4a105d4..524c557 100644 --- a/app/src/translations/tr.json +++ b/app/src/translations/tr.json @@ -135,6 +135,7 @@ "settings.echoCancellation": null, "settings.autoGainControl": null, "settings.noiseSuppression": null, + "settings.drawerOverlayed": null, "filesharing.saveFileError": "Dosya kaydedilemiyor", "filesharing.startingFileShare": "Paylaşılan dosyaya erişiliyor", diff --git a/app/src/translations/uk.json b/app/src/translations/uk.json index 71ead8e..a8cc077 100644 --- a/app/src/translations/uk.json +++ b/app/src/translations/uk.json @@ -138,6 +138,7 @@ "settings.echoCancellation": null, "settings.autoGainControl": null, "settings.noiseSuppression": null, + "settings.drawerOverlayed": null, "filesharing.saveFileError": "Неможливо зберегти файл", "filesharing.startingFileShare": "Спроба поділитися файлом",