diff --git a/src/components/TextareaWithMentions.tsx/index.tsx b/src/components/TextareaWithMentions.tsx/index.tsx index 8b291278..6e0f7561 100644 --- a/src/components/TextareaWithMentions.tsx/index.tsx +++ b/src/components/TextareaWithMentions.tsx/index.tsx @@ -1,8 +1,9 @@ import { Command, CommandInput, CommandItem, CommandList } from '@/components/ui/command' import { Textarea } from '@/components/ui/textarea' -import { useSearchProfiles } from '@/hooks' import { pubkeyToNpub } from '@/lib/pubkey' import { cn } from '@/lib/utils' +import client from '@/services/client.service' +import { TProfile } from '@/types' import React, { ComponentProps, Dispatch, @@ -30,7 +31,7 @@ export default function TextareaWithMentions({ const inputRef = useRef(null) const [commandValue, setCommandValue] = useState('') const [debouncedCommandValue, setDebouncedCommandValue] = useState(commandValue) - const { profiles, isFetching } = useSearchProfiles(debouncedCommandValue, 10) + const [profiles, setProfiles] = useState([]) useEffect(() => { const handler = setTimeout(() => { @@ -42,16 +43,27 @@ export default function TextareaWithMentions({ } }, [commandValue]) + useEffect(() => { + setProfiles([]) + if (debouncedCommandValue) { + const fetchProfiles = async () => { + const newProfiles = await client.searchProfilesFromIndex(debouncedCommandValue, 100) + setProfiles(newProfiles) + } + fetchProfiles() + } + }, [debouncedCommandValue]) + useEffect(() => { const dropdown = dropdownRef.current if (!dropdown) return - if (profiles.length > 0 && !isFetching) { + if (profiles.length > 0) { dropdown.classList.remove('hidden') } else { dropdown.classList.add('hidden') } - }, [profiles, isFetching]) + }, [profiles]) const handleBlur = useCallback(() => { const dropdown = dropdownRef.current diff --git a/src/hooks/useSearchProfiles.tsx b/src/hooks/useSearchProfiles.tsx index 382d10bc..c2b518ea 100644 --- a/src/hooks/useSearchProfiles.tsx +++ b/src/hooks/useSearchProfiles.tsx @@ -1,3 +1,4 @@ +import { SEARCHABLE_RELAY_URLS } from '@/constants' import { useFeed } from '@/providers/FeedProvider' import client from '@/services/client.service' import { TProfile } from '@/types' @@ -21,7 +22,13 @@ export function useSearchProfiles(search: string, limit: number) { setIsFetching(true) setProfiles([]) try { - const profiles = await client.searchProfilesFromIndex(search) + const profiles = await client.fetchProfiles( + searchableRelayUrls.concat(SEARCHABLE_RELAY_URLS).slice(0, 4), + { + search, + limit + } + ) if (profiles) { setProfiles(profiles) } diff --git a/src/services/client.service.ts b/src/services/client.service.ts index edffa297..f4d0c156 100644 --- a/src/services/client.service.ts +++ b/src/services/client.service.ts @@ -79,7 +79,7 @@ class ClientService extends EventTarget { }) private userIndex = new FlexSearch.Index({ - tokenize: 'full' + tokenize: 'forward' }) constructor() { @@ -504,8 +504,8 @@ class ClientService extends EventTarget { return readRelays } - async searchProfilesFromIndex(query: string) { - const result = await this.userIndex.searchAsync(query, { limit: 100 }) + async searchProfilesFromIndex(query: string, limit: number = 100) { + const result = await this.userIndex.searchAsync(query, { limit }) return Promise.all(result.map((pubkey) => this.fetchProfile(pubkey as string))).then( (profiles) => profiles.filter(Boolean) as TProfile[] )