9 changed files with 158 additions and 54 deletions
@ -1,45 +1,87 @@ |
|||||||
import logger from '@/lib/logger' |
import logger from '@/lib/logger' |
||||||
import client from '@/services/client.service' |
import client from '@/services/client.service' |
||||||
|
import indexedDb from '@/services/indexed-db.service' |
||||||
import { TRelayList } from '@/types' |
import { TRelayList } from '@/types' |
||||||
|
import { kinds } from 'nostr-tools' |
||||||
import { useEffect, useState } from 'react' |
import { useEffect, useState } from 'react' |
||||||
|
|
||||||
export function useFetchRelayList(pubkey?: string | null) { |
const emptyRelayList = (): TRelayList => ({ |
||||||
const [relayList, setRelayList] = useState<TRelayList>({ |
|
||||||
write: [], |
write: [], |
||||||
read: [], |
read: [], |
||||||
originalRelays: [], |
originalRelays: [], |
||||||
httpRead: [], |
httpRead: [], |
||||||
httpWrite: [], |
httpWrite: [], |
||||||
httpOriginalRelays: [] |
httpOriginalRelays: [] |
||||||
}) |
}) |
||||||
|
|
||||||
|
export function useFetchRelayList(pubkey?: string | null) { |
||||||
|
const [relayList, setRelayList] = useState<TRelayList>(emptyRelayList) |
||||||
const [isFetching, setIsFetching] = useState(true) |
const [isFetching, setIsFetching] = useState(true) |
||||||
|
/** True when IndexedDB has this author's kind 10002 (even if `originalRelays` is empty after merge). */ |
||||||
|
const [hasKind10002InStorage, setHasKind10002InStorage] = useState(false) |
||||||
|
|
||||||
useEffect(() => { |
useEffect(() => { |
||||||
|
let cancelled = false |
||||||
|
const targetPk = pubkey?.trim() || null |
||||||
|
|
||||||
const fetchRelayList = async () => { |
const fetchRelayList = async () => { |
||||||
setIsFetching(true) |
setIsFetching(true) |
||||||
if (!pubkey) { |
setHasKind10002InStorage(false) |
||||||
|
if (!targetPk) { |
||||||
|
setRelayList(emptyRelayList()) |
||||||
setIsFetching(false) |
setIsFetching(false) |
||||||
return |
return |
||||||
} |
} |
||||||
|
|
||||||
|
setRelayList(emptyRelayList()) |
||||||
|
|
||||||
try { |
try { |
||||||
const fromStorage = await client.peekRelayListFromStorage(pubkey) |
const [fromStorage, k10002] = await Promise.all([ |
||||||
|
client.peekRelayListFromStorage(targetPk), |
||||||
|
indexedDb.getReplaceableEvent(targetPk, kinds.RelayList).catch(() => null) |
||||||
|
]) |
||||||
|
if (cancelled) return |
||||||
|
setHasKind10002InStorage(!!k10002) |
||||||
setRelayList(fromStorage) |
setRelayList(fromStorage) |
||||||
const relayList = await client.fetchRelayList(pubkey) |
|
||||||
setRelayList(relayList) |
const merged = await client.fetchRelayList(targetPk) |
||||||
|
if (cancelled) return |
||||||
|
setRelayList(merged) |
||||||
|
const k10002After = await indexedDb.getReplaceableEvent(targetPk, kinds.RelayList).catch(() => null) |
||||||
|
if (!cancelled) { |
||||||
|
setHasKind10002InStorage(!!k10002After) |
||||||
|
} |
||||||
} catch (err) { |
} catch (err) { |
||||||
logger.error('Failed to fetch relay list', { error: err, pubkey }) |
logger.error('Failed to fetch relay list', { error: err, pubkey: targetPk }) |
||||||
try { |
try { |
||||||
setRelayList(await client.peekRelayListFromStorage(pubkey)) |
const fallback = await client.peekRelayListFromStorage(targetPk) |
||||||
|
const k10002 = await indexedDb.getReplaceableEvent(targetPk, kinds.RelayList).catch(() => null) |
||||||
|
if (!cancelled) { |
||||||
|
setRelayList(fallback) |
||||||
|
setHasKind10002InStorage(!!k10002) |
||||||
|
} |
||||||
} catch { |
} catch { |
||||||
/* keep last good state */ |
if (!cancelled) { |
||||||
|
setRelayList(emptyRelayList()) |
||||||
|
} |
||||||
} |
} |
||||||
} finally { |
} finally { |
||||||
|
if (!cancelled) { |
||||||
setIsFetching(false) |
setIsFetching(false) |
||||||
} |
} |
||||||
} |
} |
||||||
|
} |
||||||
|
|
||||||
fetchRelayList() |
void fetchRelayList() |
||||||
|
return () => { |
||||||
|
cancelled = true |
||||||
|
} |
||||||
}, [pubkey]) |
}, [pubkey]) |
||||||
|
|
||||||
return { relayList, isFetching } |
const showingRelayListFallback = |
||||||
|
!isFetching && |
||||||
|
!hasKind10002InStorage && |
||||||
|
relayList.originalRelays.length === 0 |
||||||
|
|
||||||
|
return { relayList, isFetching, hasKind10002InStorage, showingRelayListFallback } |
||||||
} |
} |
||||||
|
|||||||
Loading…
Reference in new issue