feat(config) add flag to disable lobby password & group lobby config flags (#12793)

This commit is contained in:
Mihaela Dumitru 2023-02-09 14:46:25 +02:00 committed by GitHub
parent 1a113ba733
commit 2aa770e532
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 135 additions and 42 deletions

View File

@ -542,12 +542,15 @@ var config = {
// Disables responsive tiles.
// disableResponsiveTiles: false,
// Hides lobby button
// DEPRECATED. Please use `securityUi?.hideLobbyButton` instead.
// Hides lobby button.
// hideLobbyButton: false,
// DEPRECATED. Please use `lobby?.autoKnock` instead.
// If Lobby is enabled starts knocking automatically.
// autoKnockLobby: false,
// DEPRECATED. Please use `lobby?.enableChat` instead.
// Enable lobby chat.
// enableLobbyChat: true,
@ -572,6 +575,22 @@ var config = {
// customUrl: ''
// },
// Configs for the lobby screen.
// lobby {
// // If Lobby is enabled, it starts knocking automatically. Replaces `autoKnockLobby`.
// autoKnock: false,
// // Enables the lobby chat. Replaces `enableLobbyChat`.
// enableChat: true,
// },
// Configs for the security related UI elements.
// securityUi: {
// // Hides the lobby button. Replaces `hideLobbyButton`.
// hideLobbyButton: false,
// // Hides the possibility to set and enter a lobby password.
// disableLobbyPassword: false,
// },
// Disable app shortcuts that are registered upon joining a conference
// disableShortcuts: false,

View File

@ -396,6 +396,10 @@ export interface IConfig {
validatorRegExpString?: string;
};
liveStreamingEnabled?: boolean;
lobby?: {
autoKnock?: boolean;
enableChat?: boolean;
};
localRecording?: {
disable?: boolean;
disableSelfRecording?: boolean;
@ -466,6 +470,10 @@ export interface IConfig {
enabled?: boolean;
mode?: 'always' | 'recording';
};
securityUi?: {
disableLobbyPassword?: boolean;
hideLobbyButton?: boolean;
};
serviceUrl?: string;
sipInviteUrl?: string;
speakerStats?: {

View File

@ -185,6 +185,7 @@ export default [
'inviteAppName',
'liveStreaming',
'liveStreamingEnabled',
'lobby',
'localRecording',
'localSubject',
'logging',
@ -209,6 +210,7 @@ export default [
'resolution',
'salesforceUrl',
'screenshotCapture',
'securityUi',
'speakerStats',
'startAudioMuted',
'startAudioOnly',

View File

@ -316,3 +316,13 @@ export function getDialOutStatusUrl(state: IReduxState) {
export function getDialOutUrl(state: IReduxState) {
return state['features/base/config'].guestDialOutUrl;
}
/**
* Selector to return the security UI config.
*
* @param {IReduxState} state - State object.
* @returns {Object}
*/
export function getSecurityUiConfig(state: IReduxState) {
return state['features/base/config']?.securityUi || {};
}

View File

@ -535,6 +535,30 @@ function _translateLegacyConfig(oldValue: IConfig) {
};
}
if (oldValue.autoKnockLobby !== undefined
&& newValue.lobby?.autoKnock === undefined) {
newValue.lobby = {
...newValue.lobby || {},
autoKnock: oldValue.autoKnockLobby
};
}
if (oldValue.enableLobbyChat !== undefined
&& newValue.lobby?.enableChat === undefined) {
newValue.lobby = {
...newValue.lobby || {},
enableChat: oldValue.enableLobbyChat
};
}
if (oldValue.hideLobbyButton !== undefined
&& newValue.securityUi?.hideLobbyButton === undefined) {
newValue.securityUi = {
...newValue.securityUi || {},
hideLobbyButton: oldValue.hideLobbyButton
};
}
_setDeeplinkingDefaults(newValue.deeplinking as IDeeplinkingConfig);
return newValue;

View File

@ -20,7 +20,7 @@ import {
SET_PASSWORD_JOIN_FAILED
} from './actionTypes';
import { LOBBY_CHAT_INITIALIZED, MODERATOR_IN_CHAT_WITH_LEFT } from './constants';
import { getKnockingParticipants, getLobbyEnabled } from './functions';
import { getKnockingParticipants, getLobbyConfig, getLobbyEnabled } from './functions';
import { IKnockingParticipant } from './types';
/**
@ -389,9 +389,9 @@ export function setLobbyMessageListener() {
return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const state = getState();
const conference = getCurrentConference(state);
const { enableLobbyChat = true } = state['features/base/config'];
const { enableChat = true } = getLobbyConfig(state);
if (!enableLobbyChat) {
if (!enableChat) {
return;
}

View File

@ -3,6 +3,7 @@
import React, { PureComponent } from 'react';
import { conferenceWillJoin, getConferenceName } from '../../base/conference';
import { getSecurityUiConfig } from '../../base/config/functions.any';
import { INVITE_ENABLED, getFeatureFlag } from '../../base/flags';
import { getLocalParticipant } from '../../base/participants';
import { getFieldValue } from '../../base/react';
@ -443,6 +444,7 @@ export function _mapStateToProps(state: Object): $Shape<Props> {
const { disableInviteFunctions } = state['features/base/config'];
const { knocking, passwordJoinFailed } = state['features/lobby'];
const { iAmSipGateway } = state['features/base/config'];
const { disableLobbyPassword } = getSecurityUiConfig(state);
const showCopyUrlButton = inviteEnabledFlag || !disableInviteFunctions;
const deviceStatusVisible = isDeviceStatusVisible(state);
const { membersOnly } = state['features/base/conference'];
@ -460,7 +462,7 @@ export function _mapStateToProps(state: Object): $Shape<Props> {
_participantId: participantId,
_participantName: localParticipant?.name,
_passwordJoinFailed: passwordJoinFailed,
_renderPassword: !iAmSipGateway,
_renderPassword: !iAmSipGateway && !disableLobbyPassword,
showCopyUrlButton
};
}

View File

@ -2,6 +2,7 @@ import React, { PureComponent } from 'react';
import { WithTranslation } from 'react-i18next';
import { IReduxState } from '../../../app/types';
import { getSecurityUiConfig } from '../../../base/config/functions.any';
import { translate } from '../../../base/i18n/functions';
import { isLocalParticipantModerator } from '../../../base/participants/functions';
import { connect } from '../../../base/redux/functions';
@ -83,25 +84,22 @@ class LobbySection extends PureComponent<IProps, IState> {
}
return (
<>
<div id = 'lobby-section'>
<p
className = 'description'
role = 'banner'>
{ t('lobby.enableDialogText') }
</p>
<div className = 'control-row'>
<label htmlFor = 'lobby-section-switch'>
{ t('lobby.toggleLabel') }
</label>
<Switch
checked = { this.state.lobbyEnabled }
id = 'lobby-section-switch'
onChange = { this._onToggleLobby } />
</div>
<div id = 'lobby-section'>
<p
className = 'description'
role = 'banner'>
{ t('lobby.enableDialogText') }
</p>
<div className = 'control-row'>
<label htmlFor = 'lobby-section-switch'>
{ t('lobby.toggleLabel') }
</label>
<Switch
checked = { this.state.lobbyEnabled }
id = 'lobby-section-switch'
onChange = { this._onToggleLobby } />
</div>
<div className = 'separator-line' />
</>
</div>
);
}
@ -129,7 +127,7 @@ class LobbySection extends PureComponent<IProps, IState> {
*/
function mapStateToProps(state: IReduxState): Partial<IProps> {
const { conference } = state['features/base/conference'];
const { hideLobbyButton } = state['features/base/config'];
const { hideLobbyButton } = getSecurityUiConfig(state);
return {
_lobbyEnabled: state['features/lobby'].lobbyEnabled,

View File

@ -44,6 +44,15 @@ export function getKnockingParticipantsById(state: IReduxState) {
return getKnockingParticipants(state).map(participant => participant.id);
}
/**
* Selector to return the lobby config.
*
* @param {IReduxState} state - State object.
* @returns {Object}
*/
export function getLobbyConfig(state: IReduxState) {
return state['features/base/config']?.lobby || {};
}
/**
* Function that handles the visibility of the lobby chat message.
@ -56,13 +65,13 @@ export function showLobbyChatButton(
) {
return function(state: IReduxState) {
const { enableLobbyChat = true } = state['features/base/config'];
const { enableChat = true } = getLobbyConfig(state);
const { lobbyMessageRecipient, isLobbyChatActive } = state['features/chat'];
const conference = getCurrentConference(state);
const lobbyLocalId = conference?.myLobbyUserId();
if (!enableLobbyChat) {
if (!enableChat) {
return false;
}

View File

@ -2,6 +2,7 @@ import { IReduxState } from '../app/types';
import { getRoomName } from '../base/conference/functions';
import { getDialOutStatusUrl, getDialOutUrl } from '../base/config/functions';
import { isAudioMuted, isVideoMutedByUser } from '../base/media/functions';
import { getLobbyConfig } from '../lobby/functions';
/**
* Selector for the visibility of the 'join by phone' button.
@ -159,11 +160,12 @@ export function isPrejoinPageVisible(state: IReduxState): boolean {
* @returns {boolean}
*/
export function shouldAutoKnock(state: IReduxState): boolean {
const { iAmRecorder, iAmSipGateway, autoKnockLobby, prejoinConfig } = state['features/base/config'];
const { iAmRecorder, iAmSipGateway, prejoinConfig } = state['features/base/config'];
const { userSelectedSkipPrejoin } = state['features/base/settings'];
const { autoKnock } = getLobbyConfig(state);
const isPrejoinEnabled = prejoinConfig?.enabled;
return Boolean(((isPrejoinEnabled && !userSelectedSkipPrejoin)
|| autoKnockLobby || (iAmRecorder && iAmSipGateway))
|| autoKnock || (iAmRecorder && iAmSipGateway))
&& !state['features/lobby'].knocking);
}

View File

@ -3,6 +3,7 @@
import type { Dispatch } from 'redux';
import { createToolbarEvent, sendAnalytics } from '../../../analytics';
import { getSecurityUiConfig } from '../../../base/config/functions.any';
import {
LOBBY_MODE_ENABLED,
MEETING_PASSWORD_ENABLED,
@ -81,7 +82,7 @@ export default class AbstractSecurityDialogButton<P: Props, S:*>
*/
export function _mapStateToProps(state: Object) {
const { conference } = state['features/base/conference'];
const { hideLobbyButton } = state['features/base/config'];
const { hideLobbyButton } = getSecurityUiConfig(state);
const { locked } = state['features/base/conference'];
const { lobbyEnabled } = state['features/lobby'];
const lobbySupported = conference && conference.isLobbySupported();

View File

@ -5,6 +5,7 @@ import {
} from 'react-native';
import type { Dispatch } from 'redux';
import { getSecurityUiConfig } from '../../../../base/config/functions.any';
import { MEETING_PASSWORD_ENABLED, getFeatureFlag } from '../../../../base/flags';
import { translate } from '../../../../base/i18n';
import JitsiScreen from '../../../../base/modal/components/JitsiScreen';
@ -502,7 +503,7 @@ class SecurityDialog extends PureComponent<Props, State> {
*/
function _mapStateToProps(state: Object): Object {
const { conference, locked, password } = state['features/base/conference'];
const { hideLobbyButton } = state['features/base/config'];
const { disableLobbyPassword, hideLobbyButton } = getSecurityUiConfig(state);
const { lobbyEnabled } = state['features/lobby'];
const { roomPasswordNumberOfDigits } = state['features/base/config'];
const lobbySupported = conference && conference.isLobbySupported();
@ -518,7 +519,7 @@ function _mapStateToProps(state: Object): Object {
_lockedConference: Boolean(conference && locked),
_password: password,
_passwordNumberOfDigits: roomPasswordNumberOfDigits,
_roomPasswordControls: visible
_roomPasswordControls: visible && !disableLobbyPassword
};
}

View File

@ -3,6 +3,7 @@ import React, { useEffect, useState } from 'react';
import { IReduxState } from '../../../../app/types';
import { setPassword as setPass } from '../../../../base/conference/actions';
import { getSecurityUiConfig } from '../../../../base/config/functions.any';
import { isLocalParticipantModerator } from '../../../../base/participants/functions';
import { connect } from '../../../../base/redux/functions';
import Dialog from '../../../../base/ui/components/web/Dialog';
@ -37,6 +38,11 @@ interface IProps {
*/
_conference: Object;
/**
* Whether to hide the lobby password section.
*/
_disableLobbyPassword?: boolean;
/**
* The value for how the conference is locked (or undefined if not locked)
* as defined by room-lock constants.
@ -73,6 +79,7 @@ function SecurityDialog({
_buttonsWithNotifyClick,
_canEditPassword,
_conference,
_disableLobbyPassword,
_locked,
_password,
_passwordNumberOfDigits,
@ -94,16 +101,21 @@ function SecurityDialog({
titleKey = 'security.title'>
<div className = 'security-dialog'>
<LobbySection />
<PasswordSection
buttonsWithNotifyClick = { _buttonsWithNotifyClick }
canEditPassword = { _canEditPassword }
conference = { _conference }
locked = { _locked }
password = { _password }
passwordEditEnabled = { passwordEditEnabled }
passwordNumberOfDigits = { _passwordNumberOfDigits }
setPassword = { setPassword }
setPasswordEditEnabled = { setPasswordEditEnabled } />
{!_disableLobbyPassword && (
<>
<div className = 'separator-line' />
<PasswordSection
buttonsWithNotifyClick = { _buttonsWithNotifyClick }
canEditPassword = { _canEditPassword }
conference = { _conference }
locked = { _locked }
password = { _password }
passwordEditEnabled = { passwordEditEnabled }
passwordNumberOfDigits = { _passwordNumberOfDigits }
setPassword = { setPassword }
setPasswordEditEnabled = { setPasswordEditEnabled } />
</>
)}
{
_showE2ee ? <>
<div className = 'separator-line' />
@ -131,7 +143,11 @@ function mapStateToProps(state: IReduxState) {
locked,
password
} = state['features/base/conference'];
const { roomPasswordNumberOfDigits, buttonsWithNotifyClick } = state['features/base/config'];
const {
roomPasswordNumberOfDigits,
buttonsWithNotifyClick
} = state['features/base/config'];
const { disableLobbyPassword } = getSecurityUiConfig(state);
const showE2ee = Boolean(e2eeSupported) && isLocalParticipantModerator(state);
@ -140,6 +156,7 @@ function mapStateToProps(state: IReduxState) {
_canEditPassword: isLocalParticipantModerator(state),
_conference: conference,
_dialIn: state['features/invite'],
_disableLobbyPassword: disableLobbyPassword,
_locked: locked,
_password: password,
_passwordNumberOfDigits: roomPasswordNumberOfDigits,