更新 ScriptTabContent 以支持新的剧本数据结构和属性设置逻辑。

This commit is contained in:
北枳 2025-08-07 19:50:15 +08:00
parent e6ed351cfe
commit 7568336be6
4 changed files with 76 additions and 90 deletions

View File

@ -7,6 +7,7 @@ interface AISuggestionBarProps {
suggestions: string[];
onSuggestionClick: (suggestion: string) => void;
onSubmit: (text: string) => void;
onFocus: () => void;
placeholder?: string;
}
@ -14,6 +15,7 @@ export function AISuggestionBar({
suggestions,
onSuggestionClick,
onSubmit,
onFocus,
placeholder = "输入你的想法,或点击预设词条获取 AI 建议..."
}: AISuggestionBarProps) {
const [inputText, setInputText] = useState('');
@ -177,6 +179,7 @@ export function AISuggestionBar({
if (isCollapsed) {
toggleCollapse();
}
onFocus();
}}
onBlur={() => setIsFocused(false)}
placeholder={isCollapsed ? "点击展开..." : placeholder}

View File

@ -248,6 +248,7 @@ export default function WorkFlow() {
suggestions={mockSuggestions}
onSuggestionClick={handleSuggestionClick}
onSubmit={handleSubmit}
onFocus={() => setIsPauseWorkFlow(true)}
placeholder="Please input your ideas, or click the predefined tags to receive AI advice..."
/>
</ErrorBoundary>
@ -265,6 +266,10 @@ export default function WorkFlow() {
onSketchSelect={setCurrentSketchIndex}
roles={roles}
music={music}
scriptData={scriptData}
setIsPauseWorkFlow={setIsPauseWorkFlow}
setAnyAttribute={setAnyAttribute}
isPauseWorkFlow={isPauseWorkFlow}
/>
</ErrorBoundary>
</div>

View File

@ -1,10 +1,10 @@
'use client';
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, SetStateAction } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { X, Image, Users, Video, Music, Settings, FileText, Maximize, Minimize } from 'lucide-react';
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 { ShotTabContent } from './shot-tab-content';
import { SettingsTabContent } from './settings-tab-content';
@ -23,6 +23,10 @@ interface EditModalProps {
onSketchSelect: (index: number) => void;
roles?: any[];
music?: any;
setIsPauseWorkFlow: (isPauseWorkFlow: boolean) => void;
setAnyAttribute: (type: string, value: SetStateAction<string>, tags?: string[]) => void;
isPauseWorkFlow: boolean;
scriptData: any[] | null;
}
const tabs = [
@ -46,7 +50,11 @@ export function EditModal({
currentSketchIndex,
onSketchSelect,
roles = [],
music
music,
setIsPauseWorkFlow,
setAnyAttribute,
isPauseWorkFlow,
scriptData
}: EditModalProps) {
const [activeTab, setActiveTab] = useState(activeEditTab);
const [currentIndex, setCurrentIndex] = useState(currentSketchIndex);
@ -89,7 +97,12 @@ export function EditModal({
switch (activeTab) {
case '0':
return (
<ScriptTabContent />
<ScriptTabContent
scriptData={scriptData}
setIsPauseWorkFlow={setIsPauseWorkFlow}
setAnyAttribute={setAnyAttribute}
isPauseWorkFlow={isPauseWorkFlow}
/>
);
case '1':
return (

View File

@ -1,97 +1,62 @@
import React, { useState, useCallback, useEffect } from 'react';
import React, { useState, useCallback, useEffect, SetStateAction } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { X, Check, ChevronDown } from 'lucide-react';
import * as Popover from '@radix-ui/react-popover';
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
import { FileText } from 'lucide-react';
import { ScriptRenderer } from '@/components/script-renderer/ScriptRenderer';
// 组件挂载时获取项目剧本数据
useEffect(() => {
const initializeScript = async () => {
try {
await fetchProjectScript(projectId);
} catch (error) {
console.error('初始化剧本数据失败:', error);
}
};
interface ScriptTabContentProps {
scriptData: any[] | null;
setIsPauseWorkFlow: (isPauseWorkFlow: boolean) => void;
setAnyAttribute: (type: string, value: SetStateAction<string>, tags?: string[]) => void;
isPauseWorkFlow: boolean;
}
initializeScript();
}, [projectId, fetchProjectScript]);
// 处理AI生成按钮点击
const handleAiGenerate = useCallback(async () => {
if (!userPrompt.trim()) return;
try {
await fetchScriptData(userPrompt);
} catch (error) {
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]);
export function ScriptTabContent({
scriptData = [],
setIsPauseWorkFlow,
setAnyAttribute,
isPauseWorkFlow
}: ScriptTabContentProps) {
// 如果没有数据,显示空状态
if (!scriptData || scriptData.length === 0) {
return (
<div className="flex flex-col items-center justify-center min-h-[400px] text-white/50">
<FileText className="w-16 h-16 mb-4" />
<p>No script data</p>
</div>
);
}
return (
<div className="flex flex-col h-full">
<motion.div
className="relative w-full h-[90vh] backdrop-blur-xl rounded-2xl shadow-2xl overflow-hidden flex flex-col"
initial={{ scale: 0.95, y: 10, opacity: 0 }}
animate={{
scale: 1,
y: 0,
opacity: 1,
transition: {
type: "spring",
duration: 0.3,
bounce: 0.15,
stiffness: 300,
damping: 25
}
}}
exit={{
scale: 0.95,
y: 10,
opacity: 0,
transition: {
type: "tween",
duration: 0.1,
ease: "easeOut"
}
}}
>
</motion.div>
className="relative w-full h-[90vh] backdrop-blur-xl rounded-2xl shadow-2xl overflow-hidden flex flex-col"
initial={{ scale: 0.95, y: 10, opacity: 0 }}
animate={{
scale: 1,
y: 0,
opacity: 1,
transition: {
type: "spring",
duration: 0.3,
bounce: 0.15,
stiffness: 300,
damping: 25
}
}}
exit={{
scale: 0.95,
y: 10,
opacity: 0,
transition: {
type: "tween",
duration: 0.1,
ease: "easeOut"
}
}}
>
<ScriptRenderer data={scriptData} setIsPauseWorkFlow={setIsPauseWorkFlow} setAnyAttribute={setAnyAttribute} isPauseWorkFlow={isPauseWorkFlow} />
</motion.div>
</div>
);
};
export default ScriptTabContent;