From 75431644e37ecadba2a9c6fbc81a09c98d9c623d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Le=C5=9Bniewski?= Date: Thu, 16 Apr 2026 15:07:13 +0200 Subject: [PATCH 1/4] Fix navigation arrows disappearing during report browsing Background search calls (useSearchHighlightAndScroll, useSearchPageSetup) overwrote REPORT_NAVIGATION_LAST_SEARCH_QUERY with a different search type, causing prev/next arrows to hide. Flip shouldUpdateLastSearchParams default to false in search() so background calls no longer overwrite the navigation context. Persist params explicitly when user selects an expense report row (onSelectRow) and when arrows prefetch more results (goToNextReport). Co-Authored-By: Claude Opus 4.6 --- .../MoneyRequestReportNavigation.tsx | 1 + src/components/Search/index.tsx | 14 ++++++++++++++ src/libs/actions/Search.ts | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/components/MoneyRequestReportView/MoneyRequestReportNavigation.tsx b/src/components/MoneyRequestReportView/MoneyRequestReportNavigation.tsx index 29dd908d45f6..8646f103ef01 100644 --- a/src/components/MoneyRequestReportView/MoneyRequestReportNavigation.tsx +++ b/src/components/MoneyRequestReportView/MoneyRequestReportNavigation.tsx @@ -158,6 +158,7 @@ function MoneyRequestReportNavigationInner({reportID, shouldDisplayNarrowVersion shouldCalculateTotals: false, searchKey: lastSearchQuery.searchKey, isLoading: isSearchLoading, + shouldUpdateLastSearchParams: true, }); } diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index 067631da4696..55385c6b05e1 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -27,6 +27,7 @@ import useSearchHighlightAndScroll from '@hooks/useSearchHighlightAndScroll'; import useSearchShouldCalculateTotals from '@hooks/useSearchShouldCalculateTotals'; import useThemeStyles from '@hooks/useThemeStyles'; import {turnOffMobileSelectionMode, turnOnMobileSelectionMode} from '@libs/actions/MobileSelectionMode'; +import {saveLastSearchParams} from '@libs/actions/ReportNavigation'; import type {TransactionPreviewData} from '@libs/actions/Search'; import {setOptimisticDataForTransactionThreadPreview} from '@libs/actions/Search'; import {flushDeferredWrite, getOptimisticWatchKey, hasDeferredWrite} from '@libs/deferredLayoutWrite'; @@ -1207,6 +1208,16 @@ function Search({ unmarkReportIDAsMultiTransactionExpense(reportID); } + // Persist the current search context so prev/next navigation arrows + // in the report RHP can reference the correct result set. + saveLastSearchParams({ + queryJSON, + offset, + searchKey: currentSearchKey, + hasMoreResults: !!searchResults?.search?.hasMoreResults, + allowPostSearchRecount: true, + }); + requestAnimationFrame(() => Navigation.navigate(ROUTES.SEARCH_MONEY_REQUEST_REPORT.getRoute({reportID, backTo}))); return; } @@ -1246,6 +1257,9 @@ function Search({ betas, email, accountID, + queryJSON, + offset, + searchResults?.search?.hasMoreResults, ], ); diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index bcbe634e579d..7ab32dd56905 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -531,7 +531,7 @@ function search({ prevReportsLength, isOffline = false, isLoading, - shouldUpdateLastSearchParams = true, + shouldUpdateLastSearchParams = false, skipWaitForWrites = false, }: { queryJSON: Readonly; From f76e2f8b41bdea0ca3c42024eaebeeee689a95d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Le=C5=9Bniewski?= Date: Thu, 30 Apr 2026 18:49:54 +0200 Subject: [PATCH 2/4] Address review feedback: remove unrelated blank line, fix SearchTabButton regression Remove unrelated blank line after const firstTransaction. Add saveLastSearchParams in useSearchPageSetup to persist queryJSON for SearchTabButton tab restoration, fixing the UX regression where returning to the Search tab would show the default query instead of the user's last search. Co-Authored-By: Claude Opus 4.6 --- src/hooks/useSearchPageSetup.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/hooks/useSearchPageSetup.ts b/src/hooks/useSearchPageSetup.ts index 8cf706060819..4377525e6edd 100644 --- a/src/hooks/useSearchPageSetup.ts +++ b/src/hooks/useSearchPageSetup.ts @@ -2,6 +2,7 @@ import {useFocusEffect} from '@react-navigation/native'; import {useEffect} from 'react'; import {useSearchActionsContext, useSearchStateContext} from '@components/Search/SearchContext'; import type {SearchQueryJSON} from '@components/Search/types'; +import {saveLastSearchParams} from '@libs/actions/ReportNavigation'; import {openSearch, search} from '@libs/actions/Search'; import {hasDeferredWrite} from '@libs/deferredLayoutWrite'; import {isSearchDataLoaded} from '@libs/SearchUIUtils'; @@ -56,6 +57,11 @@ function useSearchPageSetup(queryJSON: Readonly | undefined) { } const shouldSkipWaitForWrites = hasDeferredWrite(CONST.DEFERRED_LAYOUT_WRITE_KEYS.SEARCH); search({queryJSON, searchKey: currentSearchKey, offset: 0, shouldCalculateTotals, isLoading: false, skipWaitForWrites: shouldSkipWaitForWrites}); + + // Save query context so SearchTabButton can restore the last search when + // the user returns to the Search tab. This is the explicit replacement for + // the old implicit save-on-every-search() default. + saveLastSearchParams({queryJSON, offset: 0, searchKey: currentSearchKey, hasMoreResults: false, allowPostSearchRecount: false}); }, [hash, isOffline, shouldUseLiveData, queryJSON, isSnapshotDataLoaded, isSnapshotSearchLoading, currentSearchKey, shouldCalculateTotals]); useFocusEffect(() => { From 884a738f96327e687de245f93c2abf4c12366884 Mon Sep 17 00:00:00 2001 From: Lukasz Modzelewski Date: Mon, 11 May 2026 10:41:31 +0200 Subject: [PATCH 3/4] fix: persist queryJSON in useSearchPageSetup on cached-snapshot queries --- src/hooks/useSearchPageSetup.ts | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/hooks/useSearchPageSetup.ts b/src/hooks/useSearchPageSetup.ts index 4377525e6edd..38416754e129 100644 --- a/src/hooks/useSearchPageSetup.ts +++ b/src/hooks/useSearchPageSetup.ts @@ -11,6 +11,10 @@ import useNetwork from './useNetwork'; import usePrevious from './usePrevious'; import useSearchShouldCalculateTotals from './useSearchShouldCalculateTotals'; +// Gates the save below to real hash changes so snapshot-loading re-fires don't wipe fields +// (hasMoreResults, previousLengthOfResults) maintained by report-browsing callers. +let lastSavedSearchHash: number | undefined; + /** * Handles page-level setup for Search that must happen before the Search component mounts: * - Clears selected transactions when the query changes @@ -52,16 +56,19 @@ function useSearchPageSetup(queryJSON: Readonly | undefined) { if (!queryJSON || hash === undefined || shouldUseLiveData || isOffline) { return; } + + // Must run even on cached snapshots, else SearchTabButton's Onyx fallback restores + // a stale query after a tab switch (e.g. filter reappears after Reset). + if (lastSavedSearchHash !== hash) { + saveLastSearchParams({queryJSON, offset: 0, searchKey: currentSearchKey, hasMoreResults: false, allowPostSearchRecount: false}); + lastSavedSearchHash = hash; + } + if (isSnapshotDataLoaded || isSnapshotSearchLoading) { return; } const shouldSkipWaitForWrites = hasDeferredWrite(CONST.DEFERRED_LAYOUT_WRITE_KEYS.SEARCH); search({queryJSON, searchKey: currentSearchKey, offset: 0, shouldCalculateTotals, isLoading: false, skipWaitForWrites: shouldSkipWaitForWrites}); - - // Save query context so SearchTabButton can restore the last search when - // the user returns to the Search tab. This is the explicit replacement for - // the old implicit save-on-every-search() default. - saveLastSearchParams({queryJSON, offset: 0, searchKey: currentSearchKey, hasMoreResults: false, allowPostSearchRecount: false}); }, [hash, isOffline, shouldUseLiveData, queryJSON, isSnapshotDataLoaded, isSnapshotSearchLoading, currentSearchKey, shouldCalculateTotals]); useFocusEffect(() => { From 4a51eae12bf0a6894cf8302e53a687c558d880a3 Mon Sep 17 00:00:00 2001 From: Lukasz Modzelewski Date: Mon, 11 May 2026 16:05:56 +0200 Subject: [PATCH 4/4] add missing currentSearchKey dep --- src/components/Search/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index 55385c6b05e1..43eec39771ae 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -1260,6 +1260,7 @@ function Search({ queryJSON, offset, searchResults?.search?.hasMoreResults, + currentSearchKey, ], );