/*
Copyright (C) 2025 QuantumNous
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
For commercial licensing, please contact support@quantumnous.com
*/
import React, { useState, useRef, useEffect } from 'react';
import { Modal, Typography, Tag, Button } from '@douyinfe/semi-ui';
import { IconExternalOpen, IconCopy } from '@douyinfe/semi-icons';
import { useTranslation } from 'react-i18next';
const { Text, Title } = Typography;
const formatDuration = (seconds) => {
if (!seconds || seconds <= 0) return '--:--';
const m = Math.floor(seconds / 60);
const s = Math.floor(seconds % 60);
return `${m}:${s.toString().padStart(2, '0')}`;
};
const AudioClipCard = ({ clip }) => {
const { t } = useTranslation();
const [hasError, setHasError] = useState(false);
const audioRef = useRef(null);
useEffect(() => {
setHasError(false);
}, [clip.audio_url]);
const title = clip.title || t('未命名');
const tags = clip.tags || clip.metadata?.tags || '';
const duration = clip.duration || clip.metadata?.duration;
const imageUrl = clip.image_url || clip.image_large_url;
const audioUrl = clip.audio_url;
return (