Defer profile world history until needed

This commit is contained in:
test
2026-08-30 12:02:07 +02:00
parent 5c80402aed
commit 937f484cc9
8 changed files with 282 additions and 11 deletions
@@ -0,0 +1,79 @@
import { useCallback, useEffect, useRef, useState } from 'react'
export default function useLazyProfileWorldHistory({ username, initialWorldHistory, enabled }) {
const hasInitialValue = initialWorldHistory !== null && initialWorldHistory !== undefined
const [data, setData] = useState(() => hasInitialValue ? initialWorldHistory : null)
const [loaded, setLoaded] = useState(hasInitialValue)
const [loading, setLoading] = useState(false)
const [error, setError] = useState(false)
const requestKeyRef = useRef(username)
const requestedRef = useRef(hasInitialValue)
const abortRef = useRef(null)
useEffect(() => {
if (requestKeyRef.current === username) return undefined
abortRef.current?.abort()
abortRef.current = null
requestKeyRef.current = username
requestedRef.current = false
setData(null)
setLoaded(false)
setLoading(false)
setError(false)
return undefined
}, [username])
useEffect(() => {
if (!hasInitialValue || requestKeyRef.current !== username) return
abortRef.current?.abort()
abortRef.current = null
requestedRef.current = true
setData(initialWorldHistory)
setLoaded(true)
setLoading(false)
setError(false)
}, [hasInitialValue, initialWorldHistory, username])
const load = useCallback(async () => {
if (!enabled || hasInitialValue || requestKeyRef.current !== username || requestedRef.current || !username) return
requestedRef.current = true
const controller = new AbortController()
const requestKey = requestKeyRef.current
abortRef.current = controller
setLoading(true)
setError(false)
try {
const response = await fetch(`/api/profile/${encodeURIComponent(username)}/world-history`, {
headers: { Accept: 'application/json' },
credentials: 'same-origin',
signal: controller.signal,
})
if (!response.ok) throw new Error('World history could not be loaded.')
const payload = await response.json()
if (requestKey !== requestKeyRef.current || controller.signal.aborted) return
setData(payload)
setLoaded(true)
} catch (caught) {
if (caught?.name === 'AbortError' || requestKey !== requestKeyRef.current) return
requestedRef.current = false
setError(true)
} finally {
if (requestKey === requestKeyRef.current) {
abortRef.current = null
setLoading(false)
}
}
}, [enabled, hasInitialValue, username])
useEffect(() => {
if (enabled) load()
}, [enabled, load])
useEffect(() => () => abortRef.current?.abort(), [])
return { data, loaded, loading, error, retry: load }
}