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] Android/iOS- Highlighted search result go to search page rather that the highlighted detail page #53401

Open
4 of 8 tasks
IuliiaHerets opened this issue Dec 2, 2024 · 30 comments
Assignees
Labels
Bug Something is broken. Auto assigns a BugZero manager. Daily KSv2 Engineering External Added to denote the issue can be worked on by a contributor Help Wanted Apply this label when an issue is open to proposals by contributors

Comments

@IuliiaHerets
Copy link

IuliiaHerets commented Dec 2, 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: v9.0.69-4
Reproducible in staging?: Y
Reproducible in production?: N/A - new feature, doesn't exist in prod
If this was caught on HybridApp, is this reproducible on New Expensify Standalone?: Y
Email or phone of affected tester (no customers): [email protected]
Issue reported by: Applause Internal Team

Action Performed:

  1. Navigate to https://staging.new.expensify.com/

  2. Go to search router

  3. Write anything eg. "admin" and clear the search again ( to get the highlight on the first result)

  4. Click search icon on keyboard (enter)

Expected Result:

The highlighted item should open the detail page when clicking enter (Mweb behavior)

Actual Result:

The highlighted search result go to search page rather that the highlighted detail page

Workaround:

Unknown

Platforms:

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

Screenshots/Videos

Bug6682275_1733167237785.Screen_Recording_20241202_221823_Expensify.mp4

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~021866990715543185912
  • Upwork Job ID: 1866990715543185912
  • Last Price Increase: 2024-12-25
Issue OwnerCurrent Issue Owner: @ikevin127
@IuliiaHerets IuliiaHerets added DeployBlockerCash This issue or pull request should block deployment Bug Something is broken. Auto assigns a BugZero manager. labels Dec 2, 2024
Copy link

melvin-bot bot commented Dec 2, 2024

Triggered auto assignment to @luacmartins (DeployBlockerCash), see https://stackoverflowteams.com/c/expensify/questions/9980/ for more details.

Copy link

melvin-bot bot commented Dec 2, 2024

💬 A slack conversation has been started in #expensify-open-source

Copy link

melvin-bot bot commented Dec 2, 2024

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

@melvin-bot melvin-bot bot added the Daily KSv2 label Dec 2, 2024
@github-actions github-actions bot added Engineering Hourly KSv2 and removed Daily KSv2 labels Dec 2, 2024
Copy link
Contributor

github-actions bot commented Dec 2, 2024

👋 Friendly reminder that deploy blockers are time-sensitive ⏱ issues! Check out the open `StagingDeployCash` deploy checklist to see the list of PRs included in this release, then work quickly to do one of the following:

  1. Identify the pull request that introduced this issue and revert it.
  2. Find someone who can quickly fix the issue.
  3. Fix the issue yourself.

@luacmartins
Copy link
Contributor

Demoting to NAB since it's just highlighting the wrong item. This is likely the offending PR @nyomanjyotisa @Pujan92

Copy link

melvin-bot bot commented Dec 6, 2024

@luacmartins, @MitchExpensify Whoops! This issue is 2 days overdue. Let's get this updated quick!

@Pujan92
Copy link
Contributor

Pujan92 commented Dec 6, 2024

@luacmartins This doesn't seem to be from #52298, as we have specific logic on search input submit. I think for smaller screens the first item should not be highlighted in the selection list when the sections data are altered to avoid this issue.

@MitchExpensify
Copy link
Contributor

The expected behavior here is to open the "Admin" room or whatever search row is highlighted, not return to search right? Its not super clear in the OP so wanted to double check what we're aiming for here @luacmartins

@melvin-bot melvin-bot bot removed the Overdue label Dec 7, 2024
@luacmartins
Copy link
Contributor

Correct, it should open the Admin room since that's what's highlighted

@nyomanjyotisa
Copy link
Contributor

I think for smaller screens the first item should not be highlighted in the selection list when the sections data are altered to avoid this issue

Should we implement this then? Or should we update the logic on search input submit to open Admin room in this case? Because in native platforms, it will always execute submitSearch on enter click, instead of opening the focused item

@luacmartins
Copy link
Contributor

I think the behavior should be consistent on all platforms, so we should highlight the first item again once the search is altered

