This commit is contained in:
truewhile
2026-09-13 21:23:06 +08:00
parent 670dd90dbe
commit b8e48a1f45
14 changed files with 218 additions and 36 deletions
+4 -6
View File
@@ -8,6 +8,7 @@ import type { SeriesCard } from '../utils/groupSeries'
import { fetchLibraries, peekLibraries } from '../utils/libraryCache'
import { usePinnedLibraries } from '../hooks/usePinnedLibraries'
import { sortByPinnedIds } from '../utils/pinnedLibraries'
import { partitionPreviewIDs } from '../utils/remoteEmby'
import {
ContinueWatchingSection,
ContinueWatchingSkeleton,
@@ -18,7 +19,6 @@ import {
HomeLoadingState,
} from './HomePageSections'
const PREVIEW_BATCH_SIZE = 4
const hasArtwork = (media?: Media | null) => !!(media?.poster_url || media?.backdrop_url)
export function HomePage() {
@@ -102,12 +102,10 @@ export function HomePage() {
if (targets.length === 0) return
targets.forEach((id) => fetchingPreviewLimitsRef.current.set(id, limit))
const batches: string[][] = []
for (let i = 0; i < targets.length; i += PREVIEW_BATCH_SIZE) {
batches.push(targets.slice(i, i + PREVIEW_BATCH_SIZE))
}
// 本地库一次拉完(同一条窗口查询、缓存键稳定)。远程库单独一批,
// 避免一个慢的 Emby 挂载拖住整页预览。
const batches = partitionPreviewIDs(targets)
// 分批并发:一个慢库不再阻塞整页预览,先返回的批次立即渲染。
await Promise.allSettled(
batches.map(async (batch) => {
let loaded = false
+27 -23
View File
@@ -15,6 +15,7 @@ import type { Library } from '../types'
import type { SeriesCard } from '../utils/groupSeries'
import { fetchLibraries, invalidateLibraries, peekLibraries } from '../utils/libraryCache'
import { sortLibraryPreviews } from '../utils/pinnedLibraries'
import { partitionPreviewIDs } from '../utils/remoteEmby'
export function LibrariesPage() {
const [libraries, setLibraries] = useState<Library[]>([])
@@ -33,30 +34,33 @@ export function LibrariesPage() {
if (targets.length === 0) return
targets.forEach((id) => fetchingRef.current.add(id))
let loaded = false
try {
const rows = await libraryAPI.listPreviews(targets, 10)
loaded = true
setLibraryData((prev) => {
const next = { ...prev }
for (const row of rows) {
next[row.id] = {
cards: row.cards ?? [],
total: row.total ?? 0,
}
const batches = partitionPreviewIDs(targets)
await Promise.allSettled(
batches.map(async (batch) => {
let loaded = false
try {
const rows = await libraryAPI.listPreviews(batch, 10)
loaded = true
setLibraryData((prev) => {
const next = { ...prev }
for (const row of rows) {
next[row.id] = {
cards: row.cards ?? [],
total: row.total ?? 0,
}
}
return next
})
} catch {
// 单个批次失败不影响其他批次。
} finally {
batch.forEach((id) => {
if (loaded) fetchedLibIdsRef.current.add(id)
fetchingRef.current.delete(id)
})
}
return next
})
} catch {
// 容错
} finally {
targets.forEach((id) => {
if (loaded) {
fetchedLibIdsRef.current.add(id)
}
fetchingRef.current.delete(id)
})
}
}),
)
}, [])
const loadLibraries = useCallback(async (options?: { force?: boolean }) => {