Autocomplete updates (react-query refactor) (#1911)

* Unify the autocomplete code; drop fuse

* Persist autocomplete results while they're in progress

* Commit lockfile

* Use ReturnType helper

---------

Co-authored-by: Eric Bailey <git@esb.lol>
This commit is contained in:
Paul Frazee 2023-11-15 14:39:22 -08:00 committed by GitHub
parent 839e8e8d0a
commit d5ea31920c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 73 additions and 152 deletions

View file

@ -17,9 +17,7 @@ import {isUriImage, blobToDataUri} from 'lib/media/util'
import {Emoji} from './web/EmojiPicker.web'
import {LinkDecorator} from './web/LinkDecorator'
import {generateJSON} from '@tiptap/html'
import {ActorAutocomplete} from '#/state/queries/actor-autocomplete'
import {useSession} from '#/state/session'
import {useMyFollowsQuery} from '#/state/queries/my-follows'
import {useActorAutocompleteFn} from '#/state/queries/actor-autocomplete'
export interface TextInputRef {
focus: () => void
@ -52,15 +50,7 @@ export const TextInput = React.forwardRef(function TextInputImpl(
TextInputProps,
ref,
) {
const {agent} = useSession()
const autocomplete = React.useMemo(
() => new ActorAutocomplete(agent),
[agent],
)
const {data: follows} = useMyFollowsQuery()
if (follows) {
autocomplete.setFollows(follows)
}
const autocomplete = useActorAutocompleteFn()
const modeClass = useColorSchemeStyle('ProseMirror-light', 'ProseMirror-dark')
const extensions = React.useMemo(

View file

@ -1,4 +1,4 @@
import React, {useEffect} from 'react'
import React, {useEffect, useRef} from 'react'
import {Animated, TouchableOpacity, StyleSheet, View} from 'react-native'
import {observer} from 'mobx-react-lite'
import {useAnimatedValue} from 'lib/hooks/useAnimatedValue'
@ -7,6 +7,8 @@ import {Text} from 'view/com/util/text/Text'
import {UserAvatar} from 'view/com/util/UserAvatar'
import {useGrapheme} from '../hooks/useGrapheme'
import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
import {Trans} from '@lingui/macro'
import {AppBskyActorDefs} from '@atproto/api'
export const Autocomplete = observer(function AutocompleteImpl({
prefix,
@ -19,7 +21,13 @@ export const Autocomplete = observer(function AutocompleteImpl({
const positionInterp = useAnimatedValue(0)
const {getGraphemeString} = useGrapheme()
const isActive = !!prefix
const {data: suggestions} = useActorAutocompleteQuery(prefix)
const {data: suggestions, isFetching} = useActorAutocompleteQuery(prefix)
const suggestionsRef = useRef<
AppBskyActorDefs.ProfileViewBasic[] | undefined
>(undefined)
if (suggestions) {
suggestionsRef.current = suggestions
}
useEffect(() => {
Animated.timing(positionInterp, {
@ -44,8 +52,8 @@ export const Autocomplete = observer(function AutocompleteImpl({
<Animated.View style={topAnimStyle}>
{isActive ? (
<View style={[pal.view, styles.container, pal.border]}>
{suggestions?.length ? (
suggestions.slice(0, 5).map(item => {
{suggestionsRef.current?.length ? (
suggestionsRef.current.slice(0, 5).map(item => {
// Eventually use an average length
const MAX_CHARS = 40
const MAX_HANDLE_CHARS = 20
@ -84,7 +92,11 @@ export const Autocomplete = observer(function AutocompleteImpl({
})
) : (
<Text type="sm" style={[pal.text, pal.border, styles.noResults]}>
No result
{isFetching ? (
<Trans>Loading...</Trans>
) : (
<Trans>No result</Trans>
)}
</Text>
)}
</View>

View file

@ -12,7 +12,7 @@ import {
SuggestionProps,
SuggestionKeyDownProps,
} from '@tiptap/suggestion'
import {ActorAutocomplete} from '#/state/queries/actor-autocomplete'
import {ActorAutocompleteFn} from '#/state/queries/actor-autocomplete'
import {usePalette} from 'lib/hooks/usePalette'
import {Text} from 'view/com/util/text/Text'
import {UserAvatar} from 'view/com/util/UserAvatar'
@ -25,12 +25,12 @@ interface MentionListRef {
export function createSuggestion({
autocomplete,
}: {
autocomplete: ActorAutocomplete
autocomplete: ActorAutocompleteFn
}): Omit<SuggestionOptions, 'editor'> {
return {
async items({query}) {
await autocomplete.query(query)
return autocomplete.suggestions.slice(0, 8)
const suggestions = await autocomplete({query})
return suggestions.slice(0, 8)
},
render: () => {

View file

@ -26,7 +26,7 @@ import {MagnifyingGlassIcon2} from 'lib/icons'
import {NavigationProp} from 'lib/routes/types'
import {Text} from 'view/com/util/text/Text'
import {UserAvatar} from '#/view/com/util/UserAvatar'
import {useActorSearch} from '#/state/queries/actor-autocomplete'
import {useActorAutocompleteFn} from '#/state/queries/actor-autocomplete'
import {useModerationOpts} from '#/state/queries/preferences'
export function SearchResultCard({
@ -98,7 +98,7 @@ export const DesktopSearch = observer(function DesktopSearch() {
>([])
const moderationOpts = useModerationOpts()
const search = useActorSearch()
const search = useActorAutocompleteFn()
const onChangeText = React.useCallback(
async (text: string) => {