import { useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import styled from 'styled-components'; import { useHotkey } from '../../../hooks/useHotkey'; import { useIconToImageURL } from '../../../hooks/useIconToImageURL'; import { usePasswordModal } from '../../../hooks/usePasswordModal'; import { mnDecode } from '../../../session/crypto/mnemonic'; import { updateHideRecoveryPasswordModal, updateLightBoxOptions, } from '../../../state/ducks/modalDialog'; import { showSettingsSection } from '../../../state/ducks/section'; import { getIsModalVisble } from '../../../state/selectors/modal'; import { useHideRecoveryPasswordEnabled } from '../../../state/selectors/settings'; import { useIsDarkTheme } from '../../../state/selectors/theme'; import { THEME_GLOBALS } from '../../../themes/globals'; import { prepareQRCodeForLightBox } from '../../../util/qrCodes'; import { getCurrentRecoveryPhrase } from '../../../util/storage'; import { QRCodeLogoProps, SessionQRCode } from '../../SessionQRCode'; import { AnimatedFlex } from '../../basic/Flex'; import { I18n } from '../../basic/I18n'; import { SessionButtonColor } from '../../basic/SessionButton'; import { SpacerMD, SpacerSM } from '../../basic/Text'; import { CopyToClipboardIcon } from '../../buttons/CopyToClipboardButton'; import { SessionIconButton } from '../../icon'; import { SessionSettingButtonItem, SessionSettingsItemWrapper, StyledSettingItem, } from '../SessionSettingListItem'; const StyledSettingsItemContainer = styled.div` p { font-size: var(--font-size-md); line-height: 30px; margin: 0; } button[data-testid='hide-recovery-password-button'] { width: 130px; } ${StyledSettingItem} { svg { margin-top: -2px; } } `; const StyledRecoveryPassword = styled(AnimatedFlex)<{ color: string }>` font-family: var(--font-mono); font-size: var(--font-size-sm); text-align: justify; user-select: text; border: 2px solid var(--text-secondary-color); border-radius: 11px; padding: var(--margins-sm) var(--margins-sm) var(--margins-sm) var(--margins-md); margin: 0; max-width: fit-content; color: ${props => props.color}; `; const qrLogoProps: QRCodeLogoProps = { iconType: 'shield', iconSize: 56, }; export const SettingsCategoryRecoveryPassword = () => { const recoveryPhrase = getCurrentRecoveryPhrase(); if (!recoveryPhrase) { throw new Error('SettingsCategoryRecoveryPassword recovery seed is empty'); } const hexEncodedSeed = mnDecode(recoveryPhrase, 'english'); const [isQRVisible, setIsQRVisible] = useState(false); const hideRecoveryPassword = useHideRecoveryPasswordEnabled(); const isModalVisible = useSelector(getIsModalVisble); const isDarkTheme = useIsDarkTheme(); const { dataURL, iconSize, iconColor, backgroundColor, loading } = useIconToImageURL(qrLogoProps); const dispatch = useDispatch(); const { hasPassword, passwordValid } = usePasswordModal({ onClose: () => { dispatch(showSettingsSection('privacy')); }, }); useHotkey( 'v', () => { if (!isModalVisible) { setIsQRVisible(!isQRVisible); } }, (hasPassword && !passwordValid) || hideRecoveryPassword ); if ((hasPassword && !passwordValid) || hideRecoveryPassword) { return null; } return ( } inline={false} > {isQRVisible ? ( { const lightBoxOptions = prepareQRCodeForLightBox(fileName, dataUrl); window.inboxStore?.dispatch(updateLightBoxOptions(lightBoxOptions)); }} ariaLabel={'Recovery Password QR Code'} dataTestId={'session-recovery-password'} /> ) : ( {recoveryPhrase} )} { setIsQRVisible(!isQRVisible); }} padding="0" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: isQRVisible ? undefined : 'var(--margins-xs)', marginLeft: isQRVisible ? '-8px' : undefined, }} > {isQRVisible ? window.i18n('recoveryPasswordView') : window.i18n('qrView')} {!hideRecoveryPassword ? ( { dispatch(updateHideRecoveryPasswordModal({ state: 'firstWarning' })); }} buttonText={window.i18n('hide')} buttonColor={SessionButtonColor.Danger} dataTestId={'hide-recovery-password-button'} /> ) : null} ); };