@luacmartins luacmartins added the External Added to denote the issue can be worked on by a contributor label Dec 11, 2024
@melvin-bot melvin-bot bot changed the title Android/iOS- Highlighted search result go to search page rather that the highlighted detail page [$250] Android/iOS- Highlighted search result go to search page rather that the highlighted detail page Dec 11, 2024
Copy link

melvin-bot bot commented Dec 11, 2024

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

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

melvin-bot bot commented Dec 11, 2024

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

@ikevin127
Copy link
Contributor

@luacmartins Could you please confirm the nexts steps here ?

  1. Is this issue considered a regression from #52298 ?
  2. Should the issue be addressed by author / reviewer as a follow-up or we're open for proposals ?

Copy link

melvin-bot bot commented Dec 16, 2024

@luacmartins @MitchExpensify @ikevin127 this issue was created 2 weeks ago. Are we close to approving a proposal? If not, what's blocking us from getting this issue assigned? Don't hesitate to create a thread in #expensify-open-source to align faster in real time. Thanks!

@melvin-bot melvin-bot bot added the Overdue label Dec 16, 2024
@MitchExpensify
Copy link
Contributor

Reminder on this @luacmartins

@luacmartins
Copy link
Contributor

As pointed out here, I don't think this issue is a regression, so we're open to proposals

Copy link

melvin-bot bot commented Dec 17, 2024

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

Copy link

melvin-bot bot commented Dec 18, 2024

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

@luacmartins
Copy link
Contributor

Still looking for proposals

@ikevin127
Copy link
Contributor

Still looking for proposals

@melvin-bot melvin-bot bot removed the Overdue label Dec 18, 2024
@nyomanjyotisa
Copy link
Contributor

Proposal

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

Android/iOS- Highlighted search result go to search page rather that the highlighted detail page

What is the root cause of that problem?

On smaller screens, the top-most result in Recent Chats is not highlighted when the search router is opened for the first time. However, it will highlight the first item (from Recent Chats or Recent Searches, if available) when the user types in the search bar and then clears it. On native platforms specifically, every time the user presses the search icon on the keyboard (Enter), it will always execute submitSearch

const submitSearch = useCallback(
(queryString: SearchQueryString) => {
const queryWithSubstitutions = getQueryWithSubstitutions(queryString, autocompleteSubstitutions);
const updatedQuery = SearchQueryUtils.getQueryWithUpdatedValues(queryWithSubstitutions, activeWorkspaceID);
if (!updatedQuery) {
return;
}
onRouterClose();
Navigation.navigate(ROUTES.SEARCH_CENTRAL_PANE.getRoute({query: updatedQuery}));
setTextInputValue('');
setAutocompleteQueryValue('');
},
[autocompleteSubstitutions, onRouterClose, setTextInputValue, activeWorkspaceID],
);

And then will be called on this onSubmit
<SearchRouterInput
value={textInputValue}
isFullWidth={shouldUseNarrowLayout}
onSearchQueryChange={onSearchQueryChange}
onSubmit={() => {
submitSearch(textInputValue);
}}

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

We can create a new function that will handle the onSubmit. The idea is to navigate to the highlightedItem using onListItemPress if the textInputValue is not empty and it is not the initial state (i.e., the user has already typed and cleared the search query).

    // Track if the user has typed initially
    const [isInitialType, setIsInitialType] = useState(true);

We set it to false on onSearchQueryChange

            if (userQuery.length > 0) {
                setIsInitialType(false);
            }

We also need recentSearchesData to retrieve the recent searches (if available). Because if there is recent searches, the highlighted item is the last recentSearchesData

    const sortedRecentSearches = useMemo(() => {
        return Object.values(recentSearches ?? {}).sort((a, b) => b.timestamp.localeCompare(a.timestamp));
    }, [recentSearches]);

    const recentSearchesData = sortedRecentSearches?.slice(0, 5).map(({query, timestamp}) => {
        const searchQueryJSON = SearchQueryUtils.buildSearchQueryJSON(query);
        return {
            text: searchQueryJSON ? SearchQueryUtils.buildUserReadableQueryString(searchQueryJSON, personalDetails, reports, taxRates) : query,
            singleIcon: Expensicons.History,
            searchQuery: query,
            keyForList: timestamp,
            searchItemType: CONST.SEARCH.SEARCH_ROUTER_ITEM_TYPE.SEARCH,
        };
    });
    const onSubmit = useCallback(() => {
        if (!textInputValue && !isInitialType) {
            const highlightedItem = recentSearchesData[0] || searchOptions.recentReports[0];
            if (highlightedItem) {
                onListItemPress(highlightedItem);
            }
        } else {
            submitSearch(textInputValue);
        }
    }, [textInputValue, recentSearchesData, searchOptions.recentReports, onListItemPress, submitSearch]);
                    <SearchRouterInput
                        ...
                        onSubmit={onSubmit}
                        ...

