blob: 3f0c6e2236444ed5a63276bad76fa7dd1d14c9f9 [file] [log] [blame]
import React, { useState } from 'react'
import VideoPreview from './VideoPreview'
import { Play } from 'lucide-react'
// 判断文件是否为视频
const isVideoFile = (url) => {
if (!url) return false
const videoExtensions = ['.mp4', '.webm', '.ogg', '.avi', '.mov', '.wmv', '.flv', '.mkv']
const lowerUrl = url.toLowerCase()
return videoExtensions.some(ext => lowerUrl.includes(ext)) || lowerUrl.includes('video')
}
// 媒体预览组件(支持图片和视频)
const MediaPreview = ({
url,
alt = '',
className = '',
style = {},
onClick = null,
showPlayIcon = true,
maxWidth = 220,
maxHeight = 220
}) => {
const [showVideoPreview, setShowVideoPreview] = useState(false)
const handleMediaClick = () => {
if (isVideoFile(url)) {
setShowVideoPreview(true)
} else if (onClick) {
onClick(url)
}
}
const defaultStyle = {
maxWidth,
maxHeight,
borderRadius: 8,
objectFit: 'cover',
cursor: 'pointer',
...style
}
if (isVideoFile(url)) {
return (
<>
<div style={{ position: 'relative', ...defaultStyle }} onClick={handleMediaClick}>
<video
src={url}
style={defaultStyle}
preload="metadata"
muted
/>
{showPlayIcon && (
<div style={{
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
background: 'rgba(0,0,0,0.6)',
borderRadius: '50%',
padding: 12,
color: 'white'
}}>
<Play size={24} fill="white" />
</div>
)}
</div>
{/* 视频预览弹窗 */}
{showVideoPreview && (
<div
style={{
position: 'fixed',
zIndex: 9999,
top: 0,
left: 0,
right: 0,
bottom: 0,
background: 'rgba(0,0,0,0.8)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
padding: 20
}}
onClick={() => setShowVideoPreview(false)}
>
<div
style={{
maxWidth: '90vw',
maxHeight: '90vh',
width: 'auto',
height: 'auto'
}}
onClick={(e) => e.stopPropagation()}
>
<VideoPreview
src={url}
onClose={() => setShowVideoPreview(false)}
style={{ borderRadius: 12, overflow: 'hidden' }}
/>
</div>
</div>
)}
</>
)
}
return (
<img
src={url}
alt={alt}
className={className}
style={defaultStyle}
onClick={handleMediaClick}
/>
)
}
export default MediaPreview