import { useEffect, useState } from 'react' import { Link, useParams } from 'react-router-dom' import { Play } from 'lucide-react' import { mediaAPI } from '../api/library' import type { Media } from '../types' function fmtDuration(sec: number): string { if (!sec || sec <= 0) return '—' const h = Math.floor(sec / 3600) const m = Math.floor((sec % 3600) / 60) return h > 0 ? `${h}h ${m}m` : `${m}m` } function fmtSize(bytes: number): string { if (!bytes || bytes <= 0) return '—' const units = ['B', 'KB', 'MB', 'GB', 'TB'] let v = bytes let i = 0 while (v >= 1024 && i < units.length - 1) { v /= 1024 i++ } return `${v.toFixed(2)} ${units[i]}` } // Detail screen for a single media item: poster, summary and a Play CTA. export function MediaDetailPage() { const { id = '' } = useParams() const [media, setMedia] = useState(null) const [loading, setLoading] = useState(true) useEffect(() => { if (!id) return setLoading(true) mediaAPI .get(id) .then(setMedia) .finally(() => setLoading(false)) }, [id]) if (loading) return

加载中…

if (!media) return

媒体不存在

return (
{media.poster_url ? ( {media.title} ) : (
无海报
)}

{media.title}

{media.year > 0 &&

{media.year}

} {media.overview &&

{media.overview}

}
{media.video_codec && {media.video_codec.toUpperCase()}} {media.width > 0 && ( {media.width}×{media.height} )} {fmtDuration(media.duration_sec)} {fmtSize(media.size_bytes)} {media.container && {media.container.toUpperCase()}}
播放
) } function Badge({ children }: { children: React.ReactNode }) { return ( {children} ) }