diff --git a/app/src/actions/roomActions.js b/app/src/actions/roomActions.js
index ac97179..ba9d2dc 100644
--- a/app/src/actions/roomActions.js
+++ b/app/src/actions/roomActions.js
@@ -52,12 +52,18 @@ export const setJoinByAccessCode = (joinByAccessCode) =>
payload : { joinByAccessCode }
});
-export const setSettingsOpen = ({ settingsOpen }) =>
+export const setSettingsOpen = (settingsOpen) =>
({
type : 'SET_SETTINGS_OPEN',
payload : { settingsOpen }
});
+export const setSettingsTab = (tab) =>
+ ({
+ type : 'SET_SETTINGS_TAB',
+ payload : { tab }
+ });
+
export const setLockDialogOpen = ({ lockDialogOpen }) =>
({
type : 'SET_LOCK_DIALOG_OPEN',
diff --git a/app/src/components/Controls/TopBar.js b/app/src/components/Controls/TopBar.js
index 7f4be52..9b7ae92 100644
--- a/app/src/components/Controls/TopBar.js
+++ b/app/src/components/Controls/TopBar.js
@@ -427,7 +427,7 @@ const mapDispatchToProps = (dispatch) =>
},
setSettingsOpen : (settingsOpen) =>
{
- dispatch(roomActions.setSettingsOpen({ settingsOpen }));
+ dispatch(roomActions.setSettingsOpen(settingsOpen));
},
setLockDialogOpen : (lockDialogOpen) =>
{
diff --git a/app/src/components/Settings/AdvancedSettings.js b/app/src/components/Settings/AdvancedSettings.js
new file mode 100644
index 0000000..131395e
--- /dev/null
+++ b/app/src/components/Settings/AdvancedSettings.js
@@ -0,0 +1,114 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import { withStyles } from '@material-ui/core/styles';
+import { withRoomContext } from '../../RoomContext';
+import * as settingsActions from '../../actions/settingsActions';
+import PropTypes from 'prop-types';
+import { useIntl, FormattedMessage } from 'react-intl';
+import MenuItem from '@material-ui/core/MenuItem';
+import FormHelperText from '@material-ui/core/FormHelperText';
+import FormControl from '@material-ui/core/FormControl';
+import FormControlLabel from '@material-ui/core/FormControlLabel';
+import Select from '@material-ui/core/Select';
+import Checkbox from '@material-ui/core/Checkbox';
+
+const styles = (theme) =>
+ ({
+ setting :
+ {
+ padding : theme.spacing(2)
+ },
+ formControl :
+ {
+ display : 'flex'
+ }
+ });
+
+const AdvancedSettings = ({
+ roomClient,
+ settings,
+ onToggleAdvancedMode,
+ classes
+}) =>
+{
+ const intl = useIntl();
+
+ return (
+
+ }
+ label={intl.formatMessage({
+ id : 'settings.advancedMode',
+ defaultMessage : 'Advanced mode'
+ })}
+ />
+ { !window.config.lockLastN &&
+
+ }
+
+ );
+};
+
+AdvancedSettings.propTypes =
+{
+ roomClient : PropTypes.any.isRequired,
+ settings : PropTypes.object.isRequired,
+ onToggleAdvancedMode : PropTypes.func.isRequired,
+ classes : PropTypes.object.isRequired
+};
+
+const mapStateToProps = (state) =>
+ ({
+ settings : state.settings
+ });
+
+const mapDispatchToProps = {
+ onToggleAdvancedMode : settingsActions.toggleAdvancedMode
+};
+
+export default withRoomContext(connect(
+ mapStateToProps,
+ mapDispatchToProps,
+ null,
+ {
+ areStatesEqual : (next, prev) =>
+ {
+ return (
+ prev.settings === next.settings
+ );
+ }
+ }
+)(withStyles(styles)(AdvancedSettings)));
\ No newline at end of file
diff --git a/app/src/components/Settings/AppearenceSettings.js b/app/src/components/Settings/AppearenceSettings.js
new file mode 100644
index 0000000..71f250a
--- /dev/null
+++ b/app/src/components/Settings/AppearenceSettings.js
@@ -0,0 +1,132 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import * as appPropTypes from '../appPropTypes';
+import { withStyles } from '@material-ui/core/styles';
+import * as roomActions from '../../actions/roomActions';
+import * as settingsActions from '../../actions/settingsActions';
+import PropTypes from 'prop-types';
+import { useIntl, FormattedMessage } from 'react-intl';
+import MenuItem from '@material-ui/core/MenuItem';
+import FormHelperText from '@material-ui/core/FormHelperText';
+import FormControl from '@material-ui/core/FormControl';
+import FormControlLabel from '@material-ui/core/FormControlLabel';
+import Select from '@material-ui/core/Select';
+import Checkbox from '@material-ui/core/Checkbox';
+
+const styles = (theme) =>
+ ({
+ setting :
+ {
+ padding : theme.spacing(2)
+ },
+ formControl :
+ {
+ display : 'flex'
+ }
+ });
+
+const AppearenceSettings = ({
+ room,
+ settings,
+ onTogglePermanentTopBar,
+ handleChangeMode,
+ classes
+}) =>
+{
+ const intl = useIntl();
+
+ const modes = [ {
+ value : 'democratic',
+ label : intl.formatMessage({
+ id : 'label.democratic',
+ defaultMessage : 'Democratic view'
+ })
+ }, {
+ value : 'filmstrip',
+ label : intl.formatMessage({
+ id : 'label.filmstrip',
+ defaultMessage : 'Filmstrip view'
+ })
+ } ];
+
+ return (
+
+
+ }
+ label={intl.formatMessage({
+ id : 'settings.permanentTopBar',
+ defaultMessage : 'Permanent top bar'
+ })}
+ />
+
+ );
+};
+
+AppearenceSettings.propTypes =
+{
+ room : appPropTypes.Room.isRequired,
+ settings : PropTypes.object.isRequired,
+ onTogglePermanentTopBar : PropTypes.func.isRequired,
+ handleChangeMode : PropTypes.func.isRequired,
+ classes : PropTypes.object.isRequired
+};
+
+const mapStateToProps = (state) =>
+ ({
+ room : state.room,
+ settings : state.settings
+ });
+
+const mapDispatchToProps = {
+ onTogglePermanentTopBar : settingsActions.togglePermanentTopBar,
+ handleChangeMode : roomActions.setDisplayMode
+};
+
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps,
+ null,
+ {
+ areStatesEqual : (next, prev) =>
+ {
+ return (
+ prev.room === next.room &&
+ prev.settings === next.settings
+ );
+ }
+ }
+)(withStyles(styles)(AppearenceSettings));
\ No newline at end of file
diff --git a/app/src/components/Settings/MediaSettings.js b/app/src/components/Settings/MediaSettings.js
new file mode 100644
index 0000000..fa9728b
--- /dev/null
+++ b/app/src/components/Settings/MediaSettings.js
@@ -0,0 +1,284 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import * as appPropTypes from '../appPropTypes';
+import { withStyles } from '@material-ui/core/styles';
+import { withRoomContext } from '../../RoomContext';
+import PropTypes from 'prop-types';
+import { useIntl, FormattedMessage } from 'react-intl';
+import MenuItem from '@material-ui/core/MenuItem';
+import FormHelperText from '@material-ui/core/FormHelperText';
+import FormControl from '@material-ui/core/FormControl';
+import Select from '@material-ui/core/Select';
+
+const styles = (theme) =>
+ ({
+ setting :
+ {
+ padding : theme.spacing(2)
+ },
+ formControl :
+ {
+ display : 'flex'
+ }
+ });
+
+const MediaSettings = ({
+ roomClient,
+ me,
+ settings,
+ classes
+}) =>
+{
+ const intl = useIntl();
+
+ const resolutions = [ {
+ value : 'low',
+ label : intl.formatMessage({
+ id : 'label.low',
+ defaultMessage : 'Low'
+ })
+ },
+ {
+ value : 'medium',
+ label : intl.formatMessage({
+ id : 'label.medium',
+ defaultMessage : 'Medium'
+ })
+ },
+ {
+ value : 'high',
+ label : intl.formatMessage({
+ id : 'label.high',
+ defaultMessage : 'High (HD)'
+ })
+ },
+ {
+ value : 'veryhigh',
+ label : intl.formatMessage({
+ id : 'label.veryHigh',
+ defaultMessage : 'Very high (FHD)'
+ })
+ },
+ {
+ value : 'ultra',
+ label : intl.formatMessage({
+ id : 'label.ultra',
+ defaultMessage : 'Ultra (UHD)'
+ })
+ } ];
+
+ let webcams;
+
+ if (me.webcamDevices)
+ webcams = Object.values(me.webcamDevices);
+ else
+ webcams = [];
+
+ let audioDevices;
+
+ if (me.audioDevices)
+ audioDevices = Object.values(me.audioDevices);
+ else
+ audioDevices = [];
+
+ let audioOutputDevices;
+
+ if (me.audioOutputDevices)
+ audioOutputDevices = Object.values(me.audioOutputDevices);
+ else
+ audioOutputDevices = [];
+
+ return (
+
+
+
+ { 'audioOutputSupportedBrowsers' in window.config &&
+ window.config.audioOutputSupportedBrowsers.includes(me.browser.name) &&
+
+ }
+
+
+ );
+};
+
+MediaSettings.propTypes =
+{
+ roomClient : PropTypes.any.isRequired,
+ me : appPropTypes.Me.isRequired,
+ settings : PropTypes.object.isRequired,
+ classes : PropTypes.object.isRequired
+};
+
+const mapStateToProps = (state) =>
+{
+ return {
+ me : state.me,
+ settings : state.settings
+ };
+};
+
+export default withRoomContext(connect(
+ mapStateToProps,
+ null,
+ null,
+ {
+ areStatesEqual : (next, prev) =>
+ {
+ return (
+ prev.me === next.me &&
+ prev.settings === next.settings
+ );
+ }
+ }
+)(withStyles(styles)(MediaSettings)));
\ No newline at end of file
diff --git a/app/src/components/Settings/Settings.js b/app/src/components/Settings/Settings.js
index 064aa2f..6633829 100644
--- a/app/src/components/Settings/Settings.js
+++ b/app/src/components/Settings/Settings.js
@@ -1,22 +1,25 @@
import React from 'react';
import { connect } from 'react-redux';
-import * as appPropTypes from '../appPropTypes';
import { withStyles } from '@material-ui/core/styles';
-import { withRoomContext } from '../../RoomContext';
import * as roomActions from '../../actions/roomActions';
-import * as settingsActions from '../../actions/settingsActions';
import PropTypes from 'prop-types';
import { useIntl, FormattedMessage } from 'react-intl';
+import Tabs from '@material-ui/core/Tabs';
+import Tab from '@material-ui/core/Tab';
+import MediaSettings from './MediaSettings';
+import AppearenceSettings from './AppearenceSettings';
+import AdvancedSettings from './AdvancedSettings';
import Dialog from '@material-ui/core/Dialog';
import DialogTitle from '@material-ui/core/DialogTitle';
import DialogActions from '@material-ui/core/DialogActions';
import Button from '@material-ui/core/Button';
-import MenuItem from '@material-ui/core/MenuItem';
-import FormHelperText from '@material-ui/core/FormHelperText';
-import FormControl from '@material-ui/core/FormControl';
-import FormControlLabel from '@material-ui/core/FormControlLabel';
-import Select from '@material-ui/core/Select';
-import Checkbox from '@material-ui/core/Checkbox';
+
+const tabs =
+[
+ 'media',
+ 'appearence',
+ 'advanced'
+];
const styles = (theme) =>
({
@@ -43,106 +46,27 @@ const styles = (theme) =>
width : '90vw'
}
},
- setting :
+ tabsHeader :
{
- padding : theme.spacing(2)
- },
- formControl :
- {
- display : 'flex'
+ flexGrow : 1
}
});
const Settings = ({
- roomClient,
- room,
- me,
- settings,
- onToggleAdvancedMode,
- onTogglePermanentTopBar,
+ currentSettingsTab,
+ settingsOpen,
handleCloseSettings,
- handleChangeMode,
+ setSettingsTab,
classes
}) =>
{
const intl = useIntl();
- const modes = [ {
- value : 'democratic',
- label : intl.formatMessage({
- id : 'label.democratic',
- defaultMessage : 'Democratic view'
- })
- }, {
- value : 'filmstrip',
- label : intl.formatMessage({
- id : 'label.filmstrip',
- defaultMessage : 'Filmstrip view'
- })
- } ];
-
- const resolutions = [ {
- value : 'low',
- label : intl.formatMessage({
- id : 'label.low',
- defaultMessage : 'Low'
- })
- },
- {
- value : 'medium',
- label : intl.formatMessage({
- id : 'label.medium',
- defaultMessage : 'Medium'
- })
- },
- {
- value : 'high',
- label : intl.formatMessage({
- id : 'label.high',
- defaultMessage : 'High (HD)'
- })
- },
- {
- value : 'veryhigh',
- label : intl.formatMessage({
- id : 'label.veryHigh',
- defaultMessage : 'Very high (FHD)'
- })
- },
- {
- value : 'ultra',
- label : intl.formatMessage({
- id : 'label.ultra',
- defaultMessage : 'Ultra (UHD)'
- })
- } ];
-
- let webcams;
-
- if (me.webcamDevices)
- webcams = Object.values(me.webcamDevices);
- else
- webcams = [];
-
- let audioDevices;
-
- if (me.audioDevices)
- audioDevices = Object.values(me.audioDevices);
- else
- audioDevices = [];
-
- let audioOutputDevices;
-
- if (me.audioOutputDevices)
- audioOutputDevices = Object.values(me.audioOutputDevices);
- else
- audioOutputDevices = [];
-
return (