diff --git a/src/components/PDFView/index.js b/src/components/PDFView/index.js index 4fb45de1724d..485b40c1e983 100644 --- a/src/components/PDFView/index.js +++ b/src/components/PDFView/index.js @@ -9,6 +9,9 @@ import CONST from '../../CONST'; import PDFPasswordForm from './PDFPasswordForm'; import * as pdfViewPropTypes from './pdfViewPropTypes'; import withWindowDimensions from '../withWindowDimensions'; +import withLocalize from '../withLocalize'; +import Text from '../Text'; +import compose from '../../libs/compose'; class PDFView extends Component { constructor(props) { @@ -22,7 +25,7 @@ class PDFView extends Component { }; this.onDocumentLoadSuccess = this.onDocumentLoadSuccess.bind(this); this.initiatePasswordChallenge = this.initiatePasswordChallenge.bind(this); - this.attemptPdfLoad = this.attemptPdfLoad.bind(this); + this.attemptPDFLoad = this.attemptPDFLoad.bind(this); this.toggleKeyboardOnSmallScreens = this.toggleKeyboardOnSmallScreens.bind(this); } @@ -81,7 +84,7 @@ class PDFView extends Component { * * @param {String} password Password to send via callback to react-pdf */ - attemptPdfLoad(password) { + attemptPDFLoad(password) { this.onPasswordCallback(password); } @@ -125,6 +128,7 @@ class PDFView extends Component { onLayout={event => this.setState({windowWidth: event.nativeEvent.layout.width})} > {this.props.translate('attachmentView.failedToLoadPDF')}} loading={} file={this.props.sourceURL} options={{ @@ -146,7 +150,7 @@ class PDFView extends Component { {this.state.shouldRequestPassword && ( this.setState({isPasswordInvalid: false})} isPasswordInvalid={this.state.isPasswordInvalid} shouldAutofocusPasswordField={!this.props.isSmallScreenWidth} @@ -161,4 +165,7 @@ class PDFView extends Component { PDFView.propTypes = pdfViewPropTypes.propTypes; PDFView.defaultProps = pdfViewPropTypes.defaultProps; -export default withWindowDimensions(PDFView); +export default compose( + withLocalize, + withWindowDimensions, +)(PDFView); diff --git a/src/components/PDFView/index.native.js b/src/components/PDFView/index.native.js index cc4db7b97078..46474eb73705 100644 --- a/src/components/PDFView/index.native.js +++ b/src/components/PDFView/index.native.js @@ -5,11 +5,13 @@ import KeyboardAvoidingView from '../KeyboardAvoidingView'; import styles from '../../styles/styles'; import * as StyleUtils from '../../styles/StyleUtils'; import FullScreenLoadingIndicator from '../FullscreenLoadingIndicator'; +import Text from '../Text'; import PDFPasswordForm from './PDFPasswordForm'; import * as pdfViewPropTypes from './pdfViewPropTypes'; import compose from '../../libs/compose'; import withWindowDimensions from '../withWindowDimensions'; import withKeyboardState from '../withKeyboardState'; +import withLocalize from '../withLocalize'; /** * On the native layer, we use react-native-pdf/PDF to display PDFs. If a PDF is @@ -30,20 +32,34 @@ class PDFView extends Component { super(props); this.state = { shouldRequestPassword: false, - shouldAttemptPdfLoad: true, + shouldAttemptPDFLoad: true, shouldShowLoadingIndicator: true, isPasswordInvalid: false, + failedToLoadPDF: false, password: '', }; this.initiatePasswordChallenge = this.initiatePasswordChallenge.bind(this); - this.attemptPdfLoadWithPassword = this.attemptPdfLoadWithPassword.bind(this); - this.finishPdfLoad = this.finishPdfLoad.bind(this); + this.attemptPDFLoadWithPassword = this.attemptPDFLoadWithPassword.bind(this); + this.finishPDFLoad = this.finishPDFLoad.bind(this); + this.handleFailureToLoadPDF = this.handleFailureToLoadPDF.bind(this); } componentDidUpdate() { this.props.onToggleKeyboard(this.props.isShown); } + handleFailureToLoadPDF(error) { + if (error.message.match(/password/i)) { + this.initiatePasswordChallenge(); + return; + } + + this.setState({ + failedToLoadPDF: true, + shouldAttemptPDFLoad: false, + }); + } + /** * Initiate password challenge if message received from react-native-pdf/PDF * indicates that a password is required or invalid. @@ -51,20 +67,14 @@ class PDFView extends Component { * For a password challenge the message is "Password required or incorrect password." * Note that the message doesn't specify whether the password is simply empty or * invalid. - * - * @param {String} message */ - initiatePasswordChallenge({message}) { + initiatePasswordChallenge() { this.setState({shouldShowLoadingIndicator: false}); - if (!message.match(/password/i)) { - return; - } - // Render password form, and don't render PDF and loading indicator. this.setState({ shouldRequestPassword: true, - shouldAttemptPdfLoad: false, + shouldAttemptPDFLoad: false, }); // The message provided by react-native-pdf doesn't indicate whether this @@ -82,13 +92,13 @@ class PDFView extends Component { * * @param {String} password Password submitted via PDFPasswordForm */ - attemptPdfLoadWithPassword(password) { + attemptPDFLoadWithPassword(password) { // Render react-native-pdf/PDF so that it can validate the password. // Note that at this point in the password challenge, shouldRequestPassword is true. // Thus react-native-pdf/PDF will be rendered - but not visible. this.setState({ password, - shouldAttemptPdfLoad: true, + shouldAttemptPDFLoad: true, shouldShowLoadingIndicator: true, }); } @@ -97,7 +107,7 @@ class PDFView extends Component { * After the PDF is successfully loaded hide PDFPasswordForm and the loading * indicator. */ - finishPdfLoad() { + finishPDFLoad() { this.setState({ shouldRequestPassword: false, shouldShowLoadingIndicator: false, @@ -129,23 +139,30 @@ class PDFView extends Component { return ( - {this.state.shouldAttemptPdfLoad && ( + {this.state.failedToLoadPDF && ( + + + {this.props.translate('attachmentView.failedToLoadPDF')} + + + )} + {this.state.shouldAttemptPDFLoad && ( } source={{uri: this.props.sourceURL}} style={pdfStyles} - onError={this.initiatePasswordChallenge} + onError={this.handleFailureToLoadPDF} password={this.state.password} - onLoadComplete={this.finishPdfLoad} + onLoadComplete={this.finishPDFLoad} /> )} {this.state.shouldRequestPassword && ( this.setState({isPasswordInvalid: false})} isPasswordInvalid={this.state.isPasswordInvalid} shouldShowLoadingIndicator={this.state.shouldShowLoadingIndicator} @@ -163,4 +180,5 @@ PDFView.defaultProps = pdfViewPropTypes.defaultProps; export default compose( withWindowDimensions, withKeyboardState, + withLocalize, )(PDFView); diff --git a/src/languages/en.js b/src/languages/en.js index bd745b387245..283a75aab303 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -631,6 +631,7 @@ export default { unknownFilename: 'Unknown filename', passwordRequired: 'Please enter a password', passwordIncorrect: 'Incorrect password. Please try again.', + failedToLoadPDF: 'Failed to load PDF file.', pdfPasswordForm: { title: 'Password protected PDF', infoText: 'This PDF is password protected.', diff --git a/src/languages/es.js b/src/languages/es.js index 063faca6e4e2..2274968ea622 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -631,6 +631,7 @@ export default { unknownFilename: 'Archivo desconocido', passwordRequired: 'Por favor introduce tu contraseña', passwordIncorrect: 'Contraseña incorrecta. Por favor intenta de nuevo.', + failedToLoadPDF: 'Hubo un error al intentar cargar el PDF.', pdfPasswordForm: { title: 'PDF protegido con contraseña', infoText: 'Este PDF esta protegido con contraseña.',