import { useState } from 'react'; interface RefItem { type?: string; url?: string; name?: string; label?: string; thumb_url?: string; role?: string; } interface Props { references: RefItem[]; } export function ReferenceList({ references }: Props) { const [lightboxUrl, setLightboxUrl] = useState(null); const [playingMedia, setPlayingMedia] = useState<{ url: string; type: 'video' | 'audio' } | null>(null); if (references.length === 0) return null; const handleDownload = (url: string, label: string) => { const a = document.createElement('a'); a.href = url; a.download = label; a.target = '_blank'; a.rel = 'noopener noreferrer'; a.click(); }; return ( <>
{references.map((ref, i) => { const thumbUrl = ref.thumb_url || ref.url || ''; const fullUrl = ref.url || ''; const isAudio = ref.type === 'audio'; const isVideo = ref.type === 'video'; const label = ref.label || ref.name || ref.type || `素材${i + 1}`; const hasUrl = fullUrl && !fullUrl.startsWith('asset://'); return (
{/* Thumbnail area */}
{isAudio ? (
hasUrl && setPlayingMedia({ url: fullUrl, type: 'audio' })} >♫
) : isVideo ? (
hasUrl && setPlayingMedia({ url: fullUrl, type: 'video' })} >▶
) : thumbUrl && !thumbUrl.startsWith('asset://') ? ( thumbUrl && !thumbUrl.startsWith('asset://') && setLightboxUrl(thumbUrl)} /> ) : (
?
)} {/* Download button */} {hasUrl && ( )}
{label}
); })}
{/* Image lightbox */} {lightboxUrl && (
setLightboxUrl(null)}>
)} {/* Video/Audio player modal */} {playingMedia && (
setPlayingMedia(null)}>
e.stopPropagation()}> {playingMedia.type === 'video' ? (
)} ); } // Styles const overlay: React.CSSProperties = { position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.7)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 10002, }; const refsGrid: React.CSSProperties = { display: 'flex', gap: 8, flexWrap: 'wrap', }; const refItem: React.CSSProperties = { width: 80, textAlign: 'center', }; const thumbWrap: React.CSSProperties = { position: 'relative', width: 80, height: 80, }; const refImgStyle: React.CSSProperties = { width: 80, height: 80, objectFit: 'cover', borderRadius: 6, cursor: 'pointer', border: '1px solid #2a2a38', }; const placeholder: React.CSSProperties = { width: 80, height: 80, borderRadius: 6, background: '#1a1a2e', border: '1px solid #2a2a38', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 24, color: '#888', }; const downloadBtn: React.CSSProperties = { position: 'absolute', bottom: 4, right: 4, width: 22, height: 22, borderRadius: 4, background: 'rgba(0,0,0,0.6)', border: 'none', color: '#fff', fontSize: 12, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', }; const refLabel: React.CSSProperties = { fontSize: 10, color: '#888', marginTop: 4, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', }; const playerWrap: React.CSSProperties = { position: 'relative', background: '#111118', borderRadius: 12, padding: 24, border: '1px solid #2a2a38', }; const playerClose: React.CSSProperties = { position: 'absolute', top: 8, right: 12, background: 'none', border: 'none', color: '#888', fontSize: 16, cursor: 'pointer', }; const audioWrap: React.CSSProperties = { display: 'flex', flexDirection: 'column', alignItems: 'center', padding: '20px 40px', color: '#888', };