更新编辑模态框,新增保存功能及提醒面板,优化角色选择项为“Voiceover”。同时,调整脚本标签内容以支持新属性 applyScript。

This commit is contained in:
北枳 2025-08-10 19:29:50 +08:00
parent 3cac5196d4
commit 360332efbf
3 changed files with 69 additions and 8 deletions

View File

@ -2,7 +2,7 @@
import React, { useState, useEffect, SetStateAction } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { X, Image, Users, Video, Music, Settings, FileText, Maximize, Minimize } from 'lucide-react';
import { X, Image, Users, Video, Music, Settings, FileText, Undo2, TriangleAlert } from 'lucide-react';
import { cn } from '@/public/lib/utils';
import { ScriptTabContent } from './script-tab-content';
import { SceneTabContent } from './scene-tab-content';
@ -10,6 +10,7 @@ import { ShotTabContent } from './shot-tab-content';
import { SettingsTabContent } from './settings-tab-content';
import { CharacterTabContent } from './character-tab-content';
import { MusicTabContent } from './music-tab-content';
import FloatingGlassPanel from './FloatingGlassPanel';
interface EditModalProps {
isOpen: boolean;
@ -27,6 +28,7 @@ interface EditModalProps {
setAnyAttribute: any;
isPauseWorkFlow: boolean;
scriptData: any[] | null;
applyScript: any;
}
const tabs = [
@ -54,11 +56,13 @@ export function EditModal({
setIsPauseWorkFlow,
setAnyAttribute,
isPauseWorkFlow,
scriptData
scriptData,
applyScript
}: EditModalProps) {
const [activeTab, setActiveTab] = useState(activeEditTab);
const [currentIndex, setCurrentIndex] = useState(currentSketchIndex);
const [currentRoleIndex, setCurrentRoleIndex] = useState(0);
const [isRemindFallbackOpen, setIsRemindFallbackOpen] = useState(false);
useEffect(() => {
setCurrentIndex(currentSketchIndex);
@ -93,6 +97,18 @@ export function EditModal({
setCurrentIndex(0);
}
const handleSave = () => {
console.log('handleSave');
setIsRemindFallbackOpen(true);
}
const handleConfirmGotoFallback = () => {
console.log('handleConfirmGotoFallback');
}
const handleCloseRemindFallbackPanel = () => {
setIsRemindFallbackOpen(false);
}
const renderTabContent = () => {
switch (activeTab) {
case '0':
@ -102,6 +118,7 @@ export function EditModal({
setIsPauseWorkFlow={setIsPauseWorkFlow}
setAnyAttribute={setAnyAttribute}
isPauseWorkFlow={isPauseWorkFlow}
applyScript={applyScript}
/>
);
case '1':
@ -260,6 +277,7 @@ export function EditModal({
className="px-4 py-2 rounded-lg bg-blue-500 text-white hover:bg-blue-600 transition-colors"
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
onClick={() => {handleSave()}}
>
Save
</motion.button>
@ -267,6 +285,40 @@ export function EditModal({
</div>
</motion.div>
</div>
{/* 提醒用户 点击保存 工作流将回退 并重新执行工作流 */}
<FloatingGlassPanel
open={isRemindFallbackOpen}
width='500px'
clickMaskClose={false}
>
<div className="flex flex-col items-center gap-4 text-white py-4">
<div className="flex items-center gap-3">
<TriangleAlert className="w-6 h-6 text-yellow-400" />
<p className="text-lg font-medium"></p>
</div>
<div className="flex gap-3 mt-2">
<button
onClick={() => handleConfirmGotoFallback()}
data-alt="confirm-replace-button"
className="px-4 py-2 bg-blue-600 hover:bg-blue-700 rounded-md transition-colors duration-200 flex items-center gap-2"
>
<Undo2 className="w-4 h-4" />
</button>
<button
onClick={() => handleCloseRemindFallbackPanel()}
data-alt="ignore-button"
className="px-4 py-2 bg-gray-600 hover:bg-gray-700 rounded-md transition-colors duration-200 flex items-center gap-2"
>
<X className="w-4 h-4" />
</button>
</div>
</div>
</FloatingGlassPanel>
</>
)}
</AnimatePresence>

View File

@ -9,13 +9,15 @@ interface ScriptTabContentProps {
setIsPauseWorkFlow: (isPauseWorkFlow: boolean) => void;
setAnyAttribute: any;
isPauseWorkFlow: boolean;
applyScript: any;
}
export function ScriptTabContent({
scriptData = [],
setIsPauseWorkFlow,
setAnyAttribute,
isPauseWorkFlow
isPauseWorkFlow,
applyScript
}: ScriptTabContentProps) {
// 如果没有数据,显示空状态
@ -34,7 +36,14 @@ export function ScriptTabContent({
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
>
<ScriptRenderer data={scriptData} setIsPauseWorkFlow={setIsPauseWorkFlow} setAnyAttribute={setAnyAttribute} isPauseWorkFlow={isPauseWorkFlow} />
<ScriptRenderer
data={scriptData}
setIsPauseWorkFlow={setIsPauseWorkFlow}
setAnyAttribute={setAnyAttribute}
isPauseWorkFlow={isPauseWorkFlow}
applyScript={applyScript}
mode='manual'
/>
</motion.div>
</div>
);

View File

@ -157,20 +157,20 @@ export function CharacterToken(props: ReactNodeViewProps) {
<div
data-alt="role-item"
className={`flex items-center gap-3 p-2 rounded-lg cursor-pointer transition-colors duration-200
${name === '旁白' ? 'bg-blue-500/20 text-blue-400' : 'hover:bg-white/5 text-gray-200'}`}
onClick={() => handleRoleSelect({ name: '旁白', url: '' })}
${name === 'Voiceover' ? 'bg-blue-500/20 text-blue-400' : 'hover:bg-white/5 text-gray-200'}`}
onClick={() => handleRoleSelect({ name: 'Voiceover', url: '' })}
>
<div className="relative">
<CircleUserRound
className={`w-10 h-10 rounded-full border transition-all duration-200`}
/>
{name === '旁白' && (
{name === 'Voiceover' && (
<div className="absolute -top-1 -right-1 bg-blue-500 rounded-full p-0.5">
<Check className="w-3 h-3 text-white" />
</div>
)}
</div>
<span className="flex-1"></span>
<span className="flex-1">Voiceover</span>
</div>
</div>
</motion.div>