import React, { forwardRef, useRef, useState } from "react"; import { Plus, X, UserRoundPlus, MessageCirclePlus, MessageCircleMore, ClipboardType } from "lucide-react"; import ShotEditor from "./ShotEditor"; import { toast } from "sonner"; interface Shot { id: string; shotDescContent: any[]; shotDialogsContent: any[]; } interface CharacterToken { type: 'characterToken'; attrs: { name: string; gender: string; age: string; avatar: string; }; } const mockShotsData = [ { id: 'shot1', shotDescContent: [{ type: 'paragraph', content: [ { type: 'text', text: '镜头聚焦在' }, { type: 'characterToken', attrs: { name: '"沙利"·沙利文中士', gender: '男', age: '28', avatar: 'https://i.pravatar.cc/40?u=z3' }}, { type: 'text', text: ' 愤怒的脸上,他被压制住了。他发出一声绝望的吼叫,盖过了枪声。' }, ] }], shotDialogsContent: [ { type: 'paragraph', content: [ { type: 'characterToken', attrs: { name: '李四', gender: '女', age: '26', avatar: 'https://i.pravatar.cc/40?u=l4' }}, { type: 'text', text: ' 微微低头,没有说话。' } ] } ] } ] const createEmptyShot = (): Shot => ({ id: `shot${Date.now()}`, shotDescContent: [{ type: 'paragraph', content: [ { type: 'text', text: '在这里添加分镜描述...' } ] }], shotDialogsContent: [{ type: 'paragraph', content: [ { type: 'text', text: '在这里添加分镜对话...' } ] }] }); interface ShotsEditorProps { roles: any[]; } export const ShotsEditor = forwardRef(({ roles }, ref) => { const [currentShotIndex, setCurrentShotIndex] = useState(0); const [shots, setShots] = useState(mockShotsData); const descEditorRef = useRef(null); const dialogEditorRef = useRef(null); const addShot = () => { if (shots.length > 3) { toast.error('不能超过4个分镜', { duration: 3000, position: 'top-center', richColors: true, }); return; } const newShot = createEmptyShot(); setShots([...shots, newShot]); // onShotsChange([...shots, newShot]); // 自动切换到新创建的分镜 setCurrentShotIndex(shots.length); }; const handleDeleteShot = (index: number) => { if (shots.length <= 1) return; // 保留最后一个分镜 const newShots = shots.filter((_, i) => i !== index); setShots(newShots); // onShotsChange(newShots); // 如果删除的是当前选中的分镜,或者删除的是最后一个分镜 if (currentShotIndex === index || currentShotIndex >= newShots.length) { setCurrentShotIndex(Math.max(0, newShots.length - 1)); } else if (currentShotIndex > index) { // 如果删除的分镜在当前选中分镜之前,需要更新索引 setCurrentShotIndex(currentShotIndex - 1); } }; const handleAddCharacterToDesc = () => { if (!descEditorRef.current) return; // 创建一个默认角色Token const defaultCharacter: CharacterToken = { type: 'characterToken', attrs: { name: '新角色', gender: '男', age: '25', avatar: 'https://i.pravatar.cc/40' } }; // 在当前位置插入角色Token descEditorRef.current.insertCharacter(defaultCharacter); }; const handleAddCharacterToDialog = () => { if (!dialogEditorRef.current) return; // 创建一个默认角色Token const defaultCharacter: CharacterToken = { type: 'characterToken', attrs: { name: '新角色', gender: '男', age: '25', avatar: 'https://i.pravatar.cc/40' } }; // 在当前位置插入角色Token dialogEditorRef.current.insertCharacter(defaultCharacter); }; const handleAddNewDialog = () => { if (!dialogEditorRef.current) return; // 创建一个新的对话行 const newDialog = { type: 'paragraph', content: [ { type: 'characterToken', attrs: { name: '新角色', gender: '男', age: '25', avatar: 'https://i.pravatar.cc/40' } }, { type: 'text', text: ' 说道:' } ] }; // 在编辑器末尾添加新对话 dialogEditorRef.current.editor?.commands.focus('end'); dialogEditorRef.current.insertContent([ { type: 'text', text: '\n' }, newDialog ]); }; // 暴露方法给父组件 React.useImperativeHandle(ref, () => ({ addShot, })); return (
{/* 分镜标签(可删除)、新增分镜标签 */}
{shots.map((shot, index) => (
setCurrentShotIndex(index)} > 镜头{index + 1} {shots.length > 1 && ( )}
))}
{/* */}
{/* 分镜内容 */}
{/* 分镜描述 添加角色 */}
分镜描述
{/* 分镜描述内容 可视化编辑 */} {}} roles={roles} />
{/* 分镜对话 添加角色 添加对话 */}
分镜对话
{/* 分镜对话内容 可视化编辑 */} {}} roles={roles} />
); });