import { useEffect, useMemo, useState } from 'react' import { GalleryHorizontalEnd, Layers } from 'lucide-react' import { libraryAPI } from '../api/library' import { MediaCard } from '../components/MediaCard' import { groupSeries } from '../utils/groupSeries' import type { Media } from '../types' const POSTER_WALL_PAGE_SIZE = 2000 // PosterWallPage 把所有媒体的代表海报聚合到同一面墙,便于一目了然 // 浏览整个站点的内容。所有 episode 行会按剧集折叠,避免同一海报刷屏。 export function PosterWallPage() { const [items, setItems] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState('') useEffect(() => { let cancelled = false async function loadPosterWall() { setLoading(true) setError('') try { const libraries = await libraryAPI.list() const all = ( await Promise.all( libraries.map(async (library) => { const rows: Media[] = [] let page = 1 for (;;) { const data = await libraryAPI.listMedia(library.id, page, POSTER_WALL_PAGE_SIZE, { groupVersions: false }) rows.push(...(data.items || [])) if (rows.length >= data.total || data.items.length === 0) break page += 1 } return rows }), ) ).flat() if (!cancelled) setItems(all) } catch (err) { if (!cancelled) { setError((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? '海报墙加载失败') } } finally { if (!cancelled) setLoading(false) } } loadPosterWall() return () => { cancelled = true } }, []) const cards = useMemo(() => groupSeries(items).slice(0, 240), [items]) return (

海报墙

按剧集聚合 · 共 {cards.length} 个条目

{loading &&

加载中…

} {!loading && error && (

{error}

)} {!loading && !error && cards.length === 0 && (

暂无媒体。请先添加媒体库并扫描。

)}
{cards.map((s) => (
{s.count > 1 && ( {s.count} )}
))}
) }