113 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState, useCallback, useEffect } from 'react';
import { EditorContent, useEditor } from '@tiptap/react';
import StarterKit from '@tiptap/starter-kit';
import Placeholder from '@tiptap/extension-placeholder'
import { motion } from "framer-motion";
import { CharacterTokenExtension } from './CharacterToken';
import { ShotTitle } from './ShotTitle';
import { ReadonlyText } from './ReadonlyText';
interface ShotEditorProps {
content: any[];
roles?: any[];
onCharacterClick?: (attrs: any) => void;
placeholder?: string;
}
declare module '@tiptap/core' {
interface Commands<ReturnType> {
characterToken: {
setCharacterToken: (attrs: any) => ReturnType;
}
}
}
interface CharacterToken {
type: 'characterToken';
attrs: {
name: string;
gender: string;
age: string;
avatar: string;
};
}
interface EditorRef {
editor: any;
insertCharacter: (character: CharacterToken) => void;
insertContent: (content: any) => void;
getContent: () => any;
}
const ShotEditor = React.forwardRef<EditorRef, ShotEditorProps>(
function ShotEditor({ content, onCharacterClick, roles, placeholder }, ref) {
const [segments, setSegments] = useState(content);
const [isOptimizing, setIsOptimizing] = useState(false);
const handleSmartPolish = () => {
setIsOptimizing(true);
setTimeout(() => {
setIsOptimizing(false);
}, 3000);
};
const editor = useEditor({
extensions: [
StarterKit,
CharacterTokenExtension.configure({
roles
}),
ShotTitle,
ReadonlyText,
Placeholder.configure({
placeholder: placeholder || 'Add shot description here...',
showOnlyWhenEditable: true,
showOnlyCurrent: false,
}),
],
content: { type: 'doc', content: segments },
editorProps: {
attributes: {
class: 'prose prose-invert max-w-none focus:outline-none'
}
},
immediatelyRender: false,
onCreate: ({ editor }) => {
editor.setOptions({ editable: true })
},
onUpdate: ({ editor }) => {
const json = editor.getJSON()
console.log('-==========json===========-', json);
setSegments(json.content);
},
})
// 暴露方法给父组件
React.useImperativeHandle(ref, () => ({
editor,
insertCharacter: (character: CharacterToken) => {
editor?.commands.insertContent([
{ type: 'text', text: ' ' },
character,
{ type: 'text', text: ' ' }
]);
},
insertContent: (content: any) => {
editor?.commands.insertContent(content);
},
getContent: () => {
return segments;
}
}), [editor]) // 依赖 editor确保更新
if (!editor) {
return null
}
return (
<EditorContent editor={editor} />
)
}
);
export default ShotEditor;