'use client'; import React, { useRef, useEffect, useState } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { RefreshCw, User, Loader2, X, Plus, Video, CircleX } from 'lucide-react'; import { cn } from '@/public/lib/utils'; import { PersonDetection, PersonDetectionScene } from './person-detection'; import { ShotsEditor } from './shot-editor/ShotsEditor'; import { CharacterLibrarySelector } from './character-library-selector'; import FloatingGlassPanel from './FloatingGlassPanel'; import { ReplaceCharacterPanel, mockShots, mockCharacter } from './replace-character-panel'; import HorizontalScroller from './HorizontalScroller'; import { useEditData } from '@/components/pages/work-flow/use-edit-data'; interface ShotTabContentProps { currentSketchIndex: number; roles?: any[]; } export function ShotTabContent({ currentSketchIndex = 0, roles = [] }: ShotTabContentProps) { const { loading, shotData, setSelectedSegment, regenerateVideoSegment, filterRole } = useEditData('shot'); const [selectedIndex, setSelectedIndex] = useState(currentSketchIndex); const [detections, setDetections] = useState([]); const [scanState, setScanState] = useState<'idle' | 'scanning' | 'detected'>('idle'); const [isReplaceLibraryOpen, setIsReplaceLibraryOpen] = useState(false); const [isReplacePanelOpen, setIsReplacePanelOpen] = useState(false); const shotsEditorRef = useRef(null); const videoRef = useRef(null); // 监听当前选中index变化 useEffect(() => { console.log('shotTabContent-----shotData', shotData); if (shotData.length > 0) { setSelectedSegment(shotData[selectedIndex]); } }, [selectedIndex]); // 处理扫描开始 const handleScan = () => { if (scanState === 'detected') { // 如果已经有检测结果,点击按钮退出检测状态 setScanState('idle'); setDetections([]); // 清除检测结果 return; } filterRole(document.getElementById('person-detection-video') as HTMLVideoElement); setScanState('scanning'); // 模拟检测过程 setTimeout(() => { const mockDetections: PersonDetection[] = [ { id: '1', name: '人物1', position: { top: 0, left: 100, width: 100, height: 200 } } ]; setDetections(mockDetections); }, 5000); }; // 处理扫描超时/失败 const handleScanTimeout = () => { setScanState('idle'); setDetections([]); }; // 处理检测到结果 const handleDetectionsChange = (newDetections: PersonDetection[]) => { if (newDetections.length > 0 && scanState === 'scanning') { setScanState('detected'); } }; // 处理人物点击 打开角色库 const handlePersonClick = (person: PersonDetection) => { console.log('person', person); setIsReplaceLibraryOpen(true); }; // 从角色库中选择角色 const handleSelectCharacter = (index: number) => { console.log('index', index); setIsReplaceLibraryOpen(false); // 模拟打开替换面板 setTimeout(() => { setIsReplacePanelOpen(true); }, 1000); }; // 确认替换角色 const handleConfirmReplace = (selectedShots: string[], addToLibrary: boolean) => { }; // 点击按钮重新生成 const handleRegenerate = () => { console.log('regenerate'); const shotInfo = shotsEditorRef.current.getShotInfo(); console.log('shotTabContent-----shotInfo', shotInfo); setSelectedSegment({ ...shotData[selectedIndex], lens: shotInfo }); // regenerateVideoSegment(); }; // 新增分镜 const handleAddShot = () => { console.log('add shot'); shotsEditorRef.current.addShot(); }; // 切换选择分镜 const handleSelectShot = (index: number) => { // 切换前 判断数据是否发生变化 setSelectedIndex(index); }; // 如果loading 显示loading状态 if (loading) { return (

Loading...

); } // 如果没有数据,显示空状态 if (shotData.length === 0) { return (
); } return (
{/* 上部分 */} {/* 分镜缩略图行 */}
handleSelectShot(i)} > {shotData.map((shot, index) => ( {shot.status === 0 && (
)} {shot.status === 1 && (
))}
{/* 视频描述行 - 单行滚动 */}
handleSelectShot(i)} > {shotData.map((shot, index) => { const isActive = selectedIndex === index; return (
Segment {index + 1} {shot.status === 0 && ( )} {shot.status === 2 && ( )} {index < shotData.length - 1 && ( | )}
); })}
{/* 渐变遮罩 */}
{/* 下部分 */} {/* 视频预览和操作 */}
{/* 选中的视频预览 */} <> {shotData[selectedIndex]?.status === 0 && (
Loading...
)} {shotData[selectedIndex]?.status === 1 && ( {/* 人物替换按钮 */} handleScan()} className={`p-2 backdrop-blur-sm transition-colors z-10 rounded-full ${scanState === 'detected' ? 'bg-cyan-500/50 hover:bg-cyan-500/70 text-white' : 'bg-black/50 hover:bg-black/70 text-white' }`} whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }} > {scanState === 'scanning' ? ( ) : scanState === 'detected' ? ( ) : ( )} )} {shotData[selectedIndex]?.status === 2 && (
任务失败,点击重新生成
)}
{/* 基础配置 */}
{/* 重新生成按钮、新增分镜按钮 */}
handleAddShot()} className="flex items-center justify-center gap-2 px-4 py-3 bg-pink-500/10 hover:bg-pink-500/20 text-pink-500 rounded-lg transition-colors" whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }} > Add Shot handleRegenerate()} className="flex items-center justify-center gap-2 px-4 py-3 bg-blue-500/10 hover:bg-blue-500/20 text-blue-500 rounded-lg transition-colors" whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }} > Regenerate
setIsReplacePanelOpen(false)} > setIsReplacePanelOpen(false)} onConfirm={handleConfirmReplace} />
); }