Expensify / App

Welcome to New Expensify: a complete re-imagination of financial collaboration, centered around chat. Help us build the next generation of Expensify by sharing feedback and contributing to the code.
https://new.expensify.com
MIT License
3.51k stars 2.86k forks source link

[$2000] Toggle switch fails to toggle back when tapped again on preferences page #25880

Closed kavimuru closed 10 months ago

kavimuru commented 1 year ago

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. Open settings
  2. Open preferences
  3. tap on Toggle to ON/OFF

    Expected Result:

    Toggle switch should switch to ON/OFF when it is tapped again

Actual Result:

The toggle switch only works once and does not respond to subsequent taps

Workaround:

Can the user still use Expensify without this being fixed? Have you informed them of the workaround?

Platforms:

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

Version Number: needs reproduction Reproducible in staging?: needs reproduction Reproducible in production?: needs reproduction 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: Any additional supporting documentation

https://github.com/Expensify/App/assets/43996225/771bd7e9-d0ba-4312-ad36-10d25f37a9c8

Expensify/Expensify Issue URL: Issue reported by:@jo-ui Slack conversation: https://expensify.slack.com/archives/C049HHMV9SM/p1692040308927449

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~01d30a31388a44c81c
  • Upwork Job ID: 1696550383851593728
  • Last Price Increase: 2023-12-19
melvin-bot[bot] commented 1 year ago

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

melvin-bot[bot] commented 1 year ago

Bug0 Triage Checklist (Main S/O)

strepanier03 commented 1 year ago

We don't have this Samsung phone type in Browserstack so I'm stuck on repro'ing. I raised this for discussion internally on a plan to move forward.

jo-ui commented 1 year ago

@strepanier03 It does not have to be the same phone just try it on android 12

jo-ui commented 1 year ago

@strepanier03 it is also reproducible on other android versions

strepanier03 commented 1 year ago

Aaah, yeah I just realized I'm updated to Android 13 and so are our browserstack models. I am clarifying best practice and will move it forward then.

strepanier03 commented 1 year ago

Ongoing discussion, I'll update as soon as I have consensus.

strepanier03 commented 1 year ago

Since 68% of Android users are on Android 12 or lower, we want to fix this. Moving forward!

melvin-bot[bot] commented 1 year ago

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

melvin-bot[bot] commented 1 year ago

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

melvin-bot[bot] commented 1 year ago

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

strepanier03 commented 1 year ago

Waiting for proposals Melvin.

melvin-bot[bot] commented 1 year ago

@strepanier03, @thesahindia Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!

melvin-bot[bot] commented 1 year ago

📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸

ShogunFire commented 1 year ago

Proposal

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

The switches on preferences page are only working once

What is the root cause of that problem?

In Switch component we are using PressableWithFeedback, in the onPress method of PressableWithFeedback here: https://github.com/Expensify/App/blob/d447b95f71d4ce2c2400a913e8886f817c8add68/src/components/Pressable/PressableWithFeedback.js#L76

We use the singleExecution hook which goal is to guarantee that we don't run the method twice if we press twice before the first method run hasn't finished.

In this hook here: https://github.com/Expensify/App/blob/d447b95f71d4ce2c2400a913e8886f817c8add68/src/hooks/useSingleExecution.js#L26-L34 We set isExecuting to false in the callback of InteractionManager.runAfterInteractions

The root cause is that in our case runAfterInteractions never fire the callback so isExecuting stays at true and onPress method is never called again.

The reason runAfterInteractions doesn't fire is because there is a lottie animation on the page and there is an issue here https://github.com/airbnb/lottie-web/issues/3002 where the lottie animation prevents requestIdleCallback from firing, requestIdleCallback is used in runAfterInteractions for react-native-web here: https://github.com/necolas/react-native-web/blob/a3ea2a0a4fd346a1b32e6cef527878c8e433eef8/packages/react-native-web/src/exports/InteractionManager/index.js#L100-L108

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

One way is to fix Lottie so that requestIdleCallback is called, requestIdleCallback is not called because the animation constantly call requestAnimationFrame here: https://github.com/airbnb/lottie-web/blob/63a39aeb27b8c13726ce9fcf850d9351b14be3e6/player/js/animation/AnimationManager.js#L108

We could wait before requesting the frame for example like this:

setTimeout(function(){
    window.requestAnimationFrame(resume);
}, 42);

I think the best way would be to do this waiting only once in a while (for example every 100 times the method is called ) and only if the animation is a loop.

It works well.

What alternative solutions did you explore? (Optional)

We could use setDeadline of InteractionManager because using it allow to avoid using requestIdleCallback

The recommended way to use requestIdleCallback is to pass a parameter timeout to be sure that the callback will be called at some point, currently in react-native-web they don't use the timeout parameter

ShogunFire commented 1 year ago

It's hard to have a specific solution has long as we don't know in which cases runAfterInteractions was used, I will try to find the reason.

PS: I am almost sure that I was able to reproduce on windows chrome at some point during my tests but now I can't reproduce

strepanier03 commented 1 year ago

Thanks @ShogunFire. I'll let @thesahindia weigh in as the more knowledgeable person about the code here and continue following along.

thesahindia commented 1 year ago

I wasn't able to repro it locally. Trying to get my hands on a real android device.

ShogunFire commented 1 year ago

I don't think that depends on the android version I was reproducing on android 13 on emulator, maybe since this is on web that has to do with chrome version ?

melvin-bot[bot] commented 1 year ago

@strepanier03, @thesahindia Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!

