2016-08-20 05:20:17 +08:00
|
|
|
import React, { Component, PropTyes } from 'react';
|
|
|
|
import ReactDOM from 'react-dom';
|
|
|
|
import Icon from '/imports/ui/components/icon/component';
|
|
|
|
import Button from '/imports/ui/components/button/component';
|
|
|
|
import classNames from 'classnames';
|
|
|
|
import styles from './styles';
|
2016-08-24 06:19:13 +08:00
|
|
|
import { FormattedMessage } from 'react-intl';
|
2016-08-25 03:22:05 +08:00
|
|
|
import SettingsModal from '../modals/settings/SettingsModal';
|
|
|
|
import SessionMenu from '../modals/settings/submenus/SessionMenu';
|
|
|
|
import Dropdown from './dropdown-menu/component';
|
|
|
|
import DropdownTrigger from './dropdown-trigger/component';
|
|
|
|
import DropdownContent from './dropdown-content/component';
|
2016-08-20 05:20:17 +08:00
|
|
|
|
|
|
|
export default class SettingsDropdown extends Component {
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this.menus = [];
|
2016-08-24 06:19:13 +08:00
|
|
|
this.openWithKey = this.openWithKey.bind(this);
|
2016-08-20 05:20:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
componentWillMount() {
|
2016-08-24 06:19:13 +08:00
|
|
|
this.setState({ activeMenu: -1, focusedMenu: 0, });
|
2016-08-20 05:20:17 +08:00
|
|
|
this.menus.push({ className: '',
|
2016-08-24 06:19:13 +08:00
|
|
|
props: { title: 'Fullscreen', prependIconName: 'icon-', icon: 'bbb-full-screen', },
|
|
|
|
tabIndex: 1, });
|
2016-08-20 05:20:17 +08:00
|
|
|
this.menus.push({ className: SettingsModal,
|
2016-08-25 01:49:57 +08:00
|
|
|
props: { title: 'Settings', prependIconName: 'icon-', icon: 'bbb-more', },
|
2016-08-24 06:19:13 +08:00
|
|
|
tabIndex: 2, });
|
2016-08-20 05:20:17 +08:00
|
|
|
this.menus.push({ className: SessionMenu,
|
2016-08-24 06:19:13 +08:00
|
|
|
props: { title: 'Leave Session', prependIconName: 'icon-', icon: 'bbb-logout', },
|
|
|
|
tabIndex: 3, });
|
2016-08-20 05:20:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
componentWillUpdate() {
|
2016-08-24 06:19:13 +08:00
|
|
|
const DROPDOWN = this.refs.dropdown;
|
|
|
|
if (DROPDOWN.state.isMenuOpen && this.state.activeMenu >= 0) {
|
|
|
|
this.setState({ activeMenu: -1, focusedMenu: 0, });
|
2016-08-20 05:20:17 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setFocus() {
|
2016-08-24 06:19:13 +08:00
|
|
|
ReactDOM.findDOMNode(this.refs[`menu${this.state.focusedMenu}`]).focus();
|
2016-08-20 05:20:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
handleListKeyDown(event) {
|
|
|
|
const pressedKey = event.keyCode;
|
2016-08-24 06:19:13 +08:00
|
|
|
let numOfMenus = this.menus.length - 1;
|
2016-08-20 05:20:17 +08:00
|
|
|
|
2016-08-24 06:19:13 +08:00
|
|
|
// User pressed tab
|
2016-08-20 05:20:17 +08:00
|
|
|
if (pressedKey === 9) {
|
|
|
|
let newIndex = 0;
|
2016-08-24 06:19:13 +08:00
|
|
|
if (this.state.focusedMenu >= numOfMenus) { // Checks if at end of menu
|
2016-08-20 05:20:17 +08:00
|
|
|
newIndex = 0;
|
2016-08-24 06:19:13 +08:00
|
|
|
if (!event.shiftKey) {
|
2016-08-23 22:05:54 +08:00
|
|
|
this.refs.dropdown.hideMenu();
|
|
|
|
}
|
2016-08-20 05:20:17 +08:00
|
|
|
} else {
|
2016-08-24 06:19:13 +08:00
|
|
|
newIndex = this.state.focusedMenu;
|
2016-08-20 05:20:17 +08:00
|
|
|
}
|
|
|
|
|
2016-08-24 06:19:13 +08:00
|
|
|
this.setState({ focusedMenu: newIndex, });
|
2016-08-20 05:20:17 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-08-24 06:19:13 +08:00
|
|
|
// User pressed shift + tab
|
2016-08-20 05:20:17 +08:00
|
|
|
if (event.shiftKey && pressedKey === 9) {
|
|
|
|
let newIndex = 0;
|
2016-08-24 06:19:13 +08:00
|
|
|
if (this.state.focusedMenu <= 0) { // Checks if at beginning of menu
|
|
|
|
newIndex = numOfMenus;
|
2016-08-20 05:20:17 +08:00
|
|
|
} else {
|
2016-08-24 06:19:13 +08:00
|
|
|
newIndex = this.state.focusedMenu - 1;
|
2016-08-20 05:20:17 +08:00
|
|
|
}
|
|
|
|
|
2016-08-24 06:19:13 +08:00
|
|
|
this.setState({ focusedMenu: newIndex, });
|
2016-08-20 05:20:17 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-08-24 06:19:13 +08:00
|
|
|
// User pressed up key
|
2016-08-20 05:20:17 +08:00
|
|
|
if (pressedKey === 38) {
|
2016-08-24 06:19:13 +08:00
|
|
|
if (this.state.focusedMenu <= 0) { // Checks if at beginning of menu
|
|
|
|
this.setState({ focusedMenu: numOfMenus, },
|
2016-08-20 05:20:17 +08:00
|
|
|
() => { this.setFocus(); });
|
|
|
|
} else {
|
2016-08-24 06:19:13 +08:00
|
|
|
this.setState({ focusedMenu: this.state.focusedMenu - 1, },
|
2016-08-20 05:20:17 +08:00
|
|
|
() => { this.setFocus(); });
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-08-24 06:19:13 +08:00
|
|
|
// User pressed down key
|
2016-08-23 22:05:54 +08:00
|
|
|
if (pressedKey === 40) {
|
2016-08-24 06:19:13 +08:00
|
|
|
if (this.state.focusedMenu >= numOfMenus) { // Checks if at end of menu
|
|
|
|
this.setState({ focusedMenu: 0, },
|
2016-08-23 22:05:54 +08:00
|
|
|
() => { this.setFocus(); });
|
|
|
|
} else {
|
2016-08-24 06:19:13 +08:00
|
|
|
this.setState({ focusedMenu: this.state.focusedMenu + 1, },
|
2016-08-23 22:05:54 +08:00
|
|
|
() => { this.setFocus(); });
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-08-24 06:19:13 +08:00
|
|
|
// User pressed enter and spaceBar
|
2016-08-20 05:20:17 +08:00
|
|
|
if (pressedKey === 13 || pressedKey === 32) {
|
2016-08-24 06:19:13 +08:00
|
|
|
this.clickMenu(this.state.focusedMenu);
|
2016-08-20 05:20:17 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-08-24 06:19:13 +08:00
|
|
|
//User pressed ESC
|
2016-08-20 05:20:17 +08:00
|
|
|
if (pressedKey == 27) {
|
2016-08-24 06:19:13 +08:00
|
|
|
this.setState({ activeMenu: -1, focusedMenu: 0, });
|
2016-08-20 05:20:17 +08:00
|
|
|
this.refs.dropdown.hideMenu();
|
|
|
|
}
|
2016-08-24 06:19:13 +08:00
|
|
|
return;
|
2016-08-20 05:20:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
handleFocus(index) {
|
2016-08-24 06:19:13 +08:00
|
|
|
this.setState({ focusedMenu: index, },
|
2016-08-20 05:20:17 +08:00
|
|
|
() => { this.setFocus(); });
|
|
|
|
}
|
|
|
|
|
|
|
|
clickMenu(i) {
|
2016-08-24 06:19:13 +08:00
|
|
|
this.setState({ activeMenu: i, });
|
2016-08-20 05:20:17 +08:00
|
|
|
this.refs.dropdown.hideMenu();
|
|
|
|
}
|
|
|
|
|
|
|
|
createMenu() {
|
|
|
|
const curr = this.state.activeMenu;
|
|
|
|
|
2016-08-24 06:19:13 +08:00
|
|
|
switch (curr) {
|
|
|
|
case 0:
|
|
|
|
console.log(this.menus[curr].props.title);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
return <SettingsModal />;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
return <SessionMenu />;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
2016-08-20 05:20:17 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
openWithKey(event) {
|
2016-08-24 06:19:13 +08:00
|
|
|
// Focus first menu option
|
2016-08-20 05:20:17 +08:00
|
|
|
if (event.keyCode === 9) {
|
|
|
|
event.preventDefault();
|
|
|
|
event.stopPropagation();
|
|
|
|
}
|
|
|
|
|
2016-08-24 06:19:13 +08:00
|
|
|
this.setState({ focusedMenu: 0 }, () => { this.setFocus(); });
|
|
|
|
}
|
|
|
|
|
2016-08-25 04:25:27 +08:00
|
|
|
renderAriaLabelsDescs() {
|
|
|
|
return (
|
|
|
|
<div>
|
|
|
|
<p id="fullScreen" hidden>
|
|
|
|
<FormattedMessage
|
|
|
|
id="app.modals.dropdown.fullScreen"
|
|
|
|
description="Aria label for fullscreen"
|
|
|
|
defaultMessage="Make fullscreen"
|
|
|
|
/>
|
2016-08-24 06:19:13 +08:00
|
|
|
</p>
|
|
|
|
<p id="settingsModal" hidden>
|
|
|
|
<FormattedMessage
|
|
|
|
id="app.modals.dropdown.settingsModal"
|
2016-08-25 01:49:57 +08:00
|
|
|
description="Aria label for settings"
|
|
|
|
defaultMessage="Open Settings"
|
2016-08-24 06:19:13 +08:00
|
|
|
/>
|
|
|
|
</p>
|
|
|
|
<p id="leaveSession" hidden>
|
|
|
|
<FormattedMessage
|
|
|
|
id="app.modals.dropdown.leaveSession"
|
2016-08-25 01:49:57 +08:00
|
|
|
description="Aria label for logout"
|
2016-08-24 06:19:13 +08:00
|
|
|
defaultMessage="Logout"
|
|
|
|
/>
|
|
|
|
</p>
|
2016-08-25 04:25:27 +08:00
|
|
|
</div>
|
|
|
|
);
|
2016-08-24 06:19:13 +08:00
|
|
|
|
2016-08-20 05:20:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
2016-08-24 06:19:13 +08:00
|
|
|
|
2016-08-20 05:20:17 +08:00
|
|
|
return (
|
|
|
|
<div>
|
2016-08-24 06:19:13 +08:00
|
|
|
<Dropdown ref='dropdown' focusMenu={this.openWithKey}>
|
2016-08-20 05:20:17 +08:00
|
|
|
<DropdownTrigger labelBtn='setting' iconBtn='more' />
|
2016-08-24 06:19:13 +08:00
|
|
|
<DropdownContent>
|
2016-08-20 05:20:17 +08:00
|
|
|
<div className={styles.triangleOnDropdown}></div>
|
2016-08-24 06:19:13 +08:00
|
|
|
<div className={styles.dropdownActiveContent}>
|
|
|
|
<ul className={styles.menuList} role="menu">
|
|
|
|
{this.menus.map((value, index) => (
|
|
|
|
<li
|
|
|
|
key={index}
|
|
|
|
role='menuitem'
|
|
|
|
tabIndex={value.tabIndex}
|
|
|
|
onClick={this.clickMenu.bind(this, index)}
|
|
|
|
onKeyDown={this.handleListKeyDown.bind(this)}
|
|
|
|
onFocus={this.handleFocus.bind(this, index)}
|
|
|
|
ref={'menu' + index}
|
|
|
|
className={styles.settingsMenuItem}>
|
|
|
|
|
|
|
|
<Icon
|
|
|
|
key={index}
|
|
|
|
prependIconName={value.props.prependIconName}
|
|
|
|
iconName={value.props.icon}
|
|
|
|
title={value.props.title}
|
|
|
|
className={styles.iconColor}/>
|
|
|
|
|
|
|
|
<span className={styles.settingsMenuItemText}>{value.props.title}</span>
|
|
|
|
{index == '0' ? <hr className={styles.hrDropdown}/> : null}
|
|
|
|
</li>
|
|
|
|
))}
|
|
|
|
</ul>
|
2016-08-25 04:25:27 +08:00
|
|
|
{this.renderAriaLabelsDescs()}
|
2016-08-20 05:20:17 +08:00
|
|
|
</div>
|
|
|
|
</DropdownContent>
|
|
|
|
</Dropdown>
|
2016-08-24 03:18:49 +08:00
|
|
|
<div role='presentation'>{this.createMenu()}</div>
|
2016-08-24 06:19:13 +08:00
|
|
|
<p id="settingsDropdown" hidden>
|
|
|
|
<FormattedMessage
|
|
|
|
id="app.modals.dropdown.settingsDropdown"
|
2016-08-25 01:49:57 +08:00
|
|
|
description="Aria label for Options"
|
|
|
|
defaultMessage="Options"
|
2016-08-24 06:19:13 +08:00
|
|
|
/>
|
|
|
|
</p>
|
2016-08-20 05:20:17 +08:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|