| 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 |