feat(prejoin_page): Add prejoin page

This commit is contained in:
Vlad Piersec
2020-04-16 13:47:10 +03:00
committed by Saúl Ibarra Corretgé
parent 5b53232964
commit a45cbf41ef
36 changed files with 2274 additions and 147 deletions

View File

@@ -12,6 +12,11 @@ import { connect } from '../../base/redux';
import { AbstractAudioMuteButton } from '../../base/toolbox';
import type { AbstractButtonProps } from '../../base/toolbox';
import { isLocalTrackMuted } from '../../base/tracks';
import {
isPrejoinAudioMuted,
isAudioDisabled,
isPrejoinPageVisible
} from '../../prejoin';
import { muteLocal } from '../../remote-video-menu/actions';
declare var APP: Object;
@@ -144,15 +149,27 @@ class AudioMuteButton extends AbstractAudioMuteButton<Props, *> {
* @param {Object} state - The Redux state.
* @private
* @returns {{
* _audioMuted: boolean
* _audioMuted: boolean,
* _disabled: boolean
* }}
*/
function _mapStateToProps(state): Object {
const tracks = state['features/base/tracks'];
let _audioMuted;
let _disabled;
if (isPrejoinPageVisible(state)) {
_audioMuted = isPrejoinAudioMuted(state);
_disabled = state['features/base/config'].startSilent;
} else {
const tracks = state['features/base/tracks'];
_audioMuted = isLocalTrackMuted(tracks, MEDIA_TYPE.AUDIO);
_disabled = state['features/base/config'].startSilent || isAudioDisabled(state);
}
return {
_audioMuted: isLocalTrackMuted(tracks, MEDIA_TYPE.AUDIO),
_disabled: state['features/base/config'].startSilent
_audioMuted,
_disabled
};
}

View File

@@ -17,6 +17,11 @@ import { connect } from '../../base/redux';
import { AbstractVideoMuteButton } from '../../base/toolbox';
import type { AbstractButtonProps } from '../../base/toolbox';
import { getLocalVideoType, isLocalVideoTrackMuted } from '../../base/tracks';
import {
isPrejoinPageVisible,
isPrejoinVideoDisabled,
isPrejoinVideoMuted
} from '../../prejoin';
import UIEvents from '../../../../service/UI/UIEvents';
declare var APP: Object;
@@ -41,6 +46,11 @@ type Props = AbstractButtonProps & {
*/
_videoMuted: boolean,
/**
* Whether video button is disabled or not.
*/
_videoDisabled: boolean,
/**
* The redux {@code dispatch} function.
*/
@@ -96,6 +106,17 @@ class VideoMuteButton extends AbstractVideoMuteButton<Props, *> {
|| APP.keyboardshortcut.unregisterShortcut('V');
}
/**
* Indicates if video is currently disabled or not.
*
* @override
* @protected
* @returns {boolean}
*/
_isDisabled() {
return this.props._videoDisabled;
}
/**
* Indicates if video is currently muted ot nor.
*
@@ -170,11 +191,19 @@ class VideoMuteButton extends AbstractVideoMuteButton<Props, *> {
function _mapStateToProps(state): Object {
const { enabled: audioOnly } = state['features/base/audio-only'];
const tracks = state['features/base/tracks'];
let _videoMuted = isLocalVideoTrackMuted(tracks);
let _videoDisabled = false;
if (isPrejoinPageVisible(state)) {
_videoMuted = isPrejoinVideoMuted(state);
_videoDisabled = isPrejoinVideoDisabled(state);
}
return {
_audioOnly: Boolean(audioOnly),
_videoDisabled,
_videoMediaType: getLocalVideoType(tracks),
_videoMuted: isLocalVideoTrackMuted(tracks)
_videoMuted
};
}

View File

@@ -3,7 +3,7 @@
import React, { Component } from 'react';
import AudioMuteButton from '../AudioMuteButton';
import { hasAvailableDevices } from '../../../base/devices';
import { isAudioSettingsButtonDisabled } from '../../functions';
import { IconArrowDown } from '../../../base/icons';
import JitsiMeetJS from '../../../base/lib-jitsi-meet/_';
import { ToolboxButtonWithIcon } from '../../../base/toolbox';
@@ -25,9 +25,9 @@ type Props = {
permissionPromptVisibility: boolean,
/**
* If the user has audio input or audio output devices.
* If the button should be disabled.
*/
hasDevices: boolean,
isDisabled: boolean,
/**
* Flag controlling the visibility of the button.
@@ -49,6 +49,8 @@ type State = {
* @returns {ReactElement}
*/
class AudioSettingsButton extends Component<Props, State> {
_isMounted: boolean;
/**
* Initializes a new {@code AudioSettingsButton} instance.
*
@@ -58,6 +60,7 @@ class AudioSettingsButton extends Component<Props, State> {
constructor(props) {
super(props);
this._isMounted = true;
this.state = {
hasPermissions: false
};
@@ -73,7 +76,7 @@ class AudioSettingsButton extends Component<Props, State> {
'audio',
);
this.setState({
this._isMounted && this.setState({
hasPermissions
});
}
@@ -98,14 +101,23 @@ class AudioSettingsButton extends Component<Props, State> {
}
}
/**
* Implements React's {@link Component#componentWillUnmount}.
*
* @inheritdoc
*/
componentWillUnmount() {
this._isMounted = false;
}
/**
* Implements React's {@link Component#render}.
*
* @inheritdoc
*/
render() {
const { hasDevices, onAudioOptionsClick, visible } = this.props;
const settingsDisabled = !this.state.hasPermissions || !hasDevices;
const { isDisabled, onAudioOptionsClick, visible } = this.props;
const settingsDisabled = !this.state.hasPermissions || isDisabled;
return visible ? (
<AudioSettingsPopup>
@@ -128,9 +140,7 @@ class AudioSettingsButton extends Component<Props, State> {
*/
function mapStateToProps(state) {
return {
hasDevices:
hasAvailableDevices(state, 'audioInput')
|| hasAvailableDevices(state, 'audioOutput'),
isDisabled: isAudioSettingsButtonDisabled(state),
permissionPromptVisibility: getMediaPermissionPromptVisibility(state)
};
}

View File

@@ -1,11 +1,10 @@
// @flow
import React, { Component } from 'react';
import { isVideoSettingsButtonDisabled } from '../../functions';
import { toggleVideoSettings, VideoSettingsPopup } from '../../../settings';
import VideoMuteButton from '../VideoMuteButton';
import JitsiMeetJS from '../../../base/lib-jitsi-meet/_';
import { hasAvailableDevices } from '../../../base/devices';
import { IconArrowDown } from '../../../base/icons';
import { connect } from '../../../base/redux';
import { ToolboxButtonWithIcon } from '../../../base/toolbox';
@@ -25,9 +24,9 @@ type Props = {
permissionPromptVisibility: boolean,
/**
* If the user has any video devices.
* If the button should be disabled
*/
hasDevices: boolean,
isDisabled: boolean,
/**
* Flag controlling the visibility of the button.
@@ -49,6 +48,8 @@ type State = {
* @returns {ReactElement}
*/
class VideoSettingsButton extends Component<Props, State> {
_isMounted: boolean;
/**
* Initializes a new {@code VideoSettingsButton} instance.
*
@@ -58,6 +59,7 @@ class VideoSettingsButton extends Component<Props, State> {
constructor(props) {
super(props);
this._isMounted = true;
this.state = {
hasPermissions: false
};
@@ -73,7 +75,7 @@ class VideoSettingsButton extends Component<Props, State> {
'video',
);
this.setState({
this._isMounted && this.setState({
hasPermissions
});
}
@@ -98,14 +100,23 @@ class VideoSettingsButton extends Component<Props, State> {
}
}
/**
* Implements React's {@link Component#componentWillUnmount}.
*
* @inheritdoc
*/
componentWillUnmount() {
this._isMounted = false;
}
/**
* Implements React's {@link Component#render}.
*
* @inheritdoc
*/
render() {
const { hasDevices, onVideoOptionsClick, visible } = this.props;
const iconDisabled = !this.state.hasPermissions || !hasDevices;
const { isDisabled, onVideoOptionsClick, visible } = this.props;
const iconDisabled = !this.state.hasPermissions || isDisabled;
return visible ? (
<VideoSettingsPopup>
@@ -128,7 +139,7 @@ class VideoSettingsButton extends Component<Props, State> {
*/
function mapStateToProps(state) {
return {
hasDevices: hasAvailableDevices(state, 'videoInput'),
isDisabled: isVideoSettingsButtonDisabled(state),
permissionPromptVisibility: getMediaPermissionPromptVisibility(state)
};
}

View File

@@ -1,2 +1,4 @@
export { default as AudioSettingsButton } from './AudioSettingsButton';
export { default as VideoSettingsButton } from './VideoSettingsButton';
export { default as ToolbarButton } from './ToolbarButton';
export { default as Toolbox } from './Toolbox';