What specific scenarios should we cover in automated tests to prevent reintroducing this issue in the future?

What alternative solutions did you explore? (Optional)

POC

iOS-Native.mp4

@huult
Copy link
Contributor

huult commented Dec 21, 2024

Edited by proposal-police: This proposal was edited at 2024-12-21 14:07:20 UTC.

Proposal

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

Highlighted search result go to search page rather that the highlighted detail page

What is the root cause of that problem?

First, I will explain why the highlighted item on the mobile web can open the detail page when pressing Enter.

We use useKeyboardShortcut to listen for the Enter key press. When Enter is pressed, it executes the selectFocusedOption function to select the highlighted row in the list. and this useKeyboardShortcut only works on the mobile web (mWeb).

useKeyboardShortcut(CONST.KEYBOARD_SHORTCUTS.ENTER, selectFocusedOption, {
captureOnInputs: true,
shouldBubble: !flattenedSections.allOptions.at(focusedIndex) || focusedIndex === -1,
shouldStopPropagation,
shouldPreventDefault,
isActive: !disableKeyboardShortcuts && !disableEnterShortcut && isFocused,
});

const selectFocusedOption = () => {
const focusedOption = focusedIndex !== -1 ? flattenedSections.allOptions.at(focusedIndex) : undefined;
if (!focusedOption || (focusedOption.isDisabled && !focusedOption.isSelected)) {
return;
}
selectRow(focusedOption);
};

And the selected item, when Enter is pressed, will be handled for search or navigation.

onListItemPress={onListItemPress}

if (item?.reportID) {
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(item?.reportID));
} else if ('login' in item) {
ReportUserActions.navigateToAndOpenReport(item.login ? [item.login] : [], false);
}

In this case, we encountered an issue (mweb) where, if no item in the list is highlighted, pressing Enter does not trigger any action.

Screen.Recording.2024-12-21.at.16.25.56.mov

For native apps (Android/iOS), we detect the Enter key press using onSubmitEditing.

onSubmit={() => {
submitSearch(textInputValue);
}}

When we press Enter, it calls submitSearch without handling the case for navigation to the highlighted item

const submitSearch = useCallback(
(queryString: SearchQueryString) => {
const queryWithSubstitutions = getQueryWithSubstitutions(queryString, autocompleteSubstitutions);
const updatedQuery = SearchQueryUtils.getQueryWithUpdatedValues(queryWithSubstitutions, activeWorkspaceID);
if (!updatedQuery) {
return;
}
onRouterClose();
Navigation.navigate(ROUTES.SEARCH_CENTRAL_PANE.getRoute({query: updatedQuery}));
setTextInputValue('');
setAutocompleteQueryValue('');
},
[autocompleteSubstitutions, onRouterClose, setTextInputValue, activeWorkspaceID],
);

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

To resolve this issue in this ticket, on the native app, when Enter is pressed, if the text input value is empty, we need to check if a row is highlighted and then navigate to it.

  1. We need to get the focused item in the selection list.

Create getFocusedItem function

  const getFocusedItem = useCallback(() => {
      const focusedOption = focusedIndex !== -1 ? flattenedSections.allOptions.at(focusedIndex) : undefined;

      if (!focusedOption || (focusedOption.isDisabled && !focusedOption.isSelected)) {
          return;
      }

      return focusedOption;
  }, [focusedIndex, flattenedSections.allOptions]);

useImperativeHandle(ref, () => ({scrollAndHighlightItem, clearInputAfterSelect, updateAndScrollToFocusedIndex, updateExternalTextInputFocus, scrollToIndex}), [
scrollAndHighlightItem,
clearInputAfterSelect,
updateAndScrollToFocusedIndex,
updateExternalTextInputFocus,
scrollToIndex,
]);

