video-flow-b/hooks/useWorkFlow.ts
2025-07-03 05:51:09 +08:00

311 lines
8.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState, useEffect, useRef, useCallback } from 'react';
import { TaskObject, SketchItem, VideoItem, STEP_MESSAGES } from '@/components/work-flow/constants';
import {
getTaskDetail,
getTaskSketch,
getTaskRole,
getTaskBackgroundAudio,
getTaskFinalProduct,
getTaskVideo
} from '@/components/work-flow/api';
export const useWorkFlow = () => {
// 基础状态
const [taskObject, setTaskObject] = useState<TaskObject | null>(null);
const [taskSketch, setTaskSketch] = useState<SketchItem[]>([]);
const [taskVideos, setTaskVideos] = useState<VideoItem[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [currentStep, setCurrentStep] = useState('0');
const [currentSketchIndex, setCurrentSketchIndex] = useState(0);
const [currentLoadingText, setCurrentLoadingText] = useState('Loading task information...');
const [totalSketchCount, setTotalSketchCount] = useState(0);
// 生成状态
const [isGeneratingSketch, setIsGeneratingSketch] = useState(false);
const [isGeneratingVideo, setIsGeneratingVideo] = useState(false);
const [sketchCount, setSketchCount] = useState(0);
// 播放状态
const [isPlaying, setIsPlaying] = useState(false);
const [isVideoPlaying, setIsVideoPlaying] = useState(true);
const playTimerRef = useRef<NodeJS.Timeout | null>(null);
const videoPlayTimerRef = useRef<NodeJS.Timeout | null>(null);
const mainVideoRef = useRef<HTMLVideoElement>(null);
// 拖拽状态
const [isDragging, setIsDragging] = useState(false);
const [startX, setStartX] = useState(0);
const [scrollLeft, setScrollLeft] = useState(0);
// 界面状态
const [showControls, setShowControls] = useState(false);
const [isEditModalOpen, setIsEditModalOpen] = useState(false);
const [activeEditTab, setActiveEditTab] = useState('1');
// 初始化工作流
useEffect(() => {
const initWorkFlow = async () => {
const taskId = localStorage.getItem("taskId") || "taskId-123";
try {
// 获取任务详情
const data = await getTaskDetail(taskId);
setTaskObject(data);
setIsLoading(false);
setCurrentStep('1');
// 获取分镜草图
await handleGetTaskSketch(taskId);
await delay(2000);
updateTaskStatus('2');
setCurrentStep('2');
// 绘制角色
await getTaskRole(taskId);
await delay(2000);
updateTaskStatus('3');
setCurrentStep('3');
// 获取分镜视频
await handleGetTaskVideo(taskId);
await delay(2000);
updateTaskStatus('4');
setCurrentStep('4');
// 获取背景音
await getTaskBackgroundAudio(taskId);
await delay(2000);
updateTaskStatus('5');
setCurrentStep('5');
// 获取最终成品
await getTaskFinalProduct(taskId);
await delay(2000);
updateTaskStatus('6');
setCurrentStep('6');
} catch (error) {
console.error('工作流初始化失败:', error);
}
};
initWorkFlow();
}, []);
const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
const updateTaskStatus = (status: string) => {
setTaskObject(prev => prev ? { ...prev, taskStatus: status } : null);
};
const handleGetTaskSketch = async (taskId: string) => {
if (isGeneratingSketch || taskSketch.length > 0) return;
setIsGeneratingSketch(true);
setTaskSketch([]);
await getTaskSketch(taskId, (newSketch, index) => {
setTaskSketch(prev => {
if (prev.find(sketch => sketch.id === newSketch.id)) {
return prev;
}
const newSketchList = [...prev, newSketch];
if (index === 0) {
// 这里我们需要从API获取总数暂时使用当前逻辑
}
return newSketchList;
});
setCurrentSketchIndex(index);
setSketchCount(index + 1);
});
setIsGeneratingSketch(false);
setTotalSketchCount(taskSketch.length);
};
const handleGetTaskVideo = async (taskId: string) => {
setIsGeneratingVideo(true);
setTaskVideos([]);
await getTaskVideo(taskId, taskSketch.length, (newVideo, index) => {
setTaskVideos(prev => {
if (prev.find(video => video.id === newVideo.id)) {
return prev;
}
return [...prev, newVideo];
});
setCurrentSketchIndex(index);
});
setIsGeneratingVideo(false);
};
// 自动播放逻辑
useEffect(() => {
if (isPlaying && taskSketch.length > 0) {
playTimerRef.current = setInterval(() => {
setCurrentSketchIndex(prev => (prev + 1) % taskSketch.length);
}, 2000);
} else if (playTimerRef.current) {
clearInterval(playTimerRef.current);
}
return () => {
if (playTimerRef.current) {
clearInterval(playTimerRef.current);
}
};
}, [isPlaying, taskSketch.length]);
// 视频播放逻辑
useEffect(() => {
if (isVideoPlaying && taskVideos.length > 0) {
if (mainVideoRef.current) {
mainVideoRef.current.play().catch(error => {
console.log('视频播放失败:', error);
setIsVideoPlaying(false);
});
}
} else {
if (mainVideoRef.current) {
mainVideoRef.current.pause();
}
if (videoPlayTimerRef.current) {
clearInterval(videoPlayTimerRef.current);
}
}
return () => {
if (videoPlayTimerRef.current) {
clearInterval(videoPlayTimerRef.current);
}
};
}, [isVideoPlaying, taskVideos.length]);
// 当切换视频时重置播放
useEffect(() => {
if (mainVideoRef.current) {
mainVideoRef.current.currentTime = 0;
if (isVideoPlaying) {
mainVideoRef.current.play().catch(error => {
console.log('视频播放失败:', error);
setIsVideoPlaying(false);
});
}
}
}, [currentSketchIndex]);
// 更新加载文字
useEffect(() => {
if (isLoading) {
setCurrentLoadingText(STEP_MESSAGES.loading);
return;
}
switch (currentStep) {
case '1':
setCurrentLoadingText(
isGeneratingSketch
? STEP_MESSAGES.sketch(sketchCount, Math.max(totalSketchCount, sketchCount + 1))
: STEP_MESSAGES.sketchComplete
);
break;
case '2':
setCurrentLoadingText(STEP_MESSAGES.character);
break;
case '3':
setCurrentLoadingText(
isGeneratingVideo
? STEP_MESSAGES.video(taskVideos.length, taskSketch.length)
: STEP_MESSAGES.videoComplete
);
break;
case '4':
setCurrentLoadingText(STEP_MESSAGES.audio);
break;
case '5':
setCurrentLoadingText(STEP_MESSAGES.final);
break;
default:
setCurrentLoadingText(STEP_MESSAGES.complete);
}
}, [isLoading, currentStep, isGeneratingSketch, sketchCount, isGeneratingVideo, taskVideos.length, taskSketch.length, totalSketchCount]);
// 控制函数
const togglePlay = useCallback(() => {
setIsPlaying(prev => !prev);
}, []);
const toggleVideoPlay = useCallback(() => {
if (mainVideoRef.current) {
if (isVideoPlaying) {
mainVideoRef.current.pause();
} else {
mainVideoRef.current.play();
}
}
setIsVideoPlaying(prev => !prev);
}, [isVideoPlaying]);
const handleEditModalOpen = (tab: string) => {
setIsPlaying(false);
setIsVideoPlaying(false);
setActiveEditTab(tab);
setIsEditModalOpen(true);
};
// 当切换到视频模式时,停止播放
useEffect(() => {
if (currentStep === '3') {
setIsPlaying(false);
}
}, [currentStep]);
// 当切换到分镜草图模式时,停止视频播放
useEffect(() => {
if (currentStep !== '3') {
setIsVideoPlaying(false);
}
}, [currentStep]);
return {
// 数据状态
taskObject,
taskSketch,
taskVideos,
isLoading,
currentStep,
currentSketchIndex,
setCurrentSketchIndex,
currentLoadingText,
// 生成状态
isGeneratingSketch,
isGeneratingVideo,
sketchCount,
// 播放状态
isPlaying,
isVideoPlaying,
mainVideoRef,
// 拖拽状态
isDragging,
setIsDragging,
startX,
setStartX,
scrollLeft,
setScrollLeft,
// 界面状态
showControls,
setShowControls,
isEditModalOpen,
setIsEditModalOpen,
activeEditTab,
// 控制函数
togglePlay,
toggleVideoPlay,
handleEditModalOpen,
};
};