melvin-bot[bot] commented 1 year ago

📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸

strepanier03 commented 1 year ago

@thesahindia, how's it going with reproing?

mvtglobally commented 1 year ago

Issue not reproducible during KI retests. (First week)

melvin-bot[bot] commented 1 year ago

@strepanier03 @thesahindia this issue is now 3 weeks old. There is one more week left before this issue breaks WAQ and will need to go internal. What needs to happen to get a PR in review this week? Please create a thread in #expensify-open-source to discuss. Thanks!

ShogunFire commented 1 year ago

I still reproduce consistently on latest main on mweb , I am not sure how I can help you reproduce :/

strepanier03 commented 1 year ago

@ShogunFire - What is your Chrome version? I have never been able to repro this and it looks like KI testing couldn't either.

ShogunFire commented 1 year ago

@strepanier03 image

jo-ui commented 1 year ago

@strepanier03 here is another chrome version that this issue is reproducibleScreenshot_20230916-074749_Chrome.jpg

strepanier03 commented 1 year ago

Thank you @ShogunFire - I'll try to test again and update shortly.

strepanier03 commented 1 year ago

I am on Chrome version: 116.0.5845.173 and wasn't able to repro still.

There wasn't a more up-to-date version of Chrome to download so I am still unable to repro and at a loss of how to help someone else repro.

melvin-bot[bot] commented 1 year ago

📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸

ShogunFire commented 1 year ago

Maybe it has nothing to do with chrome version then :( InteractionManager.runAfterInteractions is not called in some cases but not sure what are the conditions

ShogunFire commented 1 year ago

Ok so I have more informations about why it is happening:

Here we had a kind of similar issue https://github.com/Expensify/App/issues/23052 , the root cause is well explained in the PR: https://github.com/Expensify/App/pull/23145

So basically InteractionManager.runAfterInteractions is sometimes not called when there is a lottie animation going on. The PR back then aimed to destroy the animation on unmount and that made InteractionManager.runAfterInteractions be called and was solving their issue, but for us we are not unmounting since we are still on preferences page. Here is the issue on lottie repo: https://github.com/airbnb/lottie-web/issues/3002

I still don't know why it is only happening to some of us, it could actually be a perfomance issue because requestIdleCallback that is used under the hood by runAfterInteractions is waiting for the thread to have some idle moment to make the callback, maybe if the device has better performance it will be able to do things faster and have some idle moment

@roryabraham since you worked on this

ShogunFire commented 1 year ago

A quick workaround would be to add a timeout if the runAfterInteractions is never called but that's probably not the best way: https://github.com/facebook/react-native/issues/8624#issuecomment-231040370

There is also a method setDeadline that we could use that could help I think because when the deadline is superior to 0 InteractionManager uses timeout instead of requestIdleCallback: https://github.com/necolas/react-native-web/blob/a3ea2a0a4fd346a1b32e6cef527878c8e433eef8/packages/react-native-web/src/exports/InteractionManager/index.js#L100-L108 And it's a better idea because from what I understand this timeout would only trigger the test "do we still have interactions ?" and not the callback

roryabraham commented 1 year ago

Oh, very interesting. Good investigation @ShogunFire. InteractionManager.setDeadline seems like a good solution for the delay in disabling/re-enabling inputs after a timeout. Such as we need to do for PressableWithDelayToggle

melvin-bot[bot] commented 1 year ago

@strepanier03 @thesahindia this issue is now 4 weeks old and preventing us from maintaining WAQ, can you:

Thanks!

melvin-bot[bot] commented 1 year ago

Current assignee @thesahindia is eligible for the Internal assigner, not assigning anyone new.

strepanier03 commented 1 year ago

I'm switching this back to External because it looks like we're making progress in the right direction.

melvin-bot[bot] commented 1 year ago

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

melvin-bot[bot] commented 1 year ago

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

strepanier03 commented 1 year ago

If we should do something else, ping me and I'll take care of it.

melvin-bot[bot] commented 1 year ago

@strepanier03, @thesahindia Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!

roryabraham commented 1 year ago

It seems like this issue is kind of in limbo. @ShogunFire do you want to use our proposal template to propose a solution for this issue?

melvin-bot[bot] commented 1 year ago

Upwork job price has been updated to $2000

shubham1206agra commented 1 year ago

@roryabraham If this is low priority, and if @ShogunFire RCA is correct, can we wait for https://github.com/Expensify/App/issues/28132?

melvin-bot[bot] commented 1 year ago

@strepanier03, @thesahindia Huh... This is 4 days overdue. Who can take care of this?

strepanier03 commented 1 year ago

Friendly bump @roryabraham for this but mostly to get this out of overdue because I don't think it needs to be marked that way right now.

ShogunFire commented 1 year ago

@strepanier03 I think the C+ was @thesahindia, I just tagged @roryabraham because he worked on something related.

I updated my proposal with the new informations and some possible solutions but I haven't been able to test yet. I wanted to try with setDeadline but we don't have this method yet in our repo and when I link the package to the upstream repo there is some errors. What is the process to update our repo ?

I will try to make a more specific proposal because I don't think waiting for lottie update will solve it

mvtglobally commented 1 year ago

Issue not reproducible during KI retests. (First week)

strepanier03 commented 1 year ago

I wanted to try with setDeadline but we don't have this method yet in our repo and when I link the package to the upstream repo there is some errors. What is the process to update our repo ?

@ShogunFire - I'm not sure the answer for this one, you'll want to reach out in Slack to raise this question. Sorry I don't have the info that would help here.