diff --git a/src/components/PDFView/PDFPasswordForm.js b/src/components/PDFView/PDFPasswordForm.js index adbe3e801776..3a7814684ebb 100644 --- a/src/components/PDFView/PDFPasswordForm.js +++ b/src/components/PDFView/PDFPasswordForm.js @@ -1,5 +1,5 @@ import _ from 'underscore'; -import React, {Component} from 'react'; +import React, {useState, useRef, useEffect, useMemo} from 'react'; import PropTypes from 'prop-types'; import {View, ScrollView} from 'react-native'; import Button from '../Button'; @@ -7,12 +7,11 @@ import Text from '../Text'; import TextInput from '../TextInput'; import styles from '../../styles/styles'; import PDFInfoMessage from './PDFInfoMessage'; -import compose from '../../libs/compose'; -import withLocalize, {withLocalizePropTypes} from '../withLocalize'; -import withWindowDimensions, {windowDimensionsPropTypes} from '../withWindowDimensions'; import shouldDelayFocus from '../../libs/shouldDelayFocus'; import * as Browser from '../../libs/Browser'; import CONST from '../../CONST'; +import useWindowDimensions from '../../hooks/useWindowDimensions'; +import useLocalize from '../../hooks/useLocalize'; const propTypes = { /** If the submitted password is invalid (show an error message) */ @@ -32,9 +31,6 @@ const propTypes = { /** Should focus to the password input */ isFocused: PropTypes.bool.isRequired, - - ...withLocalizePropTypes, - ...windowDimensionsPropTypes, }; const defaultProps = { @@ -45,133 +41,113 @@ const defaultProps = { onPasswordFieldFocused: () => {}, }; -class PDFPasswordForm extends Component { - constructor(props) { - super(props); - this.state = { - password: '', - validationErrorText: '', - shouldShowForm: false, - }; - this.submitPassword = this.submitPassword.bind(this); - this.updatePassword = this.updatePassword.bind(this); - this.showForm = this.showForm.bind(this); - this.validateAndNotifyPasswordBlur = this.validateAndNotifyPasswordBlur.bind(this); - this.getErrorText = this.getErrorText.bind(this); - } - - componentDidUpdate(prevProps) { - if (prevProps.isFocused || !this.props.isFocused || !this.textInputRef) { - return; - } - this.textInputRef.focus(); - } +function PDFPasswordForm({isFocused, isPasswordInvalid, shouldShowLoadingIndicator, onSubmit, onPasswordUpdated, onPasswordFieldFocused}) { + const {isSmallScreenWidth} = useWindowDimensions(); + const {translate} = useLocalize(); - getErrorText() { - if (this.props.isPasswordInvalid) { - return this.props.translate('attachmentView.passwordIncorrect'); + const [password, setPassword] = useState(''); + const [validationErrorText, setValidationErrorText] = useState(''); + const [shouldShowForm, setShouldShowForm] = useState(false); + const textInputRef = useRef(null); + + const errorText = useMemo(() => { + if (isPasswordInvalid) { + return translate('attachmentView.passwordIncorrect'); } - if (!_.isEmpty(this.state.validationErrorText)) { - return this.props.translate(this.state.validationErrorText); + if (!_.isEmpty(validationErrorText)) { + return translate(validationErrorText); } - return ''; - } + }, [isPasswordInvalid, translate, validationErrorText]); - submitPassword() { - if (!this.validate()) { + useEffect(() => { + if (!isFocused) { + return; + } + if (!textInputRef.current) { return; } - this.props.onSubmit(this.state.password); - } + textInputRef.current.focus(); + }, [isFocused]); - updatePassword(password) { - this.props.onPasswordUpdated(password); - if (!_.isEmpty(password) && this.state.validationErrorText) { - this.setState({validationErrorText: ''}); + const updatePassword = (newPassword) => { + onPasswordUpdated(newPassword); + if (!_.isEmpty(newPassword) && validationErrorText) { + setValidationErrorText(''); } - this.setState({password}); - } + setPassword(newPassword); + }; - validate() { - if (!this.props.isPasswordInvalid && !_.isEmpty(this.state.password)) { + const validate = () => { + if (!isPasswordInvalid && !_.isEmpty(password)) { return true; } - - if (_.isEmpty(this.state.password)) { - this.setState({ - validationErrorText: 'attachmentView.passwordRequired', - }); + if (_.isEmpty(password)) { + setValidationErrorText('attachmentView.passwordRequired'); } - return false; - } - - validateAndNotifyPasswordBlur() { - this.validate(); - this.props.onPasswordFieldFocused(false); - } - - showForm() { - this.setState({shouldShowForm: true}); - } - - render() { - const errorText = this.getErrorText(); - const containerStyle = this.props.isSmallScreenWidth ? [styles.flex1, styles.w100] : styles.pdfPasswordForm.wideScreenWidth; - - return ( - <> - {this.state.shouldShowForm ? ( - - - {this.props.translate('attachmentView.pdfPasswordForm.formLabel')} - - (this.textInputRef = el)} - label={this.props.translate('common.password')} - accessibilityLabel={this.props.translate('common.password')} - accessibilityRole={CONST.ACCESSIBILITY_ROLE.TEXT} - /** - * This is a workaround to bypass Safari's autofill odd behaviour. - * This tricks the browser not to fill the username somewhere else and still fill the password correctly. - */ - autoComplete={Browser.getBrowser() === CONST.BROWSER.SAFARI ? 'username' : 'off'} - autoCorrect={false} - textContentType="password" - onChangeText={this.updatePassword} - returnKeyType="done" - onSubmitEditing={this.submitPassword} - errorText={errorText} - onFocus={() => this.props.onPasswordFieldFocused(true)} - onBlur={this.validateAndNotifyPasswordBlur} - autoFocus - shouldDelayFocus={shouldDelayFocus} - secureTextEntry - /> -