feat: force refresh of user relay list cache when viewing profile

This commit is contained in:
codytseng
2025-05-21 22:52:43 +08:00
parent 2e4602e973
commit 44a9b6ee0e
4 changed files with 57 additions and 40 deletions

View File

@@ -22,7 +22,7 @@ export function useSearchProfiles(search: string, limit: number) {
setIsFetching(true) setIsFetching(true)
setProfiles([]) setProfiles([])
try { try {
const profiles = await client.fetchProfiles( const profiles = await client.searchProfiles(
searchableRelayUrls.concat(SEARCHABLE_RELAY_URLS).slice(0, 4), searchableRelayUrls.concat(SEARCHABLE_RELAY_URLS).slice(0, 4),
{ {
search, search,

View File

@@ -66,7 +66,7 @@ const ProfileListPage = forwardRef(({ index }: { index?: number }, ref) => {
if (urls.length === 0) { if (urls.length === 0) {
return setHasMore(false) return setHasMore(false)
} }
const profiles = await client.fetchProfiles(urls, { ...filter, limit: LIMIT }) const profiles = await client.searchProfiles(urls, { ...filter, limit: LIMIT })
const newPubkeySet = new Set<string>() const newPubkeySet = new Set<string>()
profiles.forEach((profile) => { profiles.forEach((profile) => {
if (!pubkeySet.has(profile.pubkey)) { if (!pubkeySet.has(profile.pubkey)) {

View File

@@ -18,6 +18,7 @@ import { generateImageByPubkey } from '@/lib/pubkey'
import { SecondaryPageLink, useSecondaryPage } from '@/PageManager' import { SecondaryPageLink, useSecondaryPage } from '@/PageManager'
import { useMuteList } from '@/providers/MuteListProvider' import { useMuteList } from '@/providers/MuteListProvider'
import { useNostr } from '@/providers/NostrProvider' import { useNostr } from '@/providers/NostrProvider'
import client from '@/services/client.service'
import { Link, Zap } from 'lucide-react' import { Link, Zap } from 'lucide-react'
import { forwardRef, useCallback, useEffect, useMemo, useState } from 'react' import { forwardRef, useCallback, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
@@ -28,7 +29,7 @@ import Relays from './Relays'
const ProfilePage = forwardRef(({ id, index }: { id?: string; index?: number }, ref) => { const ProfilePage = forwardRef(({ id, index }: { id?: string; index?: number }, ref) => {
const { t } = useTranslation() const { t } = useTranslation()
const { push } = useSecondaryPage() const { push } = useSecondaryPage()
const { profile, isFetching } = useFetchProfile(id, true) const { profile, isFetching } = useFetchProfile(id)
const { pubkey: accountPubkey } = useNostr() const { pubkey: accountPubkey } = useNostr()
const { mutePubkeys } = useMuteList() const { mutePubkeys } = useMuteList()
const { followings } = useFetchFollowings(profile?.pubkey) const { followings } = useFetchFollowings(profile?.pubkey)
@@ -50,6 +51,18 @@ const ProfilePage = forwardRef(({ id, index }: { id?: string; index?: number },
} }
}, []) }, [])
useEffect(() => {
if (!profile?.pubkey) return
const forceUpdateCache = async () => {
await Promise.all([
client.forceUpdateRelayListEvent(profile.pubkey),
client.fetchProfile(profile.pubkey, true)
])
}
forceUpdateCache()
}, [profile?.pubkey])
useEffect(() => { useEffect(() => {
if (!topContainer) return if (!topContainer) return

View File

@@ -699,7 +699,7 @@ class ClientService extends EventTarget {
} }
} }
async fetchProfiles(relayUrls: string[], filter: Filter): Promise<TProfile[]> { async searchProfiles(relayUrls: string[], filter: Filter): Promise<TProfile[]> {
const events = await this.query(relayUrls, { const events = await this.query(relayUrls, {
...filter, ...filter,
kinds: [kinds.Metadata] kinds: [kinds.Metadata]
@@ -715,21 +715,32 @@ class ClientService extends EventTarget {
} }
async fetchRelayList(pubkey: string): Promise<TRelayList> { async fetchRelayList(pubkey: string): Promise<TRelayList> {
const event = await this.relayListEventDataLoader.load(pubkey) const [relayList] = await this.fetchRelayLists([pubkey])
if (!event) { return relayList
return {
write: BIG_RELAY_URLS,
read: BIG_RELAY_URLS,
originalRelays: []
}
}
return getRelayListFromRelayListEvent(event)
} }
async fetchRelayLists(pubkeys: string[]) { async fetchRelayLists(pubkeys: string[]): Promise<TRelayList[]> {
const events = await this.relayListEventDataLoader.loadMany(pubkeys) const relayEvents = await indexedDb.getManyReplaceableEvents(pubkeys, kinds.RelayList)
return events.map((event) => { const nonExistingPubkeyIndexMap = new Map<string, number>()
pubkeys.forEach((pubkey, i) => {
if (!relayEvents[i]) {
nonExistingPubkeyIndexMap.set(pubkey, i)
}
})
const newEvents = await this.relayListEventDataLoader.loadMany(
Array.from(nonExistingPubkeyIndexMap.keys())
)
newEvents.forEach((event) => {
if (event && !(event instanceof Error)) { if (event && !(event instanceof Error)) {
const index = nonExistingPubkeyIndexMap.get(event.pubkey)
if (index !== undefined) {
relayEvents[index] = event
}
}
})
return relayEvents.map((event) => {
if (event) {
return getRelayListFromRelayListEvent(event) return getRelayListFromRelayListEvent(event)
} }
return { return {
@@ -740,6 +751,10 @@ class ClientService extends EventTarget {
}) })
} }
async forceUpdateRelayListEvent(pubkey: string) {
await this.relayListEventBatchLoadFn([pubkey])
}
async fetchFollowListEvent(pubkey: string, storeToIndexedDb = false) { async fetchFollowListEvent(pubkey: string, storeToIndexedDb = false) {
const event = await this.followListCache.fetch(pubkey) const event = await this.followListCache.fetch(pubkey)
if (storeToIndexedDb && event) { if (storeToIndexedDb && event) {
@@ -998,11 +1013,8 @@ class ClientService extends EventTarget {
} }
private async relayListEventBatchLoadFn(pubkeys: readonly string[]) { private async relayListEventBatchLoadFn(pubkeys: readonly string[]) {
const relayEvents = await indexedDb.getManyReplaceableEvents(pubkeys, kinds.RelayList)
const nonExistingPubkeys = pubkeys.filter((_, i) => !relayEvents[i])
if (nonExistingPubkeys.length) {
const events = await this.query(BIG_RELAY_URLS, { const events = await this.query(BIG_RELAY_URLS, {
authors: nonExistingPubkeys as string[], authors: pubkeys as string[],
kinds: [kinds.RelayList], kinds: [kinds.RelayList],
limit: pubkeys.length limit: pubkeys.length
}) })
@@ -1015,16 +1027,8 @@ class ClientService extends EventTarget {
} }
} }
Array.from(eventsMap.values()).forEach((evt) => indexedDb.putReplaceableEvent(evt)) Array.from(eventsMap.values()).forEach((evt) => indexedDb.putReplaceableEvent(evt))
nonExistingPubkeys.forEach((pubkey) => {
const event = eventsMap.get(pubkey)
if (event) {
const index = pubkeys.indexOf(pubkey)
relayEvents[index] = event
}
})
}
return relayEvents return pubkeys.map((pubkey) => eventsMap.get(pubkey))
} }
private async _fetchFollowListEvent(pubkey: string) { private async _fetchFollowListEvent(pubkey: string) {