Update search input with useAutocomplete (#11023)
This commit is contained in:
@@ -23,7 +23,6 @@ import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||
import {MagnifyingGlassIcon} from '#/lib/icons'
|
||||
import {type NavigationProp, type SearchParams} from '#/lib/routes/types'
|
||||
import {listenSoftReset} from '#/state/events'
|
||||
import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
|
||||
import {
|
||||
unstableCacheProfileView,
|
||||
useProfilesQuery,
|
||||
@@ -43,8 +42,8 @@ import {
|
||||
} from '#/screens/Search/searchParams'
|
||||
import {makeSearchQuery} from '#/screens/Search/utils'
|
||||
import {atoms as a, tokens, useBreakpoints, useTheme, web} from '#/alf'
|
||||
import {useAutocomplete} from '#/components/Autocomplete'
|
||||
import {Button, ButtonIcon} from '#/components/Button'
|
||||
import {SearchInput} from '#/components/forms/SearchInput'
|
||||
import {ArrowLeft_Stroke2_Corner0_Rounded as ArrowLeftIcon} from '#/components/icons/Arrow'
|
||||
import {ArrowShareRight_Stroke2_Corner2_Rounded as ShareIcon} from '#/components/icons/ArrowShareRight'
|
||||
import * as Layout from '#/components/Layout'
|
||||
@@ -57,6 +56,7 @@ import type * as bsky from '#/types/bsky'
|
||||
import {AdvancedSearchDialog} from './components/AdvancedSearchDialog'
|
||||
import {AutocompleteResults} from './components/AutocompleteResults'
|
||||
import {DetectedLanguagesAdmonition} from './components/DetectedLanguagesAdmonition'
|
||||
import {SearchAutocompleteInput} from './components/SearchAutocompleteInput'
|
||||
import {SearchHistory} from './components/SearchHistory'
|
||||
import {SearchLanguageDropdown} from './components/SearchLanguageDropdown'
|
||||
import {Explore} from './Explore'
|
||||
@@ -125,8 +125,16 @@ export function SearchScreenShell({
|
||||
setSearchText(text)
|
||||
}, [])
|
||||
|
||||
const {data: autocompleteData, isFetching: isAutocompleteFetching} =
|
||||
useActorAutocompleteQuery(searchText, true)
|
||||
const {items: autocompleteItems, isFetching: isAutocompleteFetching} =
|
||||
useAutocomplete({
|
||||
type: 'profile',
|
||||
/*
|
||||
* On web the dropdown (SearchAutocompleteInput) owns its own autocomplete
|
||||
* query; only the native inline list consumes this one, so pass an empty
|
||||
* query on web to keep the hook a no-op instead of doing wasted work.
|
||||
*/
|
||||
query: IS_NATIVE ? searchText : '',
|
||||
})
|
||||
|
||||
const [showAutocomplete, setShowAutocomplete] = useState(false)
|
||||
|
||||
@@ -388,6 +396,38 @@ export function SearchScreenShell({
|
||||
[updateProfileHistory, queryClient],
|
||||
)
|
||||
|
||||
/**
|
||||
* Web only. Selecting a profile from the anchored autocomplete dropdown.
|
||||
*/
|
||||
const onSelectProfile = useCallback(
|
||||
(profile: bsky.profile.AnyProfileView, position: number) => {
|
||||
ax.metric('search:autocomplete:press', {
|
||||
profileDid: profile.did,
|
||||
position,
|
||||
})
|
||||
handleProfileClick(profile)
|
||||
navigation.navigate('Profile', {name: profile.handle})
|
||||
},
|
||||
[ax, handleProfileClick, navigation],
|
||||
)
|
||||
|
||||
/**
|
||||
* Web only. Selecting the "Search for X" row from the anchored autocomplete
|
||||
* dropdown. This runs the typed query as-is (not a suggested profile), so it
|
||||
* is attributed to `typed` rather than `autocomplete`.
|
||||
*/
|
||||
const onSelectSearch = useCallback(
|
||||
(value: string) => {
|
||||
ax.metric('search:query', {
|
||||
source: 'typed',
|
||||
filterCount: countActiveFilters(filters),
|
||||
})
|
||||
updateSearchText(value)
|
||||
navigateToItem(value)
|
||||
},
|
||||
[ax, filters, navigateToItem, updateSearchText],
|
||||
)
|
||||
|
||||
const onSoftReset = useCallback(() => {
|
||||
if (IS_WEB) {
|
||||
/*
|
||||
@@ -495,13 +535,11 @@ export function SearchScreenShell({
|
||||
{isExplore ? <Trans>Explore</Trans> : <Trans>Search</Trans>}
|
||||
</Layout.Header.TitleText>
|
||||
</Layout.Header.Content>
|
||||
{showFilters ? (
|
||||
advancedSearchV2Enabled ? null : (
|
||||
<SearchLanguageDropdown
|
||||
value={filters.lang ?? ''}
|
||||
onChange={onChangeLang}
|
||||
/>
|
||||
)
|
||||
{showFilters && !advancedSearchV2Enabled ? (
|
||||
<SearchLanguageDropdown
|
||||
value={filters.lang ?? ''}
|
||||
onChange={onChangeLang}
|
||||
/>
|
||||
) : (
|
||||
<Layout.Header.Slot />
|
||||
)}
|
||||
@@ -528,7 +566,7 @@ export function SearchScreenShell({
|
||||
size="large"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
shape="rectangular"
|
||||
shape="round"
|
||||
style={[a.px_sm]}
|
||||
onPress={onPressCancelSearch}
|
||||
hitSlop={HITSLOP_10}>
|
||||
@@ -536,7 +574,7 @@ export function SearchScreenShell({
|
||||
</Button>
|
||||
)}
|
||||
<View style={[a.flex_1]}>
|
||||
<SearchInput
|
||||
<SearchAutocompleteInput
|
||||
testID="searchScreenInput"
|
||||
ref={textInput}
|
||||
value={searchText}
|
||||
@@ -547,6 +585,9 @@ export function SearchScreenShell({
|
||||
placeholder={inputPlaceholder ?? l`Search`}
|
||||
hitSlop={{...HITSLOP_20, top: 0}}
|
||||
hotkey={true}
|
||||
fixedParams={Boolean(fixedParams)}
|
||||
onSelectProfile={onSelectProfile}
|
||||
onSelectSearch={onSelectSearch}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
@@ -589,10 +630,10 @@ export function SearchScreenShell({
|
||||
display: showAutocomplete && !fixedParams ? 'flex' : 'none',
|
||||
flex: 1,
|
||||
}}>
|
||||
{searchText.length > 0 ? (
|
||||
{searchText.length > 0 && IS_NATIVE ? (
|
||||
<AutocompleteResults
|
||||
isAutocompleteFetching={isAutocompleteFetching}
|
||||
autocompleteData={autocompleteData}
|
||||
items={autocompleteItems}
|
||||
isFetching={isAutocompleteFetching}
|
||||
searchText={searchText}
|
||||
onSubmit={onSubmit('autocomplete')}
|
||||
onResultPress={onAutocompleteResultPress}
|
||||
|
||||
Reference in New Issue
Block a user