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.03k stars 2.54k forks source link

[HOLD setSelection refactor] [$2000] Android - Cursor is placed in wrong position after write/paste the emoji between the word Hello and nice - Reported by: @AndreasBBS #12854

Closed kbecciv closed 8 months ago

kbecciv 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!


Issue found when executing PR https://github.com/Expensify/App/pull/12632

Action Performed:

  1. Launch the app
  2. Log in with any account
  3. Go to any chat
  4. Start with a string Hello nice to meet you
  5. Write the emoji :wave: in the string Hello nice to meet you between the word Hello and nice
  6. Start with a string Hello nice to meet you
  7. Paste the string :wave: friend in the string Hello nice to meet you between the word Hello and nice

Expected Result:

Describe what you think should've happened

Actual Result:

The resulting string has the emoji converted and the cursor is placed after the word friend/ or after the emoji

Workaround:

Unknown

Platform:

Where is this issue occurring?

Version Number: 1.2.29.2

Reproducible in staging?: Yes

Reproducible in production?: No

Email or phone of affected tester (no customers):

Logs: https://stackoverflow.com/c/expensify/questions/4856

Notes/Photos/Videos: Any additional supporting documentation

https://user-images.githubusercontent.com/93399543/202586022-096c2294-9027-4a31-baf7-d96fc7c5dbec.mp4

Expensify/Expensify Issue URL:

Issue reported by: Applause - Internal Team

Slack conversation:

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~0134ac93ef23b19fbf
  • Upwork Job ID: 1594665437635485696
  • Last Price Increase: 2022-12-16
MariaHCD commented 1 year ago

I'm currently reviewing the proposal! I'll update here shortly.

dylanexpensify commented 1 year ago

@MariaHCD can we get an update today? 🙇‍♂️

MariaHCD commented 1 year ago

@mollfpr @s77rt We aren't accepting platform-specific workarounds for this issue. Our App philosophy (item 5.ii) specifically mentions:

If the reason you can't write cross-platform code is because there is a bug in ReactNative that is preventing it from working, the correct action is to fix RN and submit a PR upstream -- not to hack around RN bugs with platform-specific code paths.

The best way would be to submit a fix to RN.

melvin-bot[bot] commented 1 year ago

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

mollfpr commented 1 year ago

Still waiting for a proposal!

dylanexpensify commented 1 year ago

to confirm @mollfpr we have no pending proposals, correct?

mollfpr commented 1 year ago

@dylanexpensify Yup, we don't.

dylanexpensify commented 1 year ago

Great, given it's been some time I'm going to double then

melvin-bot[bot] commented 1 year ago

⚠️ Could not update price automatically because there is no linked Upwork Job ID. The BZ team member will need to update the price manually in Upwork.

dylanexpensify commented 1 year ago

doubled - https://expensify.slack.com/archives/C01GTK53T8Q/p1670527150372249

s77rt commented 1 year ago

I basically provided a solution. Do I need to fix this on react-native in order to actually get my proposal selected? I mean anyone can fix the issue on react-native and copy paste my proposal

mollfpr commented 1 year ago

@s77rt Which proposal do you refer to as the fix in the RN upstream?

We can accept your proposal but it's before that we need to fix this RN issue to make your proposal work both iOS and Android.

s77rt commented 1 year ago

@mollfpr I meant a solution to this issue not RN's issue. What I'm asking is what if another person fixed the RN's issue and copy pasted my proposal above

Does he get all the credit? Or is that a situation where we split the compensation?

mollfpr commented 1 year ago

@s77rt Good question!

@MariaHCD how do we handle this kind of situation?

s77rt commented 1 year ago

I took a look into this and I can say that root cause is not in react-native but in iOS it self. iOS fires textViewDidChangeSelection then textViewDidChange

Meaning, even a solution at react-native level would have to be a hacky solution

s77rt commented 1 year ago

Quick update!

I have found that react team actually did fix this on react fabric

But it's not fixed on react native, the fix is hacky as expected but since I'm just re-using their code and there is no other way around it to fix this, a PR may be accepted.

