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

[$1000] Add payment method button jumps when tapping back button on Paypal page #14843

Closed
1 task
kavimuru opened this issue Feb 6, 2023 · 52 comments
Closed
1 task
Assignees
Labels
Awaiting Payment Auto-added when associated PR is deployed to production Bug Something is broken. Auto assigns a BugZero manager. Daily KSv2 External Added to denote the issue can be worked on by a contributor

Comments

@kavimuru
Copy link

kavimuru commented Feb 6, 2023

If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!


Action Performed:

  1. Go to settings> payments
  2. Click on Add payment method button and choose paypal option
  3. Click on back button

Expected Result:

Add payment method button should not jump

Actual Result:

Add payment method button jumps

Workaround:

unknown

Platforms:

Which of our officially supported platforms is this issue occurring on?

  • iOS / native

Version Number: v1.2.65-0
Reproducible in staging?: y
Reproducible in production?: y
If this was caught during regression testing, add the test name, ID and link from TestRail:
Email or phone of affected tester (no customers):
Logs: https://stackoverflow.com/c/expensify/questions/4856
Notes/Photos/Videos:

RPReplay_Final1675419094.1.MP4
PQBV3788.MP4

Expensify/Expensify Issue URL:
Issue reported by: @gadhiyamanan
Slack conversation: https://expensify.slack.com/archives/C049HHMV9SM/p1675419194137479

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~01d9d6800730a96ae0
  • Upwork Job ID: 1622954994768916480
  • Last Price Increase: 2023-02-07
@kavimuru kavimuru added Daily KSv2 Bug Something is broken. Auto assigns a BugZero manager. labels Feb 6, 2023
@melvin-bot melvin-bot bot locked and limited conversation to collaborators Feb 6, 2023
@melvin-bot melvin-bot bot unlocked this conversation Feb 6, 2023
@melvin-bot
Copy link

melvin-bot bot commented Feb 6, 2023

