/* eslint-disable react-hooks/exhaustive-deps, no-console */ 'use client'; import { Heart, LinkIcon } from 'lucide-react'; import Image from 'next/image'; import { useSearchParams } from 'next/navigation'; import { Suspense, useEffect, useState } from 'react'; import type { PlayRecord } from '@/lib/db.client'; import { generateStorageKey, getAllPlayRecords, isFavorited, toggleFavorite, } from '@/lib/db.client'; import { type VideoDetail, fetchVideoDetail } from '@/lib/fetchVideoDetail'; import PageLayout from '@/components/PageLayout'; function DetailPageClient() { const searchParams = useSearchParams(); const [detail, setDetail] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [playRecord, setPlayRecord] = useState(null); const [favorited, setFavorited] = useState(false); // 是否倒序显示选集 const [reverseEpisodeOrder, setReverseEpisodeOrder] = useState(false); const fallbackTitle = searchParams.get('title') || ''; const fallbackYear = searchParams.get('year') || ''; // 格式化剩余时间(如 1h 50m) const formatDuration = (seconds: number) => { const h = Math.floor(seconds / 3600); const m = Math.floor((seconds % 3600) / 60); const parts: string[] = []; if (h) parts.push(`${h}h`); if (m) parts.push(`${m}m`); if (parts.length === 0) parts.push('0m'); return parts.join(' '); }; useEffect(() => { const source = searchParams.get('source'); const id = searchParams.get('id'); if (!source || !id) { setError('缺少必要参数'); setLoading(false); return; } const fetchData = async () => { try { // 获取视频详情 const detailData = await fetchVideoDetail({ source, id, fallbackTitle, fallbackYear, }); setDetail(detailData); // 获取播放记录 const allRecords = await getAllPlayRecords(); const key = generateStorageKey(source, id); setPlayRecord(allRecords[key] || null); // 检查收藏状态 try { const fav = await isFavorited(source, id); setFavorited(fav); } catch (checkErr) { console.error('检查收藏状态失败:', checkErr); } } catch (err) { setError(err instanceof Error ? err.message : '获取详情失败'); } finally { setLoading(false); } }; fetchData(); }, [searchParams]); // 切换收藏状态 const handleToggleFavorite = async () => { const source = searchParams.get('source'); const id = searchParams.get('id'); if (!source || !id || !detail) return; try { const newState = await toggleFavorite(source, id, { title: detail.title, source_name: detail.source_name, year: detail.year || fallbackYear || '', cover: detail.poster || '', total_episodes: detail.episodes.length || 1, save_time: Date.now(), }); setFavorited(newState); } catch (err) { console.error('切换收藏失败:', err); } }; return (
{/* 顶部返回按钮已移入右侧信息容器 */} {loading ? (
) : error ? (
加载失败
{error}
) : !detail ? (
未找到视频详情
) : (
{/* 主信息区:左图右文 */}
{/* 返回按钮放置在主信息区左上角 */} {/* 封面 */}
{detail.title
{/* 右侧信息 */}

{detail.title || fallbackTitle} {detail.douban_id && ( e.stopPropagation()} className='ml-2' > )}

{detail.class && ( {detail.class} )} {(detail.year || fallbackYear) && ( {detail.year || fallbackYear} )} {detail.source_name && ( {detail.source_name} )} {detail.type_name && {detail.type_name}}
{/* 按钮区域 */}
{playRecord ? ( <> {/* 恢复播放 */}
恢复播放
{/* 从头开始 */}
从头开始
) : ( <> {/* 播放 */}
播放
)} {/* 爱心按钮 */}
{/* 播放记录进度条 */} {playRecord && (
{/* 进度条 */}
{/* 剩余时间 */} {playRecord.total_episodes > 1 ? `第${playRecord.index}集 剩余 ` : '剩余 '} {formatDuration( playRecord.total_time - playRecord.play_time )}
)} {detail.desc && (
{detail.desc}
)}
{/* 选集按钮区 */} {detail.episodes && detail.episodes.length > 0 && (
选集
共 {detail.episodes.length} 集
{/* 倒序切换 */} setReverseEpisodeOrder((prev) => !prev)} className={`ml-4 text-sm cursor-pointer select-none transition-colors ${ reverseEpisodeOrder ? 'text-green-500' : 'text-gray-400 hover:text-gray-500' }`} > 倒序
{(reverseEpisodeOrder ? Array.from( { length: detail.episodes.length }, (_, i) => i ).reverse() : Array.from( { length: detail.episodes.length }, (_, i) => i ) ).map((idx) => ( {idx + 1} ))}
)}
)}
); } export default function DetailPage() { return ( ); }