forked from 77media/video-flow
更新 ScriptTabContent 以支持新的剧本数据结构和属性设置逻辑。
This commit is contained in:
parent
e6ed351cfe
commit
7568336be6
@ -7,6 +7,7 @@ interface AISuggestionBarProps {
|
|||||||
suggestions: string[];
|
suggestions: string[];
|
||||||
onSuggestionClick: (suggestion: string) => void;
|
onSuggestionClick: (suggestion: string) => void;
|
||||||
onSubmit: (text: string) => void;
|
onSubmit: (text: string) => void;
|
||||||
|
onFocus: () => void;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14,6 +15,7 @@ export function AISuggestionBar({
|
|||||||
suggestions,
|
suggestions,
|
||||||
onSuggestionClick,
|
onSuggestionClick,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
|
onFocus,
|
||||||
placeholder = "输入你的想法,或点击预设词条获取 AI 建议..."
|
placeholder = "输入你的想法,或点击预设词条获取 AI 建议..."
|
||||||
}: AISuggestionBarProps) {
|
}: AISuggestionBarProps) {
|
||||||
const [inputText, setInputText] = useState('');
|
const [inputText, setInputText] = useState('');
|
||||||
@ -177,6 +179,7 @@ export function AISuggestionBar({
|
|||||||
if (isCollapsed) {
|
if (isCollapsed) {
|
||||||
toggleCollapse();
|
toggleCollapse();
|
||||||
}
|
}
|
||||||
|
onFocus();
|
||||||
}}
|
}}
|
||||||
onBlur={() => setIsFocused(false)}
|
onBlur={() => setIsFocused(false)}
|
||||||
placeholder={isCollapsed ? "点击展开..." : placeholder}
|
placeholder={isCollapsed ? "点击展开..." : placeholder}
|
||||||
|
|||||||
@ -248,6 +248,7 @@ export default function WorkFlow() {
|
|||||||
suggestions={mockSuggestions}
|
suggestions={mockSuggestions}
|
||||||
onSuggestionClick={handleSuggestionClick}
|
onSuggestionClick={handleSuggestionClick}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
|
onFocus={() => setIsPauseWorkFlow(true)}
|
||||||
placeholder="Please input your ideas, or click the predefined tags to receive AI advice..."
|
placeholder="Please input your ideas, or click the predefined tags to receive AI advice..."
|
||||||
/>
|
/>
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
@ -265,6 +266,10 @@ export default function WorkFlow() {
|
|||||||
onSketchSelect={setCurrentSketchIndex}
|
onSketchSelect={setCurrentSketchIndex}
|
||||||
roles={roles}
|
roles={roles}
|
||||||
music={music}
|
music={music}
|
||||||
|
scriptData={scriptData}
|
||||||
|
setIsPauseWorkFlow={setIsPauseWorkFlow}
|
||||||
|
setAnyAttribute={setAnyAttribute}
|
||||||
|
isPauseWorkFlow={isPauseWorkFlow}
|
||||||
/>
|
/>
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect, SetStateAction } from 'react';
|
||||||
import { motion, AnimatePresence } from 'framer-motion';
|
import { motion, AnimatePresence } from 'framer-motion';
|
||||||
import { X, Image, Users, Video, Music, Settings, FileText, Maximize, Minimize } from 'lucide-react';
|
import { X, Image, Users, Video, Music, Settings, FileText, Maximize, Minimize } from 'lucide-react';
|
||||||
import { cn } from '@/public/lib/utils';
|
import { cn } from '@/public/lib/utils';
|
||||||
import ScriptTabContent from './script-tab-content';
|
import { ScriptTabContent } from './script-tab-content';
|
||||||
import { SceneTabContent } from './scene-tab-content';
|
import { SceneTabContent } from './scene-tab-content';
|
||||||
import { ShotTabContent } from './shot-tab-content';
|
import { ShotTabContent } from './shot-tab-content';
|
||||||
import { SettingsTabContent } from './settings-tab-content';
|
import { SettingsTabContent } from './settings-tab-content';
|
||||||
@ -23,6 +23,10 @@ interface EditModalProps {
|
|||||||
onSketchSelect: (index: number) => void;
|
onSketchSelect: (index: number) => void;
|
||||||
roles?: any[];
|
roles?: any[];
|
||||||
music?: any;
|
music?: any;
|
||||||
|
setIsPauseWorkFlow: (isPauseWorkFlow: boolean) => void;
|
||||||
|
setAnyAttribute: (type: string, value: SetStateAction<string>, tags?: string[]) => void;
|
||||||
|
isPauseWorkFlow: boolean;
|
||||||
|
scriptData: any[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tabs = [
|
const tabs = [
|
||||||
@ -46,7 +50,11 @@ export function EditModal({
|
|||||||
currentSketchIndex,
|
currentSketchIndex,
|
||||||
onSketchSelect,
|
onSketchSelect,
|
||||||
roles = [],
|
roles = [],
|
||||||
music
|
music,
|
||||||
|
setIsPauseWorkFlow,
|
||||||
|
setAnyAttribute,
|
||||||
|
isPauseWorkFlow,
|
||||||
|
scriptData
|
||||||
}: EditModalProps) {
|
}: EditModalProps) {
|
||||||
const [activeTab, setActiveTab] = useState(activeEditTab);
|
const [activeTab, setActiveTab] = useState(activeEditTab);
|
||||||
const [currentIndex, setCurrentIndex] = useState(currentSketchIndex);
|
const [currentIndex, setCurrentIndex] = useState(currentSketchIndex);
|
||||||
@ -89,7 +97,12 @@ export function EditModal({
|
|||||||
switch (activeTab) {
|
switch (activeTab) {
|
||||||
case '0':
|
case '0':
|
||||||
return (
|
return (
|
||||||
<ScriptTabContent />
|
<ScriptTabContent
|
||||||
|
scriptData={scriptData}
|
||||||
|
setIsPauseWorkFlow={setIsPauseWorkFlow}
|
||||||
|
setAnyAttribute={setAnyAttribute}
|
||||||
|
isPauseWorkFlow={isPauseWorkFlow}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
case '1':
|
case '1':
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,65 +1,32 @@
|
|||||||
import React, { useState, useCallback, useEffect } from 'react';
|
import React, { useState, useCallback, useEffect, SetStateAction } from 'react';
|
||||||
import { motion, AnimatePresence } from 'framer-motion';
|
import { motion, AnimatePresence } from 'framer-motion';
|
||||||
import { X, Check, ChevronDown } from 'lucide-react';
|
import { FileText } from 'lucide-react';
|
||||||
import * as Popover from '@radix-ui/react-popover';
|
import { ScriptRenderer } from '@/components/script-renderer/ScriptRenderer';
|
||||||
import { mockSceneOptions, mockCharacterOptions } from '@/app/model/enums';
|
|
||||||
import { Button } from './button';
|
|
||||||
import { Input } from './input';
|
|
||||||
|
|
||||||
const ScriptTabContent: React.FC = () => {
|
|
||||||
// 获取当前项目ID(这里需要根据实际项目路由或上下文获取)
|
|
||||||
const projectId = 'current-project-id'; // TODO: 从路由或上下文获取实际项目ID
|
|
||||||
|
|
||||||
|
|
||||||
// 组件挂载时获取项目剧本数据
|
interface ScriptTabContentProps {
|
||||||
useEffect(() => {
|
scriptData: any[] | null;
|
||||||
const initializeScript = async () => {
|
setIsPauseWorkFlow: (isPauseWorkFlow: boolean) => void;
|
||||||
try {
|
setAnyAttribute: (type: string, value: SetStateAction<string>, tags?: string[]) => void;
|
||||||
await fetchProjectScript(projectId);
|
isPauseWorkFlow: boolean;
|
||||||
} catch (error) {
|
|
||||||
console.error('初始化剧本数据失败:', error);
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
initializeScript();
|
export function ScriptTabContent({
|
||||||
}, [projectId, fetchProjectScript]);
|
scriptData = [],
|
||||||
|
setIsPauseWorkFlow,
|
||||||
|
setAnyAttribute,
|
||||||
|
isPauseWorkFlow
|
||||||
|
}: ScriptTabContentProps) {
|
||||||
|
|
||||||
// 处理AI生成按钮点击
|
// 如果没有数据,显示空状态
|
||||||
const handleAiGenerate = useCallback(async () => {
|
if (!scriptData || scriptData.length === 0) {
|
||||||
if (!userPrompt.trim()) return;
|
return (
|
||||||
|
<div className="flex flex-col items-center justify-center min-h-[400px] text-white/50">
|
||||||
try {
|
<FileText className="w-16 h-16 mb-4" />
|
||||||
await fetchScriptData(userPrompt);
|
<p>No script data</p>
|
||||||
} catch (error) {
|
</div>
|
||||||
console.error('生成剧本失败:', error);
|
);
|
||||||
}
|
}
|
||||||
}, [userPrompt, fetchScriptData]);
|
|
||||||
|
|
||||||
// 处理重置按钮点击
|
|
||||||
const handleReset = useCallback(() => {
|
|
||||||
resetScript();
|
|
||||||
}, [resetScript]);
|
|
||||||
|
|
||||||
// 处理确认按钮点击
|
|
||||||
const handleConfirm = useCallback(async () => {
|
|
||||||
try {
|
|
||||||
await applyScript();
|
|
||||||
} catch (error) {
|
|
||||||
console.error('应用剧本失败:', error);
|
|
||||||
}
|
|
||||||
}, [applyScript]);
|
|
||||||
|
|
||||||
// 处理提示词输入变化
|
|
||||||
const handlePromptChange = useCallback((value: string) => {
|
|
||||||
updateUserPrompt(value);
|
|
||||||
}, [updateUserPrompt]);
|
|
||||||
|
|
||||||
// 处理剧本片段文本变化
|
|
||||||
const handleScriptSliceChange = useCallback((sliceId: string, text: string) => {
|
|
||||||
setFocusedSlice(sliceId);
|
|
||||||
updateScriptSliceText(text);
|
|
||||||
}, [setFocusedSlice, updateScriptSliceText]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col h-full">
|
<div className="flex flex-col h-full">
|
||||||
<motion.div
|
<motion.div
|
||||||
@ -88,10 +55,8 @@ const ScriptTabContent: React.FC = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<ScriptRenderer data={scriptData} setIsPauseWorkFlow={setIsPauseWorkFlow} setAnyAttribute={setAnyAttribute} isPauseWorkFlow={isPauseWorkFlow} />
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ScriptTabContent;
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user