diff --git a/ui/component/wunderbarSuggestions/view.jsx b/ui/component/wunderbarSuggestions/view.jsx index de460b6eb..9a167d553 100644 --- a/ui/component/wunderbarSuggestions/view.jsx +++ b/ui/component/wunderbarSuggestions/view.jsx @@ -16,7 +16,6 @@ import WunderbarTopSuggestion from 'component/wunderbarTopSuggestion'; import WunderbarSuggestion from 'component/wunderbarSuggestion'; import { useHistory } from 'react-router'; import { formatLbryUrlForWeb } from 'util/url'; -import useThrottle from 'effects/use-throttle'; import Yrbl from 'component/yrbl'; import { SEARCH_OPTIONS } from 'constants/search'; @@ -31,6 +30,9 @@ const TAG_SEARCH_PREFIX = 'tag:'; const L_KEY_CODE = 76; const ESC_KEY_CODE = 27; +const WUNDERBAR_INPUT_DEBOUNCE_MS = 500; +const LIGHTHOUSE_MIN_CHARACTERS = 3; + type Props = { searchQuery: ?string, onSearch: (string) => void, @@ -69,14 +71,14 @@ export default function WunderBarSuggestions(props: Props) { const urlParams = new URLSearchParams(search); const queryFromUrl = urlParams.get('q') || ''; const [term, setTerm] = React.useState(queryFromUrl); - const throttledTerm = useThrottle(term, 500) || ''; + const [debouncedTerm, setDebouncedTerm] = React.useState(''); const searchSize = isMobile ? 20 : 5; const additionalOptions = channelsOnly ? { isBackgroundSearch: false, [SEARCH_OPTIONS.CLAIM_TYPE]: SEARCH_OPTIONS.INCLUDE_CHANNELS } : {}; - const { results, loading } = useLighthouse(throttledTerm, showMature, searchSize, additionalOptions); - const noResults = throttledTerm && !loading && results && results.length === 0; - const nameFromQuery = throttledTerm.trim().replace(/\s+/g, '').replace(/:/g, '#'); + const { results, loading } = useLighthouse(debouncedTerm, showMature, searchSize, additionalOptions, 0); + const noResults = debouncedTerm && !loading && results && results.length === 0; + const nameFromQuery = debouncedTerm.trim().replace(/\s+/g, '').replace(/:/g, '#'); const uriFromQuery = `lbry://${nameFromQuery}`; let uriFromQueryIsValid = false; let channelUrlForTopTest; @@ -156,6 +158,16 @@ export default function WunderBarSuggestions(props: Props) { } } + React.useEffect(() => { + const timer = setTimeout(() => { + if (debouncedTerm !== term) { + setDebouncedTerm(term.length < LIGHTHOUSE_MIN_CHARACTERS ? '' : term); + } + }, WUNDERBAR_INPUT_DEBOUNCE_MS); + + return () => clearTimeout(timer); + }, [term, debouncedTerm]); + React.useEffect(() => { function handleHomeEndCaretPos(elem, shiftKey, isHome) { if (elem) { @@ -294,7 +306,7 @@ export default function WunderBarSuggestions(props: Props) { {uriFromQueryIsValid && !noTopSuggestion ? : null}
{__('Search Results')}
- {results.slice(0, isMobile ? 20 : 5).map((uri) => ( + {results.slice(0, term.length < LIGHTHOUSE_MIN_CHARACTERS ? 0 : isMobile ? 20 : 5).map((uri) => ( ))} diff --git a/ui/effects/use-lighthouse.js b/ui/effects/use-lighthouse.js index b7d958f5d..029668c20 100644 --- a/ui/effects/use-lighthouse.js +++ b/ui/effects/use-lighthouse.js @@ -7,14 +7,15 @@ import useThrottle from './use-throttle'; export default function useLighthouse( query: string, - showMature?: boolean, - size?: number = 5, - additionalOptions: any = {} + showMature: boolean, + size: number = 5, + additionalOptions: any = {}, + throttleMs: number = 500 ) { const [results, setResults] = React.useState(); const [loading, setLoading] = React.useState(); const queryString = query ? getSearchQueryString(query, { nsfw: showMature, size, ...additionalOptions }) : ''; - const throttledQuery = useThrottle(queryString, 500); + const throttledQuery = useThrottle(queryString, throttleMs); React.useEffect(() => { if (throttledQuery) {