1
- import React , { useState , useEffect } from 'react' ;
1
+ import React , { useState , useEffect , useMemo , useCallback } from 'react' ;
2
2
3
3
import styles from './styles.module.css' ;
4
+ import { qs } from './utils' ;
4
5
5
- const qs = ( params : Record < string , string > ) => {
6
- return Object . keys ( params )
7
- . map ( key => ` ${ encodeURIComponent ( key ) } = ${ encodeURIComponent ( params [ key ] ) } ` )
8
- . join ( '&' ) ;
6
+ enum thumbnailResolution {
7
+ HIGH = 'maxresdefault' ,
8
+ MEDIUM = 'sddefault' ,
9
+ LOW = 'hqdefault'
9
10
}
10
11
11
12
// https://stackoverflow.com/questions/2068344/how-do-i-get-a-youtube-video-thumbnail-from-the-youtube-api
12
- type ResolutionType = 'maxresdefault' | 'sddefault' | 'hqdefault' ;
13
+ type ResolutionType = thumbnailResolution . HIGH | thumbnailResolution . MEDIUM | thumbnailResolution . LOW ;
13
14
14
15
interface ILiteYouTubeEmbedProps {
15
16
id : string ;
@@ -33,11 +34,11 @@ const LiteYoutubeEmbed = ({
33
34
noCookie = true ,
34
35
mute = true ,
35
36
isMobile = false ,
36
- mobileResolution = 'hqdefault' ,
37
- desktopResolution = 'maxresdefault' ,
37
+ mobileResolution = thumbnailResolution . LOW ,
38
+ desktopResolution = thumbnailResolution . HIGH ,
38
39
} : ILiteYouTubeEmbedProps ) : React . ReactElement => {
39
40
const muteParam = mute || defaultPlay ? '1' : '0' ; // Default play must be mute
40
- const queryString = qs ( { autoplay : '1' , mute : muteParam , ...params } ) ;
41
+ const queryString = useMemo ( ( ) => qs ( { autoplay : '1' , mute : muteParam , ...params } ) , [ ] ) ;
41
42
const defaultPosterUrl = isMobile ? `https://i.ytimg.com/vi/${ id } /${ mobileResolution } .jpg` : `https://i.ytimg.com/vi/${ id } /${ desktopResolution } .jpg` ;
42
43
const ytUrl = noCookie ? 'https://www.youtube-nocookie.com' : 'https://www.youtube.com' ;
43
44
const iframeSrc = isPlaylist ? `${ ytUrl } /embed/videoseries?list=${ id } ` : `${ ytUrl } /embed/${ id } ?${ queryString } ` ; // * Lo, the youtube placeholder image! (aka the thumbnail, poster image, etc)
@@ -46,19 +47,20 @@ const LiteYoutubeEmbed = ({
46
47
const [ iframeLoaded , setIframeLoaded ] = useState ( defaultPlay ) ;
47
48
const [ posterUrl , setPosterUrl ] = useState ( defaultPosterUrl ) ;
48
49
49
- const warmConnections = ( ) => {
50
+ const warmConnections = useCallback ( ( ) => {
50
51
if ( isPreconnected ) return ;
51
52
setIsPreconnected ( true ) ;
52
- } ;
53
+ } , [ ] ) ;
53
54
54
- const loadIframeFunc = ( ) => {
55
+ const loadIframeFunc = useCallback ( ( ) => {
55
56
if ( iframeLoaded ) return ;
56
57
setIframeLoaded ( true ) ;
57
- } ;
58
+ } , [ ] ) ;
58
59
59
60
// fallback to hqdefault resolution if maxresdefault is not supported.
60
61
useEffect ( ( ) => {
61
- if ( ( isMobile && mobileResolution === 'hqdefault' ) || ( ! isMobile && desktopResolution === 'hqdefault' ) ) return ;
62
+ if ( ( isMobile && mobileResolution === thumbnailResolution . LOW ) || ( ! isMobile && desktopResolution === thumbnailResolution . LOW ) ) return ;
63
+
62
64
const img = new Image ( ) ;
63
65
img . onload = function ( ) {
64
66
if ( img . width === 120 || img . width === 0 ) setPosterUrl ( `https://i.ytimg.com/vi/${ id } /hqdefault.jpg` ) ;
0 commit comments