forked from 77media/video-flow
优化 ScriptService 和 ShotService,移除调试信息,更新接口以支持新功能,重构代码以提高可读性。
This commit is contained in:
parent
817c5d5144
commit
1ef7d03830
@ -99,7 +99,6 @@ export interface UseScriptService {
|
||||
* 包括剧本生成、项目创建、剧本保存等功能
|
||||
*/
|
||||
export const useScriptService = (): UseScriptService => {
|
||||
console.log('useScriptService----9((@@@@@@@@@@@@@@@@@@');
|
||||
// 响应式状态
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [synopsis, setSynopsis] = useState<string>("");
|
||||
@ -215,7 +214,6 @@ export const useScriptService = (): UseScriptService => {
|
||||
|
||||
// 获取解析后的故事详情
|
||||
const storyDetails = newScriptEditUseCase.getStoryDetails();
|
||||
|
||||
setSynopsis(storyDetails.synopsis || "");
|
||||
setCategories(storyDetails.categories || []);
|
||||
setProtagonist(storyDetails.protagonist || "");
|
||||
@ -231,7 +229,7 @@ export const useScriptService = (): UseScriptService => {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[projectId, scriptEditUseCase]
|
||||
[generateScriptFromIdea]
|
||||
);
|
||||
|
||||
/**
|
||||
@ -392,7 +390,6 @@ export const useScriptService = (): UseScriptService => {
|
||||
|
||||
const setAnyAttributeWrapper = useCallback(
|
||||
(type: string, value: SetStateAction<string>, tags?: string[]) => {
|
||||
console.log('setAnyAttributeWrapper', type);
|
||||
if (type === 'synopsis') {
|
||||
setFieldOld(synopsis)
|
||||
scriptEditUseCase.replaceScript(fieldOld,synopsis)
|
||||
@ -492,8 +489,7 @@ export const useScriptService = (): UseScriptService => {
|
||||
];
|
||||
// 筛选出有内容的block
|
||||
const filteredArr = arr.filter(item => (item.content.length > 0 && item.content[0].text !== ''));
|
||||
console.log('scriptBlocksMemo 所有关联数据', synopsis, categories, protagonist, incitingIncident, problem, conflict, stakes, characterArc);
|
||||
console.log('scriptBlocksMemo', filteredArr);
|
||||
console.log('scriptBlocksMemo', JSON.parse(JSON.stringify(filteredArr)));
|
||||
return filteredArr;
|
||||
}, [
|
||||
synopsis,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { useState, useCallback } from "react";
|
||||
import { VideoSegmentEditUseCase } from "../usecase/ShotEditUsecase";
|
||||
import { VideoSegmentEntity } from "../domain/Entities";
|
||||
import { ContentItem, LensType } from "../domain/valueObject";
|
||||
import { LensType } from "../domain/valueObject";
|
||||
|
||||
/**
|
||||
* 视频片段服务Hook接口
|
||||
@ -15,8 +15,6 @@ export interface UseShotService {
|
||||
videoSegments: VideoSegmentEntity[];
|
||||
/** 当前选中的视频片段 */
|
||||
selectedSegment: VideoSegmentEntity | null;
|
||||
/** 错误信息 */
|
||||
error: string | null;
|
||||
|
||||
// 操作方法
|
||||
/** 获取视频片段列表 */
|
||||
@ -38,8 +36,10 @@ export interface UseShotService {
|
||||
abortOperation: () => void;
|
||||
/** 设置选中的视频片段 */
|
||||
setSelectedSegment: (segment: VideoSegmentEntity | null) => void;
|
||||
/** 清除错误信息 */
|
||||
clearError: () => void;
|
||||
/** 添加新镜头到选中的视频片段 */
|
||||
addNewLens: () => void;
|
||||
/** 删除指定镜头 */
|
||||
deleteLens: (lensName: string) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,10 +52,9 @@ export const useShotService = (): UseShotService => {
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [videoSegments, setVideoSegments] = useState<VideoSegmentEntity[]>([]);
|
||||
const [selectedSegment, setSelectedSegment] = useState<VideoSegmentEntity | null>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
// UseCase实例
|
||||
const [shotEditUseCase] = useState<VideoSegmentEditUseCase>(
|
||||
const [vidoEditUseCase] = useState<VideoSegmentEditUseCase>(
|
||||
new VideoSegmentEditUseCase()
|
||||
);
|
||||
|
||||
@ -67,19 +66,16 @@ export const useShotService = (): UseShotService => {
|
||||
async (projectId: string): Promise<void> => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
const segments = await shotEditUseCase.getVideoSegmentList(projectId);
|
||||
const segments = await vidoEditUseCase.getVideoSegmentList(projectId);
|
||||
setVideoSegments(segments);
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : "获取视频片段列表失败";
|
||||
setError(errorMessage);
|
||||
console.error("获取视频片段列表失败:", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[shotEditUseCase]
|
||||
[vidoEditUseCase]
|
||||
);
|
||||
|
||||
/**
|
||||
@ -99,9 +95,8 @@ export const useShotService = (): UseShotService => {
|
||||
): Promise<VideoSegmentEntity> => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
const regeneratedSegment = await shotEditUseCase.regenerateVideoSegment(
|
||||
const regeneratedSegment = await vidoEditUseCase.regenerateVideoSegment(
|
||||
shotPrompt,
|
||||
shotId,
|
||||
roleReplaceParams,
|
||||
@ -122,15 +117,13 @@ export const useShotService = (): UseShotService => {
|
||||
|
||||
return regeneratedSegment;
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : "重新生成视频片段失败";
|
||||
setError(errorMessage);
|
||||
console.error("重新生成视频片段失败:", error);
|
||||
throw error;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[shotEditUseCase]
|
||||
[vidoEditUseCase]
|
||||
);
|
||||
|
||||
/**
|
||||
@ -148,9 +141,8 @@ export const useShotService = (): UseShotService => {
|
||||
): Promise<LensType[]> => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
const optimizedLensData = await shotEditUseCase.optimizeVideoContent(
|
||||
const optimizedLensData = await vidoEditUseCase.optimizeVideoContent(
|
||||
shotId,
|
||||
userRequirement,
|
||||
lensData
|
||||
@ -161,23 +153,21 @@ export const useShotService = (): UseShotService => {
|
||||
|
||||
return optimizedLensData;
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : "AI优化视频内容失败";
|
||||
setError(errorMessage);
|
||||
console.error("AI优化视频内容失败:", error);
|
||||
throw error;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[shotEditUseCase]
|
||||
[vidoEditUseCase]
|
||||
);
|
||||
/**
|
||||
* 中断当前操作
|
||||
*/
|
||||
const abortOperation = useCallback((): void => {
|
||||
shotEditUseCase.abortOperation();
|
||||
vidoEditUseCase.abortOperation();
|
||||
setLoading(false);
|
||||
}, [shotEditUseCase]);
|
||||
}, [vidoEditUseCase]);
|
||||
|
||||
/**
|
||||
* 设置选中的视频片段
|
||||
@ -187,24 +177,85 @@ export const useShotService = (): UseShotService => {
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* 清除错误信息
|
||||
* 添加新镜头到选中的视频片段
|
||||
* @description 在selectedSegment的lens数组中添加一个新的空镜头,镜头名称按顺序命名
|
||||
*/
|
||||
const clearError = useCallback((): void => {
|
||||
setError(null);
|
||||
}, []);
|
||||
const addNewLens = useCallback((): void => {
|
||||
if (!selectedSegment) {
|
||||
console.warn("没有选中的视频片段,无法添加镜头");
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算下一个镜头编号
|
||||
const currentLensCount = selectedSegment.lens.length;
|
||||
const newLensName = `镜头${currentLensCount + 1}`;
|
||||
|
||||
// 创建新的空镜头
|
||||
const newLens = new LensType(newLensName, "", []);
|
||||
|
||||
// 创建更新后的片段
|
||||
const updatedSegment: VideoSegmentEntity = {
|
||||
...selectedSegment,
|
||||
lens: [...selectedSegment.lens, newLens]
|
||||
};
|
||||
|
||||
// 批量更新状态,避免多次重渲染
|
||||
setSelectedSegment(updatedSegment);
|
||||
setVideoSegments(prev => {
|
||||
const segmentIndex = prev.findIndex(segment => segment.id === selectedSegment.id);
|
||||
if (segmentIndex === -1) return prev;
|
||||
|
||||
const newSegments = [...prev];
|
||||
newSegments[segmentIndex] = updatedSegment;
|
||||
return newSegments;
|
||||
});
|
||||
}, [selectedSegment]);
|
||||
|
||||
/**
|
||||
* 删除指定镜头
|
||||
* @param lensName 要删除的镜头名称
|
||||
*/
|
||||
const deleteLens = useCallback((lensName: string): void => {
|
||||
if (!selectedSegment) {
|
||||
console.warn("没有选中的视频片段,无法删除镜头");
|
||||
return;
|
||||
}
|
||||
|
||||
// 过滤掉指定名称的镜头并重新排序
|
||||
const updatedLens = selectedSegment.lens
|
||||
.filter(lens => lens.name !== lensName)
|
||||
.map((lens, index) => new LensType(`镜头${index + 1}`, lens.script, lens.content));
|
||||
|
||||
// 创建更新后的片段
|
||||
const updatedSegment: VideoSegmentEntity = {
|
||||
...selectedSegment,
|
||||
lens: updatedLens
|
||||
};
|
||||
|
||||
// 批量更新状态,避免多次重渲染
|
||||
setSelectedSegment(updatedSegment);
|
||||
setVideoSegments(prev => {
|
||||
const segmentIndex = prev.findIndex(segment => segment.id === selectedSegment.id);
|
||||
if (segmentIndex === -1) return prev;
|
||||
|
||||
const newSegments = [...prev];
|
||||
newSegments[segmentIndex] = updatedSegment;
|
||||
return newSegments;
|
||||
});
|
||||
}, [selectedSegment]);
|
||||
|
||||
return {
|
||||
// 响应式状态
|
||||
loading,
|
||||
videoSegments,
|
||||
selectedSegment,
|
||||
error,
|
||||
// 操作方法
|
||||
getVideoSegmentList,
|
||||
regenerateVideoSegment,
|
||||
optimizeVideoContent,
|
||||
abortOperation,
|
||||
setSelectedSegment: setSelectedSegmentHandler,
|
||||
clearError,
|
||||
addNewLens,
|
||||
deleteLens,
|
||||
};
|
||||
};
|
||||
|
||||
@ -115,7 +115,9 @@ export class StoryDetails {
|
||||
* @param text 剧本文本
|
||||
*/
|
||||
updateScript(text: string) {
|
||||
console.log('text.length', text.length)
|
||||
const scriptObject = this.createFromText(text);
|
||||
console.log('scriptObject', scriptObject)
|
||||
this.setProperties(scriptObject);
|
||||
return scriptObject;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1,13 +0,0 @@
|
||||
import { useVideoSegmentService } from '../Interaction/ShotService';
|
||||
|
||||
describe('VideoSegmentService 测试', () => {
|
||||
it('初始化服务实例', () => {
|
||||
const videoSegmentService = useVideoSegmentService();
|
||||
expect(videoSegmentService).toBeDefined();
|
||||
});
|
||||
|
||||
it('获取视频片段列表', () => {
|
||||
const videoSegmentService = useVideoSegmentService();
|
||||
expect(typeof videoSegmentService.fetchVideoSegmentList).toBe('function');
|
||||
});
|
||||
});
|
||||
@ -150,7 +150,7 @@ export const ScriptRenderer: React.FC<ScriptRendererProps> = ({ data, setIsPause
|
||||
onChange={handleBlockTextChange(block)}
|
||||
onBlur={handleBlockTextBlur(block)}
|
||||
autoFocus={true}
|
||||
className="block w-full min-h-[120px] bg-white/5 backdrop-blur-md p-4 text-white/90
|
||||
className="block w-full min-h-[120px] bg-white/5 backdrop-blur-md p-4 text-white/90
|
||||
rounded-lg border-unset outline-none pb-12
|
||||
whitespace-pre-wrap break-words"
|
||||
placeholder=""
|
||||
@ -166,7 +166,7 @@ export const ScriptRenderer: React.FC<ScriptRendererProps> = ({ data, setIsPause
|
||||
{addThemeTag.map((item, index) => (
|
||||
<div key={index} className={`flex items-center gap-1 px-2 rounded-full ${Object.values(ThemeTagBgColor)[index]}`}>
|
||||
<span className={`text-sm px-2 py-1 rounded-md`}>{item}</span>
|
||||
<X className="w-4 h-4 cursor-pointer text-blue-500/80" onClick={() =>
|
||||
<X className="w-4 h-4 cursor-pointer text-blue-500/80" onClick={() =>
|
||||
handleThemeTagChange(addThemeTag.filter(v => v !== item))
|
||||
} />
|
||||
</div>
|
||||
@ -234,11 +234,11 @@ export const ScriptRenderer: React.FC<ScriptRendererProps> = ({ data, setIsPause
|
||||
const isHovered = hoveredBlockId === block.id;
|
||||
const isActive = activeBlockId === block.id;
|
||||
const isEditing = editBlockId === block.id;
|
||||
|
||||
console.log('block', block)
|
||||
return (
|
||||
<motion.div
|
||||
key={block.id}
|
||||
className={`relative p-4 mb-1 rounded-lg shadow-md transition-colors duration-300
|
||||
className={`relative p-4 mb-1 rounded-lg shadow-md transition-colors duration-300
|
||||
${isActive ? 'bg-slate-700/50' : ''} hover:bg-slate-700/30`}
|
||||
ref={(el) => (contentRefs.current[block.id] = el)}
|
||||
onMouseEnter={() => setHoveredBlockId(block.id)}
|
||||
@ -303,4 +303,4 @@ export const ScriptRenderer: React.FC<ScriptRendererProps> = ({ data, setIsPause
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user