diff --git a/components/pages/work-flow.tsx b/components/pages/work-flow.tsx index d82dfcd..77ab2a5 100644 --- a/components/pages/work-flow.tsx +++ b/components/pages/work-flow.tsx @@ -47,7 +47,8 @@ export default function WorkFlow() { setIsPauseWorkFlow, setAnyAttribute, applyScript, - fallbackToStep + fallbackToStep, + originalText } = useWorkflowData(); const { @@ -270,12 +271,10 @@ export default function WorkFlow() { onSketchSelect={setCurrentSketchIndex} roles={roles} music={music} - scriptData={scriptData} setIsPauseWorkFlow={setIsPauseWorkFlow} - setAnyAttribute={setAnyAttribute} isPauseWorkFlow={isPauseWorkFlow} - applyScript={applyScript} fallbackToStep={fallbackToStep} + originalText={originalText} /> diff --git a/components/pages/work-flow/use-edit-data.tsx b/components/pages/work-flow/use-edit-data.tsx index 8b3f522..6ab662b 100644 --- a/components/pages/work-flow/use-edit-data.tsx +++ b/components/pages/work-flow/use-edit-data.tsx @@ -4,29 +4,24 @@ import { useShotService } from "@/app/service/Interaction/ShotService"; import { useSearchParams } from 'next/navigation'; import { useRoleServiceHook } from "@/app/service/Interaction/RoleService"; import { useRoleShotServiceHook } from "@/app/service/Interaction/RoleShotService"; +import { useScriptService } from "@/app/service/Interaction/ScriptService"; -const mockRoleData = [{ - id: '1', - name: 'KAPI', - imageUrl: 'https://c.huiying.video/images/420bfb4f-b5d4-475c-a2fb-5e40af770b29.jpg', - generateText: 'A 3 to 5-year-old boy with a light to medium olive skin tone, full cheeks, and warm brown eyes. He has short, straight, dark brown hair, neatly styled with a part on his left side. His facial structure includes a small, slightly upturned nose. His lips are typically held in a slight, gentle, closed-mouth smile, which can part to show his small, white teeth.', - tags: [ - { id: '1', content: 'boy', color: 'red' }, - { id: '2', content: '3 to 5-year-old', color: 'yellow' }, - { id: '3', content: 'light to medium olive skin tone', color: 'green' }, - { id: '4', content: 'full cheeks', color: 'blue' }, - { id: '5', content: 'warm brown eyes', color: 'purple' }, - ] -}] - -export const useEditData = (tabType: string) => { +export const useEditData = (tabType: string, originalText?: string) => { const searchParams = useSearchParams(); const projectId = searchParams.get('episodeId') || ''; const [loading, setLoading] = useState(true); + const [scriptData, setScriptData] = useState([]); const [shotData, setShotData] = useState([]); const [roleData, setRoleData] = useState([]); + const { + scriptBlocksMemo, // 渲染剧本数据 + initializeFromProject, + setAnyAttribute, + applyScript + } = useScriptService(); + const { videoSegments, getVideoSegmentList, @@ -72,7 +67,15 @@ export const useEditData = (tabType: string) => { }, [selectedRole]); useEffect(() => { - if (tabType === 'shot') { + if (tabType === 'script') { + initializeFromProject(projectId, originalText || '').then(() => { + setLoading(false); + }).catch((err) => { + console.log('useEditData-----err', err); + setScriptData([]); + setLoading(false); + }); + } else if (tabType === 'shot') { getVideoSegmentList(projectId).then(() => { setLoading(false); }).catch((err) => { @@ -91,6 +94,12 @@ export const useEditData = (tabType: string) => { } }, [tabType]); + useEffect(() => { + if (scriptBlocksMemo.length > 0) { + setScriptData(scriptBlocksMemo); + } + }, [scriptBlocksMemo]); + useEffect(() => { console.log('useEditData-----videoSegments', videoSegments); setShotData(videoSegments); @@ -103,6 +112,10 @@ export const useEditData = (tabType: string) => { return { loading, + // script + scriptData, + setAnyAttribute, + applyScript, // shot shotData, setSelectedSegment, diff --git a/components/pages/work-flow/use-workflow-data.tsx b/components/pages/work-flow/use-workflow-data.tsx index 3f5b2b6..3a22ae1 100644 --- a/components/pages/work-flow/use-workflow-data.tsx +++ b/components/pages/work-flow/use-workflow-data.tsx @@ -449,10 +449,9 @@ export function useWorkflowData() { } // 如果有已完成的数据,同步到状态 - let finalStep = '0'; if (data) { if (data.sketch && data.sketch.data) { - finalStep = '1'; + taskData.status = '1'; const realSketchResultData = data.sketch.data.filter((item: any) => item.image_path); const sketchList = []; for (const sketch of realSketchResultData) { @@ -461,6 +460,8 @@ export function useWorkflowData() { script: sketch.sketch_name, }); } + taskData.sketch.data = sketchList; + taskData.sketch.total_count = data.sketch.total_count; setTaskSketch(sketchList); setTaskScenes(sketchList); updateSketchCount(sketchList.length); @@ -469,7 +470,7 @@ export function useWorkflowData() { setIsGeneratingSketch(true); loadingText = LOADING_TEXT_MAP.sketch(realSketchResultData.length, data.sketch.total_count); } else { - finalStep = '2'; + taskData.status = '2'; if (!data.character || !data.character.data || !data.character.data.length) { loadingText = LOADING_TEXT_MAP.newCharacter(0, data.character.total_count); } @@ -486,11 +487,13 @@ export function useWorkflowData() { roleDescription: character.character_description }); } + taskData.character.data = characterList; + taskData.character.total_count = data.character.total_count; setRoles(characterList); if (data.character.total_count > data.character.data.length) { loadingText = LOADING_TEXT_MAP.newCharacter(data.character.data.length, data.character.total_count); } else { - finalStep = '3'; + taskData.status = '3'; if (!data.video || !data.video.data || !data.video.data.length) { loadingText = LOADING_TEXT_MAP.getShotSketchStatus; } @@ -505,6 +508,8 @@ export function useWorkflowData() { script: sketch.description, }); } + taskData.shot_sketch.data = sketchList; + taskData.shot_sketch.total_count = data.shot_sketch.total_count; setTaskSketch(sketchList); setTaskShotSketch(sketchList); updateSketchCount(sketchList.length); @@ -513,7 +518,7 @@ export function useWorkflowData() { setIsGeneratingSketch(true); loadingText = LOADING_TEXT_MAP.shotSketch(realShotResultData.length, data.shot_sketch.total_count); } else { - finalStep = '3'; + taskData.status = '3'; setIsGeneratingVideo(true); if (!data.character || !data.character.data || !data.character.data.length) { loadingText = LOADING_TEXT_MAP.getVideoStatus; @@ -522,7 +527,7 @@ export function useWorkflowData() { } if (data.video.data) { const realDataVideoData = data.video.data.filter((item: any) => item.urls && item.urls.length > 0); - if (realDataVideoData.length === 0 && finalStep === '3') { + if (realDataVideoData.length === 0 && taskData.status === '3') { loadingText = LOADING_TEXT_MAP.video(0, data.video.total_count); } if (realDataVideoData.length > 0) { @@ -537,6 +542,8 @@ export function useWorkflowData() { video_id: video.video_id, }); } + taskData.video.data = videoList; + taskData.video.total_count = data.video.total_count; setTaskVideos(videoList); updateVideoCount(videoList.length); // 如果在视频步骤,设置为最后一个视频 @@ -544,11 +551,11 @@ export function useWorkflowData() { setIsGeneratingVideo(true); loadingText = LOADING_TEXT_MAP.video(realDataVideoData.length, data.video.total_count); } else { - finalStep = '4'; + taskData.status = '4'; loadingText = LOADING_TEXT_MAP.audio; // 暂时没有音频生成 直接跳过 - finalStep = '5'; + taskData.status = '5'; loadingText = LOADING_TEXT_MAP.postProduction('generating rough cut video...'); } } @@ -559,7 +566,7 @@ export function useWorkflowData() { setFinal({ url: data.final_simple_video.video }); - finalStep = '5.5'; + taskData.status = '5.5'; loadingText = LOADING_TEXT_MAP.postProduction('generating fine-grained video clips...'); } @@ -567,25 +574,25 @@ export function useWorkflowData() { setFinal({ url: data.final_video.video }); - finalStep = '6'; + taskData.status = '6'; loadingText = LOADING_TEXT_MAP.complete; } } // 设置步骤 - setCurrentStep(finalStep); + setCurrentStep(taskData.status); setTaskObject(prev => { if (!prev) return null; return { ...prev, - taskStatus: finalStep + taskStatus: taskData.status }; }); console.log('---------loadingText', loadingText); setCurrentLoadingText(loadingText); // 设置是否需要获取流式数据 - setNeedStreamData(status !== 'COMPLETED' && finalStep !== '6'); + setNeedStreamData(status !== 'COMPLETED' && taskData.status !== '6'); } catch (error) { console.error('初始化失败:', error); @@ -650,6 +657,7 @@ export function useWorkflowData() { setIsPauseWorkFlow, setAnyAttribute, applyScript, - fallbackToStep + fallbackToStep, + originalText }; } diff --git a/components/ui/edit-modal.tsx b/components/ui/edit-modal.tsx index f39fcbb..964a28f 100644 --- a/components/ui/edit-modal.tsx +++ b/components/ui/edit-modal.tsx @@ -25,11 +25,9 @@ interface EditModalProps { roles?: any[]; music?: any; setIsPauseWorkFlow: (isPauseWorkFlow: boolean) => void; - setAnyAttribute: any; isPauseWorkFlow: boolean; - scriptData: any[] | null; - applyScript: any; fallbackToStep: any; + originalText?: string; } const tabs = [ @@ -55,16 +53,16 @@ export function EditModal({ roles = [], music, setIsPauseWorkFlow, - setAnyAttribute, isPauseWorkFlow, - scriptData, - applyScript, - fallbackToStep + fallbackToStep, + originalText }: EditModalProps) { const [activeTab, setActiveTab] = useState(activeEditTab); const [currentIndex, setCurrentIndex] = useState(currentSketchIndex); const [currentRoleIndex, setCurrentRoleIndex] = useState(0); const [isRemindFallbackOpen, setIsRemindFallbackOpen] = useState(false); + const [isRemindResetOpen, setIsRemindResetOpen] = useState(false); + const [resetKey, setResetKey] = useState(0); useEffect(() => { setCurrentIndex(currentSketchIndex); @@ -109,7 +107,6 @@ export function EditModal({ if (activeTab === '0') { fallbackToStep('0'); // 应用剧本 - applyScript(); } else { fallbackToStep('1'); } @@ -121,7 +118,13 @@ export function EditModal({ const handleReset = () => { console.log('handleReset'); // 重置当前tab修改的数据 - + setIsRemindResetOpen(true); + } + + const handleConfirmReset = () => { + console.log('handleConfirmReset'); + setIsRemindResetOpen(false); + setResetKey(resetKey + 1); } const renderTabContent = () => { @@ -129,11 +132,9 @@ export function EditModal({ case '0': return ( ); case '1': @@ -265,7 +266,7 @@ export function EditModal({
+ + {/* 提醒用户 重置当前tab修改的数据 */} + +
+
+ +

Are you sure you want to reset the current tab?

+
+
+ + + +
+
+
)} diff --git a/components/ui/script-tab-content.tsx b/components/ui/script-tab-content.tsx index 1cb1e71..0f5de90 100644 --- a/components/ui/script-tab-content.tsx +++ b/components/ui/script-tab-content.tsx @@ -2,23 +2,31 @@ import React, { useState, useCallback, useEffect, SetStateAction } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { FileText } from 'lucide-react'; import { ScriptRenderer } from '@/components/script-renderer/ScriptRenderer'; +import { useEditData } from '@/components/pages/work-flow/use-edit-data'; interface ScriptTabContentProps { - scriptData: any[] | null; setIsPauseWorkFlow: (isPauseWorkFlow: boolean) => void; - setAnyAttribute: any; isPauseWorkFlow: boolean; - applyScript: any; + originalText?: string; } export function ScriptTabContent({ - scriptData = [], setIsPauseWorkFlow, - setAnyAttribute, isPauseWorkFlow, - applyScript + originalText, }: ScriptTabContentProps) { + const { loading, scriptData, setAnyAttribute, applyScript } = useEditData('script', originalText); + + // 如果loading 显示loading状态 + if (loading) { + return ( +
+
+

Loading...

+
+ ); + } // 如果没有数据,显示空状态 if (!scriptData || scriptData.length === 0) {