throttle searches and dedupe
This commit is contained in:
@@ -75,12 +75,18 @@ function GifPickerBody({
|
|||||||
const {getRecents, addRecent, hasRecents} = useRecentGifs()
|
const {getRecents, addRecent, hasRecents} = useRecentGifs()
|
||||||
|
|
||||||
// Determine the effective search query:
|
// Determine the effective search query:
|
||||||
// - If user is typing, use the typed text
|
// - If user is typing, use the throttled text
|
||||||
|
// - If user clears the input, immediately drop the search (don't wait for
|
||||||
|
// the throttle to catch up — otherwise the previous query keeps driving
|
||||||
|
// the visible results until the next interval tick)
|
||||||
// - If a non-trending category is active, use its searchterm
|
// - If a non-trending category is active, use its searchterm
|
||||||
// - Otherwise (trending/recents), empty string triggers the featured endpoint
|
// - Otherwise (trending/recents), empty string triggers the featured endpoint
|
||||||
const activeCategorySearchterm =
|
const activeCategorySearchterm =
|
||||||
GIF_CATEGORIES.find(c => c.id === activeCategory)?.searchterm ?? ''
|
GIF_CATEGORIES.find(c => c.id === activeCategory)?.searchterm ?? ''
|
||||||
const effectiveSearch = search.length > 0 ? search : activeCategorySearchterm
|
const effectiveSearch =
|
||||||
|
rawSearch.length > 0 && search.length > 0
|
||||||
|
? search
|
||||||
|
: activeCategorySearchterm
|
||||||
|
|
||||||
const isRecentsActive = activeCategory === 'recents' && rawSearch.length === 0
|
const isRecentsActive = activeCategory === 'recents' && rawSearch.length === 0
|
||||||
|
|
||||||
@@ -96,7 +102,9 @@ function GifPickerBody({
|
|||||||
refetch,
|
refetch,
|
||||||
} = useGifPickerData(effectiveSearch, {enabled: !isRecentsActive})
|
} = useGifPickerData(effectiveSearch, {enabled: !isRecentsActive})
|
||||||
|
|
||||||
const networkItems = data?.pages.flatMap(page => page.results) ?? []
|
const networkItems = dedupeById(
|
||||||
|
data?.pages.flatMap(page => page.results) ?? [],
|
||||||
|
)
|
||||||
const items = isRecentsActive ? getRecents() : networkItems
|
const items = isRecentsActive ? getRecents() : networkItems
|
||||||
const hasData = items.length > 0
|
const hasData = items.length > 0
|
||||||
|
|
||||||
@@ -184,3 +192,14 @@ function GifPickerBody({
|
|||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function dedupeById(items: Gif[]): Gif[] {
|
||||||
|
const seen = new Set<string>()
|
||||||
|
const out: Gif[] = []
|
||||||
|
for (const item of items) {
|
||||||
|
if (seen.has(item.id)) continue
|
||||||
|
seen.add(item.id)
|
||||||
|
out.push(item)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import {Platform} from 'react-native'
|
import {Platform} from 'react-native'
|
||||||
import {getLocales} from 'expo-localization'
|
import {getLocales} from 'expo-localization'
|
||||||
import {keepPreviousData, useInfiniteQuery} from '@tanstack/react-query'
|
import {useInfiniteQuery} from '@tanstack/react-query'
|
||||||
|
|
||||||
import {GIF_KLIPY_FEATURED, GIF_KLIPY_SEARCH} from '#/lib/constants'
|
import {GIF_KLIPY_FEATURED, GIF_KLIPY_SEARCH} from '#/lib/constants'
|
||||||
import {type Gif} from '#/features/gifPicker/types'
|
import {type Gif} from '#/features/gifPicker/types'
|
||||||
@@ -32,7 +32,6 @@ export function useGifSearchQuery(
|
|||||||
initialPageParam: undefined as string | undefined,
|
initialPageParam: undefined as string | undefined,
|
||||||
getNextPageParam: lastPage => lastPage.next,
|
getNextPageParam: lastPage => lastPage.next,
|
||||||
enabled: !!query && options?.enabled !== false,
|
enabled: !!query && options?.enabled !== false,
|
||||||
placeholderData: keepPreviousData,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user