2
2
/* eslint-disable jsx-a11y/click-events-have-key-events */
3
3
// TODO fix in https://github.com/gravity-ui/page-constructor/issues/965
4
4
5
- import React , { useCallback , useEffect , useRef , useState } from 'react' ;
5
+ import React , { useCallback , useEffect , useMemo , useRef , useState } from 'react' ;
6
6
7
7
import { PlayFill } from '@gravity-ui/icons' ;
8
8
import { Icon } from '@gravity-ui/uikit' ;
@@ -28,10 +28,13 @@ export const AUTOPLAY_ATTRIBUTES = {
28
28
autoplay : 1 ,
29
29
mute : 1 ,
30
30
} ;
31
+ const NO_AUTOPLAY_ATTRIBUTES = {
32
+ autoplay : 0 ,
33
+ } ;
31
34
32
35
const b = block ( 'VideoBlock' ) ;
33
36
34
- function getVideoSrc ( stream ?: string , record ?: string ) {
37
+ function getYoutubeVideoSrc ( stream ?: string , record ?: string ) {
35
38
if ( ! stream && ! record ) {
36
39
return null ;
37
40
}
@@ -57,6 +60,7 @@ export interface VideoBlockProps extends AnalyticsEventsBase {
57
60
id ?: string ;
58
61
stream ?: string ;
59
62
record ?: string ;
63
+ videoIframe ?: string ;
60
64
attributes ?: Record < string , string > ;
61
65
className ?: string ;
62
66
previewImg ?: string ;
@@ -71,6 +75,7 @@ const VideoBlock = (props: VideoBlockProps) => {
71
75
const {
72
76
stream,
73
77
record,
78
+ videoIframe,
74
79
attributes,
75
80
className,
76
81
id,
@@ -84,25 +89,29 @@ const VideoBlock = (props: VideoBlockProps) => {
84
89
} = props ;
85
90
const handleAnalytics = useAnalytics ( DefaultEventNames . VideoPreview ) ;
86
91
87
- const src = getVideoSrc ( stream , record ) ;
92
+ const src = videoIframe ? videoIframe : getYoutubeVideoSrc ( stream , record ) ;
88
93
const ref = useRef < HTMLDivElement > ( null ) ;
89
- const iframeRef = useRef < HTMLIFrameElement > ( ) ;
90
94
const [ hidePreview , setHidePreview ] = useState ( false ) ;
91
- const norender = ( ! stream && ! record ) || ! src ;
92
95
const [ currentHeight , setCurrentHeight ] = useState ( height || undefined ) ;
93
- const fullId = id || uuidv4 ( ) ;
96
+ const fullId = useMemo ( ( ) => id || uuidv4 ( ) , [ id ] ) ;
97
+
98
+ const [ isPlaying , setIsPlaying ] = useState ( ! previewImg ) ;
99
+
100
+ const iframeSrc =
101
+ src && isPlaying
102
+ ? `${ src } ?${ getPageSearchParams ( {
103
+ ...( attributes || { } ) ,
104
+ ...( autoplay ? AUTOPLAY_ATTRIBUTES : NO_AUTOPLAY_ATTRIBUTES ) ,
105
+ } ) } `
106
+ : undefined ;
107
+
94
108
const onPreviewClick = useCallback ( ( ) => {
95
109
handleAnalytics ( analyticsEvents ) ;
96
110
97
- if ( iframeRef . current ) {
98
- iframeRef . current . src = `${ src } ?${ getPageSearchParams ( {
99
- ...AUTOPLAY_ATTRIBUTES ,
100
- ...( attributes || { } ) ,
101
- } ) } `;
102
- }
111
+ setIsPlaying ( true ) ;
103
112
104
113
setTimeout ( ( ) => setHidePreview ( true ) , AUTOPLAY_DELAY ) ;
105
- } , [ handleAnalytics , analyticsEvents , src , attributes ] ) ;
114
+ } , [ handleAnalytics , analyticsEvents ] ) ;
106
115
107
116
useEffect ( ( ) => {
108
117
const updateSize = debounce ( ( ) => {
@@ -118,44 +127,33 @@ const VideoBlock = (props: VideoBlockProps) => {
118
127
} ;
119
128
} , [ height ] ) ;
120
129
121
- useEffect ( ( ) => {
122
- if ( norender ) {
123
- return ;
124
- }
125
-
126
- if ( ref . current && ! iframeRef . current ) {
127
- const iframe = document . createElement ( 'iframe' ) ;
128
- iframe . id = fullId ;
129
-
130
- if ( ! previewImg ) {
131
- iframe . src = `${ src } ?${ getPageSearchParams ( {
132
- ...( attributes || { } ) ,
133
- ...( autoplay ? AUTOPLAY_ATTRIBUTES : { } ) ,
134
- } ) } `;
135
- }
136
-
137
- iframe . width = '100%' ;
138
- iframe . height = '100%' ;
139
- iframe . title = i18n ( 'iframe-title' ) ;
140
- iframe . frameBorder = '0' ;
141
- iframe . setAttribute ( 'allowfullscreen' , 'true' ) ;
142
- iframe . setAttribute ( 'allow' , 'autoplay' ) ;
143
- iframe . setAttribute ( 'loading' , 'lazy' ) ;
144
- ref . current . appendChild ( iframe ) ;
145
- iframeRef . current = iframe ;
146
- }
147
- } , [ stream , record , norender , src , fullId , attributes , iframeRef , previewImg , autoplay ] ) ;
130
+ const iframeContent = useMemo ( ( ) => {
131
+ return (
132
+ < iframe
133
+ id = { fullId }
134
+ src = { iframeSrc }
135
+ width = "100%"
136
+ height = "100%"
137
+ title = { i18n ( 'iframe-title' ) }
138
+ frameBorder = "0"
139
+ allowFullScreen = { true }
140
+ allow = "autoplay; fullscreen; encrypted-media; accelerometer; gyroscope; picture-in-picture; clipboard-write; web-share; screen-wake-lock"
141
+ loading = "lazy"
142
+ />
143
+ ) ;
144
+ } , [ fullId , iframeSrc ] ) ;
148
145
149
146
useEffect ( ( ) => {
150
147
setHidePreview ( false ) ;
151
- } , [ src , setHidePreview ] ) ;
148
+ } , [ src ] ) ;
152
149
153
- if ( norender ) {
150
+ if ( ! src ) {
154
151
return null ;
155
152
}
156
153
157
154
return (
158
- < div className = { b ( null , className ) } ref = { ref } style = { { height : currentHeight } } >
155
+ < div className = { b ( null , className ) } style = { { height : currentHeight } } ref = { ref } >
156
+ { iframeContent }
159
157
{ previewImg && ! hidePreview && ! fullscreen && (
160
158
< div className = { b ( 'preview' ) } onClick = { onPreviewClick } >
161
159
< Image
0 commit comments