From 924f3e3cbc6270431e1bca7e32884d6d66adf131 Mon Sep 17 00:00:00 2001 From: vineyardbovines Date: Tue, 14 Apr 2026 15:27:34 -0400 Subject: [PATCH] refactor(gif): remove text autocomplete, increase search debounce Remove the inline text suggestion list from the GIF picker. The Threads-style approach of just letting the GIF search results update directly is simpler and gets users to the GIFs faster. Increase the search throttle from 500ms to 750ms to reduce churn while typing and give results time to load before the next query fires. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/features/gifPicker/GifPickerDialog.tsx | 14 +-- .../gifPicker/components/GifPickerHeader.tsx | 104 +++++++----------- 2 files changed, 42 insertions(+), 76 deletions(-) diff --git a/src/features/gifPicker/GifPickerDialog.tsx b/src/features/gifPicker/GifPickerDialog.tsx index 4523231303..b7876608a6 100644 --- a/src/features/gifPicker/GifPickerDialog.tsx +++ b/src/features/gifPicker/GifPickerDialog.tsx @@ -10,7 +10,6 @@ import {GifPickerErrorBoundary} from '#/features/gifPicker/components/GifPickerE import {GifPickerGrid} from '#/features/gifPicker/components/GifPickerGrid' import {GifPickerHeader} from '#/features/gifPicker/components/GifPickerHeader' import {GifPickerPlaceholder} from '#/features/gifPicker/components/GifPickerPlaceholder' -import {useGifAutocomplete} from '#/features/gifPicker/hooks/useGifAutocomplete' import {useGifPickerData} from '#/features/gifPicker/hooks/useGifPickerData' import {type Gif} from '#/features/gifPicker/types' @@ -65,16 +64,7 @@ function GifPickerBody({ const textInputRef = useRef(null) const listRef = useRef(null) const [rawSearch, setRawSearch] = useState('') - const search = useThrottledValue(rawSearch, 500) - - const autocomplete = useGifAutocomplete({ - onSelectSuggestion: text => { - setRawSearch(text) - // Set the TextInput's displayed value to match - textInputRef.current?.setNativeProps({text}) - listRef.current?.scrollToOffset({offset: 0, animated: false}) - }, - }) + const search = useThrottledValue(rawSearch, 750) const { data, @@ -107,7 +97,6 @@ function GifPickerBody({ const onChangeSearch = (text: string) => { setRawSearch(text) - autocomplete.handleTextChange(text) listRef.current?.scrollToOffset({offset: 0, animated: false}) } @@ -118,7 +107,6 @@ function GifPickerBody({ onChangeText={onChangeSearch} onClose={() => control.close()} onEscape={() => control.close()} - autocomplete={autocomplete} /> {!hasData && ( onChangeText: (text: string) => void onClose: () => void onEscape: () => void - autocomplete: GifAutocompleteState }) { const {_} = useLingui() const t = useTheme() const {gtMobile} = useBreakpoints() return ( - - - {!gtMobile && IS_WEB && ( - - )} - - - - { - if (nativeEvent.key === 'Escape') { - if (!autocomplete.handleKeyDown('Escape')) { - onEscape() - } - } else { - autocomplete.handleKeyDown(nativeEvent.key) - } - }} - // @ts-ignore web-only ARIA props - role={autocomplete.isVisible ? 'combobox' : undefined} - aria-controls={ - autocomplete.isVisible ? GIF_AUTOCOMPLETE_LISTBOX_ID : undefined - } - aria-expanded={autocomplete.isVisible} - aria-autocomplete={autocomplete.isVisible ? 'list' : undefined} - aria-activedescendant={ - autocomplete.isVisible && autocomplete.activeIndex >= 0 - ? suggestionItemId(autocomplete.activeIndex) - : undefined - } - /> - - - - {autocomplete.isVisible && ( - + + {!gtMobile && IS_WEB && ( + )} + + + + { + if (nativeEvent.key === 'Escape') { + onEscape() + } + }} + /> + + + {/* future: tabs (Trending / Recents / Categories) render here */} ) }