forked from 77media/video-flow
优化hooks多次初始化ing
This commit is contained in:
parent
fd7aa0a18e
commit
adf4579ee1
@ -58,14 +58,9 @@ const WorkFlow = React.memo(function WorkFlow() {
|
||||
} = useWorkflowData();
|
||||
|
||||
const {
|
||||
isPlaying,
|
||||
isVideoPlaying,
|
||||
showControls,
|
||||
setShowControls,
|
||||
setIsPlaying,
|
||||
togglePlay,
|
||||
toggleVideoPlay,
|
||||
playTimerRef,
|
||||
} = usePlaybackControls(taskSketch, taskVideos, currentStep);
|
||||
|
||||
useEffect(() => {
|
||||
@ -162,10 +157,8 @@ const WorkFlow = React.memo(function WorkFlow() {
|
||||
taskSketch={taskSketch}
|
||||
taskVideos={taskVideos}
|
||||
isVideoPlaying={isVideoPlaying}
|
||||
showControls={showControls}
|
||||
isGeneratingSketch={isGeneratingSketch}
|
||||
isGeneratingVideo={isGeneratingVideo}
|
||||
onControlsChange={setShowControls}
|
||||
onEditModalOpen={handleEditModalOpen}
|
||||
onToggleVideoPlay={toggleVideoPlay}
|
||||
onTogglePlay={togglePlay}
|
||||
|
||||
@ -17,10 +17,8 @@ interface MediaViewerProps {
|
||||
taskSketch: any[];
|
||||
taskVideos: any[];
|
||||
isVideoPlaying: boolean;
|
||||
showControls: boolean;
|
||||
isGeneratingSketch: boolean;
|
||||
isGeneratingVideo: boolean;
|
||||
onControlsChange: (show: boolean) => void;
|
||||
onEditModalOpen: (tab: string) => void;
|
||||
onToggleVideoPlay: () => void;
|
||||
onTogglePlay: () => void;
|
||||
@ -39,10 +37,8 @@ export const MediaViewer = React.memo(function MediaViewer({
|
||||
taskSketch,
|
||||
taskVideos,
|
||||
isVideoPlaying,
|
||||
showControls,
|
||||
isGeneratingSketch,
|
||||
isGeneratingVideo,
|
||||
onControlsChange,
|
||||
onEditModalOpen,
|
||||
onToggleVideoPlay,
|
||||
onTogglePlay,
|
||||
@ -270,7 +266,6 @@ export const MediaViewer = React.memo(function MediaViewer({
|
||||
{/* 静音按钮 */}
|
||||
<GlassIconButton
|
||||
icon={isMuted ? VolumeX : Volume2}
|
||||
tooltip={isMuted ? "取消静音" : "静音"}
|
||||
onClick={toggleMute}
|
||||
size="sm"
|
||||
/>
|
||||
@ -312,10 +307,8 @@ export const MediaViewer = React.memo(function MediaViewer({
|
||||
<div
|
||||
className="relative w-full h-full rounded-lg overflow-hidden"
|
||||
key={`render-video-${taskObject.final.note}`}
|
||||
onMouseEnter={() => onControlsChange(true)}
|
||||
onMouseLeave={() => onControlsChange(false)}
|
||||
>
|
||||
<div className="relative w-full h-full">
|
||||
<div className="relative w-full h-full group">
|
||||
{/* 背景模糊的视频 */}
|
||||
<motion.div
|
||||
className="absolute inset-0 overflow-hidden"
|
||||
@ -347,21 +340,18 @@ export const MediaViewer = React.memo(function MediaViewer({
|
||||
|
||||
{/* 操作按钮组 */}
|
||||
<AnimatePresence>
|
||||
{showControls && (
|
||||
<motion.div
|
||||
className="absolute top-4 right-4 z-10 flex gap-2"
|
||||
initial={{ opacity: 0, y: -10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -10 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<GlassIconButton
|
||||
icon={Edit3}
|
||||
tooltip="Edit sketch"
|
||||
onClick={() => handleEditClick('3', 'final')}
|
||||
/>
|
||||
</motion.div>
|
||||
)}
|
||||
<motion.div
|
||||
className="absolute top-4 right-4 z-10 gap-2 hidden group-hover:flex"
|
||||
initial={{ opacity: 0, y: -10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -10 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<GlassIconButton
|
||||
icon={Edit3}
|
||||
onClick={() => handleEditClick('3', 'final')}
|
||||
/>
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
|
||||
{/* 视频信息浮层 */}
|
||||
@ -405,7 +395,6 @@ export const MediaViewer = React.memo(function MediaViewer({
|
||||
>
|
||||
<GlassIconButton
|
||||
icon={isFinalVideoPlaying ? Pause : Play}
|
||||
tooltip={isFinalVideoPlaying ? "Pause video" : "Play video"}
|
||||
onClick={toggleFinalVideoPlay}
|
||||
size="sm"
|
||||
/>
|
||||
@ -417,7 +406,6 @@ export const MediaViewer = React.memo(function MediaViewer({
|
||||
{/* 全屏按钮 */}
|
||||
<GlassIconButton
|
||||
icon={isFullscreen ? Minimize : Maximize}
|
||||
tooltip={isFullscreen ? "退出全屏" : "全屏"}
|
||||
onClick={toggleFullscreen}
|
||||
size="sm"
|
||||
/>
|
||||
@ -442,9 +430,7 @@ export const MediaViewer = React.memo(function MediaViewer({
|
||||
const renderVideoContent = () => {
|
||||
return (
|
||||
<div
|
||||
className="relative w-full h-full rounded-lg"
|
||||
onMouseEnter={() => onControlsChange(true)}
|
||||
onMouseLeave={() => onControlsChange(false)}
|
||||
className="relative w-full h-full rounded-lg group"
|
||||
>
|
||||
{/* 只在生成过程中或没有视频时使用ProgressiveReveal */}
|
||||
<div className="relative w-full h-full">
|
||||
@ -500,21 +486,18 @@ export const MediaViewer = React.memo(function MediaViewer({
|
||||
|
||||
{/* 操作按钮组 */}
|
||||
<AnimatePresence>
|
||||
{showControls && (
|
||||
<motion.div
|
||||
className="absolute top-4 right-4 flex gap-2 z-[11]"
|
||||
initial={{ opacity: 0, y: -10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -10 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<GlassIconButton
|
||||
icon={Edit3}
|
||||
tooltip="Edit sketch"
|
||||
onClick={() => handleEditClick('3')}
|
||||
/>
|
||||
</motion.div>
|
||||
)}
|
||||
<motion.div
|
||||
className="absolute top-4 right-4 gap-2 z-[11] hidden group-hover:flex"
|
||||
initial={{ opacity: 0, y: -10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -10 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<GlassIconButton
|
||||
icon={Edit3}
|
||||
onClick={() => handleEditClick('3')}
|
||||
/>
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
|
||||
{/* 底部控制区域 */}
|
||||
@ -535,7 +518,6 @@ export const MediaViewer = React.memo(function MediaViewer({
|
||||
>
|
||||
<GlassIconButton
|
||||
icon={isVideoPlaying ? Pause : Play}
|
||||
tooltip={isVideoPlaying ? "Pause video" : "Play video"}
|
||||
onClick={onToggleVideoPlay}
|
||||
size="sm"
|
||||
/>
|
||||
@ -557,9 +539,7 @@ export const MediaViewer = React.memo(function MediaViewer({
|
||||
|
||||
return (
|
||||
<div
|
||||
className="relative w-full h-full rounded-lg"
|
||||
onMouseEnter={() => onControlsChange(true)}
|
||||
onMouseLeave={() => onControlsChange(false)}
|
||||
className="relative w-full h-full rounded-lg group"
|
||||
>
|
||||
{/* 状态 */}
|
||||
{currentSketch.status === 0 && (
|
||||
@ -590,21 +570,18 @@ export const MediaViewer = React.memo(function MediaViewer({
|
||||
|
||||
{/* 操作按钮组 */}
|
||||
<AnimatePresence>
|
||||
{showControls && (
|
||||
<motion.div
|
||||
className="absolute top-4 right-4 flex gap-2"
|
||||
initial={{ opacity: 0, y: -10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -10 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<GlassIconButton
|
||||
icon={Edit3}
|
||||
tooltip="Edit sketch"
|
||||
onClick={() => handleEditClick('1')}
|
||||
/>
|
||||
</motion.div>
|
||||
)}
|
||||
<motion.div
|
||||
className="absolute top-4 right-4 gap-2 hidden group-hover:flex"
|
||||
initial={{ opacity: 0, y: -10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -10 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<GlassIconButton
|
||||
icon={Edit3}
|
||||
onClick={() => handleEditClick('1')}
|
||||
/>
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
|
||||
{/* 底部播放按钮 */}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect, useCallback, useRef } from 'react';
|
||||
import { useState, useEffect, useCallback, useRef, useMemo } from 'react';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import { detailScriptEpisodeNew, getScriptTitle, getRunningStreamData, pauseMovieProjectPlan, resumeMovieProjectPlan } from '@/api/video_flow';
|
||||
import { useAppDispatch, useAppSelector } from '@/lib/store/hooks';
|
||||
@ -42,7 +42,7 @@ type ApiStep = keyof typeof STEP_MAP;
|
||||
|
||||
|
||||
export function useWorkflowData() {
|
||||
console.log('98877766777777888888990')
|
||||
console.log('init-useWorkflowData')
|
||||
|
||||
const searchParams = useSearchParams();
|
||||
const episodeId = searchParams.get('episodeId') || '';
|
||||
@ -78,13 +78,10 @@ export function useWorkflowData() {
|
||||
|
||||
// 更新 taskObject 的类型
|
||||
const [taskObject, setTaskObject] = useState<TaskObject>(tempTaskObject.current);
|
||||
const [originalText, setOriginalText] = useState<string>('');
|
||||
const [scriptData, setScriptData] = useState<any>(null);
|
||||
const [taskSketch, setTaskSketch] = useState<any[]>([]);
|
||||
const [taskScenes, setTaskScenes] = useState<any[]>([]);
|
||||
const [taskShotSketch, setTaskShotSketch] = useState<any[]>([]);
|
||||
const [taskVideos, setTaskVideos] = useState<any[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [currentStep, setCurrentStep] = useState('0');
|
||||
const [currentSketchIndex, setCurrentSketchIndex] = useState(0);
|
||||
const [isGeneratingSketch, setIsGeneratingSketch] = useState(false);
|
||||
@ -97,7 +94,11 @@ export function useWorkflowData() {
|
||||
const [dataLoadError, setDataLoadError] = useState<string | null>(null);
|
||||
const [needStreamData, setNeedStreamData] = useState(false);
|
||||
const [isPauseWorkFlow, setIsPauseWorkFlow] = useState(false);
|
||||
const [mode, setMode] = useState<'automatic' | 'manual' | 'auto'>('automatic');
|
||||
const [state, setState] = useState({
|
||||
mode: 'automatic' as 'automatic' | 'manual' | 'auto',
|
||||
originalText: '',
|
||||
isLoading: true
|
||||
});
|
||||
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
@ -110,12 +111,8 @@ export function useWorkflowData() {
|
||||
applyScript
|
||||
} = useScriptService();
|
||||
// 监听剧本加载完毕
|
||||
useEffect(() => {
|
||||
if (scriptBlocksMemo.length > 0) {
|
||||
console.log('scriptBlocksMemo 更新:', scriptBlocksMemo);
|
||||
setScriptData(scriptBlocksMemo);
|
||||
// setCurrentLoadingText(LOADING_TEXT_MAP.script);
|
||||
}
|
||||
const scriptData = useMemo(() => {
|
||||
return scriptBlocksMemo.length > 0 ? scriptBlocksMemo : null;
|
||||
}, [scriptBlocksMemo]);
|
||||
// 监听继续 请求更新数据
|
||||
useUpdateEffect(() => {
|
||||
@ -418,7 +415,7 @@ export function useWorkflowData() {
|
||||
} catch (error) {
|
||||
console.error('获取数据失败:', error);
|
||||
}
|
||||
}, [episodeId, needStreamData, roles.length, taskShotSketch.length]);
|
||||
}, [episodeId, needStreamData]);
|
||||
|
||||
// 轮询获取流式数据
|
||||
useUpdateEffect(() => {
|
||||
@ -440,12 +437,15 @@ export function useWorkflowData() {
|
||||
const initializeWorkflow = async () => {
|
||||
if (!episodeId) {
|
||||
setDataLoadError('缺少必要的参数');
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
setState({
|
||||
mode: 'automatic' as 'automatic' | 'manual' | 'auto',
|
||||
originalText: '',
|
||||
isLoading: true
|
||||
});
|
||||
setCurrentLoadingText('loading project info...');
|
||||
|
||||
// 获取剧集详情
|
||||
@ -455,9 +455,6 @@ export function useWorkflowData() {
|
||||
}
|
||||
|
||||
const { name, status, data, tags, mode, original_text } = response.data;
|
||||
setMode(mode as 'automatic' | 'manual' | 'auto');
|
||||
setOriginalText(original_text);
|
||||
setIsLoading(false);
|
||||
|
||||
const { current: taskCurrent } = tempTaskObject;
|
||||
|
||||
@ -585,15 +582,20 @@ export function useWorkflowData() {
|
||||
console.log('---look-taskData', taskCurrent);
|
||||
|
||||
if (taskCurrent.currentStage === 'script') {
|
||||
console.log('开始初始化剧本', originalText,episodeId);
|
||||
console.log('开始初始化剧本', original_text,episodeId);
|
||||
// TODO 为什么一开始没项目id
|
||||
originalText && initializeFromProject(episodeId, originalText).then(() => {
|
||||
original_text && initializeFromProject(episodeId, original_text).then(() => {
|
||||
console.log('应用剧本');
|
||||
// 自动模式下 应用剧本;手动模式 需要点击 下一步 触发
|
||||
mode.includes('auto') && applyScript();
|
||||
});
|
||||
}
|
||||
|
||||
setState({
|
||||
mode: mode as 'automatic' | 'manual' | 'auto',
|
||||
originalText: original_text,
|
||||
isLoading: false
|
||||
});
|
||||
// 设置步骤
|
||||
setTaskObject(prev => {
|
||||
const newState = JSON.parse(JSON.stringify({...prev, ...taskCurrent}));
|
||||
@ -606,7 +608,11 @@ export function useWorkflowData() {
|
||||
} catch (error) {
|
||||
console.error('初始化失败:', error);
|
||||
setDataLoadError('加载失败,请重试');
|
||||
setIsLoading(false);
|
||||
setState({
|
||||
mode: 'automatic' as 'automatic' | 'manual' | 'auto',
|
||||
originalText: '',
|
||||
isLoading: false
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -649,7 +655,7 @@ export function useWorkflowData() {
|
||||
taskShotSketch,
|
||||
taskVideos,
|
||||
sketchCount,
|
||||
isLoading,
|
||||
isLoading: state.isLoading,
|
||||
currentStep,
|
||||
currentSketchIndex,
|
||||
isGeneratingSketch,
|
||||
@ -664,11 +670,11 @@ export function useWorkflowData() {
|
||||
retryLoadData,
|
||||
handleManualPlay,
|
||||
isPauseWorkFlow,
|
||||
mode,
|
||||
mode: state.mode,
|
||||
setIsPauseWorkFlow,
|
||||
setAnyAttribute,
|
||||
applyScript,
|
||||
fallbackToStep,
|
||||
originalText
|
||||
originalText: state.originalText
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user