Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frenkield 8595 pdf password #9141

Merged
merged 111 commits into from
Sep 5, 2022
Merged

Frenkield 8595 pdf password #9141

merged 111 commits into from
Sep 5, 2022

Conversation

frenkield
Copy link
Contributor

@frenkield frenkield commented May 23, 2022

Details

Added password validation form for viewing password-protected PDFs.

Fixed Issues

$ #8595

Tests

Normal PDF with Send button (regression)

  1. Open a chat, click the plus button to the left of the message input, and select "Add attachment"
  2. Select a normal PDF (not password-protected)
  3. Verify that the PDF renders correctly
  4. Click Send button
  5. Verify that the PDF is sent

Normal PDF with enter key (regression web and desktop)

  1. Open a chat, click the plus button to the left of the message input, and select "Add attachment"
  2. Select a normal PDF (not password-protected)
  3. Verify that the PDF renders correctly
  4. Press enter key on keyboard
  5. Verify that the PDF is sent

Protected PDF with send button

  1. Open a chat, click the plus button to the left of the message input, and select "Add attachment"
  2. Select a password-protected PDF (there's one in a comment in this PR)
  3. Verify that the password form appears
  4. Press Confirm button
  5. Verify that password-required message appears
  6. Enter an invalid password and press Confirm button
  7. Verify that invalid-password message appears
  8. Enter correct password and press Confirm button
  9. Verify that the PDF renders correctly
  10. Click Send button
  11. Verify that the PDF is sent

Protected PDF with enter key (web and desktop)

  1. Open a chat, click the plus button to the left of the message input, and select "Add attachment"
  2. Select a password-protected PDF (there's one in a comment in this PR)
  3. Verify that the password form appears
  4. Press enter key
  5. Verify that password-required message appears
  6. Enter an invalid password and press enter key
  7. Verify that invalid-password message appears
  8. Enter correct password and press enter key
  9. Verify that the PDF renders correctly
  10. Press enter key again
  11. Verify that the PDF is sent

Protected PDF that was already sent

  1. Open a chat where a protected PDF attachment was sent or received
  2. Click on the icon for the PDF attachment
  3. Verify that the password form appears
  4. Press enter key
  5. Verify that password-required message appears
  6. Enter an invalid password and press enter key
  7. Verify that error message appears
  8. Enter correct password and press enter key
  9. Verify that the PDF renders correctly

Protected PDF without viewing

  1. Open a chat, click the plus button to the left of the message input, and select "Add attachment"
  2. Select a password-protected PDF (there's one in a comment in this PR)
  3. Verify that the password form appears
  4. Click Send button
  5. Verify that the PDF is sent
  • Verify that no errors appear in the JS console

PR Review Checklist

Contributor (PR Author) Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • iOS / native
    • Android / native
    • iOS / Safari
    • Android / Chrome
    • MacOS / Chrome
    • MacOS / Desktop
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product was added in all src/languages/* files
    • I verified any copy / text that was added to the app is correct English and approved by marketing by tagging the marketing team on the original GH to get the correct copy.
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.js or at the top of the file that uses the constant) are defined as such
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • Any functional components have the displayName property
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • I have checked off every checkbox in the PR author checklist, including those that don't apply to this PR.

PR Reviewer Checklist

  • I verified the correct issue is linked in the ### Fixed Issues section above
  • I verified testing steps are clear and they cover the changes made in this PR
    • I verified the steps for local testing are in the Tests section
    • I verified the steps for Staging and/or Production testing are in the QA steps section
    • I verified the steps cover any possible failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I checked that screenshots or videos are included for tests on all platforms
  • I verified tests pass on all platforms & I tested again on:
    • iOS / native
    • Android / native
    • iOS / Safari
    • Android / Chrome
    • MacOS / Chrome
    • MacOS / Desktop
  • I verified there are no console errors (if there’s a console error not related to the PR, report it or open an issue for it to be fixed)
  • I verified proper code patterns were followed (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick).
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained “why” the code was doing something instead of only explaining “what” the code was doing.
    • I verified any copy / text shown in the product was added in all src/languages/* files
    • I verified any copy / text that was added to the app is correct English and approved by marketing by tagging the marketing team on the original GH to get the correct copy.
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named “index.js”. All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I verified that this PR follows the guidelines as stated in the Review Guidelines
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.js or at the top of the file that uses the constant) are defined as such
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • Any functional components have the displayName property
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose and it is broken down into smaller components in order to separate concerns and functions
  • If a new CSS style is added I verified that:
    • A similar style doesn’t already exist
    • The style can’t be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.

QA Steps

Normal PDF with Send button (regression)

  1. Open a chat, click the plus button to the left of the message input, and select "Add attachment"
  2. Select a normal PDF (not password-protected)
  3. Verify that the PDF renders correctly
  4. Click Send button
  5. Verify that the PDF is sent

Normal PDF with enter key (regression web and desktop)

  1. Open a chat, click the plus button to the left of the message input, and select "Add attachment"
  2. Select a normal PDF (not password-protected)
  3. Verify that the PDF renders correctly
  4. Press enter key on keyboard
  5. Verify that the PDF is sent

Protected PDF with send button

  1. Open a chat, click the plus button to the left of the message input, and select "Add attachment"
  2. Select a password-protected PDF (there's one in a comment in this PR)
  3. Verify that the password form appears
  4. Press Confirm button
  5. Verify that password-required message appears
  6. Enter an invalid password and press Confirm button
  7. Verify that invalid-password message appears
  8. Enter correct password and press Confirm button
  9. Verify that the PDF renders correctly
  10. Click Send button
  11. Verify that the PDF is sent

Protected PDF with enter key (web and desktop)

  1. Open a chat, click the plus button to the left of the message input, and select "Add attachment"
  2. Select a password-protected PDF (there's one in a comment in this PR)
  3. Verify that the password form appears
  4. Press enter key
  5. Verify that password-required message appears
  6. Enter an invalid password and press enter key
  7. Verify that invalid-password message appears
  8. Enter correct password and press enter key
  9. Verify that the PDF renders correctly
  10. Press enter key again
  11. Verify that the PDF is sent

Protected PDF that was already sent

  1. Open a chat where a protected PDF attachment was sent or received
  2. Click on the icon for the PDF attachment
  3. Verify that the password form appears
  4. Press enter key
  5. Verify that password-required message appears
  6. Enter an invalid password and press enter key
  7. Verify that error message appears
  8. Enter correct password and press enter key
  9. Verify that the PDF renders correctly

Protected PDF without viewing

  1. Open a chat, click the plus button to the left of the message input, and select "Add attachment"
  2. Select a password-protected PDF (there's one in a comment in this PR)
  3. Verify that the password form appears
  4. Click Send button
  5. Verify that the PDF is sent
  • Verify that no errors appear in the JS console

Videos

Web

web_8595.mp4

mWeb - iOS Safari

ios_safari_8595.mp4

mWeb - Android Chrome

android_chrome_8595.mp4

Desktop

macos_desktop_8595.mp4

iOS

ios_native_8595.mp4

Android

android_native_8595.mp4

@frenkield
Copy link
Contributor Author

Here's a password-protected PDF for testing. The password is 1234

password-protected.pdf

@frenkield frenkield marked this pull request as ready for review May 24, 2022 00:33
@frenkield frenkield requested a review from a team as a code owner May 24, 2022 00:33
@melvin-bot melvin-bot bot requested review from tgolen and removed request for a team May 24, 2022 00:33

PDFPasswordForm.propTypes = propTypes;
PDFPasswordForm.defaultProps = defaultProps;
PDFPasswordForm.displayName = 'PDFPasswordForm';
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is only required for a functional component, but I'm not 100% sure when it comes to a PureComponent. If it's not necessary, would you mind removing it?

Copy link
Contributor Author

@frenkield frenkield May 24, 2022

Choose a reason for hiding this comment

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

Ah yeah, displayName is only needed for functional components. I'll remove it.

isPasswordInvalid: false,
};

class PDFPasswordForm extends PureComponent {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why use a PureComponent as opposed to just a regular component?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did that just because PDFView/index.js uses PureComponent. I'll change it to a regular compoment.

Comment on lines 78 to 81
const PasswordResponses = {
NEED_PASSWORD: 1,
INCORRECT_PASSWORD: 2,
};
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would be better to move these into CONST and just keep a comment with them about where they come from.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok I'll move it.


/**
* Send submitted password to react-pdf via its callback so it can attempt to
* open the password-protected PDf.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* open the password-protected PDf.
* open the password-protected PDF.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll fix that.

*
* @param {String} password The password entered in the form
*/
openPdfWithPassword(password) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Since this method only does one thing, and it passes the same arguments, I think the method is unnecessary and it should just reference this.onPasswordCallback directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I'll remove that.

Comment on lines 110 to 116
renderPasswordForm() {
return (
<PDFPasswordForm
onSubmit={this.openPdfWithPassword}
isPasswordInvalid={this.state.isPasswordInvalid}
/>
);
Copy link
Contributor

Choose a reason for hiding this comment

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

Please leave all rendering in the render() method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok I'll move that.

Comment on lines 155 to 157
Array.from(
new Array(this.state.numPages),
(el, index) => (
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not quite sure what this is doing. Why is Array.from() used and also new Array()?

  • We try to standardize by using _ methods, is it possible to use that here instead?
  • If not, would a simple for loop be better?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is how the code was originally. I didn't touch it. Do you want me to refactor that?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, please. I'm glad you didn't add it, but let's always be improving the code quality when we find things like this.

*
* @param {String} message
*/
initiatePasswordChallenge({message}) {
Copy link
Contributor

Choose a reason for hiding this comment

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

It feels like a lot of this code is duplicated between native and web. Can it be abstracted better so there isn't so much duplication?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok sure, I can abstract that a bit.

I don't see a component where there's something like that. What should I name the base component file? Like index.base.js or BasePDFView.js?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes create a new BasePDFView.js

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok thanks, @Santhosh-Sellavel.

And sorry, I do see examples like this.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Just move only codes that can be kept common for all platforms. The rest should be in platform-specific files.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok sounds good.

Copy link
Contributor Author

@frenkield frenkield May 25, 2022

Choose a reason for hiding this comment

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

Hey so sorry, I don't see a nice way to do this. If I understand correctly we should not extend components. So doing something like in BaseTextInput.js, for example, doesn't seem possible to me.

The main issue is that things need to be handled quite differently on web and on native in order to acheive a proper password challenge experience:

  1. On web, the react-pdf component must not be conditionally rendered - and thus hidden via styles when the password form is visible. This is because it receives the password via a callback function and so the PDF component needs to be persistent.

  2. Whereas on native, the react-native-pdf must be conditionally rendered. This is because it doesn't detect when its props.password is updated.

Both versions of my code (web/native) use similar state variables (shouldRequestPassword and isPasswordInvalid) but otherwise the code is totally different.

Can someone maybe provide some specific direction on how to refactor this?

Copy link
Member

Choose a reason for hiding this comment

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

It seems fine to me. I don't feel the need to abstraction as both of them have different approaches.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, thank you for that explanation. I agree with you now that this is probably fine the way it is.

Copy link
Collaborator

@Santhosh-Sellavel Santhosh-Sellavel left a comment

Choose a reason for hiding this comment

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

Just adding me as a reviewer

@frenkield
Copy link
Contributor Author

I have to step out for a couple hours. I'll work on the changes later today. Thanks, All!

@tgolen tgolen requested a review from a team May 24, 2022 21:24
@melvin-bot melvin-bot bot requested review from Santhosh-Sellavel and tgolen and removed request for a team May 24, 2022 21:24
@tgolen
Copy link
Contributor

tgolen commented May 24, 2022

I will be going OOO so I will be reassigning this for now.

@tgolen tgolen removed their request for review May 24, 2022 21:24
@frenkield
Copy link
Contributor Author

I pushed most of the changes. I'll push the BasePDFView.js change later today.

@frenkield
Copy link
Contributor Author

PR updated, @parasharrajat.

parasharrajat
parasharrajat previously approved these changes Aug 27, 2022
Copy link
Member

@parasharrajat parasharrajat left a comment

Choose a reason for hiding this comment

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

LGTM. Good work. There were lots of ups and downs, I appreciate your patience.

cc: @tgolen

PR Reviewer Checklist

  • I have verified the author checklist is complete (all boxes are checked off).
  • I verified the correct issue is linked in the ### Fixed Issues section above
  • I verified testing steps are clear and they cover the changes made in this PR
    • I verified the steps for local testing are in the Tests section
    • I verified the steps for Staging and/or Production testing are in the QA steps section
    • I verified the steps cover any possible failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I checked that screenshots or videos are included for tests on all platforms
  • I verified tests pass on all platforms & I tested again on:
    • iOS / native
    • Android / native
    • iOS / Safari
    • Android / Chrome
    • MacOS / Chrome
    • MacOS / Desktop
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I verified proper code patterns were followed (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick).
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product was added in all src/languages/* files
    • I verified any copy / text that was added to the app is correct English and approved by marketing by tagging the marketing team on the original GH to get the correct copy.
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I verified that this PR follows the guidelines as stated in the Review Guidelines
  • I verified other components that can be impacted by these changes have been tested, and I retested again (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar have been tested & I retested again)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.js or at the top of the file that uses the constant) are defined as such
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • Any functional components have the displayName property
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • I have checked off every checkbox in the PR reviewer checklist, including those that don't apply to this PR.

🎀 👀 🎀 C+ reviewed

* The PasswordResponses constants used below were copied from react-pdf
* because they're not exported in entry.webpack.
*
* @param {*} callback Callback used to send password to react-pdf
Copy link
Member

Choose a reason for hiding this comment

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

Not a Blocker

Suggested change
* @param {*} callback Callback used to send password to react-pdf
* @param {Function} callback Callback used to send password to react-pdf

@parasharrajat
Copy link
Member

Bump @tgolen, awaiting your review. Thanks.

Copy link
Contributor

@tgolen tgolen left a comment

Choose a reason for hiding this comment

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

Looks great! I just noticed this one thing.

shouldShowForm: false,
};
this.submitPassword = this.submitPassword.bind(this);
this.validate = this.validate.bind(this);
Copy link
Contributor

Choose a reason for hiding this comment

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

This method is only called from submitPassword() and validateAndNotifyPasswordBlur() which are already bound to this, so this line can be removed.

@frenkield
Copy link
Contributor Author

PR updated, @parasharrajat and @tgolen.

@parasharrajat
Copy link
Member

Bump @tgolen

@tgolen tgolen merged commit dc6a69a into Expensify:main Sep 5, 2022
@melvin-bot melvin-bot bot added the Emergency label Sep 5, 2022
@melvin-bot
Copy link

melvin-bot bot commented Sep 5, 2022

@tgolen looks like this was merged without passing tests. Please add a note explaining why this was done and remove the Emergency label if this is not an emergency.

@tgolen
Copy link
Contributor

tgolen commented Sep 5, 2022

OK, there it goes! 🎉

Nice work getting through this one @frenkield

@tgolen
Copy link
Contributor

tgolen commented Sep 5, 2022

It's OK, Melvin. The test is failing because this is an older PR where the comment formats don't match what the test is expecting regarding the reviewer checklist.

@OSBotify
Copy link
Contributor

OSBotify commented Sep 5, 2022

🚀 Deployed to staging by @tgolen in version: 1.1.97-2 🚀

platform result
🤖 android 🤖 success ✅
🖥 desktop 🖥 success ✅
🍎 iOS 🍎 failure ❌
🕸 web 🕸 success ✅

@frenkield
Copy link
Contributor Author

Thanks, @tgolen and @parasharrajat.

onSubmit={this.attemptPdfLoad}
onPasswordUpdated={() => this.setState({isPasswordInvalid: false})}
isPasswordInvalid={this.state.isPasswordInvalid}
shouldAutofocusPasswordField={!this.props.isSmallScreenWidth}
Copy link
Contributor

Choose a reason for hiding this comment

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

@tgolen @frenkield @parasharrajat @Santhosh-Sellavel
We're coming from this issue. Basically a request to autofocus password field on native devices. Any idea why this condition was added. Just want to clarify before we proceed with the linked issue. cc @sobitneupane

Copy link
Member

Choose a reason for hiding this comment

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

I tried to remember but didn't find the exact reason why we conditionally enabled it. But the main reason to disable the autofocus on the web was to avoid UX confusion with two buttons 'Confirm' and Send.

They both were laying over the keyboard which looked bad. #9141 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't specifically remember either.

@hungvu193
Copy link
Contributor

This PR introduced a regression: #22519
We should use translateKey instead of translation text to make sure it will be updated when we changed the language.

// Use window height changes to toggle the keyboard. To maintain keyboard state
// on all platforms we also use focus/blur events. So we need to make sure here
// that we avoid redundant keyboard toggling.
if (!this.state.isKeyboardOpen && this.props.windowHeight < prevProps.windowHeight) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This line caused #22364 because it did not factor in the offline indicator.

)}
<Button
text={this.props.translate('common.confirm')}
onPress={this.submitPassword}
Copy link
Contributor

Choose a reason for hiding this comment

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

Coming from #25570

We should have ensured that the virtual keyboard stays open on mWeb when a wrong password is provided.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think that counts as a regression rather feature request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants