import React, { useState, useRef, useEffect } from 'react'; import { motion } from 'framer-motion'; import { Check, X, CircleAlert, ArrowLeft, ArrowRight, Loader2 } from 'lucide-react'; import { cn } from '@/public/lib/utils'; import { throttle } from 'lodash'; interface ReplacePanelProps { isLoading: boolean; title: string; shots: any[]; item: any; showAddToLibrary?: boolean; addToLibraryText?: string; onClose: () => void; onConfirm: (selectedShots: string[], addToLibrary: boolean) => void; } export function ReplacePanel({ isLoading, title, shots, item, showAddToLibrary = false, addToLibraryText = "Add to library", onClose, onConfirm, }: ReplacePanelProps) { const [selectedShots, setSelectedShots] = useState( shots.filter(shot => shot.isSelected).map(shot => shot.id) ); const [addToLibrary, setAddToLibrary] = useState(false); const [hoveredVideoId, setHoveredVideoId] = useState(null); const videoRefs = useRef<{ [key: string]: HTMLVideoElement }>({}); const shotsRef = useRef(null); useEffect(() => { console.log('replace-panel-shots', shots); }, [shots]); const handleShotToggle = (shotId: string) => { // setSelectedShots(prev => // prev.includes(shotId) // ? prev.filter(id => id !== shotId) // : [...prev, shotId] // ); }; const handleMouseEnter = (shotId: string) => { setHoveredVideoId(shotId); if (videoRefs.current[shotId]) { videoRefs.current[shotId].play(); } }; const handleMouseLeave = (shotId: string) => { setHoveredVideoId(null); if (videoRefs.current[shotId]) { videoRefs.current[shotId].pause(); videoRefs.current[shotId].currentTime = 0; } }; const throttledConfirm = React.useCallback( throttle(() => { onConfirm(selectedShots, addToLibrary); }, 1000, { trailing: false }), // 1秒内只能触发一次,不要执行最后一次调用 [selectedShots, addToLibrary, onConfirm] ); // 在组件卸载时取消节流函数中的定时器 React.useEffect(() => { return () => { throttledConfirm.cancel(); }; }, [throttledConfirm]); const handleConfirm = () => { throttledConfirm(); }; const handleLeftArrowClick = () => { if (!shotsRef.current) return; shotsRef.current.scrollBy({ left: -300, // 每次滚动的距离 behavior: 'smooth' // 平滑滚动 }); }; const handleRightArrowClick = () => { if (!shotsRef.current) return; shotsRef.current.scrollBy({ left: 300, // 每次滚动的距离 behavior: 'smooth' // 平滑滚动 }); }; if (isLoading) { return (

Loading...

) } return (
{/* 标题 */}
{title}
{/* 提示信息 */}
This role appears in {shots.length} shots, replacing it will affect the following shots.
{/*
handleSelectAllShots(e.target.checked)} className="w-4 h-4 rounded border-white/20" />
*/}
{/* 分镜展示区 */}
{/*
选择需要替换的分镜:
*/}
{shots.map((shot) => ( handleShotToggle(shot.id)} onMouseEnter={() => handleMouseEnter(shot.id)} onMouseLeave={() => handleMouseLeave(shot.id)} whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }} > <> {(shot.status === 0 || !shot.videoUrl.length) && (
)} {shot.status === 2 && (
)} {shot.status === 1 && shot.videoUrl.length && (
))}
{/* 左右箭头 */}
handleLeftArrowClick()} >
handleRightArrowClick()} >
{/* 预览信息 */}
{item.name}
{item.name}
{/* 同步到库选项 */} {showAddToLibrary && (
setAddToLibrary(e.target.checked)} className="w-4 h-4 rounded border-white/20" />
)} {/* 操作按钮 */}
); }