So here is the fix:

diff --git a/RCTBackedTextInputDelegateAdapter.m b/RCTBackedTextInputDelegateAdapter2.m
index c6c254c..ebbb4f6 100644
--- a/RCTBackedTextInputDelegateAdapter.m
+++ b/RCTBackedTextInputDelegateAdapter2.m
@@ -162,6 +162,8 @@ static void *TextFieldSelectionObservingContext = &TextFieldSelectionObservingCo

 @implementation RCTBackedTextViewDelegateAdapter {
   __weak UITextView<RCTBackedTextInputViewProtocol> *_backedTextInputView;
+  NSAttributedString *_lastStringStateWasUpdatedWith;
+  BOOL _ignoreNextTextInputCall;
   BOOL _textDidChangeIsComing;
   UITextRange *_previousSelectedTextRange;
 }
@@ -246,12 +248,21 @@ static void *TextFieldSelectionObservingContext = &TextFieldSelectionObservingCo

 - (void)textViewDidChange:(__unused UITextView *)textView
 {
+  if (_ignoreNextTextInputCall && [_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) {
+    _ignoreNextTextInputCall = NO;
+    return;
+  }
+  _lastStringStateWasUpdatedWith = _backedTextInputView.attributedText;
   _textDidChangeIsComing = NO;
   [_backedTextInputView.textInputDelegate textInputDidChange];
 }

 - (void)textViewDidChangeSelection:(__unused UITextView *)textView
 {
+  if (![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) {
+    [self textViewDidChange:_backedTextInputView];
+    _ignoreNextTextInputCall = YES;
+  }
   [self textViewProbablyDidChangeSelection];
 }

https://github.com/Expensify/react-native/blob/Expensify-0.70.4-alpha.2/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m

I have tested the code for the events and the order is now as expected onChangeText then onSelectionChange

s77rt commented 1 year ago

We have a PR https://github.com/facebook/react-native/pull/35603

MariaHCD commented 1 year ago

Nice, thanks for the update @s77rt!

What I'm asking is what if another person fixed the RN's issue and copy pasted my proposal above Does he get all the credit? Or is that a situation where we split the compensation?

Correct me if I'm wrong @dylanexpensify but I think in these cases we generally try to keep one contributor for both the RN issue and our App issue.

In terms of going forward, I'm thinking we should wait for perhaps 1 week for the RN PR (although it will likely take more than that). If there is no reviews and no progress, we can have the fix as part of our RN fork instead.

cc: @roryabraham @AndrewGable

mollfpr commented 1 year ago

@MariaHCD Just to clarify, we start to wait for the RN PR https://github.com/facebook/react-native/pull/35603 to move forward then test again the current proposal from @s77rt?

MariaHCD commented 1 year ago

@mollfpr I'm thinking we wait for perhaps a week for the RN PR https://github.com/facebook/react-native/pull/35603, if there is no progress there, then we will create the same PR on our fork of RN.

dylanexpensify commented 1 year ago

Great question @MariaHCD! I think we generally keep it to one contributor, but help me understand why there'd be two different cases (1 app 1 RN) if new dot is in RN?

s77rt commented 1 year ago

@dylanexpensify In this issue we are trying to fix two bugs:

  1. The main bug as in the title
  2. The RN's bug: inverted events order in iOS

If UserA fixed bug 1 then UserB fixed bug 2

It wouldn't be fair to give all the credit to UserB

s77rt commented 1 year ago

The RN PR has been merged

MariaHCD commented 1 year ago

Just an update @mollfpr @s77rt, we're working on getting our fork of RN updated so it includes @s77rt's fix: https://github.com/facebook/react-native/pull/35603

In the meantime, @s77rt can you clarify if your latest proposal to fix the App issue remains unchanged? If not, could you post an updated proposal?

s77rt commented 1 year ago

@MariaHCD We should go with my first proposal The latest proposal was introduced to fix the iOS issue by the use of platform specific logic which is now no longer needed.

The App code has changed a bit, but the proposal will be almost the same. Will post an updated proposal when the RN fork is updated.

MariaHCD commented 1 year ago

As an update, we're going to wait until the merged RN PR is included in a release before updating our fork. I'll keep an eye out for that release.

melvin-bot[bot] commented 1 year ago

Upwork job price has been updated to $2000

melvin-bot[bot] commented 1 year ago

📣 @s77rt You have been assigned to this job by @MariaHCD! Please apply to this job in Upwork and leave a comment on the Github issue letting us know when we can expect a PR to be ready for review 🧑‍💻 Keep in mind: Code of Conduct | Contributing 📖

s77rt commented 1 year ago

@MariaHCD Why I have been assigned early? Won't that effect the PR bonus?

MariaHCD commented 1 year ago

Why I have been assigned early?

Sorry for not clarifying. We want to mark this issue as no longer open for proposals from other contributors. Especially since you've already posted a proposal that needs a bit of tweaking once our RN fork is updated.

Won't that effect the PR bonus?

In this case, I think the PR bonus will still be applicable. It will just be based on the day when our RN fork is updated and your updated proposal is approved by both @mollfpr and myself. cc: @dylanexpensify

mollfpr commented 1 year ago

Sounds good to me 👍

dylanexpensify commented 1 year ago

Correct, PR bonus can still be applicable!

MariaHCD commented 1 year ago

Not overdue, still waiting for the RN PR to be included in a release.

dylanexpensify commented 1 year ago

Any updates on the RN PR being included?

mollfpr commented 1 year ago

I’m not familiar with the RN release process 😅

Maybe @s77rt knows?

s77rt commented 1 year ago

No idea either.

mollfpr commented 1 year ago

I think we should wait for the commit to get picked for the next release. Currently, I don't see the commit picked yet https://github.com/reactwg/react-native-releases/discussions/41.

trjExpensify commented 1 year ago

Yup! Updated the issue title to add clarity on what we're held on in the meantime. Let's make sure to keep checking back in for the release 👍

roryabraham commented 1 year ago

Posting here for visibility, but since we use a fork of React Native, we'll actually need to integrate the upstream change into our fork and then re-release the fork.

MariaHCD commented 1 year ago

Doesn't look like the RN PR has been picked for the latest release 0.71.0

https://reactnative.dev/contributing/release-faq#how-do-i-know-if-my-fixfeature-is-in-a-certain-release

If the commit is only present in main (i.e. has no tags), then the commit has yet to be picked up by a release (or it may have been included in a follow up cherry pick for a patch version). You can expect it to be included in the next release candidate that is cut once the designed features have all landed.

According to the docs, it may take one or two months for the change to make it into a stable React Native release.

https://reactnative.dev/contributing/release-faq#when-will-my-fix-make-it-into-a-release

s77rt commented 1 year ago

Maybe we can get it up merged quickly upon request https://github.com/reactwg/react-native-releases/discussions/41#discussioncomment-4548354

trjExpensify commented 1 year ago

^^ Nice! So it has been added, right?

mollfpr commented 1 year ago

Yes!

s77rt commented 1 year ago

Looks like RN 0.71.0 has been just released.

mollfpr commented 1 year ago

@s77rt Can you confirm that the change is there and update your proposal?

I see that the commit is in the tag, but I just to double-check it.

Screen Shot 2023-01-13 at 00 20 15
s77rt commented 1 year ago

@mollfpr Yes confirmed it's there. I will update my proposal once we update to the latest version so we can test reliability.

cc @MariaHCD

JmillsExpensify commented 1 year ago

The latest RN version is released right? If so, let's stick the daily label back on this issue.

MariaHCD commented 1 year ago

The next step would be to have our RN fork updated. Asked In Slack here.

MariaHCD commented 1 year ago

Looks like we're waiting on updating our RN fork: https://expensify.slack.com/archives/C07J32337/p1673977754037079?thread_ts=1671097765.803029&cid=C07J32337

cc: @tgolen

dylanexpensify commented 1 year ago

not overdue