import React, { useState, useRef } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Upload, Library, Play, Pause, RefreshCw, Wand2, Users, Check, ReplaceAll, X } from 'lucide-react'; import { cn } from '@/public/lib/utils'; import CharacterEditor from './character-editor'; import ImageBlurTransition from './ImageBlurTransition'; import FloatingGlassPanel from './FloatingGlassPanel'; import { ReplaceCharacterPanel, mockShots, mockCharacter } from './replace-character-panel'; import { CharacterLibrarySelector } from './character-library-selector'; interface Appearance { hairStyle: string; skinTone: string; facialFeatures: string; bodyType: string; } interface Role { name: string; url: string; sound: string; soundDescription: string; roleDescription: string; age: number; gender: 'male' | 'female' | 'other'; ethnicity: string; appearance: Appearance; // 新增标签数组 tags: string[]; } // Mock 数据 const mockRole: Role = { name: "青春女学生", url: "/assets/3dr_chihiro.png", sound: "", soundDescription: "", roleDescription: "一位充满活力和梦想的高中女生,蓝色长发随风飘扬,眼神中透露着对未来的憧憬。她身着整洁的校服,举止优雅而不失活力。", age: 16, gender: 'female', ethnicity: '亚洲人', appearance: { hairStyle: "鲜艳蓝色长发", skinTone: "白皙", facialFeatures: "大眼睛,清秀五官", bodyType: "苗条" }, tags: ['高中生', '校服', '蓝色长发', '大眼睛', '清秀五官', '苗条'] }; interface CharacterTabContentProps { taskSketch: any[]; currentRoleIndex: number; onSketchSelect: (index: number) => void; roles: Role[]; } export function CharacterTabContent({ taskSketch, currentRoleIndex, onSketchSelect, roles = [mockRole] }: CharacterTabContentProps) { const [localRole, setLocalRole] = useState(mockRole); const [currentRole, setCurrentRole] = useState(roles[currentRoleIndex]); const [isReplacePanelOpen, setIsReplacePanelOpen] = useState(false); const [replacePanelKey, setReplacePanelKey] = useState(0); const [ignoreReplace, setIgnoreReplace] = useState(false); const [isReplaceLibraryOpen, setIsReplaceLibraryOpen] = useState(false); const handleReplaceCharacter = (url: string) => { setCurrentRole({ ...currentRole, url: url }); setIsReplacePanelOpen(true); }; const handleConfirmReplace = (selectedShots: string[], addToLibrary: boolean) => { // 处理替换确认逻辑 console.log('Selected shots:', selectedShots); console.log('Add to library:', addToLibrary); setIsReplacePanelOpen(false); }; const handleCloseReplacePanel = () => { setIsReplacePanelOpen(false); setIgnoreReplace(true); }; const handleChangeRole = (index: number) => { if (currentRole.url !== roles[currentRoleIndex].url && !ignoreReplace) { // 提示 角色已修改,弹出替换角色面板 if (isReplacePanelOpen) { setReplacePanelKey(replacePanelKey + 1); } else { setIsReplacePanelOpen(true); } return; } onSketchSelect(index); setCurrentRole(roles[index]); }; // 从角色库中选择角色 const handleSelectCharacter = (index: number) => { console.log('index', index); setIsReplaceLibraryOpen(false); handleReplaceCharacter('https://c.huiying.video/images/5740cb7c-6e08-478f-9e7c-bca7f78a2bf6.jpg'); }; // 如果没有角色数据,显示占位内容 if (!roles || roles.length === 0) { return (

No character data

); } return (
{/* 上部分:角色缩略图 */}
{roles.map((role, index) => ( handleChangeRole(index)} whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }} > {role.name}
{role.name}
))}
{/* 下部分:角色详情 */} {/* 左列:角色预览 */}
{/* 角色预览图 */}
{/* 应用角色按钮 */}
setIsReplaceLibraryOpen(true)} >
{/* 右列:角色信息 */}
{ setLocalRole({ ...localRole, roleDescription: description }); }} onAttributesChange={(attributes) => { const newRole = { ...localRole }; attributes.forEach(attr => { switch (attr.key) { case 'age': newRole.age = parseInt(attr.value); break; case 'gender': if (attr.value === '男性') { newRole.gender = 'male'; } else if (attr.value === '女性') { newRole.gender = 'female'; } else { newRole.gender = 'other'; } break; case 'hair': newRole.appearance.hairStyle = attr.value; break; case 'skin': newRole.appearance.skinTone = attr.value; break; case 'build': newRole.appearance.bodyType = attr.value; break; } }); setLocalRole(newRole); }} onReplaceCharacter={(url) => { handleReplaceCharacter(url); }} /> {/* 重新生成按钮、替换形象按钮 */}
handleReplaceCharacter('https://c.huiying.video/images/5740cb7c-6e08-478f-9e7c-bca7f78a2bf6.jpg')} className="flex items-center justify-center gap-2 px-4 py-3 bg-pink-500/10 hover:bg-pink-500/20 text-pink-500 rounded-lg transition-colors" whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }} > Replace console.log('Regenerate')} className="flex items-center justify-center gap-2 px-4 py-3 bg-blue-500/10 hover:bg-blue-500/20 text-blue-500 rounded-lg transition-colors" whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }} > Regenerate
handleCloseReplacePanel()} > handleCloseReplacePanel()} onConfirm={handleConfirmReplace} /> {/* 从角色库中选择角色 */}
); }