'use client'; import React, { useRef, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Trash2, RefreshCw, Play, Pause, Volume2, VolumeX, Upload, Library, Video, User, MapPin, Settings } from 'lucide-react'; import { GlassIconButton } from './glass-icon-button'; import { cn } from '@/public/lib/utils'; import { ReplaceVideoModal } from './replace-video-modal'; import { MediaPropertiesModal } from './media-properties-modal'; import { DramaLineChart } from './drama-line-chart'; interface ShotTabContentProps { taskSketch: any[]; currentSketchIndex: number; onSketchSelect: (index: number) => void; isPlaying?: boolean; } export function ShotTabContent({ taskSketch = [], currentSketchIndex = 0, onSketchSelect, isPlaying: externalIsPlaying = true }: ShotTabContentProps) { const thumbnailsRef = useRef(null); const videosRef = useRef(null); const videoPlayerRef = useRef(null); const [isPlaying, setIsPlaying] = React.useState(externalIsPlaying); const [isMuted, setIsMuted] = React.useState(false); const [progress, setProgress] = React.useState(0); const [isReplaceModalOpen, setIsReplaceModalOpen] = React.useState(false); const [activeReplaceMethod, setActiveReplaceMethod] = React.useState<'upload' | 'library' | 'generate'>('upload'); const [isMediaPropertiesModalOpen, setIsMediaPropertiesModalOpen] = React.useState(false); // 监听外部播放状态变化 useEffect(() => { setIsPlaying(externalIsPlaying); }, [externalIsPlaying]); // 确保 taskSketch 是数组 const sketches = Array.isArray(taskSketch) ? taskSketch : []; // 自动滚动到选中项 useEffect(() => { if (thumbnailsRef.current && videosRef.current) { const thumbnailContainer = thumbnailsRef.current; const videoContainer = videosRef.current; const thumbnailWidth = thumbnailContainer.children[0]?.clientWidth ?? 0; const thumbnailGap = 16; // gap-4 = 16px const thumbnailScrollPosition = (thumbnailWidth + thumbnailGap) * currentSketchIndex; const videoElement = videoContainer.children[currentSketchIndex] as HTMLElement; const videoScrollPosition = videoElement?.offsetLeft ?? 0; thumbnailContainer.scrollTo({ left: thumbnailScrollPosition - thumbnailContainer.clientWidth / 2 + thumbnailWidth / 2, behavior: 'smooth' }); videoContainer.scrollTo({ left: videoScrollPosition - videoContainer.clientWidth / 2 + videoElement?.clientWidth / 2, behavior: 'smooth' }); } }, [currentSketchIndex]); // 视频播放控制 useEffect(() => { if (videoPlayerRef.current) { if (isPlaying) { videoPlayerRef.current.play().catch(() => { // 处理自动播放策略限制 setIsPlaying(false); }); } else { // videoPlayerRef.current.pause(); } } }, [isPlaying, currentSketchIndex]); // 更新进度条 const handleTimeUpdate = () => { if (videoPlayerRef.current) { const progress = (videoPlayerRef.current.currentTime / videoPlayerRef.current.duration) * 100; setProgress(progress); } }; // 如果没有数据,显示空状态 if (sketches.length === 0) { return (

No sketch data

); } return (
{/* 上部分 */} {/* 分镜缩略图行 */}
{sketches.map((sketch, index) => ( onSketchSelect(index)} whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }} > ))}
{/* 视频描述行 - 单行滚动 */}
{sketches.map((video, index) => { const isActive = currentSketchIndex === index; return ( onSketchSelect(index)} initial={false} animate={{ scale: isActive ? 1.02 : 1, }} >
Shot {index + 1} {index < sketches.length - 1 && ( | )}
); })}
{/* 渐变遮罩 */}
{/* 下部分 */} {/* 视频预览和操作 */}
{/* 选中的视频预览 */}
{/* 基础配置查看 场景/人物/运镜/对话 */}
{/* 场景: */}
{/* 替换视频弹窗 */} setIsReplaceModalOpen(false)} onVideoSelect={(video) => { console.log('Selected video:', video); setIsReplaceModalOpen(false); }} /> {/* Media Properties 弹窗 */} setIsMediaPropertiesModalOpen(false)} taskSketch={taskSketch} currentSketchIndex={currentSketchIndex} onSketchSelect={onSketchSelect} />
); }