show and weight recents in search autocomplete

This commit is contained in:
vineyardbovines
2026-07-14 16:49:17 -04:00
parent a055f18cc3
commit 56618d0e9e
5 changed files with 28 additions and 6 deletions
+4
View File
@@ -59,6 +59,7 @@ import {Text} from '#/components/Typography'
import {useAnalytics} from '#/analytics' import {useAnalytics} from '#/analytics'
import {IS_NATIVE, IS_WEB} from '#/env' import {IS_NATIVE, IS_WEB} from '#/env'
import {useSearchHistory} from '#/features/searchHistory' import {useSearchHistory} from '#/features/searchHistory'
import {useRecentSearchesSource} from '#/features/searchHistory/useRecentSearchesSource'
import type * as bsky from '#/types/bsky' import type * as bsky from '#/types/bsky'
import {AdvancedSearchDialog} from './components/AdvancedSearchDialog' import {AdvancedSearchDialog} from './components/AdvancedSearchDialog'
import {AutocompleteResults} from './components/AutocompleteResults' import {AutocompleteResults} from './components/AutocompleteResults'
@@ -126,6 +127,8 @@ export function SearchScreenShell({
setSearchText(text) setSearchText(text)
}, []) }, [])
const recents = useRecentSearchesSource()
const {items: autocompleteItems, isFetching: isAutocompleteFetching} = const {items: autocompleteItems, isFetching: isAutocompleteFetching} =
useAutocomplete({ useAutocomplete({
type: 'profile', type: 'profile',
@@ -135,6 +138,7 @@ export function SearchScreenShell({
* query on web to keep the hook a no-op instead of doing wasted work. * query on web to keep the hook a no-op instead of doing wasted work.
*/ */
query: IS_NATIVE ? searchText : '', query: IS_NATIVE ? searchText : '',
sources: [recents],
}) })
const [showAutocomplete, setShowAutocomplete] = useState(false) const [showAutocomplete, setShowAutocomplete] = useState(false)
@@ -10,6 +10,7 @@ import * as Dialog from '#/components/Dialog'
import * as TextField from '#/components/forms/TextField' import * as TextField from '#/components/forms/TextField'
import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times' import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times'
import * as ProfileCard from '#/components/ProfileCard' import * as ProfileCard from '#/components/ProfileCard'
import {useRecentSearchesSource} from '#/features/searchHistory/useRecentSearchesSource'
import { import {
appendSelection, appendSelection,
type AutocompleteInputProps, type AutocompleteInputProps,
@@ -38,7 +39,12 @@ export function AutocompleteInput({
const [focused, setFocused] = useState(false) const [focused, setFocused] = useState(false)
const lastToken = lastTokenOf(value) const lastToken = lastTokenOf(value)
const {items} = useAutocomplete({type: 'profile', query: lastToken}) const recents = useRecentSearchesSource({profilesOnly: true})
const {items} = useAutocomplete({
type: 'profile',
query: lastToken,
sources: [recents],
})
const showDropdown = focused && lastToken.length > 0 && items.length > 0 const showDropdown = focused && lastToken.length > 0 && items.length > 0
@@ -14,6 +14,7 @@ import {Button, ButtonIcon} from '#/components/Button'
import * as Dialog from '#/components/Dialog' import * as Dialog from '#/components/Dialog'
import * as TextField from '#/components/forms/TextField' import * as TextField from '#/components/forms/TextField'
import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times' import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times'
import {useRecentSearchesSource} from '#/features/searchHistory/useRecentSearchesSource'
import { import {
appendSelection, appendSelection,
type AutocompleteInputProps, type AutocompleteInputProps,
@@ -54,7 +55,12 @@ export function AutocompleteInput({
}) })
const lastToken = lastTokenOf(value) const lastToken = lastTokenOf(value)
const {items} = useAutocomplete({type: 'profile', query: lastToken}) const recents = useRecentSearchesSource({profilesOnly: true})
const {items} = useAutocomplete({
type: 'profile',
query: lastToken,
sources: [recents],
})
const showDropdown = const showDropdown =
focused && !dismissedByScroll && lastToken.length > 0 && items.length > 0 focused && !dismissedByScroll && lastToken.length > 0 && items.length > 0
@@ -10,6 +10,7 @@ import {
useAutocomplete, useAutocomplete,
} from '#/components/Autocomplete' } from '#/components/Autocomplete'
import {SearchInput} from '#/components/forms/SearchInput' import {SearchInput} from '#/components/forms/SearchInput'
import {useRecentSearchesSource} from '#/features/searchHistory/useRecentSearchesSource'
import {type SearchAutocompleteInputProps} from './shared' import {type SearchAutocompleteInputProps} from './shared'
/** /**
@@ -46,6 +47,8 @@ export function SearchAutocompleteInput({
const active = focused && !dismissed const active = focused && !dismissed
const recents = useRecentSearchesSource()
const {items} = useAutocomplete({ const {items} = useAutocomplete({
type: 'profile', type: 'profile',
// The dropdown only shows while active, so don't fetch otherwise. This // The dropdown only shows while active, so don't fetch otherwise. This
@@ -53,10 +56,10 @@ export function SearchAutocompleteInput({
// present (e.g. /search?q=foo). // present (e.g. /search?q=foo).
query: active ? value : '', query: active ? value : '',
showSearchFallback: true, showSearchFallback: true,
sources: [recents],
}) })
const showDropdown = const showDropdown = active && !fixedParams && items.length > 0
active && !fixedParams && value.length > 0 && items.length > 0
function onSelect(item: AutocompleteItem) { function onSelect(item: AutocompleteItem) {
if (item.type === 'profile') { if (item.type === 'profile') {
+5 -2
View File
@@ -11,12 +11,13 @@ import {
useAutocomplete, useAutocomplete,
} from '#/components/Autocomplete' } from '#/components/Autocomplete'
import {SearchInput} from '#/components/forms/SearchInput' import {SearchInput} from '#/components/forms/SearchInput'
import {useRecentSearchesSource} from '#/features/searchHistory/useRecentSearchesSource'
export function DesktopSearch() { export function DesktopSearch() {
const navigation = useNavigation<NavigationProp>() const navigation = useNavigation<NavigationProp>()
const [active, setActive] = useState(false) const [active, setActive] = useState(false)
const [query, setQuery] = useState<string>('') const [query, setQuery] = useState<string>('')
const showResults = active && !!query.length const showResults = active
const sift = useSift({ const sift = useSift({
offset: a.p_sm.padding, offset: a.p_sm.padding,
@@ -24,7 +25,7 @@ export function DesktopSearch() {
}) })
const onFocus = () => { const onFocus = () => {
if (query.length) setActive(true) setActive(true)
} }
const onBlur = () => { const onBlur = () => {
@@ -97,10 +98,12 @@ function Inner({
onSelect: (item: AutocompleteItem) => void onSelect: (item: AutocompleteItem) => void
onDismiss: () => void onDismiss: () => void
}) { }) {
const recents = useRecentSearchesSource()
const {items} = useAutocomplete({ const {items} = useAutocomplete({
type: 'profile', type: 'profile',
query, query,
showSearchFallback: true, showSearchFallback: true,
sources: [recents],
}) })
return items && items.length ? ( return items && items.length ? (