diff --git a/react/features/invite/actions.js b/react/features/invite/actions.js index 704a6aec0..3ef96fad4 100644 --- a/react/features/invite/actions.js +++ b/react/features/invite/actions.js @@ -24,14 +24,20 @@ export function openInviteDialog() { * Opens the inline conference info dialog. * * @param {boolean} visible - Whether or not the dialog should be displayed. + * @param {boolean} autoClose - Whether or not the dialog should automatically + * close after a set period of time. * @returns {{ * type: SET_INFO_DIALOG_VISIBILITY, + * autoClose: boolean, * visible: boolean * }} */ -export function setInfoDialogVisibility(visible: boolean) { +export function setInfoDialogVisibility( + visible: boolean, + autoClose: boolean = false) { return { type: SET_INFO_DIALOG_VISIBILITY, + autoClose, visible }; } diff --git a/react/features/invite/components/InfoDialogButton.web.js b/react/features/invite/components/InfoDialogButton.web.js index dd0f6febb..a2817a185 100644 --- a/react/features/invite/components/InfoDialogButton.web.js +++ b/react/features/invite/components/InfoDialogButton.web.js @@ -40,6 +40,12 @@ class InfoDialogButton extends Component { * @static */ static propTypes = { + /** + * Whether or not the {@code InfoDialog} should close by itself after a + * a timeout. + */ + _shouldAutoClose: PropTypes.bool, + /** * Whether or not {@code InfoDialog} should be displayed. */ @@ -80,15 +86,6 @@ class InfoDialogButton extends Component { */ this._autoHideDialogTimeout = null; - this.state = { - /** - * Whether or not the dialog has been interacted with somehow, such - * as clicking or toggle display. A value of true will prevent the - * dialog from being automatically hidden. - */ - hasInteractedWithDialog: false - }; - // Bind event handlers so they are only bound once for every instance. this._onDialogClose = this._onDialogClose.bind(this); this._onDialogMouseOver = this._onDialogMouseOver.bind(this); @@ -101,23 +98,34 @@ class InfoDialogButton extends Component { * @inheritdoc */ componentDidMount() { - this._autoHideDialogTimeout = setTimeout(() => { - this._maybeHideDialog(); - }, INITIAL_TOOLBAR_TIMEOUT); + if (this.props._shouldAutoClose) { + this._setAutoCloseTimeout(); + } } /** - * Update the state when the {@code InfoDialog} visibility has been updated. + * Set or clear the timeout to automatically hide the {@code InfoDialog}. + * + * @inheritdoc + */ + componentDidUpdate(prevProps) { + // If the _shouldAutoClose flag has been updated to be true then make + // sure to set _autoHideDialogTimeout. + if (this.props._shouldAutoClose && !prevProps._shouldAutoClose) { + this._setAutoCloseTimeout(); + } else { + this._clearAutoCloseTimeout(); + } + } + + /** + * Update the visibility of the {@code InfoDialog}. * * @inheritdoc */ componentWillReceiveProps(nextProps) { - if (!this.state.hasInteractedWithDialog - && (nextProps._showDialog !== this.props._showDialog)) { - this.setState({ hasInteractedWithDialog: true }); - } - - if (!nextProps._toolboxVisible && this.props._toolboxVisible) { + // Ensure the dialog is closed when the toolbox becomes hidden. + if (nextProps._showDialog && !nextProps._toolboxVisible) { this._onDialogClose(); } } @@ -128,7 +136,7 @@ class InfoDialogButton extends Component { * @inheritdoc */ componentWillUnmount() { - clearTimeout(this._autoHideDialogTimeout); + this._clearAutoCloseTimeout(); } /** @@ -154,7 +162,6 @@ class InfoDialogButton extends Component { onMouseOver = { this._onDialogMouseOver } /> } isOpen = { _toolboxVisible && _showDialog } onClose = { this._onDialogClose } - onContentClick = { this._onDialogInteract } position = { TOOLTIP_TO_POPUP_POSITION[tooltipPosition] }> { + if (this.props._showDialog) { + this._onDialogClose(); + } + }, INITIAL_TOOLBAR_TIMEOUT); + } } /** @@ -219,13 +236,20 @@ class InfoDialogButton extends Component { * @param {Object} state - The Redux state. * @private * @returns {{ + * _shouldAutoClose: boolean, * _showDialog: boolean, * _toolboxVisible: boolean * }} */ function _mapStateToProps(state) { + const { + infoDialogVisible, + infoDialogWillAutoClose + } = state['features/invite']; + return { - _showDialog: state['features/invite'].infoDialogVisible, + _shouldAutoClose: infoDialogWillAutoClose, + _showDialog: infoDialogVisible, _toolboxVisible: state['features/toolbox'].visible }; } diff --git a/react/features/invite/middleware.js b/react/features/invite/middleware.js index 59ed12eae..df2b43b2e 100644 --- a/react/features/invite/middleware.js +++ b/react/features/invite/middleware.js @@ -18,7 +18,7 @@ MiddlewareRegistry.register(store => next => action => { switch (action.type) { case CONFERENCE_JOINED: - store.dispatch(setInfoDialogVisibility(true)); + store.dispatch(setInfoDialogVisibility(true, true)); break; case UPDATE_DIAL_IN_NUMBERS_FAILED: diff --git a/react/features/invite/reducer.js b/react/features/invite/reducer.js index cc4d1c2a0..f4f4a6173 100644 --- a/react/features/invite/reducer.js +++ b/react/features/invite/reducer.js @@ -15,7 +15,8 @@ ReducerRegistry.register('features/invite', (state = DEFAULT_STATE, action) => { case SET_INFO_DIALOG_VISIBILITY: return { ...state, - infoDialogVisible: action.visible + infoDialogVisible: action.visible, + infoDialogWillAutoClose: action.autoClose }; case UPDATE_DIAL_IN_NUMBERS_FAILED: