Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions src/components/PDFView/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
}

Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -125,6 +128,7 @@ class PDFView extends Component {
onLayout={event => this.setState({windowWidth: event.nativeEvent.layout.width})}
>
<Document

@rushatgabhane rushatgabhane Dec 8, 2022

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NAB (because unrelated to PR): There is a console error related to PDFs.

Action performed: Upload a pdf two times.

image

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say this is unrelated, I haven't changed anything related to rendering components in a map with the wrong keys. Maybe you are getting this from the repeated comments bug that we can see in your video.

error={<Text style={[styles.textLabel, styles.textLarge]}>{this.props.translate('attachmentView.failedToLoadPDF')}</Text>}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add testing copy in both languages to the QA steps? I saw you tested yourself :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do, I was just trying to escape having to take screenshots of every platform/theme/language combination 🥲

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be good to test only on dark mode for this!

loading={<FullScreenLoadingIndicator />}
file={this.props.sourceURL}
options={{
Expand All @@ -146,7 +150,7 @@ class PDFView extends Component {
</View>
{this.state.shouldRequestPassword && (
<PDFPasswordForm
onSubmit={this.attemptPdfLoad}
onSubmit={this.attemptPDFLoad}
onPasswordUpdated={() => this.setState({isPasswordInvalid: false})}
isPasswordInvalid={this.state.isPasswordInvalid}
shouldAutofocusPasswordField={!this.props.isSmallScreenWidth}
Expand All @@ -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);
54 changes: 36 additions & 18 deletions src/components/PDFView/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -30,41 +32,49 @@ 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();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious, what is this check doing?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was from the previous code to handle password protected PDFs. I didn't test it, but I'm guessing that if the PDF is password protected the error message will contain the word password.

return;
}

this.setState({
failedToLoadPDF: true,
shouldAttemptPDFLoad: false,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beep boop 🤖 🐧
Dropping a friendly note that we missed a case here - The password field loads infinitely on deleting the pdf file from the sender's account

We should have also set the following states when handling a failed PDF.

shouldRequestPassword: false,
shouldShowLoadingIndicator: false

});
}

/**
* Initiate password challenge if message received from react-native-pdf/PDF
* indicates that a password is required or invalid.
*
* 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
Expand All @@ -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,
});
}
Expand All @@ -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,
Expand Down Expand Up @@ -129,23 +139,30 @@ class PDFView extends Component {

return (
<View style={containerStyles}>
{this.state.shouldAttemptPdfLoad && (
{this.state.failedToLoadPDF && (
<View style={[styles.flex1, styles.justifyContentCenter]}>
<Text style={[styles.textLabel, styles.textLarge]}>
{this.props.translate('attachmentView.failedToLoadPDF')}
</Text>
</View>
)}
{this.state.shouldAttemptPDFLoad && (
<TouchableWithoutFeedback style={touchableStyles}>
<PDF
trustAllCerts={false}
renderActivityIndicator={() => <FullScreenLoadingIndicator />}
source={{uri: this.props.sourceURL}}
style={pdfStyles}
onError={this.initiatePasswordChallenge}
onError={this.handleFailureToLoadPDF}
password={this.state.password}
onLoadComplete={this.finishPdfLoad}
onLoadComplete={this.finishPDFLoad}
/>
</TouchableWithoutFeedback>
)}
{this.state.shouldRequestPassword && (
<KeyboardAvoidingView style={styles.flex1}>
<PDFPasswordForm
onSubmit={this.attemptPdfLoadWithPassword}
onSubmit={this.attemptPDFLoadWithPassword}
onPasswordUpdated={() => this.setState({isPasswordInvalid: false})}
isPasswordInvalid={this.state.isPasswordInvalid}
shouldShowLoadingIndicator={this.state.shouldShowLoadingIndicator}
Expand All @@ -163,4 +180,5 @@ PDFView.defaultProps = pdfViewPropTypes.defaultProps;
export default compose(
withWindowDimensions,
withKeyboardState,
withLocalize,
)(PDFView);
1 change: 1 addition & 0 deletions src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.',
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.',
Expand Down