diff --git a/bigbluebutton-html5/imports/ui/components/about/component.jsx b/bigbluebutton-html5/imports/ui/components/about/component.jsx index 9fb8d48508b756584e477f5b9948fec1c2273553..e453ebc2bdcb14aee0d8b054a754d86042dc5ece 100644 --- a/bigbluebutton-html5/imports/ui/components/about/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/about/component.jsx @@ -34,29 +34,13 @@ const intlMessages = defineMessages({ }); class AboutComponent extends Component { - constructor(props) { - super(props); - - this.handleAboutComponent = this.handleAboutComponent.bind(this); - } - - handleAboutComponent() { - console.log("TODO"); - } - render() { const { intl, clientBuild, copyright } = this.props; return ( <Modal title={intl.formatMessage(intlMessages.title)} - confirm={{ - callback: this.handleAboutComponent, - label: intl.formatMessage(intlMessages.confirmLabel), - description: intl.formatMessage(intlMessages.confirmDesc), - }} dismiss={{ - callback: this.handleAboutComponent, label: intl.formatMessage(intlMessages.dismissLabel), description: intl.formatMessage(intlMessages.dismissDesc), }}> diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx index f3d529b46ee21f17e42e08637b83681ead54d126..892311292e3e2c4bf4b0623484cea45f35c76af4 100755 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx @@ -1,5 +1,7 @@ import React, { Component } from 'react'; import { createContainer } from 'meteor/react-meteor-data'; +import { withModalMounter } from '/imports/ui/components/modal/service'; +import Audio from '/imports/ui/components/audio-modal/component'; import ActionsBar from './component'; import Service from './service'; @@ -18,14 +20,15 @@ class ActionsBarContainer extends Component { } } -export default createContainer(() => { +export default withModalMounter(createContainer(({ mountModal }) => { const isPresenter = Service.isUserPresenter(); const handleExitAudio = () => Service.handleExitAudio(); - const handleOpenJoinAudio = () => Service.handleJoinAudio(); + const handleOpenJoinAudio = () => + mountModal(<Audio handleJoinListenOnly={Service.handleJoinAudio} />); return { isUserPresenter: isPresenter, handleExitAudio: handleExitAudio, handleOpenJoinAudio: handleOpenJoinAudio, }; -}, ActionsBarContainer); +}, ActionsBarContainer)); diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/service.js b/bigbluebutton-html5/imports/ui/components/actions-bar/service.js index 05043c8900668229ab87cbe86914afb75d74881e..1e52fc73e0bfd1e189d3ce83396d8effb5887b5f 100755 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/service.js +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/service.js @@ -1,12 +1,9 @@ import AuthSingleton from '/imports/ui/services/auth/index.js'; import Users from '/imports/api/users'; import { joinListenOnly } from '/imports/api/phone'; -import { showModal } from '/imports/ui/components/app/service'; import { exitAudio } from '/imports/api/phone'; -import Audio from '/imports/ui/components/audio-modal/component'; let isUserPresenter = () => { - // check if user is a presenter let isPresenter = Users.findOne({ userId: AuthSingleton.userID, @@ -17,14 +14,9 @@ let isUserPresenter = () => { }; }; -const handleExitAudio = () => { - return exitAudio(); -} +const handleExitAudio = () => exitAudio(); -const handleJoinAudio = () => { - const handleJoinListenOnly = () => joinListenOnly(); - return showModal(<Audio handleJoinListenOnly={handleJoinListenOnly} />); -} +const handleJoinAudio = () => joinListenOnly(); export default { isUserPresenter, diff --git a/bigbluebutton-html5/imports/ui/components/app/component.jsx b/bigbluebutton-html5/imports/ui/components/app/component.jsx index bbcee025b797b3cb233f82bae7232cdc28b30587..a4c09da9895ca79f9ae2f962ece8091f53d6bb5c 100755 --- a/bigbluebutton-html5/imports/ui/components/app/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/app/component.jsx @@ -2,6 +2,7 @@ import React, { Component, PropTypes } from 'react'; import { FormattedMessage } from 'react-intl'; import _ from 'lodash'; +import ModalContainer from '../modal/container'; import NotificationsBarContainer from '../notifications-bar/container'; import AudioNotificationContainer from '../audio-notification/container'; import ChatNotificationContainer from '../chat/notification/container'; @@ -17,7 +18,6 @@ const propTypes = { sidebar: PropTypes.element, media: PropTypes.element, actionsbar: PropTypes.element, - modal: PropTypes.element, }; const defaultProps = { @@ -135,7 +135,7 @@ export default class App extends Component { </div> {this.renderSidebar()} </section> - {modal} + <ModalContainer /> <audio id="remote-media" autoPlay="autoplay"></audio> <ChatNotificationContainer currentChatID={params.chatID} /> </main> diff --git a/bigbluebutton-html5/imports/ui/components/app/container.jsx b/bigbluebutton-html5/imports/ui/components/app/container.jsx index 491f2681c88477c5ecc88819f357ef2c5f0aa6f1..9f144f5398c6d2df640cfdd34e648501c81379a5 100755 --- a/bigbluebutton-html5/imports/ui/components/app/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/app/container.jsx @@ -4,13 +4,12 @@ import { withRouter } from 'react-router'; import { defineMessages, injectIntl } from 'react-intl'; import { - getModal, - showModal, getFontSize, getCaptionsStatus, } from './service'; import { setDefaultSettings } from '../settings/service'; +import { withModalMounter } from '../modal/service'; import Auth from '/imports/ui/services/auth'; import Users from '/imports/api/users'; @@ -50,42 +49,42 @@ class AppContainer extends Component { } }; -const APP_CONFIG = Meteor.settings.public.app; +export default withRouter(injectIntl(withModalMounter(createContainer(( + { router, intl, mountModal, baseControls }) => { + // Check if user is kicked out of the session + Users.find({ userId: Auth.userID }).observeChanges({ + removed() { + Auth.clearCredentials() + .then(() => { + router.push('/error/403'); + baseControls.updateErrorState( + intl.formatMessage(intlMessages.kickedMessage), + ); + }); + }, + }); -const init = () => { - setDefaultSettings(); - if (APP_CONFIG.autoJoinAudio) { - showModal(<AudioModalContainer />); - } -}; + // Close the widow when the current breakout room ends + Breakouts.find({ breakoutMeetingId: Auth.meetingID }).observeChanges({ + removed(old) { + Auth.clearCredentials().then(window.close); + }, + }); -export default withRouter(injectIntl(createContainer(({ router, intl, baseControls }) => { - // Check if user is kicked out of the session - Users.find({ userId: Auth.userID }).observeChanges({ - removed() { - Auth.clearCredentials() - .then(() => { - router.push('/error/403'); - baseControls.updateErrorState( - intl.formatMessage(intlMessages.kickedMessage), - ); - }); - }, - }); + const APP_CONFIG = Meteor.settings.public.app; - // Close the widow when the current breakout room ends - Breakouts.find({ breakoutMeetingId: Auth.meetingID }).observeChanges({ - removed(old) { - Auth.clearCredentials().then(window.close); - }, - }); + const init = () => { + setDefaultSettings(); + if (APP_CONFIG.autoJoinAudio) { + mountModal(<AudioModalContainer />); + } + }; - return { - init, - sidebar: getCaptionsStatus() ? <ClosedCaptionsContainer /> : null, - modal: getModal(), - fontSize: getFontSize(), - }; -}, AppContainer))); + return { + init, + sidebar: getCaptionsStatus() ? <ClosedCaptionsContainer /> : null, + fontSize: getFontSize(), + }; + }, AppContainer)))); AppContainer.defaultProps = defaultProps; diff --git a/bigbluebutton-html5/imports/ui/components/app/service.js b/bigbluebutton-html5/imports/ui/components/app/service.js index 6d96eee06142437c0d9a81432aeb2bb9be4d19a5..619ce0ee11422c35474524334fe317f59e66bc05 100755 --- a/bigbluebutton-html5/imports/ui/components/app/service.js +++ b/bigbluebutton-html5/imports/ui/components/app/service.js @@ -1,27 +1,6 @@ import Breakouts from '/imports/api/breakouts'; import SettingsService from '/imports/ui/components/settings/service'; -let currentModal = { - component: null, - tracker: new Tracker.Dependency, -}; - -const getModal = () => { - currentModal.tracker.depend(); - return currentModal.component; -}; - -const showModal = (component) => { - if (currentModal.component !== component) { - currentModal.component = component; - currentModal.tracker.changed(); - } -}; - -const clearModal = () => { - showModal(null); -}; - const getCaptionsStatus = () => { const settings = SettingsService.getSettingsFor('cc'); return settings ? settings.closedCaptions : false; @@ -38,9 +17,6 @@ function meetingIsBreakout() { } export { - getModal, - showModal, - clearModal, getCaptionsStatus, getFontSize, meetingIsBreakout, diff --git a/bigbluebutton-html5/imports/ui/components/audio-modal/join-audio/component.jsx b/bigbluebutton-html5/imports/ui/components/audio-modal/join-audio/component.jsx index 0016bb361a6510ec400e4644edf67f0acb7f8af8..b48dc4a39db5b7ccad85ff5db47f27deeaedd38d 100755 --- a/bigbluebutton-html5/imports/ui/components/audio-modal/join-audio/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/audio-modal/join-audio/component.jsx @@ -1,7 +1,7 @@ import React from 'react'; import styles from '../styles.scss'; import Button from '/imports/ui/components/button/component'; -import { clearModal } from '/imports/ui/components/app/service'; +import { withModalMounter } from '/imports/ui/components/modal/service'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; const intlMessages = defineMessages({ @@ -13,7 +13,7 @@ const intlMessages = defineMessages({ }, closeLabel: { id: 'app.audioModal.closeLabel', - } + }, }); class JoinAudio extends React.Component { @@ -26,8 +26,8 @@ class JoinAudio extends React.Component { } handleClose() { - this.setState({ isOpen: false }); - clearModal(); + /* TODO: Refactor this to the outer component (audio-modal/container) */ + this.props.mountModal(null); } openAudio() { @@ -84,4 +84,4 @@ class JoinAudio extends React.Component { } }; -export default injectIntl(JoinAudio); +export default withModalMounter(injectIntl(JoinAudio)); diff --git a/bigbluebutton-html5/imports/ui/components/chat/container.jsx b/bigbluebutton-html5/imports/ui/components/chat/container.jsx index 7934eac7a3168c75602258d73b56dfbbb8c3437b..a80384bdfd1577c28f9ceed96e50c142f12a4891 100755 --- a/bigbluebutton-html5/imports/ui/components/chat/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/chat/container.jsx @@ -41,6 +41,7 @@ class ChatContainer extends Component { } export default injectIntl(createContainer(({ params, intl }) => { + console.log('james'); const chatID = params.chatID || PUBLIC_CHAT_KEY; let messages = []; @@ -61,7 +62,7 @@ export default injectIntl(createContainer(({ params, intl }) => { title = intl.formatMessage(intlMessages.titlePrivate, { name: user.name }); chatName = user.name; - + console.log('james'); if (user.isLoggedOut) { let time = Date.now(); let id = `partner-disconnected-${time}`; diff --git a/bigbluebutton-html5/imports/ui/components/modal/base/component.jsx b/bigbluebutton-html5/imports/ui/components/modal/base/component.jsx index 9bfe25e927003713cf33d9205613abc7e2025038..ef8670d5a1c842af0e6245b5debd5ec4cbbebe02 100755 --- a/bigbluebutton-html5/imports/ui/components/modal/base/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/modal/base/component.jsx @@ -3,67 +3,24 @@ import ReactModal from 'react-modal'; import styles from './styles.scss'; const propTypes = { - modalClassName: PropTypes.string.isRequired, overlayClassName: PropTypes.string.isRequired, portalClassName: PropTypes.string.isRequired, contentLabel: PropTypes.string.isRequired, isOpen: PropTypes.bool.isRequired, - onShow: PropTypes.func, - onHide: PropTypes.func, }; const defaultProps = { - modalClassName: styles.modal, + className: styles.modal, overlayClassName: styles.overlay, portalClassName: styles.portal, contentLabel: 'Modal', - isOpen: false, + isOpen: true, }; export default class ModalBase extends Component { - constructor(props) { - super(props); - - this.handleAfterOpen = this.handleAfterOpen.bind(this); - this.handleRequestClose = this.handleRequestClose.bind(this); - } - - handleAfterOpen() { - const { onShow } = this.props; - if (onShow) { - onShow.call(this, ...arguments); - } - } - - handleRequestClose() { - const { onHide } = this.props; - if (onHide) { - onHide.call(this, ...arguments); - } - } - render() { - const { - isOpen, - onShow, - onHide, - contentLabel, - shouldCloseOnOverlayClick, - modalClassName, - overlayClassName, - portalClassName, - } = this.props; - return ( - <ReactModal - className={modalClassName} - contentLabel={contentLabel} - shouldCloseOnOverlayClick={shouldCloseOnOverlayClick} - overlayClassName={overlayClassName} - portalClassName={portalClassName} - isOpen={isOpen} - onAfterOpen={this.handleAfterOpen} - onRequestClose={this.handleRequestClose}> + <ReactModal {...this.props}> {this.props.children} </ReactModal> ); @@ -73,16 +30,17 @@ export default class ModalBase extends Component { ModalBase.propTypes = propTypes; ModalBase.defaultProps = defaultProps; -export const withModalBase = (ComponentToWrap) => +export const withModalState = (ComponentToWrap) => class ModalStateWrapper extends Component { constructor(props) { super(props); this.state = { - isOpen: props.isOpen || true, + isOpen: true, }; this.hide = this.hide.bind(this); + this.show = this.show.bind(this); } hide(cb) { @@ -90,42 +48,15 @@ export const withModalBase = (ComponentToWrap) => } show(cb) { - this.setState({ isOpen: true }, cb); - } - - componentDidUpdate(prevProps, prevState) { - if (prevState.isOpen !== this.props.isOpen - && this.state.isOpen !== this.props.isOpen) { - this.setState({ isOpen: this.props.isOpen }); - } + this.setState({ isOpen: false }, cb); } render() { - const { isOpen } = this.state; - const { - modalClassName, - overlayClassName, - portalClassName, - contentLabel, - shouldCloseOnOverlayClick, - onShow, - onHide, - ...modalProps, - } = this.props; - - return ( - <ModalBase {...{ - isOpen, - modalClassName, - overlayClassName, - portalClassName, - contentLabel, - shouldCloseOnOverlayClick, - onShow, - onHide, - }}> - <ComponentToWrap {...modalProps} hide={this.hide} show={this.show}/> - </ModalBase> - ); + return <ComponentToWrap + {...this.props} + modalHide={this.hide} + modalShow={this.show} + modalisOpen={this.state.isOpen} + />; } }; diff --git a/bigbluebutton-html5/imports/ui/components/modal/container.jsx b/bigbluebutton-html5/imports/ui/components/modal/container.jsx new file mode 100644 index 0000000000000000000000000000000000000000..c8617cf0ff5bf58e07c698c0959314a7baea299a --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/modal/container.jsx @@ -0,0 +1,8 @@ +import React from 'react'; +import { createContainer } from 'meteor/react-meteor-data'; +import { getModal } from './service'; + +export default createContainer( + () => ({ modalComponent: getModal() }), + ({ modalComponent }) => modalComponent +); diff --git a/bigbluebutton-html5/imports/ui/components/modal/fullscreen/component.jsx b/bigbluebutton-html5/imports/ui/components/modal/fullscreen/component.jsx index ec29ba877f07e030be51aee12eec35a70ff8b069..0d0c0986cb196652ad881067bd25cb848bd73ee0 100755 --- a/bigbluebutton-html5/imports/ui/components/modal/fullscreen/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/modal/fullscreen/component.jsx @@ -1,5 +1,5 @@ import React, { Component, PropTypes } from 'react'; -import { withModalBase } from '../base/component'; +import ModalBase, { withModalState } from '../base/component'; import Button from '/imports/ui/components/button/component'; import styles from './styles.scss'; import cx from 'classnames'; @@ -33,18 +33,26 @@ const defaultProps = { class ModalFullscreen extends Component { handleAction(name) { const action = this.props[name]; - this.props.hide(action.callback); + this.props.modalHide(action.callback); } render() { const { title, - dismiss, confirm, + dismiss, + className, + modalisOpen, + ...otherProps, } = this.props; return ( - <div> + <ModalBase + isOpen={modalisOpen} + className={cx(className, styles.modal)} + contentLabel={title} + {...otherProps} + > <header className={styles.header}> <h1 className={styles.title}>{title}</h1> <div className={styles.actions}> @@ -68,7 +76,7 @@ class ModalFullscreen extends Component { </div> <div id="modalDismissDescription" hidden>{dismiss.description}</div> <div id="modalConfirmDescription" hidden>{confirm.description}</div> - </div> + </ModalBase> ); } }; @@ -76,4 +84,4 @@ class ModalFullscreen extends Component { ModalFullscreen.propTypes = propTypes; ModalFullscreen.defaultProps = defaultProps; -export default withModalBase(ModalFullscreen); +export default withModalState(ModalFullscreen); diff --git a/bigbluebutton-html5/imports/ui/components/modal/service.js b/bigbluebutton-html5/imports/ui/components/modal/service.js new file mode 100644 index 0000000000000000000000000000000000000000..5d68f5c363bbfbaf3ae921c31bcf3b5621167d31 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/modal/service.js @@ -0,0 +1,41 @@ +import { Tracker } from 'meteor/tracker'; +import React, { Component } from 'react'; + +let currentModal = { + component: null, + tracker: new Tracker.Dependency, +}; + +const showModal = (component) => { + if (currentModal.component !== component) { + currentModal.component = component; + currentModal.tracker.changed(); + } +}; + +export const getModal = () => { + currentModal.tracker.depend(); + return currentModal.component; +}; + +export const withModalMounter = (ComponentToWrap) => + class ModalMounterWrapper extends Component { + constructor(props) { + super(props); + this.mount = this.mount.bind(this); + } + + mount(modalComponent) { + showModal(null); + + // defer the execution to a subsequent event loop + setTimeout(() => showModal(modalComponent), 0); + } + + render() { + return <ComponentToWrap + {...this.props} + mountModal={this.mount} + />; + } + }; diff --git a/bigbluebutton-html5/imports/ui/components/modal/simple/component.jsx b/bigbluebutton-html5/imports/ui/components/modal/simple/component.jsx index 0e0518dec27288df0d3987c308b8b3c82ca8b281..7a9f887d5fbfd2536527b09ee99d58ed12a670c8 100644 --- a/bigbluebutton-html5/imports/ui/components/modal/simple/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/modal/simple/component.jsx @@ -1,5 +1,5 @@ import React, { Component, PropTypes } from 'react'; -import { withModalBase } from '../base/component'; +import ModalBase, { withModalState } from '../base/component'; import Button from '/imports/ui/components/button/component'; import styles from './styles.scss'; import cx from 'classnames'; @@ -14,46 +14,53 @@ const propTypes = { }; const defaultProps = { + shouldCloseOnOverlayClick: true, overlayClassName: styles.overlay, dismiss: { - label: 'Close', - description: 'Closes the modal', + label: 'Cancel', + description: 'Disregards changes and closes the modal', }, }; class ModalSimple extends Component { - handleAction(name) { - const action = this.props[name]; - this.props.close(action.callback); + handleDismiss() { + this.props.modalHide(this.props.dismiss.callback); } render() { const { title, dismiss, + className, + modalisOpen, + ...otherProps, } = this.props; return ( - <div> + <ModalBase + isOpen={modalisOpen} + className={cx(className, styles.modal)} + onRequestClose={this.handleDismiss.bind(this)} + contentLabel={title} + {...otherProps} + > <header className={styles.header}> <h1 className={styles.title}>{title}</h1> - <div className={styles.actions}> - <Button - className={styles.dismiss} - onClick={() => this.props.hide(dismiss.callback)} - label={dismiss.label} - aria-describedby={'modalDismissDescription'} - icon={'close'} - size={'lg'} - hideLabel={true} - tabIndex={0} /> - </div> + <Button + className={styles.dismiss} + label={dismiss.label} + icon={'close'} + circle={true} + hideLabel={true} + onClick={this.handleDismiss.bind(this)} + aria-describedby={'modalDismissDescription'} + tabIndex={0} /> </header> <div className={styles.content}> {this.props.children} </div> - <div id="modalDismissDescription" hidden>{dismiss.description}</div> - </div> + <div id="modalConfirmDescription" hidden>{confirm.description}</div> + </ModalBase> ); } }; @@ -61,4 +68,4 @@ class ModalSimple extends Component { ModalSimple.propTypes = propTypes; ModalSimple.defaultProps = defaultProps; -export default withModalBase(ModalSimple); +export default withModalState(ModalSimple); diff --git a/bigbluebutton-html5/imports/ui/components/modal/simple/styles.scss b/bigbluebutton-html5/imports/ui/components/modal/simple/styles.scss index 62c304389d9a7700fd063752249b54675c41340b..9c0878314acf4c517499caec5ad347e76d83373c 100644 --- a/bigbluebutton-html5/imports/ui/components/modal/simple/styles.scss +++ b/bigbluebutton-html5/imports/ui/components/modal/simple/styles.scss @@ -1,9 +1,9 @@ @import "../../../stylesheets/variables/_all"; +@import "../base/styles"; .modal { display: flex; flex-direction: column; - align-self: flex-start; padding: ($line-height-computed / 2) $line-height-computed; } @@ -16,18 +16,11 @@ .header { display: flex; - padding: $line-height-computed 0; + padding: ($line-height-computed / 2) 0; border-bottom: $border-size solid $color-gray-lighter; flex-shrink: 0; } -.actions { - flex: 0 1 35%; - display: flex; - align-items: center; - justify-content: space-between; -} - .title { @extend %text-elipsis; flex: 1; @@ -36,9 +29,16 @@ } .dismiss { - flex: 0 1 48%; + flex: 0; + > span:first-child { + border-color: transparent; + background-color: transparent; + + > i { color: $color-text; } + } } .overlay { + @extend .overlay; background-color: rgba(0, 0, 0, .5); } diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx index af0dd45102fb731175b5716d141bbfb27063f9e0..b40ecc8fe3657308eb692542da00dc3b119e49a1 100755 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx @@ -3,7 +3,8 @@ import { defineMessages, injectIntl } from 'react-intl'; import cx from 'classnames'; import styles from '../styles'; -import { showModal } from '/imports/ui/components/app/service'; +import { withModalMounter } from '/imports/ui/components/modal/service'; + import LogoutConfirmation from '/imports/ui/components/logout-confirmation/component'; import AboutContainer from '/imports/ui/components/about/container'; import SettingsMenuContainer from '/imports/ui/components/settings/container'; @@ -63,20 +64,13 @@ const intlMessages = defineMessages({ }, }); -const openSettings = () => showModal(<SettingsMenuContainer />); - -const openAbout = () => showModal(<AboutContainer />); - -const openLogoutConfirmation = () => showModal(<LogoutConfirmation />); - class SettingsDropdown extends Component { constructor(props) { super(props); } render() { - - const { intl, isFullScreen } = this.props; + const { intl, mountModal, isFullScreen } = this.props; let fullScreenLabel = intl.formatMessage(intlMessages.fullscreenLabel); let fullScreenDesc = intl.formatMessage(intlMessages.fullscreenDesc); @@ -114,19 +108,19 @@ class SettingsDropdown extends Component { icon="more" label={intl.formatMessage(intlMessages.settingsLabel)} description={intl.formatMessage(intlMessages.settingsDesc)} - onClick={openSettings.bind(this)} + onClick={() => mountModal(<SettingsMenuContainer />)} /> <DropdownListItem label={intl.formatMessage(intlMessages.aboutLabel)} description={intl.formatMessage(intlMessages.aboutDesc)} - onClick={openAbout.bind(this)} + onClick={() => mountModal(<AboutContainer />)} /> <DropdownListSeparator /> <DropdownListItem icon="logout" label={intl.formatMessage(intlMessages.leaveSessionLabel)} description={intl.formatMessage(intlMessages.leaveSessionDesc)} - onClick={openLogoutConfirmation.bind(this)} + onClick={() => mountModal(<LogoutConfirmation />)} /> </DropdownList> </DropdownContent> @@ -135,4 +129,4 @@ class SettingsDropdown extends Component { } } -export default injectIntl(SettingsDropdown); +export default withModalMounter(injectIntl(SettingsDropdown));