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

[$250] Exit survey response auto-validates without any user action. #50962

Open
6 of 8 tasks
m-natarajan opened this issue Oct 16, 2024 · 25 comments
Open
6 of 8 tasks

[$250] Exit survey response auto-validates without any user action. #50962

m-natarajan opened this issue Oct 16, 2024 · 25 comments
Assignees
Labels
Bug Something is broken. Auto assigns a BugZero manager. External Added to denote the issue can be worked on by a contributor Reviewing Has a PR in review Weekly KSv2

Comments

@m-natarajan
Copy link

m-natarajan commented Oct 16, 2024

If you haven’t already, check out our contributing guidelines for onboarding and email [email protected] to request to join our Slack channel!


Version Number: 9.0.49-0
Reproducible in staging?: yes
Reproducible in production?: yes
If this was caught on HybridApp, is this reproducible on New Expensify Standalone?:
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
Expensify/Expensify Issue URL:
Issue reported by: @suneox
Slack conversation: https://expensify.slack.com/archives/C049HHMV9SM/p1729102027380939

Action Performed:

  1. Go to settings.
  2. Switch to Expensify Classic.
  3. Select a reason and click Next.

Expected Result:

On the survey response page, errors should not be shown until the user clicks “Next” or focuses out of the survey response input.

Actual Result:

Upon navigating to the survey response page, the form validates automatically without any user action.

Workaround:

unknown

Platforms:

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

  • Android: Standalone
  • Android: HybridApp
  • Android: mWeb Chrome
  • iOS: Standalone
  • iOS: HybridApp
  • iOS: mWeb Safari
  • MacOS: Chrome / Safari
  • MacOS: Desktop

Screenshots/Videos

https://github.com/user-attachments/assets/106a82ee-3f8e-4ab9-9de5-0f64ead0e383
Snip - (53) New Expensify - Google Chrome (2)

Screen.Recording.2024-10-17.at.00.53.18.mp4
Add any screenshot/video evidence

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~021846936289595366564
  • Upwork Job ID: 1846936289595366564
  • Last Price Increase: 2024-10-17
  • Automatic offers:
    • suneox | Reviewer | 104592534
Issue OwnerCurrent Issue Owner: @
Issue OwnerCurrent Issue Owner: @neil-marcellini
@m-natarajan m-natarajan added Daily KSv2 Bug Something is broken. Auto assigns a BugZero manager. labels Oct 16, 2024
Copy link

melvin-bot bot commented Oct 16, 2024

