|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import React, { useState, useEffect } from 'react'; |
|
|
import { Modal, Button, Typography, Spin } from '@douyinfe/semi-ui'; |
|
|
import { IconExternalOpen, IconCopy } from '@douyinfe/semi-icons'; |
|
|
|
|
|
const { Text } = Typography; |
|
|
|
|
|
const ContentModal = ({ |
|
|
isModalOpen, |
|
|
setIsModalOpen, |
|
|
modalContent, |
|
|
isVideo, |
|
|
}) => { |
|
|
const [videoError, setVideoError] = useState(false); |
|
|
const [isLoading, setIsLoading] = useState(false); |
|
|
|
|
|
useEffect(() => { |
|
|
if (isModalOpen && isVideo) { |
|
|
setVideoError(false); |
|
|
setIsLoading(true); |
|
|
} |
|
|
}, [isModalOpen, isVideo]); |
|
|
|
|
|
const handleVideoError = () => { |
|
|
setVideoError(true); |
|
|
setIsLoading(false); |
|
|
}; |
|
|
|
|
|
const handleVideoLoaded = () => { |
|
|
setIsLoading(false); |
|
|
}; |
|
|
|
|
|
const handleCopyUrl = () => { |
|
|
navigator.clipboard.writeText(modalContent); |
|
|
}; |
|
|
|
|
|
const handleOpenInNewTab = () => { |
|
|
window.open(modalContent, '_blank'); |
|
|
}; |
|
|
|
|
|
const renderVideoContent = () => { |
|
|
if (videoError) { |
|
|
return ( |
|
|
<div style={{ textAlign: 'center', padding: '40px' }}> |
|
|
<Text |
|
|
type='tertiary' |
|
|
style={{ display: 'block', marginBottom: '16px' }} |
|
|
> |
|
|
视频无法在当前浏览器中播放,这可能是由于: |
|
|
</Text> |
|
|
<Text |
|
|
type='tertiary' |
|
|
style={{ display: 'block', marginBottom: '8px', fontSize: '12px' }} |
|
|
> |
|
|
• 视频服务商的跨域限制 |
|
|
</Text> |
|
|
<Text |
|
|
type='tertiary' |
|
|
style={{ display: 'block', marginBottom: '8px', fontSize: '12px' }} |
|
|
> |
|
|
• 需要特定的请求头或认证 |
|
|
</Text> |
|
|
<Text |
|
|
type='tertiary' |
|
|
style={{ display: 'block', marginBottom: '16px', fontSize: '12px' }} |
|
|
> |
|
|
• 防盗链保护机制 |
|
|
</Text> |
|
|
|
|
|
<div style={{ marginTop: '20px' }}> |
|
|
<Button |
|
|
icon={<IconExternalOpen />} |
|
|
onClick={handleOpenInNewTab} |
|
|
style={{ marginRight: '8px' }} |
|
|
> |
|
|
在新标签页中打开 |
|
|
</Button> |
|
|
<Button icon={<IconCopy />} onClick={handleCopyUrl}> |
|
|
复制链接 |
|
|
</Button> |
|
|
</div> |
|
|
|
|
|
<div |
|
|
style={{ |
|
|
marginTop: '16px', |
|
|
padding: '8px', |
|
|
backgroundColor: '#f8f9fa', |
|
|
borderRadius: '4px', |
|
|
}} |
|
|
> |
|
|
<Text |
|
|
type='tertiary' |
|
|
style={{ fontSize: '10px', wordBreak: 'break-all' }} |
|
|
> |
|
|
{modalContent} |
|
|
</Text> |
|
|
</div> |
|
|
</div> |
|
|
); |
|
|
} |
|
|
|
|
|
return ( |
|
|
<div style={{ position: 'relative' }}> |
|
|
{isLoading && ( |
|
|
<div |
|
|
style={{ |
|
|
position: 'absolute', |
|
|
top: '50%', |
|
|
left: '50%', |
|
|
transform: 'translate(-50%, -50%)', |
|
|
zIndex: 10, |
|
|
}} |
|
|
> |
|
|
<Spin size='large' /> |
|
|
</div> |
|
|
)} |
|
|
<video |
|
|
src={modalContent} |
|
|
controls |
|
|
style={{ width: '100%' }} |
|
|
autoPlay |
|
|
crossOrigin='anonymous' |
|
|
onError={handleVideoError} |
|
|
onLoadedData={handleVideoLoaded} |
|
|
onLoadStart={() => setIsLoading(true)} |
|
|
/> |
|
|
</div> |
|
|
); |
|
|
}; |
|
|
|
|
|
return ( |
|
|
<Modal |
|
|
visible={isModalOpen} |
|
|
onOk={() => setIsModalOpen(false)} |
|
|
onCancel={() => setIsModalOpen(false)} |
|
|
closable={null} |
|
|
bodyStyle={{ |
|
|
height: isVideo ? '450px' : '400px', |
|
|
overflow: 'auto', |
|
|
padding: isVideo && videoError ? '0' : '24px', |
|
|
}} |
|
|
width={800} |
|
|
> |
|
|
{isVideo ? ( |
|
|
renderVideoContent() |
|
|
) : ( |
|
|
<p style={{ whiteSpace: 'pre-line' }}>{modalContent}</p> |
|
|
)} |
|
|
</Modal> |
|
|
); |
|
|
}; |
|
|
|
|
|
export default ContentModal; |
|
|
|