-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
Copy pathPreview.js
112 lines (103 loc) · 2.82 KB
/
Preview.js
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
import React, { Component } from 'react'
const ICON_SIZE = '64px'
const cache = {}
export default class Preview extends Component {
mounted = false
state = {
image: null
}
componentDidMount () {
this.mounted = true
this.fetchImage(this.props)
}
componentDidUpdate (prevProps) {
const { url, light } = this.props
if (prevProps.url !== url || prevProps.light !== light) {
this.fetchImage(this.props)
}
}
componentWillUnmount () {
this.mounted = false
}
fetchImage ({ url, light, oEmbedUrl }) {
if (React.isValidElement(light)) {
return
}
if (typeof light === 'string') {
this.setState({ image: light })
return
}
if (cache[url]) {
this.setState({ image: cache[url] })
return
}
this.setState({ image: null })
return window.fetch(oEmbedUrl.replace('{url}', url))
.then(response => response.json())
.then(data => {
if (data.thumbnail_url && this.mounted) {
const image = data.thumbnail_url.replace('height=100', 'height=480').replace('-d_295x166', '-d_640')
this.setState({ image })
cache[url] = image
}
})
}
handleKeyPress = e => {
if (e.key === 'Enter' || e.key === ' ') {
this.props.onClick()
}
}
render () {
const { light, onClick, playIcon, previewTabIndex, previewAriaLabel } = this.props
const { image } = this.state
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' : 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'
onClick={onClick}
tabIndex={previewTabIndex}
onKeyPress={this.handleKeyPress}
aria-label={previewAriaLabel}
>
{isElement ? light : null}
{playIcon || defaultPlayIcon}
</div>
)
}
}