feat: 💨
This commit is contained in:
@@ -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<HTMLInputElement>(null)
|
||||
const [commandValue, setCommandValue] = useState('')
|
||||
const [debouncedCommandValue, setDebouncedCommandValue] = useState(commandValue)
|
||||
const { profiles, isFetching } = useSearchProfiles(debouncedCommandValue, 10)
|
||||
const [profiles, setProfiles] = useState<TProfile[]>([])
|
||||
|
||||
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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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[]
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user