Move old settings modal to the new component
This commit is contained in:
parent
7a33f9ee67
commit
249dd85f92
@ -1,5 +1,7 @@
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import LoadingScreen from '../loading-screen/component';
|
||||
import KickedScreen from '../kicked-screen/component';
|
||||
|
||||
@ -14,11 +16,15 @@ const propTypes = {
|
||||
sidebarRight: PropTypes.element,
|
||||
media: PropTypes.element,
|
||||
actionsbar: PropTypes.element,
|
||||
settings: PropTypes.element,
|
||||
captions: PropTypes.element,
|
||||
modal: PropTypes.element,
|
||||
};
|
||||
|
||||
export default class App extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
renderNavBar() {
|
||||
const { navbar } = this.props;
|
||||
|
||||
@ -115,26 +121,22 @@ export default class App extends Component {
|
||||
return false;
|
||||
}
|
||||
|
||||
renderSettings() {
|
||||
const { settings } = this.props;
|
||||
|
||||
if (settings) {
|
||||
return (
|
||||
<section>
|
||||
{settings}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
renderAudioElement() {
|
||||
return (
|
||||
<audio id="remote-media" autoPlay="autoplay"></audio>
|
||||
);
|
||||
}
|
||||
|
||||
renderModal() {
|
||||
const { modal } = this.props;
|
||||
|
||||
if (modal) {
|
||||
return (<div>{modal}</div>);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.props.wasKicked) {
|
||||
return (
|
||||
@ -170,8 +172,8 @@ export default class App extends Component {
|
||||
</div>
|
||||
{this.renderSidebar()}
|
||||
</section>
|
||||
{this.renderSettings()}
|
||||
{this.renderAudioElement()}
|
||||
{this.renderModal()}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
import React, { Component, PropTypes, cloneElement } from 'react';
|
||||
import { createContainer } from 'meteor/react-meteor-data';
|
||||
import App from './component';
|
||||
import { subscribeForData, wasUserKicked, redirectToLogoutUrl } from './service';
|
||||
import { subscribeForData, wasUserKicked, redirectToLogoutUrl, getModal } from './service';
|
||||
import NavBarContainer from '../nav-bar/container';
|
||||
import ActionsBarContainer from '../actions-bar/container';
|
||||
import MediaContainer from '../media/container';
|
||||
import SettingsModal from '../modals/settings/component';
|
||||
import ClosedCaptionsContainer from '../closed-captions/container';
|
||||
|
||||
const defaultProps = {
|
||||
@ -58,6 +57,7 @@ export default createContainer(() => {
|
||||
return {
|
||||
wasKicked: wasUserKicked(),
|
||||
isLoading: getLoading(),
|
||||
modal: getModal(),
|
||||
redirectToLogoutUrl,
|
||||
};
|
||||
}, AppContainer);
|
||||
|
@ -86,11 +86,28 @@ function wasUserKicked() {
|
||||
return wasKicked;
|
||||
}
|
||||
|
||||
let modal = null;
|
||||
const modalDep = new Tracker.Dependency;
|
||||
|
||||
const getModal = () => {
|
||||
modalDep.depend();
|
||||
return modal;
|
||||
};
|
||||
|
||||
const showModal = (val) => {
|
||||
if (val !== modal) {
|
||||
modal = val;
|
||||
modalDep.changed();
|
||||
}
|
||||
};
|
||||
|
||||
export {
|
||||
subscribeForData,
|
||||
setCredentials,
|
||||
subscribeFor,
|
||||
subscribeToCollections,
|
||||
wasUserKicked,
|
||||
redirectToLogoutUrl
|
||||
redirectToLogoutUrl,
|
||||
getModal,
|
||||
showModal,
|
||||
};
|
||||
|
@ -5,8 +5,8 @@ import Button from '/imports/ui/components/button/component';
|
||||
import classNames from 'classnames';
|
||||
import styles from './styles';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import SettingsModal from '../modals/settings/component';
|
||||
import SessionMenu from '../modals/settings/submenus/session/component';
|
||||
import SettingsModal from '../modals-old/settings/component';
|
||||
import SessionMenu from '../modals-old/settings/submenus/session/component';
|
||||
import Dropdown from './dropdown-menu/component';
|
||||
import DropdownTrigger from './dropdown-trigger/component';
|
||||
import DropdownContent from './dropdown-content/component';
|
||||
|
203
bigbluebutton-html5/imports/ui/components/settings/component.jsx
Normal file
203
bigbluebutton-html5/imports/ui/components/settings/component.jsx
Normal file
@ -0,0 +1,203 @@
|
||||
import React from 'react';
|
||||
import Icon from '/imports/ui/components/icon/component';
|
||||
import Button from '/imports/ui/components/button/component';
|
||||
import Modal from '/imports/ui/components/modal/component';
|
||||
import AudioMenu from './submenus/audio/component';
|
||||
import VideoMenu from './submenus/video/component';
|
||||
import ApplicationMenu from './submenus/application/component';
|
||||
import UsersMenu from './submenus/users/component';
|
||||
import classNames from 'classnames';
|
||||
import ReactDOM from 'react-dom';
|
||||
import styles from './styles.scss';
|
||||
|
||||
export default class Settings extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.submenus = [];
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
/* activeSubmenu represents the submenu in the submenus array to be displayed to the user,
|
||||
* initialized to 0
|
||||
*/
|
||||
this.setState({ activeSubmenu: 0 });
|
||||
/* focusSubmenu represents the submenu in the submenus array which currently has focus,
|
||||
* initialized to 0
|
||||
*/
|
||||
this.setState({ focusSubmenu: 0 });
|
||||
this.submenus.push({ componentName: AudioMenu, tabIndex: 3,
|
||||
props: { title: 'Audio', prependIconName: 'icon-', icon: 'bbb-audio', }, });
|
||||
this.submenus.push({ componentName: VideoMenu, tabIndex: 4,
|
||||
props: { title: 'Video', prependIconName: 'icon-', icon: 'bbb-video', }, });
|
||||
this.submenus.push({ componentName: ApplicationMenu, tabIndex: 5,
|
||||
props: { title: 'Application', prependIconName: 'icon-', icon: 'bbb-application', }, });
|
||||
this.submenus.push({ componentName: UsersMenu, tabIndex: 6,
|
||||
props: { title: 'Participants', prependIconName: 'icon-', icon: 'bbb-user', }, });
|
||||
}
|
||||
|
||||
createMenu() {
|
||||
const curr = this.state.activeSubmenu === undefined ? 0 : this.state.activeSubmenu;
|
||||
|
||||
let props = {
|
||||
title: this.submenus[curr].props.title,
|
||||
prependIconName: this.submenus[curr].props.prependIconName,
|
||||
icon: this.submenus[curr].props.icon,
|
||||
};
|
||||
|
||||
const Submenu = this.submenus[curr].componentName;
|
||||
return <Submenu {...props}/>;
|
||||
}
|
||||
|
||||
/* When an option in the menu is clicked, set the activeSubmenu and focusSubmenu
|
||||
* to the value of index. If clicked out of bounds set to 0 or end of submenus array accordingly.
|
||||
*
|
||||
* activeSubmenu: the submenu to be displayed to the user
|
||||
* focusSubmenu: the submenu to set focus to
|
||||
*/
|
||||
clickSubmenu(i) {
|
||||
if (i <= 0) {
|
||||
this.setState({ activeSubmenu: 0, focusSubmenu: 0, });
|
||||
return;
|
||||
}
|
||||
|
||||
if (i >= this.submenus.length) {
|
||||
this.setState({ activeSubmenu: this.submenus.length - 1,
|
||||
focusSubmenu: this.submenus.length - 1, });
|
||||
return;
|
||||
} else {
|
||||
this.setState({ activeSubmenu: i, focusSubmenu: i, });
|
||||
}
|
||||
}
|
||||
|
||||
/* calls the focus method on an object in the submenu */
|
||||
setFocus() {
|
||||
ReactDOM.findDOMNode(this.refs[`submenu${this.state.focusSubmenu}`]).focus();
|
||||
}
|
||||
|
||||
/* Checks for key presses within the submenu list. Key behaviour varies.
|
||||
*
|
||||
* Tab: changes focus to next submenu or element outside of menu
|
||||
* Shift+Tab: changes focus to previous submenu or element outside of menu
|
||||
* Up Arrow: changes focus to previous submenu, can cycle through menu
|
||||
* Down Arrow: changes focus to next submenu, can cycle through menu
|
||||
* Spacebar: selects submenu in focus and sets as active
|
||||
* Enter: selects submenu in focus and sets as active
|
||||
*/
|
||||
handleKeyDown(event) {
|
||||
// tab
|
||||
if (event.keyCode === 9) {
|
||||
let newIndex = 0;
|
||||
if (this.state.focusSubmenu >= this.submenus.length - 1) {
|
||||
newIndex = this.submenus.length - 1;
|
||||
} else {
|
||||
newIndex = this.state.focusSubmenu + 1;
|
||||
}
|
||||
|
||||
this.setState({ focusSubmenu: newIndex });
|
||||
return;
|
||||
}
|
||||
|
||||
// shift+tab
|
||||
if (event.shiftKey && event.keyCode === 9) {
|
||||
let newIndex = 0;
|
||||
if (this.state.focusSubmenu <= 0) {
|
||||
newIndex = 0;
|
||||
} else {
|
||||
newIndex = this.state.focusSubmenu - 1;
|
||||
}
|
||||
|
||||
this.setState({ focusSubmenu: newIndex });
|
||||
return;
|
||||
}
|
||||
|
||||
// up arrow
|
||||
if (event.keyCode === 38) {
|
||||
if (this.state.focusSubmenu <= 0) {
|
||||
this.setState({ focusSubmenu: this.submenus.length - 1 }, function () {
|
||||
this.setFocus();
|
||||
});
|
||||
} else {
|
||||
this.setState({ focusSubmenu: this.state.focusSubmenu - 1 }, function () {
|
||||
this.setFocus();
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// down arrow
|
||||
if (event.keyCode === 40) {
|
||||
if (this.state.focusSubmenu >= this.submenus.length - 1) {
|
||||
this.setState({ focusSubmenu: 0 }, function () {
|
||||
this.setFocus();
|
||||
});
|
||||
} else {
|
||||
this.setState({ focusSubmenu: this.state.focusSubmenu + 1 }, function () {
|
||||
this.setFocus();
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// spacebar or enter
|
||||
if (event.keyCode === 32 || event.keyCode === 13) {
|
||||
this.setState({ activeSubmenu: this.state.focusSubmenu });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Keeps the focusSubmenu variable at the correct value when
|
||||
* tabbing or shift-tabbing out of the submenu array
|
||||
*/
|
||||
handleFocus(index) {
|
||||
this.setState({ focusSubmenu: index });
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Modal
|
||||
title="Settings"
|
||||
confirm={{
|
||||
callback: (() => {
|
||||
this.setState({ activeSubmenu: 0, focusSubmenu: 0 });
|
||||
console.log('SHOULD APPLY SETTINGS CHANGES');
|
||||
}),
|
||||
label: 'Done',
|
||||
description: 'Saves the changes and close the settings menu',
|
||||
}}
|
||||
dismiss={{
|
||||
callback: (() => {
|
||||
this.setState({ activeSubmenu: 0, focusSubmenu: 0 });
|
||||
console.log('SHOULD DISCART SETTINGS CHANGES');
|
||||
}),
|
||||
label: 'Cancel',
|
||||
description: 'Discart the changes and close the settings menu',
|
||||
}}>
|
||||
<div className={styles.full} role='presentation'>
|
||||
<div className={styles.settingsMenuLeft}>
|
||||
<ul className={styles.settingsSubmenu} role='menu'>
|
||||
{this.submenus.map((value, index) => (
|
||||
<li key={index} ref={'submenu' + index} role='menuitem' tabIndex={value.tabIndex}
|
||||
onClick={this.clickSubmenu.bind(this, index)}
|
||||
onKeyDown={this.handleKeyDown.bind(this)}
|
||||
onFocus={this.handleFocus.bind(this, index)}
|
||||
className={classNames(styles.settingsSubmenuItem,
|
||||
index == this.state.activeSubmenu ? styles.settingsSubmenuItemActive : null)}>
|
||||
<Icon key={index} prependIconName={value.props.prependIconName}
|
||||
iconName={value.props.icon} title={value.props.title}/>
|
||||
<span className={styles.settingsSubmenuItemText}>{value.props.title}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<div className={styles.settingsMenuRight} role='presentation'>
|
||||
{this.createMenu()}
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
Settings.defaultProps = { title: 'Settings' };
|
@ -0,0 +1,49 @@
|
||||
@import "../../stylesheets/variables/_all";
|
||||
|
||||
.full {
|
||||
clear: both;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.settingsMenuLeft {
|
||||
border-right: 2px solid $color-gray-light;
|
||||
border-top: 2px solid $color-gray-light;
|
||||
float: left;
|
||||
width: 30%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.settingsMenuRight {
|
||||
border-top: 2px solid $color-gray-light;
|
||||
float: right;
|
||||
padding-left: 10px;
|
||||
width: 70%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
color: $color-heading;
|
||||
}
|
||||
|
||||
.settingsSubmenu {
|
||||
list-style-type: none;
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
.settingsSubmenuItem {
|
||||
color: $color-heading;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.settingsSubmenuItemText {
|
||||
padding-left: 10px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.settingsSubmenuItemActive {
|
||||
border-right: 4px solid $color-primary;
|
||||
color: $color-primary;
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
import React from 'react';
|
||||
import Modal from 'react-modal';
|
||||
import Icon from '/imports/ui/components/icon/component';
|
||||
import Button from '/imports/ui/components/button/component';
|
||||
import BaseMenu from '../base/component';
|
||||
import ReactDOM from 'react-dom';
|
||||
import FontControl from '/imports/api/FontControl';
|
||||
import styles from '../styles.scss';
|
||||
|
||||
export default class ApplicationMenu extends BaseMenu {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
currentFontSize: FontControl.fontSizeEnum.MEDIUM,
|
||||
};
|
||||
}
|
||||
|
||||
getContent() {
|
||||
return (
|
||||
<div className={styles.full} role='presentation'>
|
||||
<div className={styles.row} role='presentation'>
|
||||
<label><input type='checkbox' tabIndex='7' aria-labelledby='audioNotifLabel'
|
||||
aria-describedby='audioNotifDesc' />Audio notifications for chat</label>
|
||||
<div id='audioNotifLabel' hidden>Audio notifications</div>
|
||||
<div id='audioNotifDesc' hidden>
|
||||
Toggles the audio notifications for chat.</div>
|
||||
</div>
|
||||
<div className={styles.row} role='presentation'>
|
||||
<label><input type='checkbox' tabIndex='8' aria-labelledby='pushNotifLabel'
|
||||
aria-describedby='pushNotifDesc' />Push notifications for chat</label>
|
||||
<div id='pushNotifLabel' hidden>Push notifications</div>
|
||||
<div id='pushNotifDesc' hidden>
|
||||
Toggles the push notifications for chat.</div>
|
||||
</div>
|
||||
<div className={styles.applicationFontContainer} role='presentation'>
|
||||
<div className={styles.fontBarLeft}>
|
||||
<p>Font size</p>
|
||||
</div>
|
||||
<div className={styles.fontBarMid}>
|
||||
<p>{FontControl.getFontSizeName.call(this)}</p>
|
||||
</div>
|
||||
<div className={styles.fontBarRight} role='presentation'>
|
||||
<Button
|
||||
onClick={FontControl.increaseFontSize.bind(this)}
|
||||
icon={'circle-add'}
|
||||
circle={true}
|
||||
tabIndex={9}
|
||||
hideLabel={true}
|
||||
label={'Increase Font'}
|
||||
aria-labelledby={'sizeUpLabel'}
|
||||
aria-describedby={'sizeUpDesc'}
|
||||
/>
|
||||
<div id='sizeUpLabel' hidden>Font size up</div>
|
||||
<div id='sizeUpDesc' hidden>
|
||||
Increases the font size of the application.</div>
|
||||
<Button
|
||||
onClick={FontControl.decreaseFontSize.bind(this)}
|
||||
icon={'circle-minus'}
|
||||
circle={true}
|
||||
tabIndex={10}
|
||||
hideLabel={true}
|
||||
label={'Decrease Font'}
|
||||
aria-labelledby={'sizeDownLabel'}
|
||||
aria-describedby={'sizeDownDesc'}
|
||||
/>
|
||||
<div id='sizeDownLabel' hidden>Font size down</div>
|
||||
<div id='sizeDownDesc' hidden>
|
||||
Decreases the font size of the application.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
@ -0,0 +1,79 @@
|
||||
import React from 'react';
|
||||
import Modal from 'react-modal';
|
||||
import Icon from '/imports/ui/components/icon/component';
|
||||
import Button from '/imports/ui/components/button/component';
|
||||
import BaseMenu from '../base/component';
|
||||
import styles from '../styles.scss';
|
||||
import {joinListenOnly, joinMicrophone, exitAudio} from '/imports/api/phone';
|
||||
|
||||
export default class AudioMenu extends BaseMenu {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.testAudio = this.testAudio.bind(this);
|
||||
}
|
||||
|
||||
testAudio() {
|
||||
|
||||
}
|
||||
|
||||
getContent() {
|
||||
return (
|
||||
<div className={styles.full} role='presentation'>
|
||||
<div className={styles.containerLeftHalf}>
|
||||
<label htmlFor='microphone'>Microphone source</label>
|
||||
</div>
|
||||
<div className={styles.containerRightHalf}>
|
||||
<label htmlFor='audioVolume'>Your audio stream volume</label>
|
||||
</div>
|
||||
<div className={styles.containerLeftHalfContent} role='presentation'>
|
||||
<select id='microphone' defaultValue='0' tabIndex='7' role='listbox'
|
||||
aria-labelledby='micLabel' aria-describedby='micDesc'>
|
||||
<option value='0' disabled>Displace Audio</option>
|
||||
<option value='1' role='option'>audio 1</option>
|
||||
<option value='2' role='option'>audio 2</option>
|
||||
<option value='3' role='option'>audio 3</option>
|
||||
</select>
|
||||
<div id='micLabel' hidden>Select microphone source</div>
|
||||
<div id='micDesc' hidden>
|
||||
Chooses a microphone source from the dropdown menu.</div>
|
||||
</div>
|
||||
<div className={styles.containerRightHalfContent}>
|
||||
<input style={{ width: '90%' }} type='text' placeholder='volume bar placeholder'
|
||||
tabIndex='-1' />
|
||||
</div>
|
||||
<div className={styles.containerLeftHalf}>
|
||||
<label htmlFor='speaker'>Speaker source</label>
|
||||
</div>
|
||||
<div className={styles.containerRightHalf}><br/></div>
|
||||
<div className={styles.containerLeftHalfContent} role='presentation'>
|
||||
<select id='speaker' defaultValue='0' tabIndex='8' role='listbox'
|
||||
aria-labelledby='spkrLabel' aria-describedby='spkrDesc'>
|
||||
<option value='0' disabled>Displace Audio</option>
|
||||
<option value='1' role='option'>audio 1</option>
|
||||
<option value='2' role='option'>audio 2</option>
|
||||
<option value='3' role='option'>audio 3</option>
|
||||
</select>
|
||||
<div id='spkrLabel' hidden>Select speaker source</div>
|
||||
<div id='spkrDesc' hidden>
|
||||
Chooses a speaker source from the dropdown menu.</div>
|
||||
</div>
|
||||
<div className={styles.containerRightHalfContent} role='presentation'>
|
||||
<Button className={styles.testAudioBtn}
|
||||
onClick={this.testAudio}
|
||||
label={'Test Audio'}
|
||||
color={'primary'}
|
||||
ghost={true}
|
||||
icon={'audio'}
|
||||
tabIndex={9}
|
||||
aria-labelledby={'testAudioLabel'}
|
||||
aria-describedby={'testAudioDesc'}
|
||||
/>
|
||||
<div id='testAudioLabel' hidden>Test audio</div>
|
||||
<div id='testAudioDesc' hidden>
|
||||
Previews the audio output of your microphone.</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
@ -0,0 +1,26 @@
|
||||
import React from 'react';
|
||||
import Modal from 'react-modal';
|
||||
import Icon from '/imports/ui/components/icon/component';
|
||||
import Button from '/imports/ui/components/button/component';
|
||||
import styles from '../styles.scss';
|
||||
|
||||
export default class BaseMenu extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
getContent() {
|
||||
return (<div>parent content</div>);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className={styles.full} role='presentation'>
|
||||
<h3 className={styles.submenuTitle}>{this.props.title}</h3>
|
||||
<div className={styles.submenuContent} role='presentation'>
|
||||
{this.getContent()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
@ -0,0 +1,140 @@
|
||||
@import "../../../stylesheets/variables/_all";
|
||||
|
||||
/* General Submenu */
|
||||
.submenuTitle {
|
||||
height: 45px;
|
||||
margin: 0px;
|
||||
padding-top: 12px;
|
||||
font-size: $font-size-large;
|
||||
font-weight: $headings-font-weight;
|
||||
}
|
||||
|
||||
.submenuContent {
|
||||
height: 85%;
|
||||
margin: 0px;
|
||||
padding-top: 12px;
|
||||
font-size: $font-size-base;
|
||||
color: $color-gray-light;
|
||||
}
|
||||
|
||||
div.submenuContent select {
|
||||
width: 90%;
|
||||
padding-top: 5px;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
/*outline: none;*/
|
||||
color: $color-gray-light;
|
||||
}
|
||||
|
||||
.containerLeftHalf {
|
||||
width: 50%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.containerRightHalf {
|
||||
width: 50%;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.containerLeftHalfContent {
|
||||
@extend .containerLeftHalf;
|
||||
@extend .row;
|
||||
}
|
||||
|
||||
.containerRightHalfContent {
|
||||
@extend .containerRightHalf;
|
||||
@extend .row;
|
||||
}
|
||||
|
||||
div.containerLeftHalf label, div.containerRightHalf label {
|
||||
font-size: 0.75em;
|
||||
font-weight: 600;
|
||||
color: $color-primary;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
input[type=checkbox] {
|
||||
float: right;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
ul li {
|
||||
padding-bottom: 9%;
|
||||
}
|
||||
|
||||
/* Application Submenu */
|
||||
.applicationFontContainer {
|
||||
border-top: solid 1px $color-gray-light;
|
||||
margin-top: 10%;
|
||||
padding-top: 10%;
|
||||
}
|
||||
|
||||
.fontBarLeft {
|
||||
float: left;
|
||||
margin: 0px;
|
||||
height: 100%;
|
||||
width: 25%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.fontBarMid {
|
||||
float: left;
|
||||
margin: 0px;
|
||||
height: 100%;
|
||||
width: 50%;
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.fontBarRight {
|
||||
float: left;
|
||||
margin: 0px;
|
||||
height: 100%;
|
||||
width: 25%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.fontBarLeft p, .fontBarMid p {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
/* Users Submenu */
|
||||
.checkboxOffset {
|
||||
margin-right: 5%;
|
||||
}
|
||||
|
||||
|
||||
/* Buttons */
|
||||
.defaultBtn {
|
||||
width: 90px;
|
||||
border-radius: 18px;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.testAudioBtn {
|
||||
@extend .defaultBtn;
|
||||
width: 140px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
/* Submenu containers */
|
||||
.full {
|
||||
clear: both;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.row {
|
||||
height: 42px;
|
||||
}
|
||||
|
||||
.indentedRow {
|
||||
@extend .row;
|
||||
padding-left: 10%;
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
import React from 'react';
|
||||
import Modal from 'react-modal';
|
||||
import Icon from '/imports/ui/components/icon/component';
|
||||
import Button from '/imports/ui/components/button/component';
|
||||
import BaseMenu from '../base/component';
|
||||
import styles from '../styles.scss';
|
||||
|
||||
export default class UsersMenu extends BaseMenu {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
getContent() {
|
||||
return (
|
||||
<div className={styles.full} role='presentation'>
|
||||
<div className={styles.row} role='presentation'>
|
||||
<label><input className={styles.checkboxOffset} type='checkbox' tabIndex='7'
|
||||
aria-labelledby='muteALlLabel' aria-describedby='muteAllDesc' />
|
||||
Mute all except the presenter</label>
|
||||
</div>
|
||||
<div id='muteAllLabel' hidden>Mute all</div>
|
||||
<div id='muteAllDesc' hidden>Mutes all participants except the presenter.</div>
|
||||
|
||||
<div className={styles.row} role='presentation'>
|
||||
<label><input className={styles.checkboxOffset} type="checkbox" tabIndex='8'
|
||||
aria-labelledby='lockAllLabel' aria-describedby='lockAllDesc' />
|
||||
Lock all participants</label>
|
||||
</div>
|
||||
<div id='lockAllLabel' hidden>Lock all</div>
|
||||
<div id='lockAllDesc' hidden>Toggles locked status for all participants.</div>
|
||||
|
||||
<div className={styles.indentedRow} role='presentation'>
|
||||
<label><input className={styles.checkboxOffset} type='checkbox' tabIndex='9'
|
||||
aria-labelledby='webcamLabel' aria-describedby='webcamDesc' />Webcam</label>
|
||||
</div>
|
||||
<div id='webcamLabel' hidden>Webcam lock</div>
|
||||
<div id='webcamDesc' hidden>Disables the webcam for all locked participants.</div>
|
||||
|
||||
<div className={styles.indentedRow} role='presentation'>
|
||||
<label><input className={styles.checkboxOffset} type='checkbox' tabIndex='10'
|
||||
aria-labelledby='micLabel' aria-describedby='micDesc' />Microphone</label>
|
||||
</div>
|
||||
<div id='micLabel' hidden>Microphone lock</div>
|
||||
<div id='micDesc' hidden>Disables the microphone for all locked participants.</div>
|
||||
|
||||
<div className={styles.indentedRow} role='presentation'>
|
||||
<label><input className={styles.checkboxOffset} type='checkbox' tabIndex='11'
|
||||
aria-labelledby='pubChatLabel' aria-describedby='pubChatDesc' />Public chat</label>
|
||||
</div>
|
||||
<div id='pubChatLabel' hidden>Public chat lock</div>
|
||||
<div id='pubChatDesc' hidden>Disables public chat for all locked participants.</div>
|
||||
|
||||
<div className={styles.indentedRow} role='presentation'>
|
||||
<label><input className={styles.checkboxOffset} type='checkbox' tabIndex='12'
|
||||
aria-labelledby='privChatLabel' aria-describedby='privChatDesc' />Private chat</label>
|
||||
</div>
|
||||
<div id='privChatLabel' hidden>Private chat lock</div>
|
||||
<div id='privChatDesc' hidden>Disables private chat for all locked participants.</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
@ -0,0 +1,52 @@
|
||||
import React from 'react';
|
||||
import Modal from 'react-modal';
|
||||
import Icon from '/imports/ui/components/icon/component';
|
||||
import Button from '/imports/ui/components/button/component';
|
||||
import BaseMenu from '../base/component';
|
||||
import styles from '../styles.scss';
|
||||
|
||||
export default class VideoMenu extends BaseMenu {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
getContent() {
|
||||
return (
|
||||
<div className={styles.full} role='presentation'>
|
||||
<div className={styles.containerLeftHalf}>
|
||||
<label htmlFor='camera'>Select camera</label>
|
||||
</div>
|
||||
<div className={styles.containerRightHalf}>
|
||||
<label htmlFor='quality' >Video quality</label>
|
||||
</div>
|
||||
<div className={styles.containerLeftHalfContent} role='presentation'>
|
||||
<select id='camera' defaultValue='0' tabIndex='7'
|
||||
aria-labelledby='camLabel' aria-describedby='camDesc'>
|
||||
<option value='0' disabled>Select camera</option>
|
||||
<option value='1'>Camera 1</option>
|
||||
<option value='2'>Camera 2</option>
|
||||
<option value='3'>Camera 3</option>
|
||||
</select>
|
||||
<div id='camLabel' hidden>Camera source</div>
|
||||
<div id='camDesc' hidden>
|
||||
Chooses a camera source from the dropdown menu.</div>
|
||||
</div>
|
||||
<div className={styles.containerRightHalfContent} role='presentation'>
|
||||
<select id='quality' defaultValue='0' tabIndex='8'
|
||||
aria-labelledby='vidLabel' aria-describedby='vidDesc'>
|
||||
<option value='0' disabled>Select quality</option>
|
||||
<option value='1'>Low</option>
|
||||
<option value='2'>Medium</option>
|
||||
<option value='3'>High</option>
|
||||
</select>
|
||||
<div id='vidLabel' hidden>Video quality</div>
|
||||
<div id='vidDesc' hidden>
|
||||
Chooses the video quality level from the dropdown menu.</div>
|
||||
</div>
|
||||
<div className={styles.row}>
|
||||
<div>Viewing participants webcams</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue
Block a user