Update to

    useImperativeHandle(ref, () => ({scrollAndHighlightItem, clearInputAfterSelect, updateAndScrollToFocusedIndex, updateExternalTextInputFocus, scrollToIndex, getFocusedItem}), [
        scrollAndHighlightItem,
        clearInputAfterSelect,
        updateAndScrollToFocusedIndex,
        updateExternalTextInputFocus,
        scrollToIndex,
        getFocusedItem,
    ]);
  1. We will update onSubmit

onSubmit={() => {
submitSearch(textInputValue);
}}

  onSubmit={() => {
      const item = listRef.current?.getFocusedItem();
      if (!item) {
          submitSearch(textInputValue);
          return;
      }
      onListItemPress(item);
  }}

or

  onSubmit={() => {
      const item = listRef.current?.getFocusedItem();

      if (!textInputValue && !isSearchQueryItem(item)) {
      // or if (!textInputValue && item && !isSearchQueryItem(item)) {
          onRouterClose();

          if (item?.reportID) {
              Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(item?.reportID));
          } else if ('login' in item) {
              ReportUserActions.navigateToAndOpenReport(item.login ? [item.login] : [], false);
          }
          return;
      }
      submitSearch(textInputValue);
  }}

Regarding the mWeb issue, if we want to fix it in this ticket, we will update it as follows:

    <TextInput
        ...
        onKeyPress={(event) => {
          const isWeb = getPlatform() === CONST.PLATFORM.WEB;
          if (!isWeb) {
              return;
          }
          if (event.nativeEvent.key !== 'Enter') {
              return;
          }
          onSubmit();
        }}
    />
POC
Screen.Recording.2024-12-21.at.20.59.15.mp4

Test branch

What specific scenarios should we cover in automated tests to prevent reintroducing this issue in the future?

Test getFocusedItem :

  1. should return undefined when focusedIndex is -1
  2. should return undefined when focused item is undefined
  3. should return undefined when focused item is disabled and not selected
  4. should return the focused item when it is valid

Test onSubmit logic:

  1. calls submitSearch when no item is focused
  2. calls onListItemPress with the focused item

What alternative solutions did you explore? (Optional)

Reminder: Please use plain English, be brief and avoid jargon. Feel free to use images, charts or pseudo-code if necessary. Do not post large multi-line diffs or write walls of text. Do not create PRs unless you have been hired for this job.

@melvin-bot melvin-bot bot added the Overdue label Dec 21, 2024
@MitchExpensify
Copy link
Contributor

@ikevin127 Proposals are ready for your review

@ikevin127

This comment was marked as outdated.

@melvin-bot melvin-bot bot removed the Overdue label Dec 23, 2024
@ikevin127
Copy link
Contributor

Both proposals are suggesting similar solutions when it comes to our main issue with slightly different implementations, both are fixing the issue, but the second proposal is considering another case that is related / in scope. Before I make a decision I want to check with @Expensify/design and / or @luacmartins on whether we should address the related case here.

The issue is that, on mWeb, if no item is selected and input is empty and we press Enter aka software keyboard search button, nothing happens. Compared to Native where the search input page is dismissed (w/ no specific search query):

iOS: Native iOS: mWeb Safari
ios-noHighlight.mp4
ios-mweb-noHighlight.mp4

IMO pressing Enter aka software keyboard search button should do something like it happens on Native, should dismiss the search input page with no specific search query, as to me it feels like something's broken on mWeb when it doesn't do anything.

I think we should fix the mWeb case such that we would have the same behaviour on both mWeb and Native.
Please let me know what do you think!

@shawnborton
Copy link
Contributor

Interesting, I think I tend to agree with you. Basically hitting enter on a blank Search query essentially is like resetting the search query back to nothing, aka searching for nothing which would just bring you back to the default home state of Search.

Copy link

melvin-bot bot commented Dec 25, 2024

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

Copy link

melvin-bot bot commented Dec 27, 2024

@luacmartins, @MitchExpensify, @ikevin127 Whoops! This issue is 2 days overdue. Let's get this updated quick!

@melvin-bot melvin-bot bot added the Overdue label Dec 27, 2024
@ikevin127
Copy link
Contributor

We're still awaiting some more input on #53401 (comment) regarding final decision.

@melvin-bot melvin-bot bot removed the Overdue label Dec 27, 2024
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. Daily KSv2 Engineering External Added to denote the issue can be worked on by a contributor Help Wanted Apply this label when an issue is open to proposals by contributors
Projects
None yet
Development

No branches or pull requests

8 participants