diff --git a/lang/main.json b/lang/main.json
index 0299cf89dc..da3a2813f0 100644
--- a/lang/main.json
+++ b/lang/main.json
@@ -870,9 +870,11 @@
"lookGood": "Your microphone is working properly",
"or": "or",
"premeeting": "Pre meeting",
+ "proceedAnyway": "Proceed anyway",
"screenSharingError": "Screen sharing error:",
"showScreen": "Enable pre meeting screen",
"startWithPhone": "Start with phone audio",
+ "unsafeRoomConsent": "I understand the risks, I want to join the meeting",
"videoOnlyError": "Video error:",
"videoTrackError": "Could not create video track.",
"viewAllNumbers": "view all numbers"
@@ -974,8 +976,14 @@
"security": {
"about": "You can add a $t(lockRoomPassword) to your meeting. Participants will need to provide the $t(lockRoomPassword) before they are allowed to join the meeting.",
"aboutReadOnly": "Moderator participants can add a $t(lockRoomPassword) to the meeting. Participants will need to provide the $t(lockRoomPassword) before they are allowed to join the meeting.",
- "insecureRoomNameWarning": "The room name is unsafe. Unwanted participants may join your conference. Consider securing your meeting using the security button.",
- "title": "Security Options"
+ "insecureRoomNameWarningNative": "The room name is unsafe. Unwanted participants may join your meeting. {{recommendAction}} Learn more about securing you meeting ",
+ "insecureRoomNameWarningWeb": "The room name is unsafe. Unwanted participants may join your meeting. {{recommendAction}} Learn more about securing you meeting here.",
+ "title": "Security Options",
+ "unsafeRoomActions": {
+ "meeting": "Consider securing your meeting using the security button.",
+ "prejoin": "Consider using a more unique meeting name.",
+ "welcome": "Consider using a more unique meeting name, or pick one of the suggestions."
+ }
},
"settings": {
"audio": "Audio",
diff --git a/react/features/app/actions.native.ts b/react/features/app/actions.native.ts
index 84740276f1..98c61e1eb3 100644
--- a/react/features/app/actions.native.ts
+++ b/react/features/app/actions.native.ts
@@ -12,6 +12,7 @@ import {
import { connect, disconnect, setLocationURL } from '../base/connection/actions';
import { loadConfig } from '../base/lib-jitsi-meet/functions.native';
import { createDesiredLocalTracks } from '../base/tracks/actions';
+import isInsecureRoomName from '../base/util/isInsecureRoomName';
import { parseURLParams } from '../base/util/parseURLParams';
import {
appendURLParam,
@@ -136,6 +137,11 @@ export function appNavigate(uri?: string, options: IReloadNowOptions = {}) {
dispatch(setRoom(room));
if (room) {
+ if (isInsecureRoomName(room)) {
+ navigateRoot(screen.unsafeRoomWarning);
+
+ return;
+ }
dispatch(createDesiredLocalTracks());
dispatch(clearNotifications());
diff --git a/react/features/app/reducers.web.ts b/react/features/app/reducers.web.ts
index a8075eb332..071d0534ef 100644
--- a/react/features/app/reducers.web.ts
+++ b/react/features/app/reducers.web.ts
@@ -1,4 +1,5 @@
import '../base/devices/reducer';
+import '../base/premeeting/reducer';
import '../base/tooltip/reducer';
import '../e2ee/reducer';
import '../face-landmarks/reducer';
diff --git a/react/features/app/types.ts b/react/features/app/types.ts
index 485895d5a5..9293206b5c 100644
--- a/react/features/app/types.ts
+++ b/react/features/app/types.ts
@@ -20,6 +20,7 @@ import { ILoggingState } from '../base/logging/reducer';
import { IMediaState } from '../base/media/reducer';
import { INetInfoState } from '../base/net-info/reducer';
import { IParticipantsState } from '../base/participants/reducer';
+import { IPreMeetingState } from '../base/premeeting/types';
import { IResponsiveUIState } from '../base/responsive-ui/reducer';
import { ISettingsState } from '../base/settings/reducer';
import { ISoundsState } from '../base/sounds/reducer';
@@ -110,6 +111,7 @@ export interface IReduxState {
'features/base/net-info': INetInfoState;
'features/base/no-src-data': INoSrcDataState;
'features/base/participants': IParticipantsState;
+ 'features/base/premeeting': IPreMeetingState;
'features/base/responsive-ui': IResponsiveUIState;
'features/base/settings': ISettingsState;
'features/base/sounds': ISoundsState;
diff --git a/react/features/base/config/configType.ts b/react/features/base/config/configType.ts
index 096d989ef9..80ad10c5fa 100644
--- a/react/features/base/config/configType.ts
+++ b/react/features/base/config/configType.ts
@@ -408,6 +408,7 @@ export interface IConfig {
legalUrls?: {
helpCentre: string;
privacy: string;
+ security: string;
terms: string;
};
liveStreaming?: {
diff --git a/react/features/base/premeeting/actionTypes.ts b/react/features/base/premeeting/actionTypes.ts
new file mode 100644
index 0000000000..82400d3564
--- /dev/null
+++ b/react/features/base/premeeting/actionTypes.ts
@@ -0,0 +1,9 @@
+/**
+ * Type for setting the user's consent for unsafe room joining.
+ *
+ * {
+ * type: SET_UNSAFE_ROOM_CONSENT,
+ * consent: boolean
+ * }
+ */
+export const SET_UNSAFE_ROOM_CONSENT = 'SET_UNSAFE_ROOM_CONSENT'
\ No newline at end of file
diff --git a/react/features/base/premeeting/actions.web.ts b/react/features/base/premeeting/actions.web.ts
new file mode 100644
index 0000000000..79013f08b4
--- /dev/null
+++ b/react/features/base/premeeting/actions.web.ts
@@ -0,0 +1,17 @@
+import { SET_UNSAFE_ROOM_CONSENT } from './actionTypes';
+
+/**
+ * Sets the consent of the user for joining the unsafe room.
+ *
+ * @param {boolean} consent - The user's consent.
+ * @returns {{
+ * type: SET_UNSAFE_ROOM_CONSENT,
+* consent: boolean
+* }}
+ */
+export function setUnsafeRoomConsent(consent: boolean) {
+ return {
+ type: SET_UNSAFE_ROOM_CONSENT,
+ consent
+ };
+}
diff --git a/react/features/base/premeeting/components/web/PreMeetingScreen.tsx b/react/features/base/premeeting/components/web/PreMeetingScreen.tsx
index 7a7c5925f6..7df61848b4 100644
--- a/react/features/base/premeeting/components/web/PreMeetingScreen.tsx
+++ b/react/features/base/premeeting/components/web/PreMeetingScreen.tsx
@@ -13,6 +13,7 @@ import { withPixelLineHeight } from '../../../styles/functions.web';
import ConnectionStatus from './ConnectionStatus';
import Preview from './Preview';
+import UnsafeRoomWarning from './UnsafeRoomWarning';
interface IProps {
@@ -56,6 +57,11 @@ interface IProps {
*/
showDeviceStatus: boolean;
+ /**
+ * If should show unsafe room warning when joining.
+ */
+ showUnsafeRoomWarning?: boolean;
+
/**
* The 'Skip prejoin' button to be rendered (if any).
*/
@@ -161,6 +167,7 @@ const PreMeetingScreen = ({
children,
className,
showDeviceStatus,
+ showUnsafeRoomWarning,
skipPrejoinButton,
title,
videoMuted,
@@ -191,6 +198,7 @@ const PreMeetingScreen = ({
{children}
{_buttons.length && }
{skipPrejoinButton}
+ {showUnsafeRoomWarning && }
{showDeviceStatus && }
diff --git a/react/features/base/premeeting/components/web/UnsafeRoomWarning.tsx b/react/features/base/premeeting/components/web/UnsafeRoomWarning.tsx
new file mode 100644
index 0000000000..f4e3cc3d42
--- /dev/null
+++ b/react/features/base/premeeting/components/web/UnsafeRoomWarning.tsx
@@ -0,0 +1,54 @@
+import React, { useCallback } from 'react';
+import { useTranslation } from 'react-i18next';
+import { useDispatch, useSelector } from 'react-redux';
+import { makeStyles } from 'tss-react/mui';
+
+import { IReduxState } from '../../../../app/types';
+import { withPixelLineHeight } from '../../../styles/functions.web';
+import Checkbox from '../../../ui/components/web/Checkbox';
+import getUnsafeRoomText from '../../../util/getUnsafeRoomText.web';
+import { setUnsafeRoomConsent } from '../../actions.web';
+
+const useStyles = makeStyles()(theme => {
+ return {
+ warning: {
+ backgroundColor: theme.palette.warning01,
+ color: theme.palette.text04,
+ ...withPixelLineHeight(theme.typography.bodyShortRegular),
+ padding: theme.spacing(3),
+ borderRadius: theme.shape.borderRadius,
+ marginBottom: theme.spacing(3)
+ },
+ consent: {
+ padding: `0 ${theme.spacing(3)}`,
+ '@media (max-width: 720px)': {
+ marginBottom: theme.spacing(3)
+ }
+ }
+ };
+});
+
+const UnsafeRoomWarning = () => {
+ const { t } = useTranslation();
+ const { classes } = useStyles();
+ const dispatch = useDispatch();
+ const { unsafeRoomConsent } = useSelector((state: IReduxState) => state['features/base/premeeting']);
+ const toggleConsent = useCallback(
+ () => dispatch(setUnsafeRoomConsent(!unsafeRoomConsent))
+ , [ unsafeRoomConsent, dispatch ]);
+
+ return (
+ <>
+
+ {getUnsafeRoomText(t, 'prejoin')}
+
+
+ >
+ );
+};
+
+export default UnsafeRoomWarning;
diff --git a/react/features/base/premeeting/reducer.web.ts b/react/features/base/premeeting/reducer.web.ts
new file mode 100644
index 0000000000..37ce364373
--- /dev/null
+++ b/react/features/base/premeeting/reducer.web.ts
@@ -0,0 +1,33 @@
+import ReducerRegistry from '../redux/ReducerRegistry';
+
+import { SET_UNSAFE_ROOM_CONSENT } from './actionTypes';
+import { IPreMeetingState } from './types';
+
+
+const DEFAULT_STATE: IPreMeetingState = {
+ unsafeRoomConsent: false
+};
+
+/**
+ * Listen for actions which changes the state of known and used devices.
+ *
+ * @param {IDevicesState} state - The Redux state of the feature features/base/devices.
+ * @param {Object} action - Action object.
+ * @param {string} action.type - Type of action.
+ * @returns {IPreMeetingState}
+ */
+ReducerRegistry.register(
+ 'features/base/premeeting',
+ (state = DEFAULT_STATE, action): IPreMeetingState => {
+ switch (action.type) {
+ case SET_UNSAFE_ROOM_CONSENT: {
+ return {
+ ...state,
+ unsafeRoomConsent: action.consent
+ };
+ }
+ default:
+ return state;
+ }
+ });
+
diff --git a/react/features/base/premeeting/types.ts b/react/features/base/premeeting/types.ts
new file mode 100644
index 0000000000..ff431750ec
--- /dev/null
+++ b/react/features/base/premeeting/types.ts
@@ -0,0 +1,3 @@
+export interface IPreMeetingState {
+ unsafeRoomConsent?: boolean;
+}
diff --git a/react/features/base/tooltip/actions.tsx b/react/features/base/tooltip/actions.tsx
index 3d2aa2bd37..0b9c1c8a5d 100644
--- a/react/features/base/tooltip/actions.tsx
+++ b/react/features/base/tooltip/actions.tsx
@@ -1,3 +1,5 @@
+import { ReactElement } from 'react';
+
import { HIDE_TOOLTIP, SHOW_TOOLTIP } from './actionTypes';
/**
@@ -7,7 +9,7 @@ import { HIDE_TOOLTIP, SHOW_TOOLTIP } from './actionTypes';
* Used as unique identifier for tooltip.
* @returns {Object}
*/
-export function showTooltip(content: string) {
+export function showTooltip(content: string | ReactElement) {
return {
type: SHOW_TOOLTIP,
content
@@ -21,7 +23,7 @@ export function showTooltip(content: string) {
* Used as unique identifier for tooltip.
* @returns {Object}
*/
-export function hideTooltip(content: string) {
+export function hideTooltip(content: string | ReactElement) {
return {
type: HIDE_TOOLTIP,
content
diff --git a/react/features/base/tooltip/components/Tooltip.tsx b/react/features/base/tooltip/components/Tooltip.tsx
index a2632ec755..497223ac2c 100644
--- a/react/features/base/tooltip/components/Tooltip.tsx
+++ b/react/features/base/tooltip/components/Tooltip.tsx
@@ -16,7 +16,7 @@ const ANIMATION_DURATION = 0.2;
interface IProps {
children: ReactElement;
containerClassName?: string;
- content: string;
+ content: string | ReactElement;
position?: TOOLTIP_POSITION;
}
diff --git a/react/features/base/ui/Tokens.ts b/react/features/base/ui/Tokens.ts
index a7b366cc59..159707becb 100644
--- a/react/features/base/ui/Tokens.ts
+++ b/react/features/base/ui/Tokens.ts
@@ -167,6 +167,7 @@ export const font = {
export const shape = {
borderRadius: 6,
+ circleRadius: 50,
boxShadow: 'inset 0px -1px 0px rgba(255, 255, 255, 0.15)'
};
diff --git a/react/features/base/util/contants.ts b/react/features/base/util/contants.ts
new file mode 100644
index 0000000000..3732139031
--- /dev/null
+++ b/react/features/base/util/contants.ts
@@ -0,0 +1 @@
+export const SECURITY_URL = 'https://jitsi.org/security/';
diff --git a/react/features/base/util/getUnsafeRoomText.native.ts b/react/features/base/util/getUnsafeRoomText.native.ts
new file mode 100644
index 0000000000..b37e0faf86
--- /dev/null
+++ b/react/features/base/util/getUnsafeRoomText.native.ts
@@ -0,0 +1,31 @@
+import React from 'react';
+import { Text } from 'react-native';
+
+
+import { IReduxState } from '../../app/types';
+import Link from '../react/components/native/Link';
+import BaseTheme from '../ui/components/BaseTheme.native';
+
+import { SECURITY_URL } from './contants';
+
+/**
+ * Gets the unsafe room text for the given context.
+ *
+ * @param {IReduxState} state - The redux state.
+ * @param {Function} t - The translation function.
+ * @param {'meeting'|'prejoin'|'welcome'} context - The given context of the warining.
+ * @returns {Text}
+ */
+export default function getUnsafeRoomText(state: IReduxState, t: Function, context: 'meeting' | 'prejoin' | 'welcome') {
+ const securityUrl = state['features/base/config'].legalUrls?.security ?? SECURITY_URL;
+ const link = React.createElement(Link, {
+ url: securityUrl,
+ children: 'here',
+ style: { color: BaseTheme.palette.action01 } });
+
+ const options = {
+ recommendAction: t(`security.unsafeRoomActions.${context}`)
+ };
+
+ return React.createElement(Text, { children: [ t('security.insecureRoomNameWarningNative', options), link, '.' ] });
+}
diff --git a/react/features/base/util/getUnsafeRoomText.web.ts b/react/features/base/util/getUnsafeRoomText.web.ts
new file mode 100644
index 0000000000..3c2abb2bd1
--- /dev/null
+++ b/react/features/base/util/getUnsafeRoomText.web.ts
@@ -0,0 +1,20 @@
+import { translateToHTML } from '../i18n/functions';
+
+import { SECURITY_URL } from './contants';
+
+/**
+ * Gets the unsafe room text for the given context.
+ *
+ * @param {Function} t - The translation function.
+ * @param {'meeting'|'prejoin'|'welcome'} context - The given context of the warining.
+ * @returns {string}
+ */
+export default function getUnsafeRoomText(t: Function, context: 'meeting' | 'prejoin' | 'welcome') {
+ const securityUrl = APP.store.getState()['features/base/config'].legalUrls?.security ?? SECURITY_URL;
+ const options = {
+ recommendAction: t(`security.unsafeRoomActions.${context}`),
+ securityUrl
+ };
+
+ return translateToHTML(t, 'security.insecureRoomNameWarningWeb', options);
+}
diff --git a/react/features/conference/components/native/InsecureRoomNameExpandedLabel.ts b/react/features/conference/components/native/InsecureRoomNameExpandedLabel.tsx
similarity index 50%
rename from react/features/conference/components/native/InsecureRoomNameExpandedLabel.ts
rename to react/features/conference/components/native/InsecureRoomNameExpandedLabel.tsx
index 092150c1a1..8d4e781ad3 100644
--- a/react/features/conference/components/native/InsecureRoomNameExpandedLabel.ts
+++ b/react/features/conference/components/native/InsecureRoomNameExpandedLabel.tsx
@@ -1,17 +1,22 @@
import { WithTranslation } from 'react-i18next';
+import { connect } from 'react-redux';
+import { IReduxState } from '../../../app/types';
import { translate } from '../../../base/i18n/functions';
import ExpandedLabel, { IProps as AbstractProps } from '../../../base/label/components/native/ExpandedLabel';
+import getUnsafeRoomText from '../../../base/util/getUnsafeRoomText.native';
import { INSECURE_ROOM_NAME_LABEL_COLOR } from './styles';
-type Props = AbstractProps & WithTranslation;
+interface IProps extends AbstractProps, WithTranslation {
+ getUnsafeRoomTextFn: Function;
+}
/**
* A react {@code Component} that implements an expanded label as tooltip-like
* component to explain the meaning of the {@code InsecureRoomNameExpandedLabel}.
*/
-class InsecureRoomNameExpandedLabel extends ExpandedLabel {
+class InsecureRoomNameExpandedLabel extends ExpandedLabel {
/**
* Returns the color this expanded label should be rendered with.
*
@@ -27,8 +32,20 @@ class InsecureRoomNameExpandedLabel extends ExpandedLabel {
* @returns {string}
*/
_getLabel() {
- return this.props.t('security.insecureRoomNameWarning');
+ return this.props.getUnsafeRoomTextFn(this.props.t);
}
}
-export default translate(InsecureRoomNameExpandedLabel);
+/**
+ * Maps part of the Redux state to the props of this component.
+ *
+ * @param {Object} state - The Redux state.
+ * @returns {IProps}
+ */
+function _mapStateToProps(state: IReduxState) {
+ return {
+ getUnsafeRoomTextFn: (t: Function) => getUnsafeRoomText(state, t, 'meeting')
+ };
+}
+
+export default translate(connect(_mapStateToProps)(InsecureRoomNameExpandedLabel));
diff --git a/react/features/conference/components/web/InsecureRoomNameLabel.tsx b/react/features/conference/components/web/InsecureRoomNameLabel.tsx
index 0ed47d22b0..0a4b622a47 100644
--- a/react/features/conference/components/web/InsecureRoomNameLabel.tsx
+++ b/react/features/conference/components/web/InsecureRoomNameLabel.tsx
@@ -6,6 +6,7 @@ import { IconExclamationTriangle } from '../../../base/icons/svg';
import Label from '../../../base/label/components/web/Label';
import { COLORS } from '../../../base/label/constants';
import Tooltip from '../../../base/tooltip/components/Tooltip';
+import getUnsafeRoomText from '../../../base/util/getUnsafeRoomText.web';
import AbstractInsecureRoomNameLabel, { _mapStateToProps } from '../AbstractInsecureRoomNameLabel';
/**
@@ -20,7 +21,7 @@ class InsecureRoomNameLabel extends AbstractInsecureRoomNameLabel {
_render() {
return (
+
= ({ navigation }: IPrejoinProps) => {
+ const dispatch = useDispatch();
+ const { t } = useTranslation();
+ const roomName = useSelector((state: IReduxState) => getConferenceName(state));
+ const aspectRatio = useSelector(
+ (state: IReduxState) => state['features/base/responsive-ui']?.aspectRatio
+ );
+ const unsafeRoomText = useSelector((state: IReduxState) => getUnsafeRoomText(state, t, 'prejoin'));
+
+ const goBack = useCallback(() => {
+ dispatch(appNavigate(undefined));
+
+ return true;
+ }, [ dispatch ]);
+
+ const onProceed = useCallback(() => {
+ navigateRoot(screen.preJoin);
+
+ return true;
+ }, [ dispatch ]);
+
+ const headerLeft = () => {
+ if (Platform.OS === 'ios') {
+ return (
+
+ );
+ }
+
+ return (
+
+ );
+ };
+
+ useLayoutEffect(() => {
+ navigation.setOptions({
+ headerLeft,
+ headerTitle: t('prejoin.joinMeeting')
+ });
+ }, [ navigation ]);
+
+ let unsafeRoomContentContainer;
+
+ if (aspectRatio === ASPECT_RATIO_NARROW) {
+ unsafeRoomContentContainer = styles.unsafeRoomContentContainer;
+ } else {
+ unsafeRoomContentContainer = styles.unsafeRoomContentContainerWide;
+ }
+
+
+ return (
+
+ }>
+ }>
+ { roomName }
+
+
+ }>
+ }>
+
+
+
+ }>
+ { unsafeRoomText }
+
+
+
+
+ );
+};
+
+export default UnsafeRoomWarning;
diff --git a/react/features/prejoin/components/native/styles.ts b/react/features/prejoin/components/native/styles.ts
index b5e8bc8149..62030893e0 100644
--- a/react/features/prejoin/components/native/styles.ts
+++ b/react/features/prejoin/components/native/styles.ts
@@ -23,7 +23,8 @@ export const preJoinStyles = {
},
contentWrapper: {
- flex: 1
+ flex: 1,
+ flexDirection: 'row'
},
contentWrapperWide: {
@@ -97,7 +98,53 @@ export const preJoinStyles = {
paddingHorizontal: BaseTheme.spacing[3],
paddingVertical: BaseTheme.spacing[1],
position: 'absolute',
- width: 243,
+ maxWidth: 243,
zIndex: 1
+ },
+ unsafeRoomWarningContainer: {
+ height: '100%',
+ width: '100%',
+ backgroundColor: BaseTheme.palette.ui01,
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ color: 'white'
+ },
+ unsafeRoomContentContainer: {
+ justifySelf: 'center',
+ height: '100%',
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ paddingHorizontal: BaseTheme.spacing[4]
+ },
+
+ unsafeRoomContentContainerWide: {
+ alignItems: 'center',
+ justifySelf: 'center',
+ height: '100%',
+ display: 'flex',
+ justifyContent: 'center',
+ marginLeft: BaseTheme.spacing[7],
+ paddingHorizontal: BaseTheme.spacing[6]
+ },
+
+ warningText: {
+ ...BaseTheme.typography.bodyLongRegularLarge,
+ color: BaseTheme.palette.text01,
+ textAlign: 'center',
+ marginBottom: BaseTheme.spacing[4]
+ },
+ warningIconWrapper: {
+ backgroundColor: BaseTheme.palette.warning01,
+ borderRadius: BaseTheme.shape.circleRadius,
+ padding: BaseTheme.spacing[4],
+ marginBottom: BaseTheme.spacing[4],
+ zIndex: 0
+
+ },
+ warningIcon: {
+ color: BaseTheme.palette.ui01,
+ fontSize: 40
}
};
diff --git a/react/features/prejoin/components/web/Prejoin.tsx b/react/features/prejoin/components/web/Prejoin.tsx
index 66e03ad822..1b0056974e 100644
--- a/react/features/prejoin/components/web/Prejoin.tsx
+++ b/react/features/prejoin/components/web/Prejoin.tsx
@@ -20,6 +20,7 @@ import { getLocalJitsiVideoTrack } from '../../../base/tracks/functions.web';
import Button from '../../../base/ui/components/web/Button';
import Input from '../../../base/ui/components/web/Input';
import { BUTTON_TYPES } from '../../../base/ui/constants.any';
+import isInsecureRoomName from '../../../base/util/isInsecureRoomName';
import {
joinConference as joinConferenceAction,
joinConferenceWithoutAudio as joinConferenceWithoutAudioAction,
@@ -107,6 +108,16 @@ interface IProps {
*/
showErrorOnJoin: boolean;
+ /**
+ * If should show unsafe room warning when joining.
+ */
+ showUnsafeRoomWarning: boolean;
+
+ /**
+ * Whether the user has approved to join a room with unsafe name.
+ */
+ unsafeRoomConsent?: boolean;
+
/**
* Updates settings.
*/
@@ -195,6 +206,8 @@ const Prejoin = ({
showCameraPreview,
showDialog,
showErrorOnJoin,
+ showUnsafeRoomWarning,
+ unsafeRoomConsent,
updateSettings: dispatchUpdateSettings,
videoTrack
}: IProps) => {
@@ -353,6 +366,7 @@ const Prejoin = ({
return (
@@ -405,7 +419,7 @@ const Prejoin = ({
ariaDropDownLabel = { t('prejoin.joinWithoutAudio') }
ariaLabel = { t('prejoin.joinMeeting') }
ariaPressed = { showJoinByPhoneButtons }
- disabled = { joiningInProgress }
+ disabled = { joiningInProgress || (showUnsafeRoomWarning && !unsafeRoomConsent) }
hasOptions = { hasExtraJoinButtons }
onClick = { onJoinButtonClick }
onOptionsClick = { onOptionsClick }
@@ -439,6 +453,9 @@ function mapStateToProps(state: IReduxState) {
const showErrorOnJoin = isDisplayNameRequired(state) && !name;
const { id: participantId } = getLocalParticipant(state) ?? {};
const { joiningInProgress } = state['features/prejoin'];
+ const { room } = state['features/base/conference'];
+ const { enableInsecureRoomNameWarning = false } = state['features/base/config'];
+ const { unsafeRoomConsent } = state['features/base/premeeting'];
return {
canEditDisplayName: isPrejoinDisplayNameVisible(state),
@@ -452,6 +469,8 @@ function mapStateToProps(state: IReduxState) {
showCameraPreview: !isVideoMutedByUser(state),
showDialog: isJoinByPhoneDialogVisible(state),
showErrorOnJoin,
+ showUnsafeRoomWarning: isInsecureRoomName(room) && enableInsecureRoomNameWarning,
+ unsafeRoomConsent,
videoTrack: getLocalJitsiVideoTrack(state)
};
}
diff --git a/react/features/welcome/components/WelcomePage.native.tsx b/react/features/welcome/components/WelcomePage.native.tsx
index 48339adc8a..565a46f3e5 100644
--- a/react/features/welcome/components/WelcomePage.native.tsx
+++ b/react/features/welcome/components/WelcomePage.native.tsx
@@ -21,6 +21,7 @@ import BaseTheme from '../../base/ui/components/BaseTheme.native';
import Button from '../../base/ui/components/native/Button';
import Input from '../../base/ui/components/native/Input';
import { BUTTON_TYPES } from '../../base/ui/constants.native';
+import getUnsafeRoomText from '../../base/util/getUnsafeRoomText.native';
import WelcomePageTabs
from '../../mobile/navigation/components/welcome/components/WelcomePageTabs';
@@ -33,6 +34,11 @@ import styles from './styles.native';
interface IProps extends AbstractProps {
+ /**
+ * Function for getting the unsafe room text.
+ */
+ getUnsafeRoomTextFn: Function;
+
/**
* Default prop for navigating between screen components(React Navigation).
*/
@@ -151,7 +157,7 @@ class WelcomePage extends AbstractWelcomePage {
src = { IconWarning }
style = { styles.insecureRoomNameWarningIcon } />
- { this.props.t('security.insecureRoomNameWarning') }
+ { this.props.getUnsafeRoomTextFn(this.props.t) }
);
@@ -399,9 +405,10 @@ class WelcomePage extends AbstractWelcomePage {
*/
function _mapStateToProps(state: IReduxState) {
return {
- ..._abstractMapStateToProps(state)
+ ..._abstractMapStateToProps(state),
// _reducedUI: state['features/base/responsive-ui'].reducedUI
+ getUnsafeRoomTextFn: (t: Function) => getUnsafeRoomText(state, t, 'welcome')
};
}
diff --git a/react/features/welcome/components/WelcomePage.web.tsx b/react/features/welcome/components/WelcomePage.web.tsx
index 07b2a68982..810e6758f4 100644
--- a/react/features/welcome/components/WelcomePage.web.tsx
+++ b/react/features/welcome/components/WelcomePage.web.tsx
@@ -6,6 +6,7 @@ import { translate, translateToHTML } from '../../base/i18n/functions';
import Icon from '../../base/icons/components/Icon';
import { IconWarning } from '../../base/icons/svg';
import Watermarks from '../../base/react/components/web/Watermarks';
+import getUnsafeRoomText from '../../base/util/getUnsafeRoomText.web';
import CalendarList from '../../calendar-sync/components/CalendarList.web';
import RecentList from '../../recent-list/components/RecentList.web';
import SettingsButton from '../../settings/components/web/SettingsButton';
@@ -294,7 +295,7 @@ class WelcomePage extends AbstractWelcomePage {
- { this.props.t('security.insecureRoomNameWarning') }
+ { getUnsafeRoomText(this.props.t, 'welcome') }
);
diff --git a/react/features/welcome/components/styles.native.ts b/react/features/welcome/components/styles.native.ts
index ed909a011e..a6a77591c1 100644
--- a/react/features/welcome/components/styles.native.ts
+++ b/react/features/welcome/components/styles.native.ts
@@ -197,7 +197,7 @@ export default {
},
insecureRoomNameWarningText: {
- color: BaseTheme.palette.warning02,
+ color: BaseTheme.palette.text01,
flex: 1
},