From ad5c88976d413f31492dce0bbc155ccae1b40d41 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 6 May 2024 17:11:23 -0600 Subject: [PATCH 01/11] expose onEndReached and onEndReachedThreshold --- src/components/SelectionList/BaseSelectionList.tsx | 4 ++++ src/components/SelectionList/types.ts | 11 +++++++++++ src/libs/actions/OnyxUpdateManager/utils/index.ts | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/components/SelectionList/BaseSelectionList.tsx b/src/components/SelectionList/BaseSelectionList.tsx index 76c54d3c37cb..0982dc11b409 100644 --- a/src/components/SelectionList/BaseSelectionList.tsx +++ b/src/components/SelectionList/BaseSelectionList.tsx @@ -76,6 +76,8 @@ function BaseSelectionList( sectionTitleStyles, textInputAutoFocus = true, shouldTextInputInterceptSwipe = false, + onEndReached = () => {}, + onEndReachedThreshold, }: BaseSelectionListProps, ref: ForwardedRef, ) { @@ -618,6 +620,8 @@ function BaseSelectionList( onLayout={onSectionListLayout} style={(!maxToRenderPerBatch || (shouldHideListOnInitialRender && isInitialSectionListRender)) && styles.opacity0} ListFooterComponent={listFooterContent ?? ShowMoreButtonInstance} + onEndReached={onEndReached} + onEndReachedThreshold={onEndReachedThreshold} /> {children} diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts index 8a2a1efdd030..538d61b61a2b 100644 --- a/src/components/SelectionList/types.ts +++ b/src/components/SelectionList/types.ts @@ -404,6 +404,17 @@ type BaseSelectionListProps = Partial & { * When false, the list will render immediately and scroll to the bottom which works great for small lists. */ shouldHideListOnInitialRender?: boolean; + + /** Called once when the scroll position gets within onEndReachedThreshold of the rendered content. */ + onEndReached?: () => void; + + /** + * How far from the end (in units of visible length of the list) the bottom edge of the + * list must be from the end of the content to trigger the `onEndReached` callback. + * Thus a value of 0.5 will trigger `onEndReached` when the end of the content is + * within half the visible length of the list. + */ + onEndReachedThreshold?: number; } & TRightHandSideComponent; type SelectionListHandle = { diff --git a/src/libs/actions/OnyxUpdateManager/utils/index.ts b/src/libs/actions/OnyxUpdateManager/utils/index.ts index 4df22d292d19..1ed7c2c0ff7e 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/index.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/index.ts @@ -109,7 +109,7 @@ function validateAndApplyDeferredUpdates(clientLastUpdateID?: number): Promise Date: Mon, 6 May 2024 17:27:11 -0600 Subject: [PATCH 02/11] call fetchMoreResults --- src/CONST.ts | 2 ++ src/ROUTES.ts | 4 ++-- src/components/Search.tsx | 10 ++++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index ae78c2f02a05..bb7737be0add 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -4729,6 +4729,8 @@ const CONST = { CARD: 'card', DISTANCE: 'distance', }, + + SEARCH_RESULTS_PAGE_SIZE: 50, } as const; type Country = keyof typeof CONST.ALL_COUNTRIES; diff --git a/src/ROUTES.ts b/src/ROUTES.ts index d59bb9a3a981..9c428bfabeba 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -24,8 +24,8 @@ const ROUTES = { ALL_SETTINGS: 'all-settings', SEARCH: { - route: '/search/:query', - getRoute: (query: string) => `search/${query}` as const, + route: '/search/:query/:offset', + getRoute: (query: string, offset: number) => `search/${query}/${offset}` as const, }, SEARCH_REPORT: { diff --git a/src/components/Search.tsx b/src/components/Search.tsx index d8d3160a2633..4c18d7e3a311 100644 --- a/src/components/Search.tsx +++ b/src/components/Search.tsx @@ -11,6 +11,7 @@ import useCustomBackHandler from '@pages/Search/useCustomBackHandler'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import CONST from '@src/CONST'; import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue'; import SelectionList from './SelectionList'; import SearchTableHeader from './SelectionList/SearchTableHeader'; @@ -55,6 +56,13 @@ function Search({query}: SearchProps) { Navigation.navigate(ROUTES.SEARCH_REPORT.getRoute(query, reportID)); }; + const fetchMoreResults = () => { + const currentOffset = searchResults?.search?.offset ?? 0; + const nexOffset = currentOffset + CONST.SEARCH_RESULTS_PAGE_SIZE; + + Navigation.navigate(ROUTES.SEARCH.getRoute(query, nexOffset)); + } + const ListItem = SearchUtils.getListItem(); const data = SearchUtils.getSections(searchResults?.data ?? {}); const shouldShowMerchant = SearchUtils.getShouldShowMerchant(searchResults?.data ?? {}); @@ -70,6 +78,8 @@ function Search({query}: SearchProps) { shouldPreventDefaultFocusOnSelectRow={!DeviceCapabilities.canUseTouchScreen()} listHeaderWrapperStyle={[styles.ph9, styles.pv3, styles.pb5]} containerStyle={[styles.pv0]} + onEndReachedThreshold={0.75} + onEndReached={fetchMoreResults} /> ); } From 957853df61ae3245c42f3923744ae59b2c57b3f6 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 6 May 2024 17:37:32 -0600 Subject: [PATCH 03/11] add consts, types, tweak function --- src/ROUTES.ts | 2 +- src/components/Search.tsx | 15 +++++++++------ src/libs/API/parameters/Search.ts | 1 + src/libs/actions/Search.ts | 4 ++-- src/pages/Search/SearchPage.tsx | 3 ++- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 9c428bfabeba..da2ee1f5701c 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -25,7 +25,7 @@ const ROUTES = { SEARCH: { route: '/search/:query/:offset', - getRoute: (query: string, offset: number) => `search/${query}/${offset}` as const, + getRoute: (query: string, offset = 0) => `search/${query}/${offset}` as const, }, SEARCH_REPORT: { diff --git a/src/components/Search.tsx b/src/components/Search.tsx index 4c18d7e3a311..6a09a82f5463 100644 --- a/src/components/Search.tsx +++ b/src/components/Search.tsx @@ -19,9 +19,10 @@ import TableListItemSkeleton from './Skeletons/TableListItemSkeleton'; type SearchProps = { query: string; + offset: number; }; -function Search({query}: SearchProps) { +function Search({query, offset}: SearchProps) { const {isOffline} = useNetwork(); const styles = useThemeStyles(); useCustomBackHandler(); @@ -34,8 +35,8 @@ function Search({query}: SearchProps) { return; } - SearchActions.search(query); - }, [query, isOffline]); + SearchActions.search(query, offset); + }, [query, offset, isOffline]); const isLoading = (!isOffline && isLoadingOnyxValue(searchResultsMeta)) || searchResults?.data === undefined; const shouldShowEmptyState = !isLoading && isEmptyObject(searchResults?.data); @@ -57,10 +58,12 @@ function Search({query}: SearchProps) { }; const fetchMoreResults = () => { - const currentOffset = searchResults?.search?.offset ?? 0; - const nexOffset = currentOffset + CONST.SEARCH_RESULTS_PAGE_SIZE; + if (!searchResults?.search?.hasMoreResults) { + return; + } - Navigation.navigate(ROUTES.SEARCH.getRoute(query, nexOffset)); + const nextOffset = offset + CONST.SEARCH_RESULTS_PAGE_SIZE; + Navigation.navigate(ROUTES.SEARCH.getRoute(query, nextOffset)); } const ListItem = SearchUtils.getListItem(); diff --git a/src/libs/API/parameters/Search.ts b/src/libs/API/parameters/Search.ts index 44e8c9f2d0fb..415c6b7cfd35 100644 --- a/src/libs/API/parameters/Search.ts +++ b/src/libs/API/parameters/Search.ts @@ -1,6 +1,7 @@ type SearchParams = { query: string; hash: number; + offset: number; }; export default SearchParams; diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index 03179fae93cc..fb6f82c0b1ab 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -2,9 +2,9 @@ import * as API from '@libs/API'; import {READ_COMMANDS} from '@libs/API/types'; import * as SearchUtils from '@libs/SearchUtils'; -function search(query: string) { +function search(query: string, offset: number) { const hash = SearchUtils.getQueryHash(query); - API.read(READ_COMMANDS.SEARCH, {query, hash}); + API.read(READ_COMMANDS.SEARCH, {query, hash, offset}); } export { diff --git a/src/pages/Search/SearchPage.tsx b/src/pages/Search/SearchPage.tsx index 499b09fd4eb9..19d857f2f656 100644 --- a/src/pages/Search/SearchPage.tsx +++ b/src/pages/Search/SearchPage.tsx @@ -18,6 +18,7 @@ type SearchPageProps = StackScreenProps - + ); From 9936959d4edfdb9bbe94b91d6635697a723a852f Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 7 May 2024 16:20:29 -0600 Subject: [PATCH 04/11] add offset --- src/pages/Search/SearchPage.tsx | 2 +- src/pages/Search/SearchPageBottomTab.tsx | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/Search/SearchPage.tsx b/src/pages/Search/SearchPage.tsx index 19d857f2f656..8e204dcb24df 100644 --- a/src/pages/Search/SearchPage.tsx +++ b/src/pages/Search/SearchPage.tsx @@ -18,7 +18,7 @@ type SearchPageProps = StackScreenProps - {isSmallScreenWidth && } + {isSmallScreenWidth && } ); From b235980013e867421cf8f5bbc9cbfc95a9dd273f Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 8 May 2024 10:18:41 -0600 Subject: [PATCH 05/11] add loading skeleton --- src/components/Search.tsx | 21 +++++++++---- .../SelectionList/BaseSelectionList.tsx | 3 +- src/components/SelectionList/types.ts | 2 +- .../Skeletons/ItemListSkeletonView.tsx | 9 ++++-- .../Skeletons/TableListItemSkeleton.tsx | 4 ++- src/libs/actions/Search.ts | 30 ++++++++++++++++++- src/pages/Search/SearchPage.tsx | 5 +++- src/pages/Search/SearchPageBottomTab.tsx | 7 ++++- src/types/onyx/SearchResults.ts | 1 + 9 files changed, 68 insertions(+), 14 deletions(-) diff --git a/src/components/Search.tsx b/src/components/Search.tsx index 6a09a82f5463..b23b350af5ab 100644 --- a/src/components/Search.tsx +++ b/src/components/Search.tsx @@ -1,4 +1,4 @@ -import React, {useEffect} from 'react'; +import React, {useEffect, useRef} from 'react'; import {useOnyx} from 'react-native-onyx'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -8,10 +8,10 @@ import * as SearchUtils from '@libs/SearchUtils'; import Navigation from '@navigation/Navigation'; import EmptySearchView from '@pages/Search/EmptySearchView'; import useCustomBackHandler from '@pages/Search/useCustomBackHandler'; +import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; -import CONST from '@src/CONST'; import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue'; import SelectionList from './SelectionList'; import SearchTableHeader from './SelectionList/SearchTableHeader'; @@ -38,10 +38,11 @@ function Search({query, offset}: SearchProps) { SearchActions.search(query, offset); }, [query, offset, isOffline]); - const isLoading = (!isOffline && isLoadingOnyxValue(searchResultsMeta)) || searchResults?.data === undefined; - const shouldShowEmptyState = !isLoading && isEmptyObject(searchResults?.data); + const isLoadingInitialItems = (!isOffline && isLoadingOnyxValue(searchResultsMeta)) || searchResults?.data === undefined; + const isLoadingMoreItems = !isLoadingInitialItems && searchResults?.search?.isLoading; + const shouldShowEmptyState = !isLoadingInitialItems && isEmptyObject(searchResults?.data); - if (isLoading) { + if (isLoadingInitialItems) { return ; } @@ -64,7 +65,7 @@ function Search({query, offset}: SearchProps) { const nextOffset = offset + CONST.SEARCH_RESULTS_PAGE_SIZE; Navigation.navigate(ROUTES.SEARCH.getRoute(query, nextOffset)); - } + }; const ListItem = SearchUtils.getListItem(); const data = SearchUtils.getSections(searchResults?.data ?? {}); @@ -83,6 +84,14 @@ function Search({query, offset}: SearchProps) { containerStyle={[styles.pv0]} onEndReachedThreshold={0.75} onEndReached={fetchMoreResults} + listFooterContent={ + isLoadingMoreItems ? ( + + ) : undefined + } /> ); } diff --git a/src/components/SelectionList/BaseSelectionList.tsx b/src/components/SelectionList/BaseSelectionList.tsx index 0982dc11b409..ee2f53dfcde1 100644 --- a/src/components/SelectionList/BaseSelectionList.tsx +++ b/src/components/SelectionList/BaseSelectionList.tsx @@ -78,6 +78,7 @@ function BaseSelectionList( shouldTextInputInterceptSwipe = false, onEndReached = () => {}, onEndReachedThreshold, + onContentSizeChange, }: BaseSelectionListProps, ref: ForwardedRef, ) { @@ -486,7 +487,7 @@ function BaseSelectionList( [flattenedSections.allOptions, setFocusedIndex, updateAndScrollToFocusedIndex], ); - useImperativeHandle(ref, () => ({scrollAndHighlightItem}), [scrollAndHighlightItem]); + useImperativeHandle(ref, () => ({scrollAndHighlightItem, scrollToIndex}), [scrollAndHighlightItem, scrollToIndex]); /** Selects row when pressing Enter */ useKeyboardShortcut(CONST.KEYBOARD_SHORTCUTS.ENTER, selectFocusedOption, { diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts index 538d61b61a2b..5ee9871f0888 100644 --- a/src/components/SelectionList/types.ts +++ b/src/components/SelectionList/types.ts @@ -408,7 +408,7 @@ type BaseSelectionListProps = Partial & { /** Called once when the scroll position gets within onEndReachedThreshold of the rendered content. */ onEndReached?: () => void; - /** + /** * How far from the end (in units of visible length of the list) the bottom edge of the * list must be from the end of the content to trigger the `onEndReached` callback. * Thus a value of 0.5 will trigger `onEndReached` when the end of the content is diff --git a/src/components/Skeletons/ItemListSkeletonView.tsx b/src/components/Skeletons/ItemListSkeletonView.tsx index 00854471f2e3..5c46dbdddbfc 100644 --- a/src/components/Skeletons/ItemListSkeletonView.tsx +++ b/src/components/Skeletons/ItemListSkeletonView.tsx @@ -8,13 +8,14 @@ import CONST from '@src/CONST'; type ListItemSkeletonProps = { shouldAnimate?: boolean; renderSkeletonItem: (args: {itemIndex: number}) => React.ReactNode; + fixedNumItems?: number; }; -function ItemListSkeletonView({shouldAnimate = true, renderSkeletonItem}: ListItemSkeletonProps) { +function ItemListSkeletonView({shouldAnimate = true, renderSkeletonItem, fixedNumItems}: ListItemSkeletonProps) { const theme = useTheme(); const themeStyles = useThemeStyles(); - const [numItems, setNumItems] = useState(0); + const [numItems, setNumItems] = useState(fixedNumItems ?? 0); const skeletonViewItems = useMemo(() => { const items = []; for (let i = 0; i < numItems; i++) { @@ -38,6 +39,10 @@ function ItemListSkeletonView({shouldAnimate = true, renderSkeletonItem}: ListIt { + if (fixedNumItems) { + return; + } + const newNumItems = Math.ceil(event.nativeEvent.layout.height / CONST.LHN_SKELETON_VIEW_ITEM_HEIGHT); if (newNumItems === numItems) { return; diff --git a/src/components/Skeletons/TableListItemSkeleton.tsx b/src/components/Skeletons/TableListItemSkeleton.tsx index d24268521100..4b2c214921d0 100644 --- a/src/components/Skeletons/TableListItemSkeleton.tsx +++ b/src/components/Skeletons/TableListItemSkeleton.tsx @@ -4,16 +4,18 @@ import ItemListSkeletonView from './ItemListSkeletonView'; type TableListItemSkeletonProps = { shouldAnimate?: boolean; + fixedNumItems?: number; }; const barHeight = '10'; const shortBarWidth = '40'; const longBarWidth = '120'; -function TableListItemSkeleton({shouldAnimate = true}: TableListItemSkeletonProps) { +function TableListItemSkeleton({shouldAnimate = true, fixedNumItems}: TableListItemSkeletonProps) { return ( ( <> - + ); diff --git a/src/pages/Search/SearchPageBottomTab.tsx b/src/pages/Search/SearchPageBottomTab.tsx index b0b8a73f3e5a..6954a8cd1a8e 100644 --- a/src/pages/Search/SearchPageBottomTab.tsx +++ b/src/pages/Search/SearchPageBottomTab.tsx @@ -41,7 +41,12 @@ function SearchPageBottomTab() { shouldDisplaySearch={false} /> - {isSmallScreenWidth && } + {isSmallScreenWidth && ( + + )} ); diff --git a/src/types/onyx/SearchResults.ts b/src/types/onyx/SearchResults.ts index af23821d70e8..a91366f18046 100644 --- a/src/types/onyx/SearchResults.ts +++ b/src/types/onyx/SearchResults.ts @@ -6,6 +6,7 @@ type SearchResultsInfo = { offset: number; type: string; hasMoreResults: boolean; + isLoading: boolean; }; type SearchPersonalDetails = { From d56a3cda74c521bbb63d96287ef53e381580e17e Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 8 May 2024 10:57:55 -0600 Subject: [PATCH 06/11] set route params --- src/components/Search.tsx | 8 ++++++-- src/components/SelectionList/BaseSelectionList.tsx | 3 +-- src/libs/actions/OnyxUpdateManager/utils/index.ts | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/Search.tsx b/src/components/Search.tsx index b23b350af5ab..bc1926426f36 100644 --- a/src/components/Search.tsx +++ b/src/components/Search.tsx @@ -1,4 +1,4 @@ -import React, {useEffect, useRef} from 'react'; +import React, {useEffect} from 'react'; import {useOnyx} from 'react-native-onyx'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -63,8 +63,12 @@ function Search({query, offset}: SearchProps) { return; } + if (isLoadingMoreItems) { + return; + } + const nextOffset = offset + CONST.SEARCH_RESULTS_PAGE_SIZE; - Navigation.navigate(ROUTES.SEARCH.getRoute(query, nextOffset)); + Navigation.setParams({offset: nextOffset}); }; const ListItem = SearchUtils.getListItem(); diff --git a/src/components/SelectionList/BaseSelectionList.tsx b/src/components/SelectionList/BaseSelectionList.tsx index ee2f53dfcde1..0982dc11b409 100644 --- a/src/components/SelectionList/BaseSelectionList.tsx +++ b/src/components/SelectionList/BaseSelectionList.tsx @@ -78,7 +78,6 @@ function BaseSelectionList( shouldTextInputInterceptSwipe = false, onEndReached = () => {}, onEndReachedThreshold, - onContentSizeChange, }: BaseSelectionListProps, ref: ForwardedRef, ) { @@ -487,7 +486,7 @@ function BaseSelectionList( [flattenedSections.allOptions, setFocusedIndex, updateAndScrollToFocusedIndex], ); - useImperativeHandle(ref, () => ({scrollAndHighlightItem, scrollToIndex}), [scrollAndHighlightItem, scrollToIndex]); + useImperativeHandle(ref, () => ({scrollAndHighlightItem}), [scrollAndHighlightItem]); /** Selects row when pressing Enter */ useKeyboardShortcut(CONST.KEYBOARD_SHORTCUTS.ENTER, selectFocusedOption, { diff --git a/src/libs/actions/OnyxUpdateManager/utils/index.ts b/src/libs/actions/OnyxUpdateManager/utils/index.ts index 0b24cf5975db..6d51d3ac02a6 100644 --- a/src/libs/actions/OnyxUpdateManager/utils/index.ts +++ b/src/libs/actions/OnyxUpdateManager/utils/index.ts @@ -114,7 +114,7 @@ function validateAndApplyDeferredUpdates(clientLastUpdateID?: number, previousPa // the initial "updatesAfterGaps" and all new deferred updates will be applied in order, // as long as there was no new gap detected. Otherwise repeat the process. - const newLastUpdateIDFromClient = 0; + const newLastUpdateIDFromClient = clientLastUpdateID ?? lastUpdateIDAppliedToClient ?? 0; deferredUpdatesProxy.deferredUpdates = {...deferredUpdatesProxy.deferredUpdates, ...updatesAfterGaps}; From 18c8069434c23a4eaefc39f66e9c2685ce7b7456 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 8 May 2024 12:35:09 -0600 Subject: [PATCH 07/11] do not use route param --- src/ROUTES.ts | 4 ++-- src/components/Search.tsx | 20 +++++++------------- src/pages/Search/SearchPage.tsx | 2 -- src/pages/Search/SearchPageBottomTab.tsx | 2 -- 4 files changed, 9 insertions(+), 19 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 8325dff1f6e4..9f84b3db0de1 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -24,8 +24,8 @@ const ROUTES = { ALL_SETTINGS: 'all-settings', SEARCH: { - route: '/search/:query/:offset', - getRoute: (query: string, offset = 0) => `search/${query}/${offset}` as const, + route: '/search/:query', + getRoute: (query: string) => `search/${query}` as const, }, SEARCH_REPORT: { diff --git a/src/components/Search.tsx b/src/components/Search.tsx index bc1926426f36..f3a895808373 100644 --- a/src/components/Search.tsx +++ b/src/components/Search.tsx @@ -19,10 +19,9 @@ import TableListItemSkeleton from './Skeletons/TableListItemSkeleton'; type SearchProps = { query: string; - offset: number; }; -function Search({query, offset}: SearchProps) { +function Search({query}: SearchProps) { const {isOffline} = useNetwork(); const styles = useThemeStyles(); useCustomBackHandler(); @@ -35,8 +34,8 @@ function Search({query, offset}: SearchProps) { return; } - SearchActions.search(query, offset); - }, [query, offset, isOffline]); + SearchActions.search(query, 0); + }, [query, isOffline]); const isLoadingInitialItems = (!isOffline && isLoadingOnyxValue(searchResultsMeta)) || searchResults?.data === undefined; const isLoadingMoreItems = !isLoadingInitialItems && searchResults?.search?.isLoading; @@ -59,16 +58,11 @@ function Search({query, offset}: SearchProps) { }; const fetchMoreResults = () => { - if (!searchResults?.search?.hasMoreResults) { + if (!searchResults?.search?.hasMoreResults || isLoadingInitialItems || isLoadingMoreItems) { return; } - - if (isLoadingMoreItems) { - return; - } - - const nextOffset = offset + CONST.SEARCH_RESULTS_PAGE_SIZE; - Navigation.setParams({offset: nextOffset}); + const currentOffset = searchResults?.search?.offset ?? 0; + SearchActions.search(query, currentOffset + CONST.SEARCH_RESULTS_PAGE_SIZE); }; const ListItem = SearchUtils.getListItem(); @@ -92,7 +86,7 @@ function Search({query, offset}: SearchProps) { isLoadingMoreItems ? ( ) : undefined } diff --git a/src/pages/Search/SearchPage.tsx b/src/pages/Search/SearchPage.tsx index 71ed2a066b9e..b8cf277d5a31 100644 --- a/src/pages/Search/SearchPage.tsx +++ b/src/pages/Search/SearchPage.tsx @@ -18,7 +18,6 @@ type SearchPageProps = StackScreenProps diff --git a/src/pages/Search/SearchPageBottomTab.tsx b/src/pages/Search/SearchPageBottomTab.tsx index 6954a8cd1a8e..5a43ded89e09 100644 --- a/src/pages/Search/SearchPageBottomTab.tsx +++ b/src/pages/Search/SearchPageBottomTab.tsx @@ -20,7 +20,6 @@ function SearchPageBottomTab() { const styles = useThemeStyles(); const currentQuery = activeRoute?.params && 'query' in activeRoute.params ? activeRoute?.params?.query : ''; - const offset = activeRoute?.params && 'offset' in activeRoute.params ? parseInt(activeRoute?.params?.offset as string, 10) : 0; const query = currentQuery as SearchQuery; const isValidQuery = Object.values(CONST.TAB_SEARCH).includes(query); @@ -44,7 +43,6 @@ function SearchPageBottomTab() { {isSmallScreenWidth && ( )} From 40652b458ed9bc6bb26415e3a62ef21c4e0525cf Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 8 May 2024 12:39:39 -0600 Subject: [PATCH 08/11] add default --- src/components/Search.tsx | 6 +++--- src/libs/actions/Search.ts | 2 +- src/pages/Search/SearchPage.tsx | 4 +--- src/pages/Search/SearchPageBottomTab.tsx | 6 +----- 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/components/Search.tsx b/src/components/Search.tsx index f3a895808373..3b02ebbf2a49 100644 --- a/src/components/Search.tsx +++ b/src/components/Search.tsx @@ -34,11 +34,11 @@ function Search({query}: SearchProps) { return; } - SearchActions.search(query, 0); + SearchActions.search(query); }, [query, isOffline]); const isLoadingInitialItems = (!isOffline && isLoadingOnyxValue(searchResultsMeta)) || searchResults?.data === undefined; - const isLoadingMoreItems = !isLoadingInitialItems && searchResults?.search?.isLoading; + const isLoadingMoreItems = searchResults?.search?.isLoading ?? false; const shouldShowEmptyState = !isLoadingInitialItems && isEmptyObject(searchResults?.data); if (isLoadingInitialItems) { @@ -86,7 +86,7 @@ function Search({query}: SearchProps) { isLoadingMoreItems ? ( ) : undefined } diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index 965e7b01e5c8..8902dbf7b648 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -5,7 +5,7 @@ import {READ_COMMANDS} from '@libs/API/types'; import * as SearchUtils from '@libs/SearchUtils'; import ONYXKEYS from '@src/ONYXKEYS'; -function search(query: string, offset: number) { +function search(query: string, offset = 0) { const hash = SearchUtils.getQueryHash(query); const optimisticData: OnyxUpdate[] = [ diff --git a/src/pages/Search/SearchPage.tsx b/src/pages/Search/SearchPage.tsx index b8cf277d5a31..499b09fd4eb9 100644 --- a/src/pages/Search/SearchPage.tsx +++ b/src/pages/Search/SearchPage.tsx @@ -36,9 +36,7 @@ function SearchPage({route}: SearchPageProps) { icon={Illustrations.MoneyReceipts} shouldShowBackButton={false} /> - + ); diff --git a/src/pages/Search/SearchPageBottomTab.tsx b/src/pages/Search/SearchPageBottomTab.tsx index 5a43ded89e09..3d2ee267b7a9 100644 --- a/src/pages/Search/SearchPageBottomTab.tsx +++ b/src/pages/Search/SearchPageBottomTab.tsx @@ -40,11 +40,7 @@ function SearchPageBottomTab() { shouldDisplaySearch={false} /> - {isSmallScreenWidth && ( - - )} + {isSmallScreenWidth && } ); From d1d34d4320b3ee697280273b64f4d6e9414af6f3 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 8 May 2024 12:41:44 -0600 Subject: [PATCH 09/11] fix isLoadingMoreItems --- src/components/Search.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Search.tsx b/src/components/Search.tsx index 3b02ebbf2a49..c8efe13f7003 100644 --- a/src/components/Search.tsx +++ b/src/components/Search.tsx @@ -38,7 +38,7 @@ function Search({query}: SearchProps) { }, [query, isOffline]); const isLoadingInitialItems = (!isOffline && isLoadingOnyxValue(searchResultsMeta)) || searchResults?.data === undefined; - const isLoadingMoreItems = searchResults?.search?.isLoading ?? false; + const isLoadingMoreItems = !isLoadingInitialItems && searchResults?.search?.isLoading; const shouldShowEmptyState = !isLoadingInitialItems && isEmptyObject(searchResults?.data); if (isLoadingInitialItems) { From 9457168007e4fead24e0af9de6239e9b2718d9ec Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 8 May 2024 12:43:31 -0600 Subject: [PATCH 10/11] reduce number of items --- src/components/Search.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Search.tsx b/src/components/Search.tsx index c8efe13f7003..7cc7ad7f7f9b 100644 --- a/src/components/Search.tsx +++ b/src/components/Search.tsx @@ -86,7 +86,7 @@ function Search({query}: SearchProps) { isLoadingMoreItems ? ( ) : undefined } From 0677a8a58754286e3e3337056163d6af7c6dc512 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 15 May 2024 07:59:56 +0900 Subject: [PATCH 11/11] fix param order --- src/components/Search.tsx | 4 ++-- src/libs/actions/Search.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/Search.tsx b/src/components/Search.tsx index 7d8dbb2de6a1..27e87017bfee 100644 --- a/src/components/Search.tsx +++ b/src/components/Search.tsx @@ -36,7 +36,7 @@ function Search({query, policyIDs}: SearchProps) { return; } - SearchActions.search(hash, query, policyIDs); + SearchActions.search(hash, query, 0, policyIDs); // eslint-disable-next-line react-hooks/exhaustive-deps }, [hash, isOffline]); @@ -65,7 +65,7 @@ function Search({query, policyIDs}: SearchProps) { return; } const currentOffset = searchResults?.search?.offset ?? 0; - SearchActions.search(query, currentOffset + CONST.SEARCH_RESULTS_PAGE_SIZE); + SearchActions.search(hash, query, currentOffset + CONST.SEARCH_RESULTS_PAGE_SIZE); }; const type = SearchUtils.getSearchType(searchResults?.search); diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index bd26a1829400..fae9a427f4fa 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -4,7 +4,7 @@ import * as API from '@libs/API'; import {READ_COMMANDS} from '@libs/API/types'; import ONYXKEYS from '@src/ONYXKEYS'; -function search(hash: number, query: string, offset = 0, policyIDs?: string, ) { +function search(hash: number, query: string, offset = 0, policyIDs?: string) { const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE,