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

248 lines
7.0 KiB
JavaScript
Raw Normal View History

import InlineDialog from '@atlaskit/inline-dialog';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createToolbarEvent, sendAnalytics } from '../../analytics';
import { translate } from '../../base/i18n';
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
import { JitsiRecordingConstants } from '../../base/lib-jitsi-meet';
import { getParticipantCount } from '../../base/participants';
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
import { getActiveSession } from '../../recording';
import { ToolbarButton } from '../../toolbox';
import { updateDialInNumbers } from '../actions';
import { InfoDialog } from './info-dialog';
/**
* The amount of time, in milliseconds, to wait until automatically showing
* the {@code InfoDialog}. This is essentially a hack as automatic showing
* should happen in a lonely call and some time is needed to populate
* participants already in the call.
*/
const INFO_DIALOG_AUTO_SHOW_TIMEOUT = 1500;
/**
* 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 {
/**
* {@code InfoDialogButton} component's property types.
*
* @static
*/
static propTypes = {
/**
* The redux state representing the dial-in numbers feature.
*/
_dialIn: PropTypes.object,
/**
* Whether or not the {@code InfoDialog} should display automatically
* after {@link INFO_DIALOG_AUTO_SHOW_TIMEOUT}.
*/
_disableAutoShow: PropTypes.bool,
/**
* The URL for a currently active live broadcast
*/
_liveStreamViewURL: PropTypes.string,
/**
* The number of real participants in the call. If in a lonely call,
* the {@code InfoDialog} will be automatically shown.
*/
_participantCount: PropTypes.number,
/**
* Whether or not the toolbox, in which this component exists, are
* visible.
*/
_toolboxVisible: PropTypes.bool,
/**
* Invoked to toggle display of the info dialog
*/
dispatch: PropTypes.func,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func,
/**
* From which side tooltips should display. Will be re-used for
* displaying the inline dialog for video quality adjustment.
*/
tooltipPosition: PropTypes.string
};
/**
* Initializes new {@code InfoDialogButton} instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
super(props);
/**
* The timeout to automatically show the {@code InfoDialog} if it has
* not been shown yet in a lonely call.
*
* @type {timeoutID}
*/
this._autoShowTimeout = null;
this.state = {
/**
* Whether or not {@code InfoDialog} should be visible.
*/
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);
}
/**
* Set a timeout to automatically hide the {@code InfoDialog}.
*
* @inheritdoc
*/
componentDidMount() {
this._autoShowTimeout = setTimeout(() => {
this._maybeAutoShowDialog();
}, INFO_DIALOG_AUTO_SHOW_TIMEOUT);
if (!this.props._dialIn.numbers) {
this.props.dispatch(updateDialInNumbers());
}
}
/**
* Update the visibility of the {@code InfoDialog}.
*
* @inheritdoc
*/
componentWillReceiveProps(nextProps) {
// Ensure the dialog is closed when the toolbox becomes hidden.
if (this.state.showDialog && !nextProps._toolboxVisible) {
this._onDialogClose();
}
}
/**
* Clear the timeout to automatically show the {@code InfoDialog}.
*
* @inheritdoc
*/
componentWillUnmount() {
clearTimeout(this._autoShowTimeout);
}
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
const { _dialIn, _liveStreamViewURL, t } = this.props;
const { showDialog } = this.state;
const iconClass = `icon-info ${showDialog ? 'toggled' : ''}`;
return (
<div className = 'toolbox-button-wth-dialog'>
<InlineDialog
content = {
<InfoDialog
dialIn = { _dialIn }
liveStreamViewURL = { _liveStreamViewURL }
onClose = { this._onDialogClose } /> }
isOpen = { showDialog }
onClose = { this._onDialogClose }
position = { 'top right' }>
<ToolbarButton
accessibilityLabel = 'Info'
iconName = { iconClass }
onClick = { this._onDialogToggle }
tooltip = { t('info.tooltip') } />
</InlineDialog>
</div>
);
}
/**
* Callback invoked after a timeout to trigger display of the
* {@code InfoDialog} if certain conditions are met.
*
* @private
* @returns {void}
*/
_maybeAutoShowDialog() {
if (this.props._participantCount < 2 && !this.props._disableAutoShow) {
this.setState({ showDialog: true });
}
}
/**
* Hides {@code InfoDialog}.
*
* @private
* @returns {void}
*/
_onDialogClose() {
this.setState({ showDialog: false });
}
/**
* 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,
* _liveStreamViewURL: string,
* _participantCount: number,
* _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);
return {
_dialIn: state['features/invite'],
_disableAutoShow: state['features/base/config'].iAmRecorder,
_liveStreamViewURL:
currentLiveStreamingSession
&& currentLiveStreamingSession.liveStreamViewURL,
_participantCount: getParticipantCount(state),
_toolboxVisible: state['features/toolbox'].visible
};
}
export default translate(connect(_mapStateToProps)(InfoDialogButton));