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

Allow user to modify IOU amount with on-screen keyboard #10147

Merged
merged 27 commits into from
Aug 29, 2022

Conversation

eVoloshchak
Copy link
Contributor

@eVoloshchak eVoloshchak commented Jul 28, 2022

Details

This PR allows user to modify IOU amount by moving cursor, selecting any part of the number, pasting any valid number into input.

Fixed Issues

$ #6154

Tests

  1. Click FAB > Request Money
  2. Enter an amount
  3. Try moving the cursor and modifying amount,validate that it is updated accordingly, not just the last symbol
  4. Select some part of the text, use on-screen keyboard to update the amount, validate that it is updated accordingly

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

The Contributor+ will copy/paste it into a new comment and complete it after the author checklist is completed

  • 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.

QA Steps

  1. Click FAB > Request Money
  2. Enter an amount
  3. Move cursor to the middle of the amount
    4.1. Enter a symbol
    4.2. Delete a symbol
    4.3. Paste a couple of symbols
    4.4. Cut a couple of symbols
    4.5. Press and hold < key on the on-screen keyboard
  4. Validate that symbols are added/deleted according to cursor's postition, not just the last symbol is changed
  5. Select portion of the text, use on-screen keyboard to update the amount, validate that it is updated accordingly
  6. Test all TextInputs on storybook

Screenshots

Web

cinnamon-20220728-4.mp4

Note: since there were no changes to the updateAmount method, behavior on Web is unchanged

Mobile Web

video_2022-07-28_10-01-40.mp4

Desktop

I'm unable to launch the desktop app due to #8888. It is not present if you downgrade to certain node and npm versions, but since I use MacinCloud, I'm unable to do so. But since there were no changes to the updateAmount method, behavior on Desktop is unchanged.

iOS

cinnamon-20220728-1.1.mp4

Note: I'm unable to paste in iOS simulator due to this bug

Android

22-07-28-10-29-19.mp4

Note:

@eVoloshchak eVoloshchak requested a review from a team as a code owner July 28, 2022 07:36
@melvin-bot
Copy link

melvin-bot bot commented Jul 28, 2022

Hey! I see that you made changes to our Form component. Make sure to update the docs in FORMS.md accordingly. Cheers!

@melvin-bot melvin-bot bot requested review from chiragsalian and rushatgabhane and removed request for a team July 28, 2022 07:36
@rushatgabhane
Copy link
Member

@eVoloshchak can you please spend some time writing test steps for QA? So that we can discover all possible bugs

@eVoloshchak
Copy link
Contributor Author

@eVoloshchak can you please spend some time writing test steps for QA? So that we can discover all possible bugs

Updated QA steps

