详情点击可大图

This commit is contained in:
mtvpls
2026-02-06 10:34:14 +08:00
parent 161243b0a7
commit deb887c6e1
4 changed files with 240 additions and 5 deletions
+35 -3
View File
@@ -8,6 +8,8 @@ import { createPortal } from 'react-dom';
import { getTMDBImageUrl } from '@/lib/tmdb.client';
import { processImageUrl } from '@/lib/utils';
import ImageViewer from '@/components/ImageViewer';
interface DetailPanelProps {
isOpen: boolean;
onClose: () => void;
@@ -91,6 +93,8 @@ const DetailPanel: React.FC<DetailPanelProps> = ({
const [expandedEpisodes, setExpandedEpisodes] = useState<Set<number>>(new Set());
const [selectedSeason, setSelectedSeason] = useState<number>(1);
const [seasonsLoaded, setSeasonsLoaded] = useState(false);
const [showImageViewer, setShowImageViewer] = useState(false);
const [selectedImage, setSelectedImage] = useState<string>('');
// 拖动滚动状态
const [isDragging, setIsDragging] = useState(false);
@@ -99,6 +103,12 @@ const DetailPanel: React.FC<DetailPanelProps> = ({
const [scrollLeft, setScrollLeft] = useState(0);
const episodesScrollRef = React.useRef<HTMLDivElement>(null);
// 图片点击处理
const handleImageClick = (imageUrl: string) => {
setSelectedImage(imageUrl);
setShowImageViewer(true);
};
// 确保组件在客户端挂载后才渲染 Portal
useEffect(() => {
setMounted(true);
@@ -608,7 +618,10 @@ const DetailPanel: React.FC<DetailPanelProps> = ({
{/* 海报和基本信息 */}
<div className="flex gap-6 mb-6">
{detailData.poster && (
<div className="relative w-32 h-48 rounded-lg overflow-hidden bg-gray-100 dark:bg-gray-800 flex-shrink-0">
<div
className="relative w-32 h-48 rounded-lg overflow-hidden bg-gray-100 dark:bg-gray-800 flex-shrink-0 cursor-pointer hover:opacity-90 transition-opacity"
onClick={() => handleImageClick(detailData.poster!)}
>
<Image src={detailData.poster} alt={detailData.title} fill className="object-cover" draggable={false} />
</div>
)}
@@ -788,7 +801,13 @@ const DetailPanel: React.FC<DetailPanelProps> = ({
}`}
>
{season.poster_path && (
<div className="relative w-12 h-16 rounded overflow-hidden bg-gray-200 dark:bg-gray-700 flex-shrink-0">
<div
className="relative w-12 h-16 rounded overflow-hidden bg-gray-200 dark:bg-gray-700 flex-shrink-0 hover:opacity-80 transition-opacity"
onClick={(e) => {
e.stopPropagation();
handleImageClick(processImageUrl(getTMDBImageUrl(season.poster_path, 'w500')));
}}
>
<Image
src={processImageUrl(getTMDBImageUrl(season.poster_path, 'w92'))}
alt={season.name}
@@ -840,7 +859,10 @@ const DetailPanel: React.FC<DetailPanelProps> = ({
style={{ pointerEvents: isDragging ? 'none' : 'auto' }}
>
{episode.still_path && (
<div className="relative w-full h-36 rounded overflow-hidden bg-gray-200 dark:bg-gray-700 mb-2">
<div
className="relative w-full h-36 rounded overflow-hidden bg-gray-200 dark:bg-gray-700 mb-2 cursor-pointer hover:opacity-90 transition-opacity"
onClick={() => handleImageClick(processImageUrl(getTMDBImageUrl(episode.still_path, 'w500')))}
>
<Image
src={processImageUrl(getTMDBImageUrl(episode.still_path, 'w300'))}
alt={episode.name}
@@ -889,6 +911,16 @@ const DetailPanel: React.FC<DetailPanelProps> = ({
)}
</div>
</div>
{/* 图片查看器 */}
{showImageViewer && (
<ImageViewer
isOpen={showImageViewer}
onClose={() => setShowImageViewer(false)}
imageUrl={selectedImage}
alt={detailData?.title || title}
/>
)}
</div>
);