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