@@ -59,6 +59,7 @@ class IOUAmountPage extends React.Component {

this.state = {
amount: props.selectedAmount,
selection: {start: 0, end: 0},
Copy link
Member

@rushatgabhane rushatgabhane Jul 29, 2022

Choose a reason for hiding this comment

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

nab

Suggested change
selection: {start: 0, end: 0},
selection: {
start: 0,
end: 0,
},

@@ -134,19 +135,32 @@ class IOUAmountPage extends React.Component {
* @param {String} key
*/
updateAmountNumberPad(key) {
// Returns the new selection object based on updated amount
const getNewSelection = (oldSelection, oldAmount, newAmount) => {
Copy link
Member

Choose a reason for hiding this comment

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

can you please make this a class method instead?

@@ -274,6 +273,7 @@ class BaseTextInput extends Component {
onPressOut={this.props.onPress}
showSoftInputOnFocus={!this.props.disableKeyboard}
keyboardType={getSecureEntryKeyboardType(this.props.keyboardType, this.props.secureTextEntry, this.state.passwordHidden)}
value={this.props.value}
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, @eVoloshchak did you test on the production build for Android?

My cursor is in the middle and holding backspace deletes all the numbers

screen-20220731-154846.mp4

Copy link
Contributor Author

@eVoloshchak eVoloshchak Jul 31, 2022

Choose a reason for hiding this comment

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

Hmm, @eVoloshchak did you test on the production build for Android?

Weird, I remember this behavior being present only on DEV. And it seemed to be the same for 7433. But now i'm getting this bug with about 60% chance.
This is happening because when user holds <, updateAmountNumberPad is called every 100 ms. But due to some kind of event bundling issue (maybe related to setState being async?), textinput's onSelectionChange method is called with selection object being incorrect, probably due to poor performance, since it intencifies in DEV mode. Since we're controlling selection manually in updateAmountNumberPad method, we don't need the selection data from onSelectionChange when user is holding the < button (or using any key of onscreen keyboard)

  1. We can add a local variable in IOUAmountPage
this.shouldUpdateSelection = true;
  1. Add a new method to BigNumberPad, which will be called when user starts and stops long pressing
    handleLongPress(key) {
        // Only handles deleting.
        if (key !== '<') {
            return;
        }
+       this.props.longPressHandlerStateChanged(true);
        const timer = setInterval(() => {
            this.props.numberPressed(key);
        }, 100);
        this.setState({timer});
    }
  onPressOut={() => {
      clearInterval(this.state.timer);
      ControlSelection.unblock();
+     this.props.longPressHandlerStateChanged(false);
  }}
  1. And then on IOUAmountPage we can ignore onSelectionChange if user is long pressing
  <BigNumberPad
      numberPressed={this.updateAmountNumberPad}
+     longPressHandlerStateChanged={state => this.shouldUpdateSelection = !state}
  />
  onSelectionChange={(e) => {
+    if (!this.shouldUpdateSelection) {
+        return;
+    }
      this.setState({selection: e.nativeEvent.selection});
  }}
22-07-31-15-24-23.mp4

@@ -274,6 +273,7 @@ class BaseTextInput extends Component {
onPressOut={this.props.onPress}
showSoftInputOnFocus={!this.props.disableKeyboard}
keyboardType={getSecureEntryKeyboardType(this.props.keyboardType, this.props.secureTextEntry, this.state.passwordHidden)}
value={this.props.value}
Copy link
Member

Choose a reason for hiding this comment

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

Also, use of both state.value and props.value in this component is confusing.

Can we use state.value in all the possible places?

@eVoloshchak
Copy link
Contributor Author

Updated PR with all the suggested changes and a fix for issue with holding < buton

@rushatgabhane
Copy link
Member

rushatgabhane commented Aug 1, 2022

Still reviewing, just got hands on a physical iPhone because pasting didn't seem to work on my simulator

Copy link
Member

@rushatgabhane rushatgabhane left a comment

Choose a reason for hiding this comment

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

@eVoloshchak bug - cursor isn't at end when going back to amount page.

  1. Request / split amount
  2. Enter any amount and go next
  3. Go back

Expected: cursor is at end of amount
Actual : cursor is at start of amount

Screen.Recording.2022-08-02.at.9.35.35.AM.mov

@eVoloshchak
Copy link
Contributor Author

@eVoloshchak bug - cursor isn't at end when going back to amount page.

Good catch, thank you.
This happens because in IOUAmountPage's constructor i set selection like this

  selection: {
      start: 0,
      end: 0,
  },

But it should depend on the selectedAmount length

  selection: {
      start: props.selectedAmount.length,
      end: props.selectedAmount.length,
  },

Updated the PR

@eVoloshchak
Copy link
Contributor Author

eVoloshchak commented Aug 2, 2022

Also found a console error
Screenshot from 2022-08-02 07-33-02
Since our BaseTextInput is now controlled and has value prop, defaultValue is not needed.
Also updated the PR

@eVoloshchak
Copy link
Contributor Author

All done

Copy link
Member

@rushatgabhane rushatgabhane left a comment

Choose a reason for hiding this comment

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

@eVoloshchak thanks for your patience on this one.

@chiragsalian LGTM! 🎉🎉

We still have this bug which is less noticeable on release builds.
And there is no way around it at the moment because we're using controlled text and selection.

We have a gut feeling (no evidence) that enabling RN's fabric architecture should help with it.

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.
  • I have checked off every checkbox in the PR author checklist, including those that don't apply to this PR.

@eVoloshchak
Copy link
Contributor Author

@eVoloshchak thanks for your patience on this one.

I think you needed even more patience, so thank you too :)

@chiragsalian
Copy link
Contributor

Sorry for the delay. I totally missed reviewing this. Reviewing now.

Copy link
Contributor

@chiragsalian chiragsalian left a comment

Choose a reason for hiding this comment

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

Is it just me. I feel like something weird is happening here when i'm testing it. In normal testing this works fine. But if i use a keyboard to type the numbers fast on ios the focus is really weird.
For example, i'm typing 12121212 fast on my keyboard but the numbers show up as 22211211, and the input focus is on the wrong spot.

Screen.Recording.2022-08-29.at.12.55.30.PM.mov

P.S i pulled main into your branch to test to make sure its got the latest code. I found the issue only on your branch and when i tested on main there was no issue.

@rushatgabhane
Copy link
Member

rushatgabhane commented Aug 29, 2022

@chiragsalian no it's not just you, it is an expected bug that I mentioned in my PR approval #10147 (review)

This is because of controlled nature of selection prop. We aren't using setNativeProps because it'll be deprecated when we move to Fabric architecture.

It is less noticeable on release builds.
npx react-native run-ios --configuration Release

We are assuming that this issue might be resolved when we enable Fabric architecture as it'll supposedly boost performance by getting rid of JS bridge bottleneck

@chiragsalian
Copy link
Contributor

Oh wow, i totally forgot to click into your comment to see the details of the bug. Cool, thank you for capturing. Code LGTM.

@chiragsalian chiragsalian merged commit ca481ed into Expensify:main Aug 29, 2022
@rushatgabhane
Copy link
Member

No worries :)

@OSBotify
Copy link
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@OSBotify
Copy link
Contributor

🚀 Deployed to staging by @chiragsalian in version: 1.1.94-0 🚀

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

@parasharrajat
Copy link
Member

A big change was done on this PR and QA tests do not justify those changes. Was this discussed anywhere before the PR was created?

TextInput was migrated to controlled from uncontrolled. Did we take consenses before applying these changes? Could you please share the link for the discussion, I have another issue so it is good to check out?
cc: @rushatgabhane

@rushatgabhane
Copy link
Member

rushatgabhane commented Aug 31, 2022

TextInput was migrated to controlled from uncontrolled

Thanks for raising this!

Here is what @chiragsalian and I felt was a good way to move forward. #6154 (comment)

TextInput was migrated to controlled because setNativeProps will not be supported when we move to Fabric in PR #8503 (comment)
It didn't make much sense to go uncontrolled, when we know that we'll have to shift everything to controlled very soon..

I also made an announcement for it on slack - https://expensify.slack.com/archives/C01GTK53T8Q/p1656632630394839?thread_ts=1654878284.799759&cid=C01GTK53T8Q

@rushatgabhane
Copy link
Member

I verified text inputs on storybook, and a few pages on newDot.

@eVoloshchak can you please add a QA step to test all TextInputs on storybook as well?

@parasharrajat
Copy link
Member

Thanks for the details.

@s77rt
Copy link
Contributor

s77rt commented Apr 19, 2023

This PR caused a problem (not a regression) here #16385. The bug is that we are returning prev state here that includes the selection object in an attempt to revert the selection. However, on RNW using the same selection object will not trigger the setSelection method. So the selection won't be revered as intended. What we should have done instead is to return a shallow copy of selection.

@rushatgabhane
Copy link
Member

rushatgabhane commented Apr 19, 2023

@s77rt thanks! that's a good learning

return {amount: prevState.amount, selection: {...prevState.selection}};

but isn't this a deep copy?? sorry if it's a noob question

@s77rt
Copy link
Contributor

s77rt commented Apr 19, 2023

@rushatgabhane That's a shallow copy.

Shallow copy:

objA = {x: 1, nes: {y: 2}};
objB = {...objA};

objB is a shallow copy of objA, meaning that the props of objB are independent of objA as long as they (the props) are not objects (bcz objects are referenced by address).

Changing prop x of objA have no effect on objB

objA.x = 100;
100
objB.x;
1

But changing prop nes of objA have an effect on objB:

objA.nes.y = 200;
200
objB.nes.y;
200

Deep copy:

objA = {x: 1, nes: {y: 2}};
objB = _.cloneDeep(objA);

objB is a deep copy of objA, meaning that the props of objB are truly independent of objA.

Changing prop x of objA have no effect on objB

objA.x = 100;
100
objB.x;
1

And also changing prop nes of objA have no effect on objB

objA.nes.y = 200;
200
objB.nes.y;
2

In our case selection only have two simple props start and end that are not objects so both shallow and deep copy will produce the same results. But I think it's less confusing to refer to that as shallow copy.

@rushatgabhane
Copy link
Member

ohhh thanks for such a detailed explanation

@@ -30,6 +30,7 @@ class BaseTextInput extends Component {
passwordHidden: props.secureTextEntry,
textInputWidth: 0,
prefixWidth: 0,
selection: props.selection,
Copy link
Contributor

Choose a reason for hiding this comment

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

@eVoloshchak sorry I know it has been a long time, but what is the purpose of copying the props.selection to an internal state instead of just using it directly the props like selection={this.props.selection} here:

https://github.com/eVoloshchak/App/blob/d072ac100ae93cd4c6a1665777451caa72550853/src/components/TextInput/BaseTextInput.js#L277

Copy link
Contributor

Choose a reason for hiding this comment

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

Check #10147 (comment) So apparently we used state to delay the selection by one cycle to fix a bug in iOS Safari.

We have this PR #16825 that fixed a similar bug on Web. So maybe the original bug is fixed now and we can pass the prop directly.

Curious though, what are you doing 😁 @aldo-expensify

Copy link
Contributor

Choose a reason for hiding this comment

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

Check #10147 (comment) So apparently we used state to delay the selection by one cycle to fix a bug in iOS Safari.

Thanks for the explanation :). I think I would have been good to leave a comment so we don't just remove it in the future.

Curious though, what are you doing 😁 @aldo-expensify

Just reviewing this PR: https://github.com/Expensify/App/pull/18579/files and I got curious about that.

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

Successfully merging this pull request may close these issues.

7 participants