video-flow-b/components/ui/script-tab-content.tsx

112 lines
3.1 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 React, { useState, useCallback, useEffect } 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';
import { useScriptService } from '@/app/service/Interaction/ScriptService';
const ScriptTabContent: React.FC = () => {
// 获取当前项目ID这里需要根据实际项目路由或上下文获取
const projectId = 'current-project-id'; // TODO: 从路由或上下文获取实际项目ID
const {
scriptSlices,
userPrompt,
loading,
error,
updateUserPrompt,
fetchScriptData,
setFocusedSlice,
updateScriptSliceText,
resetScript,
applyScript,
fetchProjectScript
} = useScriptService();
// 组件挂载时获取项目剧本数据
useEffect(() => {
const initializeScript = async () => {
try {
await fetchProjectScript(projectId);
} catch (error) {
console.error('初始化剧本数据失败:', error);
}
};
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]);
return (
<div className="flex flex-col h-full">
<motion.div
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"
}
}}
>
</motion.div>
</div>
);
};
export default ScriptTabContent;