bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/settings/component.jsx

211 lines
6.8 KiB
React
Raw Normal View History

2016-05-06 05:14:39 +08:00
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';
2016-05-06 05:14:39 +08:00
import classNames from 'classnames';
2016-05-07 01:46:14 +08:00
import ReactDOM from 'react-dom';
import styles from './styles.scss';
2016-05-06 05:14:39 +08:00
export default class Settings extends React.Component {
2016-05-06 05:14:39 +08:00
constructor(props) {
super(props);
this.submenus = [];
this.state = { activeSubmenu: 0, focusSubmenu: 0 };
2016-05-06 05:14:39 +08:00
}
2016-11-24 10:01:51 +08:00
renderSettingOptions() {
const { isPresenter, role } = this.props;
this.submenus = [];
this.submenus.push({ componentName: AudioMenu, tabIndex: 3,
2016-08-06 03:21:35 +08:00
props: { title: 'Audio', prependIconName: 'icon-', icon: 'bbb-audio', }, });
this.submenus.push({ componentName: VideoMenu, tabIndex: 4,
2016-08-06 03:21:35 +08:00
props: { title: 'Video', prependIconName: 'icon-', icon: 'bbb-video', }, });
this.submenus.push({ componentName: ApplicationMenu, tabIndex: 5,
2016-08-06 03:21:35 +08:00
props: { title: 'Application', prependIconName: 'icon-', icon: 'bbb-application', }, });
2016-11-24 10:01:51 +08:00
if (isPresenter || role === 'MODERATOR') {
this.submenus.push({ componentName: UsersMenu, tabIndex: 6,
props: { title: 'Participants', prependIconName: 'icon-', icon: 'bbb-user', }, });
}
2016-11-24 10:01:51 +08:00
return (
<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>
);
2016-05-06 05:14:39 +08:00
}
createMenu() {
let curr = this.state.activeSubmenu === undefined ? 0 : this.state.activeSubmenu;
2016-11-24 10:01:51 +08:00
if (!this.submenus[curr]) {
curr = (this.state.activeSubmenu - 1);
}
2016-05-06 05:14:39 +08:00
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;
2016-05-06 05:14:39 +08:00
return <Submenu {...props}/>;
}
2016-08-09 22:18:31 +08:00
/* 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
*/
2016-05-06 05:14:39 +08:00
clickSubmenu(i) {
if (i <= 0) {
this.setState({ activeSubmenu: 0, focusSubmenu: 0, });
return;
}
2016-08-06 03:21:35 +08:00
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, });
}
2016-06-24 22:48:09 +08:00
}
/* calls the focus method on an object in the submenu */
setFocus() {
ReactDOM.findDOMNode(this.refs[`submenu${this.state.focusSubmenu}`]).focus();
}
2016-08-09 22:18:31 +08:00
/* 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;
}
2016-08-06 03:21:35 +08:00
this.setState({ focusSubmenu: newIndex });
return;
2016-06-24 22:48:09 +08:00
}
2016-05-06 05:14:39 +08:00
// shift+tab
if (event.shiftKey && event.keyCode === 9) {
let newIndex = 0;
if (this.state.focusSubmenu <= 0) {
newIndex = 0;
} else {
newIndex = this.state.focusSubmenu - 1;
}
2016-08-06 03:21:35 +08:00
this.setState({ focusSubmenu: newIndex });
return;
}
// up arrow
if (event.keyCode === 38) {
if (this.state.focusSubmenu <= 0) {
2016-08-06 03:21:35 +08:00
this.setState({ focusSubmenu: this.submenus.length - 1 }, function () {
this.setFocus();
});
2016-07-12 01:43:42 +08:00
} else {
2016-08-06 03:21:35 +08:00
this.setState({ focusSubmenu: this.state.focusSubmenu - 1 }, function () {
this.setFocus();
});
2016-07-12 01:43:42 +08:00
}
2016-08-06 03:21:35 +08:00
return;
2016-07-12 01:43:42 +08:00
}
// down arrow
if (event.keyCode === 40) {
if (this.state.focusSubmenu >= this.submenus.length - 1) {
2016-08-06 03:21:35 +08:00
this.setState({ focusSubmenu: 0 }, function () {
this.setFocus();
2016-08-06 03:21:35 +08:00
});
2016-07-12 01:43:42 +08:00
} else {
2016-08-06 03:21:35 +08:00
this.setState({ focusSubmenu: this.state.focusSubmenu + 1 }, function () {
this.setFocus();
});
2016-07-12 01:43:42 +08:00
}
2016-08-06 03:21:35 +08:00
return;
2016-07-12 01:43:42 +08:00
}
// spacebar or enter
if (event.keyCode === 32 || event.keyCode === 13) {
this.setState({ activeSubmenu: this.state.focusSubmenu });
return;
2016-07-12 01:43:42 +08:00
}
}
2016-08-09 22:18:31 +08:00
/* Keeps the focusSubmenu variable at the correct value when
* tabbing or shift-tabbing out of the submenu array
*/
handleFocus(index) {
this.setState({ focusSubmenu: index });
2016-07-12 01:43:42 +08:00
}
render() {
2016-05-06 05:14:39 +08:00
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',
}}>
2016-11-24 09:55:14 +08:00
{this.renderSettingOptions()}
</Modal>
2016-05-06 05:14:39 +08:00
);
}
};
2016-05-07 01:46:14 +08:00
Settings.defaultProps = { title: 'Settings' };