Triggered auto assignment to @NicMendonca (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details.

@melvin-bot melvin-bot bot locked and limited conversation to collaborators Feb 6, 2023
@melvin-bot
Copy link

melvin-bot bot commented Feb 6, 2023

Bug0 Triage Checklist (Main S/O)

  • This "bug" occurs on a supported platform (ensure Platforms in OP are ✅)
  • This bug is not a duplicate report (check E/App issues and #expensify-bugs)
    • If it is, comment with a link to the original report, close the issue and add any novel details to the original issue instead
  • This bug is reproducible using the reproduction steps in the OP. S/O
    • If the reproduction steps are clear and you're unable to reproduce the bug, check with the reporter and QA first, then close the issue.
    • If the reproduction steps aren't clear and you determine the correct steps, please update the OP.
  • This issue is filled out as thoroughly and clearly as possible
    • Pay special attention to the title, results, platforms where the bug occurs, and if the bug happens on staging/production.
  • I have reviewed and subscribed to the linked Slack conversation to ensure Slack/Github stay in sync

@melvin-bot melvin-bot bot unlocked this conversation Feb 6, 2023
@melvin-bot melvin-bot bot locked and limited conversation to collaborators Feb 6, 2023
@NicMendonca
Copy link
Contributor

RPReplay_Final1675777517.MP4

Can confirm its only happening with the paypal option

@NicMendonca NicMendonca added the External Added to denote the issue can be worked on by a contributor label Feb 7, 2023
@melvin-bot melvin-bot bot unlocked this conversation Feb 7, 2023
@melvin-bot melvin-bot bot changed the title Add payment method button jumps when press back button tapping back button in paypal page [$1000] Add payment method button jumps when press back button tapping back button in paypal page Feb 7, 2023
@MelvinBot
Copy link

Job added to Upwork: https://www.upwork.com/jobs/~01d9d6800730a96ae0

@MelvinBot
Copy link

Current assignee @NicMendonca is eligible for the External assigner, not assigning anyone new.

@MelvinBot
Copy link

Triggered auto assignment to Contributor-plus team member for initial proposal review - @mananjadhav (External)

@melvin-bot melvin-bot bot added the Help Wanted Apply this label when an issue is open to proposals by contributors label Feb 7, 2023
@MelvinBot
Copy link

Triggered auto assignment to @mountiny (External), see https://stackoverflow.com/c/expensify/questions/7972 for more details.

@tienifr
Copy link
Contributor

tienifr commented Feb 7, 2023

Proposal

Problem

When we navigate from the PayPal screen (which at the time has keyboard open) back to the Payment page, the keyboard closing behavior interferes with the Payment page View's layout, causing the Add payment method button to jump.

Solution

We should disable the KeyboardAvoidingView behavior in the Payment page to prevent this. The Payment page does not have any text input and never needs the keyboard avoiding behavior so it's safe to disable it here. Other pages with KeyboardAvoidingView will still work as expected.

diff --git a/src/components/ScreenWrapper/index.js b/src/components/ScreenWrapper/index.js
index e7ba7e5d0e..64ddd46319 100644
--- a/src/components/ScreenWrapper/index.js
+++ b/src/components/ScreenWrapper/index.js
@@ -96,7 +96,11 @@ class ScreenWrapper extends React.Component {
                                 paddingStyle,
                             ]}
                         >
-                            <KeyboardAvoidingView style={[styles.w100, styles.h100, {maxHeight: this.props.windowHeight}]} behavior={this.props.keyboardAvoidingViewBehavior}>
+                            <KeyboardAvoidingView
+                                style={[styles.w100, styles.h100, {maxHeight: this.props.windowHeight}]}
+                                behavior={this.props.keyboardAvoidingViewBehavior}
+                                enabled={this.props.keyboardAvoidingViewEnabled}
+                            >
                                 <HeaderGap />
                                 {// If props.children is a function, call it to provide the insets to the children.
                                     _.isFunction(this.props.children)
diff --git a/src/components/ScreenWrapper/propTypes.js b/src/components/ScreenWrapper/propTypes.js
index 46cc9ed631..08aaaa151c 100644
--- a/src/components/ScreenWrapper/propTypes.js
+++ b/src/components/ScreenWrapper/propTypes.js
@@ -28,6 +28,9 @@ const propTypes = {
         /** Indicates when an Alert modal is about to be visible */
         willAlertModalBecomeVisible: PropTypes.bool,
     }),
+
+    /** The enabled flag to pass to the KeyboardAvoidingView */
+    keyboardAvoidingViewEnabled: PropTypes.bool,
 };
 
 const defaultProps = {
@@ -37,6 +40,7 @@ const defaultProps = {
     onTransitionEnd: () => {},
     modal: {},
     keyboardAvoidingViewBehavior: 'padding',
+    keyboardAvoidingViewEnabled: true,
 };
 
 export {propTypes, defaultProps};
diff --git a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
index 9a480454ea..5f8c0a6212 100644
--- a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
+++ b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
@@ -342,7 +342,7 @@ class BasePaymentsPage extends React.Component {
         // Determines whether or not the modal popup is mounted from the bottom of the screen instead of the side mount on Web or Desktop screens
         const isPopoverBottomMount = this.state.anchorPositionTop === 0 || this.props.isSmallScreenWidth;
         return (
-            <ScreenWrapper>
+            <ScreenWrapper keyboardAvoidingViewEnabled={false}>
                 <HeaderWithCloseButton
                     title={this.props.translate('common.payments')}
                     shouldShowBackButton

@tienifr
Copy link
Contributor

tienifr commented Feb 7, 2023

Working well after the fix:

Screen.Recording.2023-02-07.at.22.12.03.mov

@tienifr
Copy link
Contributor

tienifr commented Feb 7, 2023

Proposal 2

I managed to find the actual root cause of this. This happens due to the focusPayPalMeInput is called both when we navigate into and out of the PayPal screen (the onTransitionEnd are triggered in both cases). When focusPayPalMeInput is called when navigating from the PayPal screen to the Payment screen, it causes the keyboard to open and move the Add payment method button. In order to fix this we need to check that we're not going back to previous screen before calling the focusPayPalMeInput.

diff --git a/src/pages/settings/Payments/AddPayPalMePage.js b/src/pages/settings/Payments/AddPayPalMePage.js
index ba2b5ec994..2b3aa88ae1 100644
--- a/src/pages/settings/Payments/AddPayPalMePage.js
+++ b/src/pages/settings/Payments/AddPayPalMePage.js
@@ -23,6 +23,7 @@ class AddPayPalMePage extends React.Component {
         this.state = {
             payPalMeUsername: '',
             payPalMeUsernameError: false,
+            didGoBack: false,
         };
         this.setPayPalMeUsername = this.setPayPalMeUsername.bind(this);
         this.focusPayPalMeInput = this.focusPayPalMeInput.bind(this);
@@ -54,11 +55,18 @@ class AddPayPalMePage extends React.Component {
 
     render() {
         return (
-            <ScreenWrapper onTransitionEnd={this.focusPayPalMeInput}>
+            <ScreenWrapper onTransitionEnd={() => {
+                if (!this.state.didGoBack) {
+                    this.focusPayPalMeInput();
+                }
+            }}>
                 <HeaderWithCloseButton
                     title={this.props.translate('common.payPalMe')}
                     shouldShowBackButton
-                    onBackButtonPress={() => Navigation.navigate(ROUTES.SETTINGS_PAYMENTS)}
+                    onBackButtonPress={() => {
+                        this.setState({didGoBack: true});
+                        Navigation.navigate(ROUTES.SETTINGS_PAYMENTS);
+                    }}
                     onCloseButtonPress={() => Navigation.dismissModal(true)}
                 />
                 <View style={[styles.flex1, styles.p5]}>

Some other variations of this solution that I suggest include:

  1. calling focusPayPalMeInput inside InteractionManager.runAfterInteractions inside componentDidMount instead (this seems to be the cleanest solution)
  2. Checking if the page is currently visible before calling the focusPayPalMeInput
  3. make onTransitionEnd only called when we're navigating into the ScreenWrapper instead, or we can even split to 2 different events: onTransitionInEnd, onTransitionOutEnd, same for start, so that it's clear what event we're listening to
    ...

But the approach should generally be similar: call the focusPayPalMeInput only once when entering the screen. I can send here the code change once we decide what implementation details we're interested in.

@MelvinBot
Copy link

Looks like something related to react-navigation may have been mentioned in this issue discussion.

As a reminder, please make sure that all proposals are not workarounds and that any and all attempt to fix the issue holistically have been made before proceeding with a solution. Proposals to change our DeprecatedCustomActions.js files should not be accepted.

Feel free to drop a note in #expensify-open-source with any questions.

@tienifr
Copy link
Contributor

tienifr commented Feb 7, 2023

calling focusPayPalMeInput inside InteractionManager.runAfterInteractions inside componentDidMount instead (this seems to be the cleanest solution)

Here is the diff for variation 1 of the above solution, it's clean and works well

@tienifr
Copy link
Contributor

tienifr commented Feb 7, 2023

We might also want to take a look at other places where we use onTransitionEnd to make sure the same issue doesn't happen. I checked the PasswordPage and AddSecondaryLoginPage, they both triggered the onTransitionEnd (hence the focus) twice but there's no button inside KeyboardAvoidingView like in this issue, so there's no visual glitch.

@s77rt
Copy link
Contributor

s77rt commented Feb 7, 2023

Proposal

Please re-state the problem that we are trying to solve in this issue.

On back navigation the add payment method button jumps

What is the root cause of that problem?

On back navigation after hiding the screen we are focusing the paypal input that causes the keyboard to briefly shows up resulting in the jump behaviour. The focus call is initialised by the ScreenWrapper's callback onTransitionEnd where that callback is executed twice since the transition happens twice (on showing the page and on hiding it).

What changes do you think we should make in order to solve the problem?

  1. Do not focus the paypal input using ScreenWrapper's onTransitionEnd callback. Instead pass autoFocus and shouldDelayFocus to the <TextInput />.
  2. Currently the <TextInput />'s shouldDelayFocus functionality is based on setTimeout and since we have found a better and a more reliable alternative which is the navigation callback onTransitionEnd we should use that instead. That can be done by using HOC withNavigation in BaseTextInput.

Step 2 in pseudo-code:

- On component mount: register the transitionEnd callback if shouldDelayFocus is true
- On transitionEnd callback: if we are opening the page focus the input
- On component unmount: unregister the transitionEnd callback

We can apply the same fix to other effected pages

What alternative solutions did you explore? (Optional)

  • Instead of completely replacing the setTimeout used on shouldDelayFocus. We can keep it as a fallback if there are cases where navigation would not be available.

@tienifr
Copy link
Contributor

tienifr commented Feb 8, 2023

@s77rt I thought about using autoFocus and shouldDelayFocus too but that causes a minor UI glitch for me (the Button of the next screen is pushed up by the keyboard before the Button of the previous screen fully disappears).

Also I think shouldDelayFocus is a hack that uses setTimeout which should only be used for Android when we have no other options. Like in here, all of its usage needs to have comments explaining

@s77rt
Copy link
Contributor

s77rt commented Feb 8, 2023

Thanks for the feedback @tienifr. I do have answers for your concerns but let's not focus on the technical details for now not to create unnecessary back and forth communications.

@MelvinBot
Copy link

Reviewing label has been removed, please complete the "BugZero Checklist".

@MelvinBot
Copy link

The solution for this issue has been 🚀 deployed to production 🚀 in version 1.2.73-1 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:

If no regressions arise, payment will be issued on 2023-02-24. 🎊

After the hold period is over and BZ checklist items are completed, please complete any of the applicable payments for this issue, and check them off once done.

  • External issue reporter
  • Contributor that fixed the issue
  • Contributor+ that helped on the issue and/or PR

As a reminder, here are the bonuses/penalties that should be applied for any External issue:

  • Merged PR within 3 business days of assignment - 50% bonus
  • Merged PR more than 9 business days after assignment - 50% penalty

@MelvinBot
Copy link

BugZero Checklist: The PR fixing this issue has been merged! The following checklist (instructions) will need to be completed before the issue can be closed:

@mountiny
Copy link
Contributor

@parasharrajat @mananjadhav Would you be bale to handle the checklist points please? Thanks!

@mananjadhav
Copy link
Collaborator

I'll try to update the checklist by today/tomorrow

@MelvinBot
Copy link

📣 @mananjadhav! 📣

Hey, it seems we don’t have your contributor details yet! You'll only have to do this once, and this is how we'll hire you on Upwork.
Please follow these steps:

  1. Get the email address used to login to your Expensify account. If you don't already have an Expensify account, create one here. If you have multiple accounts (e.g. one for testing), please use your main account email.
  2. Get the link to your Upwork profile. It's necessary because we only pay via Upwork. You can access it by logging in, and then clicking on your name. It'll look like this. If you don't already have an account, sign up for one here.
  3. Copy the format below and paste it in a comment on this issue. Replace the placeholder text with your actual details.

Screen Shot 2022-11-16 at 4 42 54 PM

Format:

Contributor details
Your Expensify account email: <REPLACE EMAIL HERE>
Upwork Profile Link: <REPLACE LINK HERE>

@melvin-bot melvin-bot bot added Daily KSv2 and removed Weekly KSv2 labels Feb 23, 2023
@mananjadhav
Copy link
Collaborator

@mountiny @parasharrajat

Regression Test Proposal

  1. Open the app.
  2. Go to Settings page.
  3. Open the Payments Page
  4. Click on Add Payments Button -> Choose Paypal.me
  5. Check that input is focused by default on opening the page.
  6. Press Arrow icon from the top left, to go back.
  7. Notice that the Add Payments Button page doesn't flicker/jump.

Do we agree 👍 or 👎


Apart from that I tried to track the PR but I think this existed long before. @parasharrajat do you have any insights on which PR must've caused this regression?

@parasharrajat
Copy link
Member

No idea, my best guess is that it came with a React-navigation version upgrade.

@mountiny
Copy link
Contributor

looks good, I think we are fine without the PR

@mananjadhav
Copy link
Collaborator

@NicMendonca this is ready for payout today. Can you please help with that?

@melvin-bot melvin-bot bot added the Overdue label Feb 27, 2023
@mountiny
Copy link
Contributor

@NicMendonca Should be able to get to this today 🙌

@melvin-bot melvin-bot bot removed the Overdue label Feb 27, 2023
@mananjadhav
Copy link
Collaborator

@mountiny @NicMendonca Quick bump on this one.

@NicMendonca
Copy link
Contributor

I am so sorry @mananjadhav @parasharrajat can you please apply to the job/ accept my offer: https://www.upwork.com/jobs/~01d9d6800730a96ae0

@gadhiyamanan
Copy link
Contributor

@NicMendonca applied for reporting

@NicMendonca
Copy link
Contributor

@gadhiyamanan yep - I got yours!

@NicMendonca
Copy link
Contributor

@gadhiyamanan paid - thank you!

@gadhiyamanan
Copy link
Contributor

@NicMendonca please close the upwork contract 🙇‍♂️

@NicMendonca
Copy link
Contributor

@mananjadhav paid!

@NicMendonca NicMendonca changed the title [HOLD for payment 2023-02-24] [$1000] Add payment method button jumps when tapping back button on Paypal page [Pending - Rajat Payment] [$1000] Add payment method button jumps when tapping back button on Paypal page Mar 1, 2023
@NicMendonca
Copy link
Contributor

@parasharrajat I will check back here for your payment tomorrow because of this. Thanks!

@NicMendonca
Copy link
Contributor

Everyone had been paid 🎉 I am incredibly sorry again for the delay! Thank you!

@NicMendonca NicMendonca changed the title [Pending - Rajat Payment] [$1000] Add payment method button jumps when tapping back button on Paypal page [$1000] Add payment method button jumps when tapping back button on Paypal page Mar 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting Payment Auto-added when associated PR is deployed to production Bug Something is broken. Auto assigns a BugZero manager. Daily KSv2 External Added to denote the issue can be worked on by a contributor
Projects
None yet
Development

No branches or pull requests

9 participants