import React, { useState, useRef } from 'react'; import { motion } from 'framer-motion'; import { Check, X, CircleAlert, ArrowLeft, ArrowRight } from 'lucide-react'; import { cn } from '@/public/lib/utils'; interface ReplacePanelProps { title: string; shots: any[]; item: any; showAddToLibrary?: boolean; addToLibraryText?: string; onClose: () => void; onConfirm: (selectedShots: string[], addToLibrary: boolean) => void; } export function ReplacePanel({ title, shots, item, showAddToLibrary = false, addToLibraryText = "同步添加至库", 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 [isAtStart, setIsAtStart] = useState(true); const [isAtEnd, setIsAtEnd] = useState(false); const videoRefs = useRef<{ [key: string]: HTMLVideoElement }>({}); const shotsRef = useRef(null); // 检查滚动位置 const checkScrollPosition = () => { if (!shotsRef.current) return; const { scrollLeft, scrollWidth, clientWidth } = shotsRef.current; setIsAtStart(scrollLeft <= 0); setIsAtEnd(Math.ceil(scrollLeft + clientWidth) >= scrollWidth); }; // 添加滚动事件监听 React.useEffect(() => { const shotsElement = shotsRef.current; if (!shotsElement) return; shotsElement.addEventListener('scroll', checkScrollPosition); // 初始检查 checkScrollPosition(); return () => { shotsElement.removeEventListener('scroll', checkScrollPosition); }; }, []); const handleShotToggle = (shotId: string) => { setSelectedShots(prev => prev.includes(shotId) ? prev.filter(id => id !== shotId) : [...prev, shotId] ); }; const handleSelectAllShots = (checked: boolean) => { setSelectedShots(checked ? shots.map(shot => shot.id) : []); }; 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 handleConfirm = () => { onConfirm(selectedShots, addToLibrary); }; 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' // 平滑滚动 }); }; return (
{/* 标题 */}
{title}
{/* 提示信息 */}
该内容出现在 {shots.length} 个分镜中,替换后将影响如下分镜
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.videoUrl && ( ))}
{/* 左右箭头 */}
!isAtStart && handleLeftArrowClick()} >
!isAtEnd && handleRightArrowClick()} >
{/* 预览信息 */}
{item.name}
{item.name}
{/* 同步到库选项 */} {showAddToLibrary && (
setAddToLibrary(e.target.checked)} className="w-4 h-4 rounded border-white/20" />
)} {/* 操作按钮 */}
); }