forked from cookpete/react-player
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPreview.tsx
More file actions
124 lines (108 loc) · 2.87 KB
/
Copy pathPreview.tsx
File metadata and controls
124 lines (108 loc) · 2.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import React, { useState, useEffect } from 'react';
import type { PreviewProps } from './types';
const ICON_SIZE = '64px';
const cache: Record<string, string> = {};
const Preview = ({
src,
light,
oEmbedUrl,
onClickPreview,
playIcon,
previewTabIndex,
previewAriaLabel,
}: PreviewProps) => {
const [image, setImage] = useState<string | null>(null);
useEffect(() => {
if (!src || !light || !oEmbedUrl) return;
fetchImage({ src, light, oEmbedUrl });
}, [src, light, oEmbedUrl]);
const fetchImage = async ({
src,
light,
oEmbedUrl,
}: {
src: string;
light: boolean | string | React.ReactElement;
oEmbedUrl: string;
}) => {
if (React.isValidElement(light)) {
return;
}
if (typeof light === 'string') {
setImage(light);
return;
}
if (cache[src]) {
setImage(cache[src]);
return;
}
setImage(null);
const response = await fetch(oEmbedUrl.replace('{url}', src));
const data = await response.json();
if (data.thumbnail_url) {
const fetchedImage = data.thumbnail_url
.replace('height=100', 'height=480')
.replace('-d_295x166', '-d_640');
setImage(fetchedImage);
cache[src] = fetchedImage;
}
};
const handleKeyPress = (e: React.KeyboardEvent<HTMLDivElement>) => {
if (e.key === 'Enter' || e.key === ' ') {
onClickPreview?.(e);
}
};
const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
onClickPreview?.(e);
};
const isElement = React.isValidElement(light);
const flexCenter = {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
};
const styles = {
preview: {
width: '100%',
height: '100%',
backgroundImage: image && !isElement ? `url(${image})` : undefined,
backgroundSize: 'cover',
backgroundPosition: 'center',
cursor: 'pointer',
...flexCenter,
},
shadow: {
background: 'radial-gradient(rgb(0, 0, 0, 0.3), rgba(0, 0, 0, 0) 60%)',
borderRadius: ICON_SIZE,
width: ICON_SIZE,
height: ICON_SIZE,
position: isElement ? 'absolute' as const : undefined,
...flexCenter,
},
playIcon: {
borderStyle: 'solid',
borderWidth: '16px 0 16px 26px',
borderColor: 'transparent transparent transparent white',
marginLeft: '7px',
},
};
const defaultPlayIcon = (
<div style={styles.shadow} className="react-player__shadow">
<div style={styles.playIcon} className="react-player__play-icon" />
</div>
);
return (
<div
style={styles.preview}
className="react-player__preview"
tabIndex={previewTabIndex}
onClick={handleClick}
onKeyDown={handleKeyPress}
{...(previewAriaLabel ? { 'aria-label': previewAriaLabel } : {})}
>
{isElement ? light : null}
{playIcon || defaultPlayIcon}
</div>
);
};
export default Preview;