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.58k stars 2.92k forks source link

mWeb - Group - Name input is displayed in the middle while editing a large group name #53011

Open lanitochka17 opened 3 days ago

lanitochka17 commented 3 days 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!


Version Number: 9.0.66-0 Reproducible in staging?: Y Reproducible in production?: Y If this was caught on HybridApp, is this reproducible on New Expensify Standalone?: N/A If this was caught during regression testing, add the test name, ID and link from TestRail: https://expensify.testrail.io/index.php?/tests/view/5256940&group_by=cases:section_id&group_order=asc&group_id=229067 Email or phone of affected tester (no customers): ibellicotest+36@gmail.com Issue reported by: Applause - Internal Team

Action Performed:

  1. Open the staging.new.expensify.com website
  2. Tap on the FAB and select "Start Chat"
  3. Add several users to group chat
  4. Tap on "Next"
  5. Tap on the group´s name
  6. Verify the name´s input is displayed at the end of the name

Expected Result:

When opening group´s name tab to edit it, the input should be displayed at the end of the group´s name

Actual Result:

When trying to edit a group´s long name, the input shows the name in the middle and the user has to scroll to the right to reach the end of the name and the cursor

Workaround:

Unknown

Platforms:

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

Screenshots/Videos

Add any screenshot/video evidence

https://github.com/user-attachments/assets/50f318b3-a69a-477d-a83c-0cc22b01a44b

View all open jobs on GitHub

melvin-bot[bot] commented 3 days ago

Triggered auto assignment to @RachCHopkins (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.

prakashbask commented 3 days ago

Proposal

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

When opening group´s name tab to edit it, the input should be displayed at the end of the group´s name

What is the root cause of that problem?

1) The underlying component for TextInput accepts a prop selection={{start, end}} to control the cursor position, ensuring it is displayed at the end of the text value. This prop needs to be passed from the GroupChatNameEditPage to achieve the desired behaviour https://github.com/Expensify/App/blob/3ebe8520d74c57a2fe9548b7d4307206e2b7c673/src/pages/GroupChatNameEditPage.tsx#L102

2) In addition to this, the selection prop is only supported in the native environment. For the web environment, additional logic is required to achieve the desired behaviour. This can be implemented by setting the selectionRange and scrollLeft on the inputRef explicitly to ensure the cursor is positioned at the end of the text value. https://github.com/Expensify/App/blob/3ebe8520d74c57a2fe9548b7d4307206e2b7c673/src/components/TextInput/BaseTextInput/index.tsx#L32

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

1) Add the selection prop with the value selection={{start: currentChatName?.length ?? 0, end: currentChatName?.length ?? 0}} to the InputWrapper in the GroupChatNameEditPage https://github.com/Expensify/App/blob/3ebe8520d74c57a2fe9548b7d4307206e2b7c673/src/pages/GroupChatNameEditPage.tsx#L102

2) Add a useEffect in the web implementation of BaseTextInput to handle text selection and scrolling. The effect listens for changes to isFocused and inputProps.selection. When triggered, it validates the selection props and sets the cursor or selection range using setSelectionRange. Additionally, it adjusts the scrollLeft property of the input element to ensure the text is scrolled to the end if necessary. https://github.com/Expensify/App/blob/3ebe8520d74c57a2fe9548b7d4307206e2b7c673/src/components/TextInput/BaseTextInput/index.tsx#L32

    useEffect(() => {
        const inputElement = input.current;
        // Set selection range and handle scrolling
        inputElement.setSelectionRange(inputProps.selection.start, inputProps.selection.end);
        inputElement.scrollLeft = inputElement.scrollWidth;
    }, [isFocused, inputProps.selection]);

What alternative solutions did you explore? (Optional)

RachCHopkins commented 1 day ago

Works fine on iOS. I will need Android to test this properly

daledah commented 23 hours ago

Proposal

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

When trying to edit a group´s long name, the input shows the name in the middle and the user has to scroll to the right to reach the end of the name and the cursor

What is the root cause of that problem?

https://github.com/Expensify/App/blob/2d5479e4a416da6a4617476dbfba67541adeed68/src/components/TextInput/BaseTextInput/index.tsx#L430

to:

                            {isFocused && !isReadOnly && shouldShowClearButton && !!value && (
                                <View
                                    onLayout={() => {
                                        if (!didScrollToEndRef.current) {
                                            input.current.scrollLeft = input.current?.scrollWidth;
                                            didScrollToEndRef.current = true;
                                        }
                                    }}
                                >
                                    <TextInputClearButton onPressButton={() => setValue('')} />
                                </View>
                            )}

In the example above, I added an onLayout function that scrolls the input cursor to the end only the first time (when the input is auto-focused). For subsequent focuses, scrolling isn't necessary as those are triggered manually.

What alternative solutions did you explore? (Optional)

Alternative solution 1:

    useEffect(() => {
        if (!didScrollToEndRef.current && isFocused && !isReadOnly && shouldShowClearButton && !!value) {
            input.current.scrollLeft = input.current?.scrollWidth;
            didScrollToEndRef.current = true;
        }
    }, [isFocused, shouldShowClearButton, value, isReadOnly]);

to this place instead of using onLayout.

Alternative solution 2:

        setTimeout(()=>{
            inputRef.current.scrollLeft = inputRef.current?.scrollWidth;
        }, 300)

to this place: https://github.com/Expensify/App/blob/2d5479e4a416da6a4617476dbfba67541adeed68/src/hooks/useAutoFocusInput.ts#L32

It will auto-scroll the input cursor to the end after 300ms