feat: improve mention search results

This commit is contained in:
codytseng
2025-02-03 16:17:14 +08:00
parent faa7298f89
commit 699f3a792d
5 changed files with 47 additions and 8 deletions

View File

@@ -5,6 +5,7 @@ import { extractPubkeysFromEventTags } from '@/lib/tag'
import { TDraftEvent, TProfile, TRelayInfo, TRelayList } from '@/types'
import { sha256 } from '@noble/hashes/sha2'
import DataLoader from 'dataloader'
import FlexSearch from 'flexsearch'
import { LRUCache } from 'lru-cache'
import {
EventTemplate,
@@ -77,6 +78,10 @@ class ClientService extends EventTarget {
fetchMethod: this._fetchFollowListEvent.bind(this)
})
private userIndex = new FlexSearch.Index({
tokenize: 'full'
})
constructor() {
super()
}
@@ -499,6 +504,18 @@ class ClientService extends EventTarget {
return readRelays
}
async searchProfilesFromIndex(query: string) {
const result = await this.userIndex.searchAsync(query, { limit: 10 })
return Promise.all(result.map((pubkey) => this.fetchProfile(pubkey as string))).then(
(profiles) => profiles.filter(Boolean) as TProfile[]
)
}
async initUserIndexFromFollowings(pubkey: string) {
const followings = await this.fetchFollowings(pubkey)
await this.profileEventDataloader.loadMany(followings)
}
private async fetchEventById(relayUrls: string[], id: string): Promise<NEvent | undefined> {
const event = await this.fetchEventFromDefaultRelaysDataloader.load(id)
if (event) {
@@ -577,6 +594,7 @@ class ClientService extends EventTarget {
const profileFromDefaultRelays =
await this.fetchProfileEventFromDefaultRelaysDataloader.load(pubkey)
if (profileFromDefaultRelays) {
this.addUsernameToIndex(profileFromDefaultRelays)
return profileFromDefaultRelays
}
@@ -593,9 +611,29 @@ class ClientService extends EventTarget {
this.profileEventDataloader.prime(pubkey, Promise.resolve(profileEvent))
}
if (profileEvent) {
this.addUsernameToIndex(profileEvent)
}
return profileEvent
}
private addUsernameToIndex(profileEvent: NEvent) {
try {
const profileObj = JSON.parse(profileEvent.content)
const text = [
profileObj.display_name?.trim() ?? '',
profileObj.name?.trim() ?? '',
profileObj.nip05?.split('@')[0]?.trim() ?? ''
].join(' ')
if (!text) return
this.userIndex.add(profileEvent.pubkey, text)
} catch {
return
}
}
private async tryHarderToFetchEvent(
relayUrls: string[],
filter: Filter,