'use client' import { useState, useRef } from 'react' import { useTranslations } from 'next-intl' import { useDeleteVoice } from '@/lib/query/mutations' import { AppIcon } from '@/components/ui/icons' interface Voice { id: string name: string description: string | null voiceId: string | null voiceType: string customVoiceUrl: string | null voicePrompt: string | null gender: string | null language: string folderId: string | null } interface VoiceCardProps { voice: Voice onSelect?: (voice: Voice) => void // 选择模式时使用 isSelected?: boolean // 是否被选中 selectionMode?: boolean // 是否在选择模式 } export function VoiceCard({ voice, onSelect, isSelected = false, selectionMode = false }: VoiceCardProps) { // 🔥 使用 mutation hook const deleteVoice = useDeleteVoice() const t = useTranslations('assetHub') const [showDeleteConfirm, setShowDeleteConfirm] = useState(false) const [isPlaying, setIsPlaying] = useState(false) const audioRef = useRef(null) // 播放预览 const handlePlay = () => { if (!voice.customVoiceUrl) return if (isPlaying && audioRef.current) { audioRef.current.pause() setIsPlaying(false) return } const audio = new Audio(voice.customVoiceUrl) audioRef.current = audio audio.onended = () => setIsPlaying(false) audio.onerror = () => setIsPlaying(false) audio.play() setIsPlaying(true) } // 删除音色 const handleDelete = () => { deleteVoice.mutate(voice.id, { onSettled: () => setShowDeleteConfirm(false) }) } // 选择模式点击 const handleCardClick = () => { if (selectionMode && onSelect) { onSelect(voice) } } // 性别图标 const genderIcon = voice.gender === 'male' ? 'M' : voice.gender === 'female' ? 'F' : '' return (
{/* 选中标记 */} {isSelected && (
)} {/* 音色图标区域 */}
{/* 性别标签 */} {genderIcon && (
{genderIcon}
)} {/* 试听按钮 */} {voice.customVoiceUrl && ( )}
{/* 信息区域 */}

{voice.name}

{!selectionMode && ( )}
{voice.description && (

{voice.description}

)} {voice.voicePrompt && !voice.description && (

{voice.voicePrompt}

)}
{/* 删除确认 */} {showDeleteConfirm && (
e.stopPropagation()}>

{t('confirmDeleteVoice')}

)}
) } export default VoiceCard