import React, { useState, useRef } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Upload, Library, Play, Pause, RefreshCw, Wand2, Users } from 'lucide-react'; import { cn } from '@/public/lib/utils'; import { GlassIconButton } from './glass-icon-button'; import { ReplaceCharacterModal } from './replace-character-modal'; interface Role { name: string; url: string; sound: string; soundDescription: string; roleDescription: string; } interface CharacterTabContentProps { taskSketch: any[]; currentSketchIndex: number; onSketchSelect: (index: number) => void; roles: Role[]; } export function CharacterTabContent({ taskSketch, currentSketchIndex, onSketchSelect, roles = [] }: CharacterTabContentProps) { const [selectedCharacterIndex, setSelectedCharacterIndex] = useState(0); const [isReplaceModalOpen, setIsReplaceModalOpen] = useState(false); const [activeReplaceMethod, setActiveReplaceMethod] = useState('upload'); const [isPlaying, setIsPlaying] = useState(false); const [progress, setProgress] = useState(0); const [editingField, setEditingField] = useState<{ type: 'name' | 'voiceDescription' | 'characterDescription' | null; value: string; }>({ type: null, value: '' }); const audioRef = useRef(null); // 如果没有角色数据,显示占位内容 if (!roles || roles.length === 0) { return (

No character data

); } // 处理音频播放进度 const handleTimeUpdate = () => { if (audioRef.current) { const progress = (audioRef.current.currentTime / audioRef.current.duration) * 100; setProgress(progress); } }; // 处理播放/暂停 const togglePlay = () => { if (audioRef.current) { if (isPlaying) { audioRef.current.pause(); } else { audioRef.current.play(); } setIsPlaying(!isPlaying); } }; // 处理进度条点击 const handleProgressClick = (e: React.MouseEvent) => { if (audioRef.current) { const rect = e.currentTarget.getBoundingClientRect(); const x = e.clientX - rect.left; const percentage = (x / rect.width) * 100; const time = (percentage / 100) * audioRef.current.duration; audioRef.current.currentTime = time; setProgress(percentage); } }; // 获取当前选中的角色 const currentRole = roles[selectedCharacterIndex]; return (
{/* 上部分:角色缩略图 */}
{roles.map((role, index) => ( setSelectedCharacterIndex(index)} whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }} > {role.name}
{role.name}
))}
{/* 中间部分:替换角色 */}

Replace character

{ setActiveReplaceMethod('upload'); setIsReplaceModalOpen(true); }} whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }} > Upload character { setActiveReplaceMethod('library'); setIsReplaceModalOpen(true); }} whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }} > Character library
{/* 下部分:角色详情 */} {/* 左列:角色信息 */}
{/* 角色姓名 */}
console.log('name changed:', e.target.value)} className="w-full px-3 py-2 bg-white/5 border border-white/10 rounded-lg focus:outline-none focus:border-blue-500" />
{/* 声音描述 */}