jiti-meet/react/features/invite/components/info-dialog/web/InfoDialogButton.js

269 lines
7.5 KiB
JavaScript
Raw Normal View History

// @flow
import InlineDialog from '@atlaskit/inline-dialog';
import React, { Component } from 'react';
2019-03-19 15:42:25 +00:00
import type { Dispatch } from 'redux';
2019-04-02 13:16:52 +00:00
import { createToolbarEvent, sendAnalytics } from '../../../../analytics';
import { openDialog } from '../../../../base/dialog';
import { translate } from '../../../../base/i18n';
2019-08-30 16:39:06 +00:00
import { IconInfo } from '../../../../base/icons';
2019-04-02 13:16:52 +00:00
import { JitsiRecordingConstants } from '../../../../base/lib-jitsi-meet';
import { getParticipantCount } from '../../../../base/participants';
import { OverflowMenuItem } from '../../../../base/toolbox';
import { connect } from '../../../../base/redux';
import { getActiveSession } from '../../../../recording';
import { ToolbarButton } from '../../../../toolbox';
import { updateDialInNumbers } from '../../../actions';
import InfoDialog from './InfoDialog';
/**
* The type of the React {@code Component} props of {@link InfoDialogButton}.
*/
type Props = {
/**
* The redux state representing the dial-in numbers feature.
*/
_dialIn: Object,
/**
* Whether or not the {@code InfoDialog} should display automatically when
* in a lonely call.
*/
_disableAutoShow: boolean,
/**
* Whether or not the local participant has joined a
* {@code JitsiConference}. Used to trigger auto showing of the
* {@code InfoDialog}.
*/
_isConferenceJoined: Boolean,
/**
* The URL for a currently active live broadcast
*/
_liveStreamViewURL: ?string,
/**
* True if the number of real participants in the call is less than 2. If in a lonely call, the
* {@code InfoDialog} will be automatically shown.
*/
_isLonelyCall: boolean,
/**
* Whether or not the toolbox, in which this component exists, is visible.
*/
_toolboxVisible: boolean,
/**
* Invoked to toggle display of the info dialog.
*/
2019-03-19 15:42:25 +00:00
dispatch: Dispatch<any>,
/**
* Whether to show the label or not.
*/
showLabel: boolean,
/**
* Invoked to obtain translated strings.
*/
t: Function
};
/**
* The type of the React {@code Component} state of {@link InfoDialogButton}.
*/
type State = {
/**
* Cache the conference connection state to derive when transitioning from
* not joined to join, in order to auto-show the InfoDialog.
*/
hasConnectedToConference: boolean,
/**
* Whether or not {@code InfoDialog} should be visible.
*/
showDialog: boolean
};
/**
* A React Component for displaying a button which opens a dialog with
* information about the conference and with ways to invite people.
*
* @extends Component
*/
class InfoDialogButton extends Component<Props, State> {
/**
* Implements React's {@link Component#getDerivedStateFromProps()}.
*
* @inheritdoc
*/
static getDerivedStateFromProps(props, state) {
return {
hasConnectedToConference: props._isConferenceJoined,
showDialog: (props._toolboxVisible && state.showDialog)
|| (!state.hasConnectedToConference
&& props._isConferenceJoined
&& props._isLonelyCall
&& props._toolboxVisible
&& !props._disableAutoShow)
};
}
/**
* Initializes new {@code InfoDialogButton} instance.
*
* @inheritdoc
*/
constructor(props) {
super(props);
this.state = {
hasConnectedToConference: props._isConferenceJoined,
showDialog: false
};
// Bind event handlers so they are only bound once for every instance.
this._onDialogClose = this._onDialogClose.bind(this);
this._onDialogToggle = this._onDialogToggle.bind(this);
this._onClickOverflowMenuButton
= this._onClickOverflowMenuButton.bind(this);
}
/**
* Update dial-in numbers {@code InfoDialog}.
*
* @inheritdoc
*/
componentDidMount() {
if (!this.props._dialIn.numbers) {
this.props.dispatch(updateDialInNumbers());
}
}
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
const { _dialIn, _liveStreamViewURL, showLabel, t } = this.props;
const { showDialog } = this.state;
if (showLabel) {
return (
<OverflowMenuItem
accessibilityLabel = { t('info.accessibilityLabel') }
icon = 'icon-info'
key = 'info-button'
onClick = { this._onClickOverflowMenuButton }
text = { t('info.label') } />
);
}
return (
<div className = 'toolbox-button-wth-dialog'>
<InlineDialog
content = {
<InfoDialog
dialIn = { _dialIn }
isInlineDialog = { true }
liveStreamViewURL = { _liveStreamViewURL }
onClose = { this._onDialogClose } /> }
isOpen = { showDialog }
onClose = { this._onDialogClose }
position = { 'top right' }>
<ToolbarButton
fix(i18n) Accessiblity labels translations (#3071) * fix(toolbar): accessibilityLabel should be translatable. This commit adds a helper property to get the accessibilityLabel of an item, providing a translation if one is available. This mimics the behavior of label and tooltip. * fix(toolbar) 'hangup' button accessibilityLabel i18n * fix(toolbar) 'mute' button accessibilityLabel i18n * fix(toolbar) 'videomute' button accessibilityLabel i18n * fix(toolbar) 'moreActions' button accessibilityLabel i18n * fix(toolbar) 'shareRoom' button accessibilityLabel i18n * fix(toolbar) 'audioRoute' button accessibilityLabel i18n * fix(toolbar) 'toggleCamera' button accessibilityLabel i18n * fix(toolbar) 'audioOnly' button accessibilityLabel i18n * fix(toolbar) 'roomLock' button accessibilityLabel i18n * fix(toolbar) 'pip' button accessibilityLabel i18n * fix(toolbar) 'invite' button accessibilityLabel i18n * fix(toolbar) 'raiseHand' button accessibilityLabel i18n * fix(toolbar) 'chat' button accessibilityLabel i18n * fix(toolbar) 'shareYourScreen' button accessibilityLabel i18n * fix(toolbar) 'fullScreen' button accessibilityLabel i18n * fix(toolbar) 'sharedvideo' button accessibilityLabel i18n * fix(toolbar) 'document' button accessibilityLabel i18n * fix(toolbar) 'speakerStats' button accessibilityLabel i18n * fix(toolbar) 'feedback' button accessibilityLabel i18n * fix(toolbar) 'shortcuts' button accessibilityLabel i18n * fix(toolbar) 'recording' button accessibilityLabel i18n * fix(toolbar) 'settings' button accessibilityLabel i18n * fix(welcomepage) accessibilityLabels i18n * fix(toolbar) 'info' button accessibilityLabel i18n * fix(i18n): Add translation to various aria-label property values. * fix(i18n): Differentiate between overflow menu and button.
2018-06-07 20:32:18 +00:00
accessibilityLabel = { t('info.accessibilityLabel') }
2019-08-30 16:39:06 +00:00
icon = { IconInfo }
onClick = { this._onDialogToggle }
tooltip = { t('info.tooltip') } />
</InlineDialog>
</div>
);
}
_onDialogClose: () => void;
/**
* Hides {@code InfoDialog}.
*
* @private
* @returns {void}
*/
_onDialogClose() {
this.setState({ showDialog: false });
}
_onClickOverflowMenuButton: () => void;
/**
* Opens the Info dialog.
*
* @returns {void}
*/
_onClickOverflowMenuButton() {
const { _dialIn, _liveStreamViewURL } = this.props;
this.props.dispatch(openDialog(InfoDialog, {
dialIn: _dialIn,
liveStreamViewURL: _liveStreamViewURL,
isInlineDialog: false
}));
}
_onDialogToggle: () => void;
/**
* Toggles the display of {@code InfoDialog}.
*
* @private
* @returns {void}
*/
_onDialogToggle() {
sendAnalytics(createToolbarEvent('info'));
this.setState({ showDialog: !this.state.showDialog });
}
}
/**
* Maps (parts of) the Redux state to the associated {@code InfoDialogButton}
* component's props.
*
* @param {Object} state - The Redux state.
* @private
* @returns {{
* _dialIn: Object,
* _disableAutoShow: boolean,
* _isConferenceIsJoined: boolean,
* _liveStreamViewURL: string,
* _isLonelyCall: boolean,
* _toolboxVisible: boolean
* }}
*/
function _mapStateToProps(state) {
feat(recording): frontend logic can support live streaming and recording (#2952) * feat(recording): frontend logic can support live streaming and recording Instead of either live streaming or recording, now both can live together. The changes to facilitate such include the following: - Killing the state storing in Recording.js. Instead state is stored in the lib and updated in redux for labels to display the necessary state updates. - Creating a new container, Labels, for recording labels. Previously labels were manually created and positioned. The container can create a reasonable number of labels and only the container itself needs to be positioned with CSS. The VideoQualityLabel has been shoved into the container as well because it moves along with the recording labels. - The action for updating recording state has been modified to enable updating an array of recording sessions to support having multiple sessions. - Confirmation dialogs for stopping and starting a file recording session have been created, as they previously were jquery modals opened by Recording.js. - Toolbox.web displays live streaming and recording buttons based on configuration instead of recording availability. - VideoQualityLabel and RecordingLabel have been simplified to remove any positioning logic, as the Labels container handles such. - Previous recording state update logic has been moved into the RecordingLabel component. Each RecordingLabel is in charge of displaying state for a recording session. The display UX has been left alone. - Sipgw availability is no longer broadcast so remove logic depending on its state. Some moving around of code was necessary to get around linting errors about the existing code being too deeply nested (even though I didn't touch it). * work around lib-jitsi-meet circular dependency issues * refactor labels to use html base * pass in translation keys to video quality label * add video quality classnames for torture tests * break up, rearrange recorder session update listener * add comment about disabling startup resize animation * rename session to sessionData * chore(deps): update to latest lib for recording changes
2018-05-16 14:00:16 +00:00
const currentLiveStreamingSession
= getActiveSession(state, JitsiRecordingConstants.mode.STREAM);
const { iAmRecorder, iAmSipGateway } = state['features/base/config'];
feat(recording): frontend logic can support live streaming and recording (#2952) * feat(recording): frontend logic can support live streaming and recording Instead of either live streaming or recording, now both can live together. The changes to facilitate such include the following: - Killing the state storing in Recording.js. Instead state is stored in the lib and updated in redux for labels to display the necessary state updates. - Creating a new container, Labels, for recording labels. Previously labels were manually created and positioned. The container can create a reasonable number of labels and only the container itself needs to be positioned with CSS. The VideoQualityLabel has been shoved into the container as well because it moves along with the recording labels. - The action for updating recording state has been modified to enable updating an array of recording sessions to support having multiple sessions. - Confirmation dialogs for stopping and starting a file recording session have been created, as they previously were jquery modals opened by Recording.js. - Toolbox.web displays live streaming and recording buttons based on configuration instead of recording availability. - VideoQualityLabel and RecordingLabel have been simplified to remove any positioning logic, as the Labels container handles such. - Previous recording state update logic has been moved into the RecordingLabel component. Each RecordingLabel is in charge of displaying state for a recording session. The display UX has been left alone. - Sipgw availability is no longer broadcast so remove logic depending on its state. Some moving around of code was necessary to get around linting errors about the existing code being too deeply nested (even though I didn't touch it). * work around lib-jitsi-meet circular dependency issues * refactor labels to use html base * pass in translation keys to video quality label * add video quality classnames for torture tests * break up, rearrange recorder session update listener * add comment about disabling startup resize animation * rename session to sessionData * chore(deps): update to latest lib for recording changes
2018-05-16 14:00:16 +00:00
return {
_dialIn: state['features/invite'],
_disableAutoShow: iAmRecorder || iAmSipGateway,
_isConferenceJoined:
Boolean(state['features/base/conference'].conference),
_liveStreamViewURL:
currentLiveStreamingSession
&& currentLiveStreamingSession.liveStreamViewURL,
_isLonelyCall: getParticipantCount(state) < 2,
_toolboxVisible: state['features/toolbox'].visible
};
}
export default translate(connect(_mapStateToProps)(InfoDialogButton));