Skip to content

Commit b294ff5

Browse files
authored
Merge pull request #1554 from feitianbubu/pr/fix-video-preview
feat: if video cannot play open in a new tab
2 parents 096141b + ef0780c commit b294ff5

File tree

1 file changed

+110
-4
lines changed

1 file changed

+110
-4
lines changed

web/src/components/table/task-logs/modals/ContentModal.jsx

Lines changed: 110 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,132 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
1717
For commercial licensing, please contact support@quantumnous.com
1818
*/
1919

20-
import React from 'react';
21-
import { Modal } from '@douyinfe/semi-ui';
20+
import React, { useState, useEffect } from 'react';
21+
import { Modal, Button, Typography, Spin } from '@douyinfe/semi-ui';
22+
import { IconExternalOpen, IconCopy } from '@douyinfe/semi-icons';
23+
24+
const { Text } = Typography;
2225

2326
const ContentModal = ({
2427
isModalOpen,
2528
setIsModalOpen,
2629
modalContent,
2730
isVideo,
2831
}) => {
32+
const [videoError, setVideoError] = useState(false);
33+
const [isLoading, setIsLoading] = useState(false);
34+
35+
useEffect(() => {
36+
if (isModalOpen && isVideo) {
37+
setVideoError(false);
38+
setIsLoading(true);
39+
}
40+
}, [isModalOpen, isVideo]);
41+
42+
const handleVideoError = () => {
43+
setVideoError(true);
44+
setIsLoading(false);
45+
};
46+
47+
const handleVideoLoaded = () => {
48+
setIsLoading(false);
49+
};
50+
51+
const handleCopyUrl = () => {
52+
navigator.clipboard.writeText(modalContent);
53+
};
54+
55+
const handleOpenInNewTab = () => {
56+
window.open(modalContent, '_blank');
57+
};
58+
59+
const renderVideoContent = () => {
60+
if (videoError) {
61+
return (
62+
<div style={{ textAlign: 'center', padding: '40px' }}>
63+
<Text type="tertiary" style={{ display: 'block', marginBottom: '16px' }}>
64+
视频无法在当前浏览器中播放,这可能是由于:
65+
</Text>
66+
<Text type="tertiary" style={{ display: 'block', marginBottom: '8px', fontSize: '12px' }}>
67+
• 视频服务商的跨域限制
68+
</Text>
69+
<Text type="tertiary" style={{ display: 'block', marginBottom: '8px', fontSize: '12px' }}>
70+
• 需要特定的请求头或认证
71+
</Text>
72+
<Text type="tertiary" style={{ display: 'block', marginBottom: '16px', fontSize: '12px' }}>
73+
• 防盗链保护机制
74+
</Text>
75+
76+
<div style={{ marginTop: '20px' }}>
77+
<Button
78+
icon={<IconExternalOpen />}
79+
onClick={handleOpenInNewTab}
80+
style={{ marginRight: '8px' }}
81+
>
82+
在新标签页中打开
83+
</Button>
84+
<Button
85+
icon={<IconCopy />}
86+
onClick={handleCopyUrl}
87+
>
88+
复制链接
89+
</Button>
90+
</div>
91+
92+
<div style={{ marginTop: '16px', padding: '8px', backgroundColor: '#f8f9fa', borderRadius: '4px' }}>
93+
<Text
94+
type="tertiary"
95+
style={{ fontSize: '10px', wordBreak: 'break-all' }}
96+
>
97+
{modalContent}
98+
</Text>
99+
</div>
100+
</div>
101+
);
102+
}
103+
104+
return (
105+
<div style={{ position: 'relative' }}>
106+
{isLoading && (
107+
<div style={{
108+
position: 'absolute',
109+
top: '50%',
110+
left: '50%',
111+
transform: 'translate(-50%, -50%)',
112+
zIndex: 10
113+
}}>
114+
<Spin size="large" />
115+
</div>
116+
)}
117+
<video
118+
src={modalContent}
119+
controls
120+
style={{ width: '100%' }}
121+
autoPlay
122+
crossOrigin="anonymous"
123+
onError={handleVideoError}
124+
onLoadedData={handleVideoLoaded}
125+
onLoadStart={() => setIsLoading(true)}
126+
/>
127+
</div>
128+
);
129+
};
130+
29131
return (
30132
<Modal
31133
visible={isModalOpen}
32134
onOk={() => setIsModalOpen(false)}
33135
onCancel={() => setIsModalOpen(false)}
34136
closable={null}
35-
bodyStyle={{ height: '400px', overflow: 'auto' }}
137+
bodyStyle={{
138+
height: isVideo ? '450px' : '400px',
139+
overflow: 'auto',
140+
padding: isVideo && videoError ? '0' : '24px'
141+
}}
36142
width={800}
37143
>
38144
{isVideo ? (
39-
<video src={modalContent} controls style={{ width: '100%' }} autoPlay />
145+
renderVideoContent()
40146
) : (
41147
<p style={{ whiteSpace: 'pre-line' }}>{modalContent}</p>
42148
)}

0 commit comments

Comments
 (0)