Merge pull request #3269 from JaeeunCho/dropdown
HTML5 dropdown for settings menu
This commit is contained in:
commit
4811b521a6
@ -57,7 +57,6 @@ modules-runtime@0.7.6
|
||||
mongo@1.1.11
|
||||
mongo-id@1.0.5
|
||||
mrt:external-file-loader@0.1.4
|
||||
mrt:redis@0.1.3
|
||||
nathantreid:css-modules@2.2.2
|
||||
nathantreid:css-modules-import-path-helpers@0.1.4
|
||||
npm-mongo@1.5.46
|
||||
|
@ -25,5 +25,12 @@
|
||||
"app.whiteboard.slideControls.zoomDescrip": "Change the zoom level of the presentation",
|
||||
"app.failedMessage": "Apologies, trouble connecting to the server.",
|
||||
"app.connectingMessage": "Connecting...",
|
||||
"app.waitingMessage": "Disconnected. Trying to reconnect in {seconds} seconds..."
|
||||
"app.waitingMessage": "Disconnected. Trying to reconnect in {seconds} seconds...",
|
||||
"app.dropdown.options": "Options",
|
||||
"app.dropdown.fullscreenLabel": "Make fullscreen",
|
||||
"app.dropdown.settingsLabel": "Open settings",
|
||||
"app.dropdown.leaveSessionLabel": "Logout",
|
||||
"app.dropdown.fullscreenDesc": "Make the settings menu fullscreen",
|
||||
"app.dropdown.settingsDesc": "Change the general settings",
|
||||
"app.dropdown.leaveSessionDesc": "Leave the meeting"
|
||||
}
|
||||
|
@ -5,14 +5,12 @@ import { subscribeForData, wasUserKicked, redirectToLogoutUrl } from './service'
|
||||
import NavBarContainer from '../nav-bar/container';
|
||||
import ActionsBarContainer from '../actions-bar/container';
|
||||
import MediaContainer from '../media/container';
|
||||
import SettingsModal from '../modals/settings/SettingsModal';
|
||||
import ClosedCaptionsContainer from '../closed-captions/container';
|
||||
|
||||
const defaultProps = {
|
||||
navbar: <NavBarContainer />,
|
||||
actionsbar: <ActionsBarContainer />,
|
||||
media: <MediaContainer />,
|
||||
settings: <SettingsModal />,
|
||||
|
||||
//CCs UI is commented till the next pull request
|
||||
//captions: <ClosedCaptionsContainer />,
|
||||
|
@ -55,7 +55,7 @@ export default class ButtonBase extends Component {
|
||||
this.internalKeyUpHandler = this.internalKeyUpHandler.bind(this);
|
||||
}
|
||||
|
||||
validateDisabled(eventHandler, args) {
|
||||
validateDisabled(eventHandler, ...args) {
|
||||
if (!this.props.disabled && typeof eventHandler === 'function') {
|
||||
return eventHandler(...args);
|
||||
}
|
||||
|
264
bigbluebutton-html5/imports/ui/components/dropdown/component.jsx
Executable file
264
bigbluebutton-html5/imports/ui/components/dropdown/component.jsx
Executable file
@ -0,0 +1,264 @@
|
||||
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';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
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';
|
||||
|
||||
export default class SettingsDropdown extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.menus = [];
|
||||
this.openWithKey = this.openWithKey.bind(this);
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.setState({ activeMenu: -1, focusedMenu: 0, });
|
||||
this.menus.push({ className: '',
|
||||
props: { title: 'Fullscreen', prependIconName: 'icon-', icon: 'bbb-full-screen',
|
||||
ariaLabelleby: 'fullscreenLabel', ariaDescribedby:'fullscreenDesc', },
|
||||
tabIndex: 1, });
|
||||
this.menus.push({ className: SettingsModal,
|
||||
props: { title: 'Settings', prependIconName: 'icon-', icon: 'bbb-more',
|
||||
ariaLabelleby: 'settingsLabel', ariaDescribedby:'settingsDesc', },
|
||||
tabIndex: 2, });
|
||||
this.menus.push({ className: SessionMenu,
|
||||
props: { title: 'Leave Session', prependIconName: 'icon-', icon: 'bbb-logout',
|
||||
ariaLabelleby: 'leaveSessionLabel', ariaDescribedby:'leaveSessionDesc', },
|
||||
tabIndex: 3, });
|
||||
}
|
||||
|
||||
componentWillUpdate() {
|
||||
const DROPDOWN = this.refs.dropdown;
|
||||
if (DROPDOWN.state.isMenuOpen && this.state.activeMenu >= 0) {
|
||||
this.setState({ activeMenu: -1, focusedMenu: 0, });
|
||||
}
|
||||
}
|
||||
|
||||
setFocus() {
|
||||
ReactDOM.findDOMNode(this.refs[`menu${this.state.focusedMenu}`]).focus();
|
||||
}
|
||||
|
||||
handleListKeyDown(event) {
|
||||
const pressedKey = event.keyCode;
|
||||
let numOfMenus = this.menus.length - 1;
|
||||
|
||||
// User pressed tab
|
||||
if (pressedKey === 9) {
|
||||
let newIndex = 0;
|
||||
if (this.state.focusedMenu >= numOfMenus) { // Checks if at end of menu
|
||||
newIndex = 0;
|
||||
if (!event.shiftKey) {
|
||||
this.refs.dropdown.hideMenu();
|
||||
}
|
||||
} else {
|
||||
newIndex = this.state.focusedMenu;
|
||||
}
|
||||
|
||||
this.setState({ focusedMenu: newIndex, });
|
||||
return;
|
||||
}
|
||||
|
||||
// User pressed shift + tab
|
||||
if (event.shiftKey && pressedKey === 9) {
|
||||
let newIndex = 0;
|
||||
if (this.state.focusedMenu <= 0) { // Checks if at beginning of menu
|
||||
newIndex = numOfMenus;
|
||||
} else {
|
||||
newIndex = this.state.focusedMenu - 1;
|
||||
}
|
||||
|
||||
this.setState({ focusedMenu: newIndex, });
|
||||
return;
|
||||
}
|
||||
|
||||
// User pressed up key
|
||||
if (pressedKey === 38) {
|
||||
if (this.state.focusedMenu <= 0) { // Checks if at beginning of menu
|
||||
this.setState({ focusedMenu: numOfMenus, },
|
||||
() => { this.setFocus(); });
|
||||
} else {
|
||||
this.setState({ focusedMenu: this.state.focusedMenu - 1, },
|
||||
() => { this.setFocus(); });
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// User pressed down key
|
||||
if (pressedKey === 40) {
|
||||
if (this.state.focusedMenu >= numOfMenus) { // Checks if at end of menu
|
||||
this.setState({ focusedMenu: 0, },
|
||||
() => { this.setFocus(); });
|
||||
} else {
|
||||
this.setState({ focusedMenu: this.state.focusedMenu + 1, },
|
||||
() => { this.setFocus(); });
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// User pressed enter and spaceBar
|
||||
if (pressedKey === 13 || pressedKey === 32) {
|
||||
this.clickMenu(this.state.focusedMenu);
|
||||
return;
|
||||
}
|
||||
|
||||
//User pressed ESC
|
||||
if (pressedKey == 27) {
|
||||
this.setState({ activeMenu: -1, focusedMenu: 0, });
|
||||
this.refs.dropdown.hideMenu();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
handleFocus(index) {
|
||||
this.setState({ focusedMenu: index, },
|
||||
() => { this.setFocus(); });
|
||||
}
|
||||
|
||||
clickMenu(i) {
|
||||
this.setState({ activeMenu: i, });
|
||||
this.refs.dropdown.hideMenu();
|
||||
}
|
||||
|
||||
createMenu() {
|
||||
const curr = this.state.activeMenu;
|
||||
|
||||
switch (curr) {
|
||||
case 0:
|
||||
console.log(this.menus[curr].props.title);
|
||||
break;
|
||||
case 1:
|
||||
return <SettingsModal />;
|
||||
break;
|
||||
case 2:
|
||||
return <SessionMenu />;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
openWithKey(event) {
|
||||
// Focus first menu option
|
||||
if (event.keyCode === 9) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
this.setState({ focusedMenu: 0 }, () => { this.setFocus(); });
|
||||
}
|
||||
|
||||
renderAriaLabelsDescs() {
|
||||
return (
|
||||
<div>
|
||||
|
||||
{/* aria-labelledby */}
|
||||
<p id="fullscreenLabel" hidden>
|
||||
<FormattedMessage
|
||||
id="app.dropdown.fullscreenLabel"
|
||||
description="Aria label for fullscreen"
|
||||
defaultMessage="Make fullscreen"
|
||||
/>
|
||||
</p>
|
||||
<p id="settingsLabel" hidden>
|
||||
<FormattedMessage
|
||||
id="app.dropdown.settingsLabel"
|
||||
description="Aria label for settings"
|
||||
defaultMessage="Open Settings"
|
||||
/>
|
||||
</p>
|
||||
<p id="leaveSessionLabel" hidden>
|
||||
<FormattedMessage
|
||||
id="app.dropdown.leaveSessionLabel"
|
||||
description="Aria label for logout"
|
||||
defaultMessage="Logout"
|
||||
/>
|
||||
</p>
|
||||
|
||||
{/* aria-describedby */}
|
||||
<p id="fullscreenDesc" hidden>
|
||||
<FormattedMessage
|
||||
id="app.dropdown.fullscreenDesc"
|
||||
description="Aria label for fullscreen"
|
||||
defaultMessage="Make the settings menu fullscreen"
|
||||
/>
|
||||
</p>
|
||||
<p id="settingsDesc" hidden>
|
||||
<FormattedMessage
|
||||
id="app.dropdown.settingsDesc"
|
||||
description="Aria label for settings"
|
||||
defaultMessage="Change the general settings"
|
||||
/>
|
||||
</p>
|
||||
<p id="leaveSessionDesc" hidden>
|
||||
<FormattedMessage
|
||||
id="app.dropdown.leaveSessionDesc"
|
||||
description="Aria label for logout"
|
||||
defaultMessage="Leave the meeting"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Dropdown ref='dropdown' focusMenu={this.openWithKey}>
|
||||
<DropdownTrigger labelBtn='setting' iconBtn='more' />
|
||||
<DropdownContent>
|
||||
<div className={styles.triangleOnDropdown}></div>
|
||||
<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}
|
||||
aria-labelledby={value.props.ariaLabelleby}
|
||||
aria-describedby={value.props.ariaDescribedby}>
|
||||
|
||||
<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>
|
||||
{this.renderAriaLabelsDescs()}
|
||||
</div>
|
||||
</DropdownContent>
|
||||
</Dropdown>
|
||||
<div role='presentation'>{this.createMenu()}</div>
|
||||
<p id="settingsDropdown" hidden>
|
||||
<FormattedMessage
|
||||
id="app.dropdown.options"
|
||||
description="Aria label for Options"
|
||||
defaultMessage="Options"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import styles from '../styles';
|
||||
|
||||
export default class DropdownContent extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { findDOMNode } from 'react-dom';
|
||||
import styles from '../styles';
|
||||
import DropdownTrigger from '../dropdown-trigger/component';
|
||||
|
||||
export default class Dropdown extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { isMenuOpen: false, };
|
||||
this.showMenu = this.showMenu.bind(this);
|
||||
this.hideMenu = this.hideMenu.bind(this);
|
||||
this.toggle = this.toggle.bind(this);
|
||||
this.onWindowClick = this.onWindowClick.bind(this);
|
||||
}
|
||||
|
||||
showMenu(event) {
|
||||
let pressedKey = event.keyCode;
|
||||
this.setState({ isMenuOpen: true, });
|
||||
|
||||
// User pressed tab
|
||||
if (pressedKey === 9) {
|
||||
this.hideMenu();
|
||||
}
|
||||
|
||||
// User pressed down arrow or enter or space
|
||||
if (pressedKey === 40 || pressedKey === 13 || pressedKey === 32) {
|
||||
this.props.focusMenu(event);
|
||||
}
|
||||
}
|
||||
|
||||
hideMenu() {
|
||||
this.setState({ isMenuOpen: false, });
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
const { addEventListener } = window;
|
||||
addEventListener('click', this.onWindowClick, false);
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
const { removeEventListener } = window;
|
||||
removeEventListener('click', this.onWindowClick, false);
|
||||
}
|
||||
|
||||
onWindowClick(event) {
|
||||
const dropdownElement = findDOMNode(this);
|
||||
const shouldUpdateState = event.target !== dropdownElement &&
|
||||
!dropdownElement.contains(event.target) &&
|
||||
this.state.isMenuOpen;
|
||||
|
||||
if (shouldUpdateState) {
|
||||
this.hideMenu();
|
||||
}
|
||||
}
|
||||
|
||||
toggle(event) {
|
||||
if (this.state.isMenuOpen) {
|
||||
this.hideMenu();
|
||||
} else {
|
||||
this.showMenu(event);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const toggle = this.toggle;
|
||||
|
||||
// stick callback on trigger element
|
||||
const boundChildren = React.Children.map(this.props.children, (child) => {
|
||||
if (child.type === DropdownTrigger) {
|
||||
child = React.cloneElement(child, {
|
||||
toggle: toggle,
|
||||
});
|
||||
}
|
||||
|
||||
return child;
|
||||
});
|
||||
|
||||
let trigger = boundChildren[0];
|
||||
let content = boundChildren[1];
|
||||
|
||||
return (
|
||||
<div className={styles.dropdown}>
|
||||
{trigger}
|
||||
{this.state.isMenuOpen ?
|
||||
content : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import Button from '/imports/ui/components/button/component';
|
||||
import styles from '../styles';
|
||||
|
||||
export default class DropdownTrigger extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.toggle = this.props.toggle.bind(this);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { labelBtn, iconBtn } = this.props;
|
||||
|
||||
return (
|
||||
<Button
|
||||
className={styles.settingBtn}
|
||||
role='button'
|
||||
label={labelBtn}
|
||||
icon={iconBtn}
|
||||
ghost={true}
|
||||
circle={true}
|
||||
hideLabel={true}
|
||||
onClick={this.toggle}
|
||||
onKeyDown={this.toggle}
|
||||
aria-haspopup={'true'}/>
|
||||
);
|
||||
}
|
||||
}
|
67
bigbluebutton-html5/imports/ui/components/dropdown/styles.scss
Executable file
67
bigbluebutton-html5/imports/ui/components/dropdown/styles.scss
Executable file
@ -0,0 +1,67 @@
|
||||
@import "../../stylesheets/variables/_all";
|
||||
|
||||
.settingsMenuItem {
|
||||
padding-top:20px;
|
||||
}
|
||||
|
||||
.settingsMenuItemText {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.menuList {
|
||||
list-style-type: none;
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
.settingBtn {
|
||||
-ms-transform: rotate( 90deg ); /* IE 9 */
|
||||
-webkit-transform: rotate( 90deg ); /* Safari */
|
||||
transform: rotate( 90deg );
|
||||
color: #ffffff;
|
||||
span {
|
||||
border: 0px solid;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.hrDropdown {
|
||||
border: 0.3px solid $color-gray-light;
|
||||
width: 165px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dropdownActiveContent {
|
||||
margin-top: 14px;
|
||||
margin-right: -3px;
|
||||
padding-left: 15px;
|
||||
height: auto;
|
||||
width: 190px;
|
||||
display: block;
|
||||
background-color: #ffffff;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
text-align: left;
|
||||
font-size: $font-size-base;
|
||||
border-radius: 3%;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.triangleOnDropdown {
|
||||
position: absolute;
|
||||
margin-top: 5px;
|
||||
margin-left: -2px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 18px solid transparent;
|
||||
border-right: 18px solid transparent;
|
||||
border-bottom: 18px solid #ffffff;
|
||||
}
|
||||
|
||||
.iconColor {
|
||||
font-size: $font-size-base;
|
||||
color: $color-gray-light;
|
||||
}
|
@ -23,15 +23,13 @@ export default class BaseModal extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
modalIsOpen: false,
|
||||
// You need to set isOpen={true} on the modal component for it to render its children.
|
||||
modalIsOpen: true,
|
||||
title: props.title || 'title',
|
||||
content: <div>hello</div>,
|
||||
};
|
||||
this.openModal = this.openModal.bind(this);
|
||||
this.closeModal = this.closeModal.bind(this);
|
||||
this.handleModalCloseRequest = this.handleModalCloseRequest.bind(this);
|
||||
this.handleSaveClicked = this.handleSaveClicked.bind(this);
|
||||
this.afterOpenModal = this.afterOpenModal.bind(this);
|
||||
this.setTitle = this.setTitle.bind(this);
|
||||
}
|
||||
|
||||
@ -47,18 +45,6 @@ export default class BaseModal extends React.Component {
|
||||
this.setState({ modalIsOpen: false });
|
||||
}
|
||||
|
||||
afterOpenModal() {}
|
||||
|
||||
handleModalCloseRequest() {
|
||||
// opportunity to validate something and keep the modal open even if it
|
||||
// requested to be closed
|
||||
this.setState({ modalIsOpen: false });
|
||||
}
|
||||
|
||||
handleSaveClicked(e) {
|
||||
alert('Save button was clicked');
|
||||
}
|
||||
|
||||
getContent() {
|
||||
return (<div>parent content</div>);
|
||||
}
|
||||
@ -68,11 +54,8 @@ export default class BaseModal extends React.Component {
|
||||
<span>
|
||||
<Modal
|
||||
isOpen={this.state.modalIsOpen}
|
||||
onAfterOpen={this.afterOpenModal}
|
||||
onRequestClose={this.closeModal}
|
||||
shouldCloseOnOverlayClick={false}
|
||||
style={customStyles} >
|
||||
|
||||
<span className={classNames(styles.modalHeaderTitle, 'largeFont')}>
|
||||
{this.state.title}
|
||||
</span>
|
||||
|
@ -19,7 +19,6 @@ export default class SettingsModal extends BaseModal {
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.setState({ activeSubmenu: 0 });
|
||||
this.submenus.push({ className: AudioMenu,
|
||||
props: { title: 'Audio', prependIconName: 'ion-', icon: 'ios-mic-outline', }, });
|
||||
this.submenus.push({ className: VideoMenu,
|
||||
@ -33,11 +32,7 @@ export default class SettingsModal extends BaseModal {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
ReactDOM.render(
|
||||
<Button componentClass='button' style={{ width: '30px', height: '30px', float: 'right' }}
|
||||
onClick={this.openModal} i_class='icon ion-gear-b' rel='tooltip' title='Settings'>
|
||||
<Icon iconName='icon ion-gear-b' className='mediumFont icon ion-gear-b'/>
|
||||
</Button>, document.getElementById('settingsButtonPlaceHolder'));
|
||||
return (<div onClick={this.openModal}></div>);
|
||||
}
|
||||
|
||||
createMenu() {
|
||||
@ -54,15 +49,7 @@ export default class SettingsModal extends BaseModal {
|
||||
}
|
||||
|
||||
clickSubmenu(i) {
|
||||
if (this.submenus[i].className != SessionMenu) {
|
||||
this.setState({ activeSubmenu: i });
|
||||
};
|
||||
}
|
||||
|
||||
doubleClickSubmenu(i) {
|
||||
if (this.submenus[i].className == SessionMenu) {
|
||||
this.setState({ activeSubmenu: i });
|
||||
}
|
||||
}
|
||||
|
||||
getContent() {
|
||||
@ -72,7 +59,6 @@ export default class SettingsModal extends BaseModal {
|
||||
<ul style={{ listStyleType: 'none' }}>
|
||||
{this.submenus.map((value, index) => (
|
||||
<li key={index} onClick={this.clickSubmenu.bind(this, index)}
|
||||
onDoubleClick={this.doubleClickSubmenu.bind(this, index)}
|
||||
className={classNames(styles.settingsSubmenuItem,
|
||||
index == this.state.activeSubmenu ? styles.settingsSubmenuItemActive : null)}>
|
||||
<Icon key={index} prependIconName={value.props.prependIconName}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Modal from 'react-modal';
|
||||
import Button from '/imports/ui/components/button/component';
|
||||
import BaseMenu from './BaseMenu';
|
||||
@ -40,18 +41,24 @@ export default class SessionMenu extends BaseMenu {
|
||||
<span>
|
||||
<Modal
|
||||
isOpen={this.state.openConfirm}
|
||||
style={customModal} >
|
||||
style={customModal}
|
||||
onRequestClose={this.closeLogout}
|
||||
tabIndex="-1">
|
||||
<span className={classNames(styles.modalHeaderTitle, 'largeFont')}> Leave Session</span>
|
||||
<hr className={styles.modalHorizontalRule} />
|
||||
<span>Do you want to leave this meeting?</span>
|
||||
<br />
|
||||
<button onClick={Auth.completeLogout}
|
||||
className={classNames(styles.modalButton, styles.done)}
|
||||
tabindex="0"
|
||||
tabIndex='8'
|
||||
aria-labelledby="logout_okay"
|
||||
aria-describedby="logout_okay"
|
||||
role="button">Yes</button>
|
||||
<button onClick={this.closeLogout}
|
||||
className={classNames(styles.modalButton, styles.close)}
|
||||
tabindex="1"
|
||||
tabIndex='9'
|
||||
aria-labelledby="logout_cancel"
|
||||
aria-describedby="logout_cancel"
|
||||
role="button">No</button>
|
||||
</Modal>
|
||||
</span>
|
||||
|
@ -2,6 +2,7 @@ import React, { Component, PropTypes } from 'react';
|
||||
import styles from './styles.scss';
|
||||
import Button from '../button/component';
|
||||
import RecordButton from './recordbutton/component';
|
||||
import SettingsDropdown from '../dropdown/component';
|
||||
|
||||
const propTypes = {
|
||||
presentationTitle: PropTypes.string.isRequired,
|
||||
@ -51,7 +52,7 @@ class NavBar extends Component {
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.right}>
|
||||
<span id="settingsButtonPlaceHolder"></span>
|
||||
<SettingsDropdown />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user