Browse Source

fix profile threads

imwald
Silberengel 4 weeks ago
parent
commit
fedba2eedc
  1. 2
      src/PageManager.tsx
  2. 13
      src/components/NoteList/index.tsx
  3. 11
      src/hooks/useProfileReportsEvents.tsx
  4. 37
      src/hooks/useProfileWall.tsx
  5. 8
      src/services/client.service.ts

2
src/PageManager.tsx

@ -2165,7 +2165,7 @@ export function PageManager({ maxStackSize = 5 }: { maxStackSize?: number }) {
const primaryFrozen = const primaryFrozen =
secondaryStack.length > 0 && (isSmallScreen || panelMode === 'double') secondaryStack.length > 0 && (isSmallScreen || panelMode === 'double')
useEffect(() => { useLayoutEffect(() => {
noteStatsService.setBackgroundStatsPaused(primaryFrozen) noteStatsService.setBackgroundStatsPaused(primaryFrozen)
if (primaryFrozen) { if (primaryFrozen) {
client.interruptBackgroundQueries() client.interruptBackgroundQueries()

13
src/components/NoteList/index.tsx

@ -995,6 +995,11 @@ const NoteList = forwardRef(
const primaryPageCtx = usePrimaryPageOptional() const primaryPageCtx = usePrimaryPageOptional()
const primaryPageCurrent = primaryPageCtx?.current ?? null const primaryPageCurrent = primaryPageCtx?.current ?? null
const primaryPanelFrozen = primaryPageCtx?.frozen ?? false const primaryPanelFrozen = primaryPageCtx?.frozen ?? false
/** Only pause timelines on the active primary page feed — not secondary-panel profiles, search, etc. */
const pauseTimelineForPrimaryFreeze =
primaryPanelFrozen &&
hostPrimaryPageName != null &&
hostPrimaryPageName === primaryPageCurrent
/** Clears text/author/time/full-search; does not change panel open state. */ /** Clears text/author/time/full-search; does not change panel open state. */
const clearFeedClientSearchCriteria = useCallback(() => { const clearFeedClientSearchCriteria = useCallback(() => {
@ -1890,7 +1895,7 @@ const NoteList = forwardRef(
timelineEstablishedCloserRef.current?.() timelineEstablishedCloserRef.current?.()
timelineEstablishedCloserRef.current = null timelineEstablishedCloserRef.current = null
if (primaryPanelFrozen) { if (pauseTimelineForPrimaryFreeze) {
return () => {} return () => {}
} }
@ -3251,12 +3256,12 @@ const NoteList = forwardRef(
progressiveWarmupQuery, progressiveWarmupQuery,
hostPrimaryPageName, hostPrimaryPageName,
relayAuthoritativeFeedOnly, relayAuthoritativeFeedOnly,
primaryPanelFrozen pauseTimelineForPrimaryFreeze
]) ])
useEffect(() => { useEffect(() => {
if (oneShotFetch) return if (oneShotFetch) return
if (primaryPanelFrozen) { if (pauseTimelineForPrimaryFreeze) {
followingFeedDeltaCloserRef.current?.() followingFeedDeltaCloserRef.current?.()
followingFeedDeltaCloserRef.current = null followingFeedDeltaCloserRef.current = null
return return
@ -3519,7 +3524,7 @@ const NoteList = forwardRef(
showKind1OPs, showKind1OPs,
showKind1Replies, showKind1Replies,
showKind1111, showKind1111,
primaryPanelFrozen pauseTimelineForPrimaryFreeze
]) ])
const oneShotDebugPrevLoadingRef = useRef(false) const oneShotDebugPrevLoadingRef = useRef(false)

11
src/hooks/useProfileReportsEvents.tsx

@ -236,7 +236,8 @@ export function useProfileReportsEvents({
const fetched = await client.fetchEvents(provisionalUrls, filter, { const fetched = await client.fetchEvents(provisionalUrls, filter, {
cache: true, cache: true,
eoseTimeout: 4500, eoseTimeout: 4500,
globalTimeout: 14_000 globalTimeout: 14_000,
foreground: true
}) })
if (!cancelled) { if (!cancelled) {
for (const e of fetched) pool.set(e.id, e) for (const e of fetched) pool.set(e.id, e)
@ -266,7 +267,8 @@ export function useProfileReportsEvents({
const fetchedDelta = await client.fetchEvents(deltaUrls, filter, { const fetchedDelta = await client.fetchEvents(deltaUrls, filter, {
cache: true, cache: true,
eoseTimeout: 4500, eoseTimeout: 4500,
globalTimeout: 14_000 globalTimeout: 14_000,
foreground: true
}) })
if (!cancelled) { if (!cancelled) {
for (const e of fetchedDelta) pool.set(e.id, e) for (const e of fetchedDelta) pool.set(e.id, e)
@ -295,14 +297,15 @@ export function useProfileReportsEvents({
} }
setIsLoading(true) setIsLoading(true)
try {
await Promise.all([ await Promise.all([
loadMode('received', receivedCacheKey, setReceived), loadMode('received', receivedCacheKey, setReceived),
loadMode('made', madeCacheKey, setMade) loadMode('made', madeCacheKey, setMade)
]) ])
} finally {
if (!cancelled) setIsLoading(false) if (!cancelled) setIsLoading(false)
} }
}
void run() void run()

37
src/hooks/useProfileWall.tsx

@ -65,7 +65,8 @@ async function fetchBadgeDefinitionOnRelays(
{ {
replaceableRace: true, replaceableRace: true,
eoseTimeout: METADATA_BATCH_QUERY_EOSE_TIMEOUT_MS, eoseTimeout: METADATA_BATCH_QUERY_EOSE_TIMEOUT_MS,
globalTimeout: METADATA_BATCH_QUERY_GLOBAL_TIMEOUT_MS globalTimeout: METADATA_BATCH_QUERY_GLOBAL_TIMEOUT_MS,
foreground: true
} }
) )
const matches = rows.filter((e) => e.kind === ExtendedKind.BADGE_DEFINITION) const matches = rows.filter((e) => e.kind === ExtendedKind.BADGE_DEFINITION)
@ -110,8 +111,6 @@ export function useProfileWall(pubkey: string, profileEventId: string | undefine
useEffect(() => { useEffect(() => {
let cancelled = false let cancelled = false
let idleHandle: number | undefined
let idleTimeout: ReturnType<typeof setTimeout> | undefined
const run = async () => { const run = async () => {
const mem = wallCacheByKey.get(cacheKey) const mem = wallCacheByKey.get(cacheKey)
@ -123,14 +122,18 @@ export function useProfileWall(pubkey: string, profileEventId: string | undefine
} }
setIsLoading(true) setIsLoading(true)
try {
const pkNorm = userIdToPubkey(pubkey) || pubkey const pkNorm = userIdToPubkey(pubkey) || pubkey
if (!isValidPubkey(pkNorm)) { if (!isValidPubkey(pkNorm)) {
if (!cancelled) setIsLoading(false)
return return
} }
const emptyAuthor = { read: [] as string[], write: [] as string[], httpRead: [] as string[], httpWrite: [] as string[] } const emptyAuthor = {
read: [] as string[],
write: [] as string[],
httpRead: [] as string[],
httpWrite: [] as string[]
}
const authorRl = await client.peekRelayListFromStorage(pubkey).catch(() => emptyAuthor) const authorRl = await client.peekRelayListFromStorage(pubkey).catch(() => emptyAuthor)
if (cancelled) return if (cancelled) return
@ -181,7 +184,8 @@ export function useProfileWall(pubkey: string, profileEventId: string | undefine
client.fetchEvents(relayUrls, filter, { client.fetchEvents(relayUrls, filter, {
cache: true, cache: true,
eoseTimeout: 4500, eoseTimeout: 4500,
globalTimeout: 14_000 globalTimeout: 14_000,
foreground: true
}) })
) )
) )
@ -209,26 +213,15 @@ export function useProfileWall(pubkey: string, profileEventId: string | undefine
comments: wallComments, comments: wallComments,
lastUpdated: Date.now() lastUpdated: Date.now()
}) })
setIsLoading(false) } finally {
} if (!cancelled) setIsLoading(false)
const scheduleRun = () => {
if (typeof requestIdleCallback === 'function') {
idleHandle = requestIdleCallback(() => void run(), { timeout: 4_000 })
} else {
idleTimeout = setTimeout(() => void run(), 400)
} }
} }
scheduleRun()
void run()
return () => { return () => {
cancelled = true cancelled = true
if (idleHandle !== undefined && typeof cancelIdleCallback === 'function') {
cancelIdleCallback(idleHandle)
}
if (idleTimeout !== undefined) {
clearTimeout(idleTimeout)
}
} }
}, [pubkey, profileEventId, cacheKey, refreshToken, relayListsKey]) }, [pubkey, profileEventId, cacheKey, refreshToken, relayListsKey])

8
src/services/client.service.ts

@ -3419,7 +3419,8 @@ class ClientService extends EventTarget {
globalTimeout, globalTimeout,
firstRelayResultGraceMs, firstRelayResultGraceMs,
replaceableRace, replaceableRace,
immediateReturn immediateReturn,
foreground
}: { }: {
onevent?: (evt: NEvent) => void onevent?: (evt: NEvent) => void
cache?: boolean cache?: boolean
@ -3428,6 +3429,8 @@ class ClientService extends EventTarget {
firstRelayResultGraceMs?: number | false firstRelayResultGraceMs?: number | false
replaceableRace?: boolean replaceableRace?: boolean
immediateReturn?: boolean immediateReturn?: boolean
/** When true, ignore {@link QueryService.interruptBackgroundQueries} (e.g. secondary-panel profile loads). */
foreground?: boolean
} = {} } = {}
) { ) {
const originalDedupedRelays = Array.from(new Set(urls)) const originalDedupedRelays = Array.from(new Set(urls))
@ -3467,7 +3470,8 @@ class ClientService extends EventTarget {
globalTimeout, globalTimeout,
firstRelayResultGraceMs, firstRelayResultGraceMs,
replaceableRace, replaceableRace,
immediateReturn immediateReturn,
foreground
}) })
if (cache) { if (cache) {
events.forEach((evt) => { events.forEach((evt) => {

Loading…
Cancel
Save