From 7568336be69f5ebecc4b86518cf9fa1afb229e1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8C=97=E6=9E=B3?= <7854742+wang_rumeng@user.noreply.gitee.com> Date: Thu, 7 Aug 2025 19:50:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20ScriptTabContent=20?= =?UTF-8?q?=E4=BB=A5=E6=94=AF=E6=8C=81=E6=96=B0=E7=9A=84=E5=89=A7=E6=9C=AC?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=BB=93=E6=9E=84=E5=92=8C=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E9=80=BB=E8=BE=91=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/ai-suggestion-bar.tsx | 3 + components/pages/work-flow.tsx | 5 + components/ui/edit-modal.tsx | 21 +++- components/ui/script-tab-content.tsx | 137 ++++++++++----------------- 4 files changed, 76 insertions(+), 90 deletions(-) diff --git a/components/ai-suggestion-bar.tsx b/components/ai-suggestion-bar.tsx index 58952a9..ecb8211 100644 --- a/components/ai-suggestion-bar.tsx +++ b/components/ai-suggestion-bar.tsx @@ -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} diff --git a/components/pages/work-flow.tsx b/components/pages/work-flow.tsx index 04edc4a..b24e582 100644 --- a/components/pages/work-flow.tsx +++ b/components/pages/work-flow.tsx @@ -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..." /> @@ -265,6 +266,10 @@ export default function WorkFlow() { onSketchSelect={setCurrentSketchIndex} roles={roles} music={music} + scriptData={scriptData} + setIsPauseWorkFlow={setIsPauseWorkFlow} + setAnyAttribute={setAnyAttribute} + isPauseWorkFlow={isPauseWorkFlow} /> diff --git a/components/ui/edit-modal.tsx b/components/ui/edit-modal.tsx index 73ae68b..790e431 100644 --- a/components/ui/edit-modal.tsx +++ b/components/ui/edit-modal.tsx @@ -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, 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 ( - + ); case '1': return ( diff --git a/components/ui/script-tab-content.tsx b/components/ui/script-tab-content.tsx index 7830750..2c91e7a 100644 --- a/components/ui/script-tab-content.tsx +++ b/components/ui/script-tab-content.tsx @@ -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, 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 ( +
+ +

No script data

+
+ ); + } return (
- - + 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" + } + }} + > + +
); }; - -export default ScriptTabContent;