重构核心模块并同步更新项目配置与相关实现

This commit is contained in:
truewhile
2026-09-13 20:36:14 +08:00
parent 386fc358d1
commit 9a68ef701f
38 changed files with 1587 additions and 678 deletions
+44
View File
@@ -0,0 +1,44 @@
import { useEffect, useRef, type RefObject } from 'react'
const DEFAULT_ROOT_MARGIN = '480px 0px'
/**
* 元素首次进入滚动容器附近时触发一次。用于媒体库预览的按需加载。
*/
export function useInViewOnce<T extends Element>(
onVisible: () => void,
rootMargin = DEFAULT_ROOT_MARGIN,
): RefObject<T> {
const ref = useRef<T>(null)
const callbackRef = useRef(onVisible)
useEffect(() => {
callbackRef.current = onVisible
}, [onVisible])
useEffect(() => {
const element = ref.current
if (!element) return
if (typeof IntersectionObserver === 'undefined') {
callbackRef.current()
return
}
const root = document.getElementById('app-main-scroll')
let fired = false
const observer = new IntersectionObserver(
(entries) => {
if (fired || !entries.some((entry) => entry.isIntersecting)) return
fired = true
observer.disconnect()
callbackRef.current()
},
{ root, rootMargin, threshold: 0.01 },
)
observer.observe(element)
return () => observer.disconnect()
}, [rootMargin])
return ref
}
+40
View File
@@ -0,0 +1,40 @@
import { useCallback, useEffect, useRef } from 'react'
/**
* 合并短时间内进入视口的预览请求,避免每个卡片各发一次 HTTP 请求。
* 回调放在 ref 中,调用方每次渲染传新的闭包也不会重建定时器。
*/
export function useLazyPreviewBatch(
onNeedPreviews?: (ids: string[]) => void,
delayMs = 48,
) {
const pendingRef = useRef<Set<string>>(new Set())
const timerRef = useRef<number | null>(null)
const callbackRef = useRef(onNeedPreviews)
useEffect(() => {
callbackRef.current = onNeedPreviews
}, [onNeedPreviews])
useEffect(() => {
return () => {
if (timerRef.current !== null) {
window.clearTimeout(timerRef.current)
}
}
}, [])
return useCallback((id: string) => {
if (!id || !callbackRef.current) return
pendingRef.current.add(id)
if (timerRef.current !== null) return
timerRef.current = window.setTimeout(() => {
timerRef.current = null
const ids = Array.from(pendingRef.current)
pendingRef.current.clear()
if (ids.length > 0) {
callbackRef.current?.(ids)
}
}, delayMs)
}, [delayMs])
}