Triggered auto assignment to @bfitzexpensify (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details. Please add this bug to a GH project, as outlined in the SO.

@abzokhattab
Copy link
Contributor

abzokhattab commented Oct 16, 2024

Edited by proposal-police: This proposal was edited at 2024-10-16 21:57:00 UTC.

Proposal

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

Exit survey response auto-validates on blur even though the input is empty

What is the root cause of that problem?

the form auto validates because of the shouldValidateOnBlur here

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

we should disable it shouldValidateOnBlur={false} as we are doing with other similar forms (ex)

optionally we can remove the shouldValidateOnChange since the default value is already true

What alternative solutions did you explore? (Optional)

@suneox
Copy link
Contributor

suneox commented Oct 17, 2024

@bfitzexpensify I’ve reported this issue and have more context on it, so I can assist with reviewing the proposal as a C+.

@truph01
Copy link
Contributor

truph01 commented Oct 17, 2024

@suneox Can you reproduce the issue in MacOS: Chrome / Safari?

@suneox
Copy link
Contributor

suneox commented Oct 17, 2024

Can you reproduce the issue in MacOS: Chrome / Safari?

This issue can only be reproduced on MacOS/Safari, iOS/Safari and does not occur on MacOS/Chrome, Android/Chrome

Screen.Recording.2024-10-17.at.01.01.50.mp4

@bernhardoj
Copy link
Contributor

Proposal

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

The exit survey input field shows validation error when open the page.

What is the root cause of that problem?

On the page, we have a text input and a ref which calls updateMultilineInputRange.

ref={(el: AnimatedTextInputRef) => {
if (!el) {
return;
}
if (!inputRef.current) {
updateMultilineInputRange(el);
}
inputCallbackRef(el);
}}

In updateMultilineInputRange, we do 2 things, setting the selection to the last character and scroll the input to the last line.

if ('value' in input && typeof input.value === 'string' && input.setSelectionRange) {
const length = input.value.length;
if (shouldAutoFocus) {
(input as HTMLInputElement).setSelectionRange(length, length);
}
// eslint-disable-next-line no-param-reassign
input.scrollTop = input.scrollHeight;
}

On safari, setting the selection will focus on the input. There is a comment about that but was removed here.

Because we focus the input too early, the input gets blurred which I think is already a known issue which is why we delay an input focus. This is similar to iOS. updateMultilineInputRange has a file for iOS only which immediately focus on the input.

if (shouldAutoFocus) {
input.focus();
}

So, this issue happens on iOS native too.

Note that the updateMultilineInputRange index.ts file checks for setSelectionRange and value which only exists on web, so basically updateMultilineInputRange is only made for web.

if ('value' in input && typeof input.value === 'string' && input.setSelectionRange) {

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

As mentioned before, updateMultilineInputRange does 2 things, setting the selection to the last character and scroll the input to the last line. We need to scroll the input to the last line immediately when mounted, but we need to delay setting the selection. The delay is happening inside useAutoFocusInput, so the solution is to duplicate the updateMultilineInputRange logic to useAutoFocusInput.

  1. Accept a new param called shouldUpdateMultilineInputRange for useAutoFocusInput.
  2. When the input callback ref is called, scroll the textinput
    const inputCallbackRef = (ref: TextInput | null) => {
    inputRef.current = ref;
    if (isInputInitialized) {
    return;
    }
    setIsInputInitialized(true);
    };
if (shouldUpdateMultilineInputRange && ref && 'scrollTop' in ref) {
    ref.scrollTop = ref.scrollHeight;
}
  1. When it's time to focus, set the selection
    const focusTaskHandle = InteractionManager.runAfterInteractions(() => {
    inputRef.current?.focus();
    setIsScreenTransitionEnded(false);
    });
if (shouldUpdateMultilineInputRange && inputRef.current && 'setSelectionRange' in inputRef.current) {
    const length = inputRef.current.value.length;
    (inputRef.current as HTMLInputElement).setSelectionRange(length, length);
}
  1. Change all the ref type to AnimatedTextInputRef to fix the typing.
  2. Pass true to useAutoFocusInput.
    const {inputCallbackRef, inputRef} = useAutoFocusInput();
  3. Remove updateMultilineInputRange here
    ref={(el: AnimatedTextInputRef) => {
    if (!el) {
    return;
    }
    if (!inputRef.current) {
    updateMultilineInputRange(el);
    }
    inputCallbackRef(el);
    }}

For step 2 & 3, we can optionally create a platform-specific file for that to make it cleaner.

@truph01
Copy link
Contributor

truph01 commented Oct 17, 2024

Proposal

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

Upon navigating to the survey response page, the form validates automatically without any user action.

What is the root cause of that problem?

  • In Safari, calling the setSelectionRange function:
    updateMultilineInputRange(el);

    always causes the input to focus. This is standard behavior in Safari. If we attempt to set focus earlier, the input blurs, triggering validation logic tied to the onBlur event.

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

  • We need to make sure, we only call the updateMultilineInputRange if the input is focused.

  • So we can remove:

if (!inputRef.current) {
updateMultilineInputRange(el);
}

then add:

                            onFocus={(el) => {
                                if (hasSetRangeRef.current) {
                                    return;
                                }
                                hasSetRangeRef.current = true;
                                updateMultilineInputRange(inputRef.current);
                            }}

to this. hasSetRangeRef is a ref flag to make sure we only call the set selection range one time.

What alternative solutions did you explore? (Optional)

@bfitzexpensify bfitzexpensify added the External Added to denote the issue can be worked on by a contributor label Oct 17, 2024
@melvin-bot melvin-bot bot changed the title Exit survey response auto-validates without any user action. [$250] Exit survey response auto-validates without any user action. Oct 17, 2024
Copy link

melvin-bot bot commented Oct 17, 2024

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

@melvin-bot melvin-bot bot added the Help Wanted Apply this label when an issue is open to proposals by contributors label Oct 17, 2024
Copy link

melvin-bot bot commented Oct 17, 2024

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

@bfitzexpensify
Copy link
Contributor

Cool, assigned you @suneox

@fasileds
Copy link

The error seems to come from how the form validation is configured. Instead of running the validation when the screen opens, we should trigger it only when the "Next" button is clicked. One way to fix this is by using a form validation library like Zod or Yup, and tying the validation logic to the button's onPress event. This way, the validation will only run when the user interacts with the form.

Another option is to manage the error state manually, where we keep error messages in the component’s state and trigger validation only on button click. We could also consider moving all the error handling logic into a separate file to keep the code cleaner and more manageable.

Copy link

melvin-bot bot commented Oct 17, 2024

📣 @fasileds! 📣
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. Make sure you've read and understood the contributing guidelines.
  2. 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.
  3. 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.
  4. 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>

@fasileds
Copy link

@fasileds
Copy link

and if it is only for specific device tell me the device names and i will shear you my thoughts 10Q

@suneox
Copy link
Contributor

suneox commented Oct 18, 2024

@fasileds Welcome to Expensify! First, please take some time to read through the guidelines on how to contribute to this project. This will help you understand the process and expectations for contributing effectively.

@suneox
Copy link
Contributor

suneox commented Oct 18, 2024

@truph01 proposal LGTM it’s a simple solution to handle this issue.

@bernhardoj proposal to separate the logic for setting the selection range and setting the scroll to the bottom immediately, while keeping the current implementation LGTM.

🎀 👀 🎀 C+ reviewed

Copy link

melvin-bot bot commented Oct 18, 2024

Triggered auto assignment to @neil-marcellini, see https://stackoverflow.com/c/expensify/questions/7972 for more details.

@bernhardoj
Copy link
Contributor

If we apply the selected solution, the text input scroll to bottom will only happen on focus.

after.mp4

This is how it behaves currently.

curr.mp4

I mentioned this in my proposal too

We need to scroll the input to the last line immediately when mounted, but we need to delay setting the selection.

@suneox
Copy link
Contributor

suneox commented Oct 18, 2024

If we apply the selected solution, the text input scroll to bottom will only happen on focus.

I don’t think it’s a big issue since this behavior currently happens in other areas as well, like in the task description.

ScreenRecording_10-19-2024.01-18-06_1_2.mp4

@bernhardoj
Copy link
Contributor

It happens in task description because it uses a markdown text input, which doesn't have setSelectionRange.

if ('value' in input && typeof input.value === 'string' && input.setSelectionRange) {
const length = input.value.length;
if (shouldAutoFocus) {
(input as HTMLInputElement).setSelectionRange(length, length);
}
// eslint-disable-next-line no-param-reassign
input.scrollTop = input.scrollHeight;
}

We scroll immediately to the bottom to solve this issue. If we are fine to change it back, then I think we can just remove updateMultilineInputRange.

Or we can just take input.scrollTop = input.scrollHeight; and not the setSelectionRange because looks like all platforms by default set the selection to the end already.

@suneox
Copy link
Contributor

suneox commented Oct 19, 2024

We scroll immediately to the bottom to solve this #21654.

@bernhardoj Thanks for pointing out the implementation history. Since we already have issue coverage for the case of setting scrollTop immediately so we can proceed with your solution.

@melvin-bot melvin-bot bot added the Overdue label Oct 21, 2024
@suneox
Copy link
Contributor

suneox commented Oct 22, 2024

I have updated the selected proposal

cc: @neil-marcellini

@melvin-bot melvin-bot bot added Overdue and removed Overdue labels Oct 22, 2024
@neil-marcellini
Copy link
Contributor

Ok, I'm good with @bernhardoj's proposal too

@melvin-bot melvin-bot bot removed the Overdue label Oct 25, 2024
@melvin-bot melvin-bot bot removed the Help Wanted Apply this label when an issue is open to proposals by contributors label Oct 25, 2024
Copy link

melvin-bot bot commented Oct 25, 2024

📣 @suneox 🎉 An offer has been automatically sent to your Upwork account for the Reviewer role 🎉 Thanks for contributing to the Expensify app!

Offer link
Upwork job

@melvin-bot melvin-bot bot added Reviewing Has a PR in review Weekly KSv2 and removed Daily KSv2 labels Oct 26, 2024
@bernhardoj
Copy link
Contributor

PR is ready

cc: @suneox

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something is broken. Auto assigns a BugZero manager. External Added to denote the issue can be worked on by a contributor Reviewing Has a PR in review Weekly KSv2
Projects
None yet
Development

No branches or pull requests

8 participants