/* eslint-disable react/jsx-no-bind */ import React, { useCallback, useRef, useState } from 'react'; import { WithTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; import { IReduxState } from '../../../../app/types'; import { translate } from '../../../../base/i18n/functions'; import { copyText } from '../../../../base/util/copyText.web'; import { LOCKED_LOCALLY } from '../../../../room-lock/constants'; import { NOTIFY_CLICK_MODE } from '../../../../toolbox/types'; import PasswordForm from './PasswordForm'; const DIGITS_ONLY = /^\d+$/; const KEY = 'add-passcode'; interface IProps extends WithTranslation { /** * Whether or not the current user can modify the current password. */ canEditPassword: boolean; /** * The JitsiConference for which to display a lock state and change the * password. */ conference: any; /** * The value for how the conference is locked (or undefined if not locked) * as defined by room-lock constants. */ locked?: string; /** * The current known password for the JitsiConference. */ password?: string; /** * Whether or not to show the password in editing mode. */ passwordEditEnabled: boolean; /** * The number of digits to be used in the password. */ passwordNumberOfDigits?: number; /** * Action that sets the conference password. */ setPassword: Function; /** * Method that sets whether the password editing is enabled or not. */ setPasswordEditEnabled: Function; } /** * Component that handles the password manipulation from the invite dialog. * * @returns {React$Element} */ function PasswordSection({ canEditPassword, conference, locked, password, passwordEditEnabled, passwordNumberOfDigits, setPassword, setPasswordEditEnabled, t }: IProps) { const formRef = useRef(null); const [ passwordVisible, setPasswordVisible ] = useState(false); const buttonsWithNotifyClick = useSelector( (state: IReduxState) => state['features/toolbox'].buttonsWithNotifyClick); /** * Callback invoked to set a password on the current JitsiConference. * * @param {string} enteredPassword - The new password to be used to lock the * current JitsiConference. * @private * @returns {void} */ function onPasswordSubmit(enteredPassword: string) { if (enteredPassword && passwordNumberOfDigits && !DIGITS_ONLY.test(enteredPassword)) { // Don't set the password. return; } setPassword(conference, conference.lock, enteredPassword); } /** * Toggles whether or not the password should currently be shown as being * edited locally. * * @private * @returns {void} */ const onTogglePasswordEditState = useCallback(() => { if (typeof APP === 'undefined' || !buttonsWithNotifyClick?.size) { setPasswordEditEnabled(!passwordEditEnabled); return; } const notifyMode = buttonsWithNotifyClick?.get(KEY); if (notifyMode) { APP.API.notifyToolbarButtonClicked( KEY, notifyMode === NOTIFY_CLICK_MODE.PREVENT_AND_NOTIFY ); } if (!notifyMode || notifyMode === NOTIFY_CLICK_MODE.ONLY_NOTIFY) { setPasswordEditEnabled(!passwordEditEnabled); } }, [ buttonsWithNotifyClick, setPasswordEditEnabled, passwordEditEnabled ]); /** * Method to remotely submit the password from outside of the password form. * * @returns {void} */ function onPasswordSave() { if (formRef.current) { // @ts-ignore const { value } = formRef.current.querySelector('div > input'); if (value) { onPasswordSubmit(value); } } } /** * Callback invoked to unlock the current JitsiConference. * * @returns {void} */ function onPasswordRemove() { onPasswordSubmit(''); } /** * Copies the password to the clipboard. * * @returns {void} */ function onPasswordCopy() { copyText(password ?? ''); } /** * Callback invoked to show the current password. * * @returns {void} */ function onPasswordShow() { setPasswordVisible(true); } /** * Callback invoked to hide the current password. * * @returns {void} */ function onPasswordHide() { setPasswordVisible(false); } /** * Method that renders the password action(s) based on the current * locked-status of the conference. * * @returns {React$Element} */ function renderPasswordActions() { if (!canEditPassword) { return null; } if (passwordEditEnabled) { return ( <> ); } if (locked) { return ( <> { // There are cases like lobby and grant moderator when password is not available password ? <> : null } {locked === LOCKED_LOCALLY && ( )} ); } return ( ); } return (

{ t(canEditPassword ? 'security.about' : 'security.aboutReadOnly') }

{ renderPasswordActions() }
); } export default translate(PasswordSection);