forked from 77media/video-flow
Merge branch 'dev' of https://git.qikongjian.com/77media/video-flow into dev
This commit is contained in:
commit
3cac5196d4
@ -190,18 +190,25 @@ export class TextToShotAdapter {
|
||||
shotData.shotDialogsContent.forEach(paragraph => {
|
||||
let dialogRoleName = '';
|
||||
let dialogContent = '';
|
||||
let firstFindRole = false;
|
||||
|
||||
// 遍历段落内容
|
||||
paragraph.content.forEach((node, index) => {
|
||||
if (node.type === 'characterToken') {
|
||||
// 记录说话角色的名称
|
||||
index === 0 && (dialogRoleName = node.attrs.name);
|
||||
index !== 0 && (dialogContent += node.attrs.name);
|
||||
} else if (node.type === 'text') {
|
||||
// 累积对话内容
|
||||
dialogContent += node.text;
|
||||
}
|
||||
});
|
||||
if (paragraph.content) {
|
||||
paragraph.content.forEach((node, index) => {
|
||||
if (node.type === 'characterToken') {
|
||||
// 记录说话角色的名称
|
||||
if (!firstFindRole) {
|
||||
dialogRoleName = node.attrs.name;
|
||||
firstFindRole = true;
|
||||
} else {
|
||||
dialogContent += node.attrs.name;
|
||||
}
|
||||
} else if (node.type === 'text') {
|
||||
// 累积对话内容
|
||||
dialogContent += node.text;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 如果有角色名和对话内容,添加到结果中
|
||||
if (dialogRoleName && dialogContent) {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import React, { useState, useCallback, useEffect } from 'react';
|
||||
import { flushSync } from 'react-dom';
|
||||
import { EditorContent, useEditor } from '@tiptap/react';
|
||||
import StarterKit from '@tiptap/starter-kit';
|
||||
import Placeholder from '@tiptap/extension-placeholder'
|
||||
@ -12,6 +13,7 @@ interface ShotEditorProps {
|
||||
roles?: any[];
|
||||
onCharacterClick?: (attrs: any) => void;
|
||||
placeholder?: string;
|
||||
onChangeContent?: (content: any) => void;
|
||||
}
|
||||
|
||||
declare module '@tiptap/core' {
|
||||
@ -36,14 +38,17 @@ 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) {
|
||||
function ShotEditor({ content, onCharacterClick, roles, placeholder, onChangeContent }, ref) {
|
||||
const [segments, setSegments] = useState(content);
|
||||
const [isOptimizing, setIsOptimizing] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
onChangeContent?.(segments);
|
||||
}, [segments]);
|
||||
|
||||
const handleSmartPolish = () => {
|
||||
setIsOptimizing(true);
|
||||
setTimeout(() => {
|
||||
@ -60,9 +65,11 @@ const ShotEditor = React.forwardRef<EditorRef, ShotEditorProps>(
|
||||
ShotTitle,
|
||||
ReadonlyText,
|
||||
Placeholder.configure({
|
||||
placeholder: placeholder || 'Add shot description here...',
|
||||
showOnlyWhenEditable: true,
|
||||
showOnlyCurrent: false,
|
||||
placeholder: ({ node }) => {
|
||||
console.log('-==========placeholder node===========-', segments);
|
||||
|
||||
return placeholder || 'Add shot description here...';
|
||||
},
|
||||
}),
|
||||
],
|
||||
content: { type: 'doc', content: segments },
|
||||
@ -76,9 +83,10 @@ const ShotEditor = React.forwardRef<EditorRef, ShotEditorProps>(
|
||||
editor.setOptions({ editable: true })
|
||||
},
|
||||
onUpdate: ({ editor }) => {
|
||||
const json = editor.getJSON()
|
||||
console.log('-==========json===========-', json);
|
||||
setSegments(json.content);
|
||||
const json = editor.getJSON();
|
||||
flushSync(() => {
|
||||
setSegments(json.content);
|
||||
});
|
||||
},
|
||||
})
|
||||
|
||||
@ -94,9 +102,6 @@ const ShotEditor = React.forwardRef<EditorRef, ShotEditorProps>(
|
||||
},
|
||||
insertContent: (content: any) => {
|
||||
editor?.commands.insertContent(content);
|
||||
},
|
||||
getContent: () => {
|
||||
return segments;
|
||||
}
|
||||
}), [editor]) // 依赖 editor,确保更新
|
||||
|
||||
|
||||
@ -23,8 +23,20 @@ interface CharacterToken {
|
||||
|
||||
const createEmptyShot = (): Shot => ({
|
||||
name: `shot${Date.now()}`,
|
||||
shotDescContent: [],
|
||||
shotDialogsContent: []
|
||||
shotDescContent: [{
|
||||
type: 'paragraph',
|
||||
content: [{
|
||||
type: 'text',
|
||||
text: 'Add shot description here...'
|
||||
}]
|
||||
}],
|
||||
shotDialogsContent: [{
|
||||
type: 'paragraph',
|
||||
content: [{
|
||||
type: 'text',
|
||||
text: 'Add shot dialogue here...'
|
||||
}]
|
||||
}]
|
||||
});
|
||||
|
||||
interface ShotsEditorProps {
|
||||
@ -50,32 +62,31 @@ export const ShotsEditor = forwardRef<any, ShotsEditorProps>(({ roles, shotInfo,
|
||||
}
|
||||
}, [shotInfo]);
|
||||
|
||||
// 更新当前分镜内容
|
||||
const updateShot = () => {
|
||||
const handleDescContentChange = (content: any) => {
|
||||
const shot = shots[currentShotIndex];
|
||||
if (descEditorRef.current) {
|
||||
const content = descEditorRef.current.getContent();
|
||||
console.log('-==========descEditorcontent===========-', content);
|
||||
shot.shotDescContent = content;
|
||||
}
|
||||
if (dialogEditorRef.current) {
|
||||
const content = dialogEditorRef.current.getContent();
|
||||
console.log('-==========dialogEditorcontent===========-', content);
|
||||
shot.shotDialogsContent = content;
|
||||
}
|
||||
setShots([...shots]);
|
||||
shot.shotDescContent = content;
|
||||
setShots(prevShots =>
|
||||
prevShots.map((item, index) =>
|
||||
index === currentShotIndex ? shot : item
|
||||
)
|
||||
);
|
||||
}
|
||||
const handleDialogContentChange = (content: any) => {
|
||||
const shot = shots[currentShotIndex];
|
||||
shot.shotDialogsContent = content;
|
||||
setShots(prevShots =>
|
||||
prevShots.map((item, index) =>
|
||||
index === currentShotIndex ? shot : item
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const handleShotTabClick = (index: number) => {
|
||||
// 切换前更新当前分镜内容
|
||||
updateShot();
|
||||
setCurrentShotIndex(index);
|
||||
}
|
||||
|
||||
const getShotInfo = () => {
|
||||
// 生成前 更新当前分镜内容
|
||||
updateShot();
|
||||
console.log('-==========shots===========-', shots);
|
||||
console.log('-==========getShotInfo shots===========-', shots);
|
||||
const shotInfo = shots.map((shot) => {
|
||||
return TextToShotAdapter.toLensType(shot);
|
||||
});
|
||||
@ -93,7 +104,6 @@ export const ShotsEditor = forwardRef<any, ShotsEditorProps>(({ roles, shotInfo,
|
||||
}
|
||||
const newShot = createEmptyShot();
|
||||
setShots([...shots, newShot]);
|
||||
// onShotsChange([...shots, newShot]);
|
||||
// 自动切换到新创建的分镜
|
||||
setCurrentShotIndex(shots.length);
|
||||
};
|
||||
@ -250,6 +260,7 @@ export const ShotsEditor = forwardRef<any, ShotsEditorProps>(({ roles, shotInfo,
|
||||
onCharacterClick={() => {}}
|
||||
roles={roles}
|
||||
placeholder="Add shot description here..."
|
||||
onChangeContent={(content) => {handleDescContentChange(content)}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -281,6 +292,7 @@ export const ShotsEditor = forwardRef<any, ShotsEditorProps>(({ roles, shotInfo,
|
||||
onCharacterClick={() => {}}
|
||||
roles={roles}
|
||||
placeholder="Add shot dialogue here..."
|
||||
onChangeContent={(content) => {handleDialogContentChange(content)}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -113,7 +113,7 @@ export function ShotTabContent({
|
||||
...shotData[selectedIndex],
|
||||
lens: shotInfo
|
||||
});
|
||||
// regenerateVideoSegment();
|
||||
regenerateVideoSegment();
|
||||
};
|
||||
|
||||
// 新增分镜
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user