feat(prejoin): Add 'skip prejoin' button

This commit is contained in:
Vlad Piersec 2020-07-15 11:06:14 +03:00 committed by Saúl Ibarra Corretgé
parent c8444a9a0d
commit 035f720a50
7 changed files with 168 additions and 23 deletions

View File

@ -36,13 +36,7 @@
}
&-checkbox-container {
align-items: center;
color: #fff;
display: none;
font-size: 13px;
justify-content: center;
line-height: 20px;
margin-top: 16px;
margin-bottom: 14px;
width: 100%;
}
}

View File

@ -216,3 +216,66 @@
width: 100%;
}
}
@mixin flex-centered() {
align-items: center;
display: flex;
justify-content: center;
}
@mixin icon-container($bg, $fill) {
.toggle-button-icon-container {
background: $bg;
svg {
fill: $fill
}
}
}
.toggle-button {
border-radius: 3px;
cursor: pointer;
color: #fff;
font-size: 13px;
height: 40px;
margin: 0 auto;
width: 320px;
@include flex-centered();
svg {
fill: transparent;
}
&:hover {
background: #1C2025;
@include icon-container(#A4B8D1, #1C2025);
}
&-container {
position: relative;
@include flex-centered();
}
&-icon-container {
border-radius: 50%;
left: -22px;
padding: 2px;
position: absolute;
}
&--toggled {
background: #75757A;
&:hover {
background: #75757A;
@include icon-container(#A4B8D1, #75757A);
}
@include icon-container(#A4B8D1, #75757A);
}
}

View File

@ -39,6 +39,11 @@ type Props = {
*/
title: string,
/**
* The 'Skip prejoin' button to be rendered (if any).
*/
skipPrejoinButton?: React$Node,
/**
* True if the preview overlay should be muted, false otherwise.
*/
@ -97,6 +102,7 @@ export default class PreMeetingScreen extends PureComponent<Props> {
<AudioSettingsButton visible = { true } />
<VideoSettingsButton visible = { true } />
</div>
{ this.props.skipPrejoinButton }
{ this.props.footer }
</div>
</div>

View File

@ -0,0 +1,52 @@
// @flow
import React from 'react';
import { Icon, IconCheck } from '../../../icons';
const mainClass = 'toggle-button';
type Props = {
/**
* Text of the button.
*/
children: React$Node,
/**
* If the button is toggled or not.
*/
isToggled?: boolean,
/**
* OnClick button handler.
*/
onClick: Function
}
/**
* Button used as a toggle.
*
* @returns {ReactElement}
*/
function ToggleButton({ children, isToggled, onClick }: Props) {
const className = isToggled ? `${mainClass} ${mainClass}--toggled` : mainClass;
return (
<div
className = { className }
onClick = { onClick }>
<div className = 'toggle-button-container'>
<div className = 'toggle-button-icon-container'>
<Icon
className = 'toggle-button-icon'
size = { 10 }
src = { IconCheck } />
</div>
<span>{children}</span>
</div>
</div>
);
}
export default ToggleButton;

View File

@ -3,3 +3,4 @@
export { default as ActionButton } from './ActionButton';
export { default as InputField } from './InputField';
export { default as PreMeetingScreen } from './PreMeetingScreen';
export { default as ToggleButton } from './ToggleButton';

View File

@ -7,7 +7,7 @@ import { getRoomName } from '../../base/conference';
import { translate } from '../../base/i18n';
import { Icon, IconPhone, IconVolumeOff } from '../../base/icons';
import { isVideoMutedByUser } from '../../base/media';
import { ActionButton, InputField, PreMeetingScreen } from '../../base/premeeting';
import { ActionButton, InputField, PreMeetingScreen, ToggleButton } from '../../base/premeeting';
import { connect } from '../../base/redux';
import { getDisplayName, updateSettings } from '../../base/settings';
import { getLocalJitsiVideoTrack } from '../../base/tracks';
@ -21,7 +21,8 @@ import {
isDeviceStatusVisible,
isDisplayNameRequired,
isJoinByPhoneButtonVisible,
isJoinByPhoneDialogVisible
isJoinByPhoneDialogVisible,
isPrejoinSkipped
} from '../functions';
import JoinByPhoneDialog from './dialogs/JoinByPhoneDialog';
@ -29,6 +30,11 @@ import DeviceStatus from './preview/DeviceStatus';
type Props = {
/**
* Flag signaling if the 'skip prejoin' button is toggled or not.
*/
buttonIsToggled: boolean,
/**
* Flag signaling if the device status is visible or not.
*/
@ -145,22 +151,22 @@ class Prejoin extends Component<Props, State> {
this._closeDialog = this._closeDialog.bind(this);
this._showDialog = this._showDialog.bind(this);
this._onCheckboxChange = this._onCheckboxChange.bind(this);
this._onToggleButtonClick = this._onToggleButtonClick.bind(this);
this._onDropdownClose = this._onDropdownClose.bind(this);
this._onOptionsClick = this._onOptionsClick.bind(this);
this._setName = this._setName.bind(this);
}
_onCheckboxChange: () => void;
_onToggleButtonClick: () => void;
/**
* Handler for the checkbox.
* Handler for the toggle button.
*
* @param {Object} e - The synthetic event.
* @returns {void}
*/
_onCheckboxChange(e) {
this.props.setSkipPrejoin(e.target.checked);
_onToggleButtonClick() {
this.props.setSkipPrejoin(!this.props.buttonIsToggled);
}
_onDropdownClose: () => void;
@ -250,7 +256,7 @@ class Prejoin extends Component<Props, State> {
videoTrack
} = this.props;
const { _closeDialog, _onCheckboxChange, _onDropdownClose, _onOptionsClick, _setName, _showDialog } = this;
const { _closeDialog, _onDropdownClose, _onOptionsClick, _setName, _showDialog } = this;
const { showJoinByPhoneButtons } = this.state;
return (
@ -259,6 +265,7 @@ class Prejoin extends Component<Props, State> {
name = { name }
showAvatar = { showAvatar }
showConferenceInfo = { showJoinActions }
skipPrejoinButton = { this._renderSkipPrejoinButton() }
title = { t('prejoin.joinMeeting') }
videoMuted = { !showCameraPreview }
videoTrack = { videoTrack }>
@ -306,14 +313,6 @@ class Prejoin extends Component<Props, State> {
</InlineDialog>
</div>
</div>
<div className = 'prejoin-checkbox-container'>
<input
className = 'prejoin-checkbox'
onChange = { _onCheckboxChange }
type = 'checkbox' />
<span>{t('prejoin.doNotShow')}</span>
</div>
</div>
)}
{ showDialog && (
@ -333,6 +332,25 @@ class Prejoin extends Component<Props, State> {
_renderFooter() {
return this.props.deviceStatusVisible && <DeviceStatus />;
}
/**
* Renders the 'skip prejoin' button.
*
* @returns {React$Element}
*/
_renderSkipPrejoinButton() {
const { buttonIsToggled, t } = this.props;
return (
<div className = 'prejoin-checkbox-container'>
<ToggleButton
isToggled = { buttonIsToggled }
onClick = { this._onToggleButtonClick }>
{t('prejoin.doNotShow')}
</ToggleButton>
</div>
);
}
}
/**
@ -346,6 +364,7 @@ function mapStateToProps(state): Object {
const joinButtonDisabled = isDisplayNameRequired(state) && !name;
return {
buttonIsToggled: isPrejoinSkipped(state),
joinButtonDisabled,
name,
deviceStatusVisible: isDeviceStatusVisible(state),

View File

@ -36,6 +36,16 @@ export function isDisplayNameRequired(state: Object): boolean {
|| state['features/base/config'].requireDisplayName;
}
/**
* Selector for determining if the user has chosen to skip prejoin page.
*
* @param {Object} state - The state of the app.
* @returns {boolean}
*/
export function isPrejoinSkipped(state: Object) {
return state['features/prejoin'].userSelectedSkipPrejoin;
}
/**
* Returns the text for the prejoin status bar.
*