@@ -110,10 +110,10 @@ export const LoopVideo = ({
110110 const [ currentTime , setCurrentTime ] = useState ( 0 ) ;
111111 const [ playerState , setPlayerState ] =
112112 useState < ( typeof PLAYER_STATES ) [ number ] > ( 'NOT_STARTED' ) ;
113-
114113 const [ isAutoplayAllowed , setIsAutoplayAllowed ] = useState < boolean | null > (
115114 null ,
116115 ) ;
116+ const [ isRestoredFromBFCache , setIsRestoredFromBFCache ] = useState ( false ) ;
117117
118118 /**
119119 * Keep a track of whether the video has been in view. We only
@@ -139,11 +139,15 @@ export const LoopVideo = ({
139139 await startPlayPromise
140140 . then ( ( ) => {
141141 // Autoplay succeeded
142+ console . log (
143+ 'playVideo function - Autoplay succeeded. Video playing. Setting player state to PLAYING' ,
144+ ) ;
142145 dispatchOphanAttentionEvent ( 'videoPlaying' ) ;
143146 setPlayerState ( 'PLAYING' ) ;
144147 } )
145148 . catch ( ( error : Error ) => {
146149 // Autoplay failed
150+ console . log ( 'playVideo function - Autoplay Failed' ) ;
147151 logAndReportError ( src , error ) ;
148152 setShowPosterImage ( true ) ;
149153 setPlayerState ( 'PAUSED_BY_BROWSER' ) ;
@@ -197,6 +201,10 @@ export const LoopVideo = ({
197201 * 2. Creates event listeners to control playback when there are multiple videos.
198202 */
199203 useEffect ( ( ) => {
204+ console . log (
205+ 'Setup useeffect - isRestoredFromBFCache:' ,
206+ isRestoredFromBFCache ,
207+ ) ;
200208 /**
201209 * The user indicates a preference for reduced motion: https://web.dev/articles/prefers-reduced-motion
202210 */
@@ -211,9 +219,13 @@ export const LoopVideo = ({
211219 * `autoplayPreference` is explicitly `false`
212220 * when the user has said they don't want autoplay video.
213221 */
222+ console . log ( 'Setup useeffect - isAutoplayAllowed' , isAutoplayAllowed ) ;
214223 setIsAutoplayAllowed (
215224 ! userPrefersReducedMotion && autoplayPreference !== false ,
216225 ) ;
226+ if ( ! userPrefersReducedMotion && autoplayPreference !== false ) {
227+ console . log ( 'Setup useeffect 2 - isAutoplayAllowed set to true' ) ;
228+ }
217229
218230 /**
219231 * Mutes the current video when another video is unmuted
@@ -259,6 +271,7 @@ export const LoopVideo = ({
259271 handleCustomPlayYoutubeEvent ,
260272 ) ;
261273 } ;
274+ // eslint-disable-next-line react-hooks/exhaustive-deps -- logs
262275 } , [ uniqueId ] ) ;
263276
264277 /**
@@ -308,18 +321,37 @@ export const LoopVideo = ({
308321 } , [ isInView , hasBeenInView , atomId ] ) ;
309322
310323 /**
311- * Autoplay the video when it comes into view .
324+ * Play/pause, including autoplay .
312325 */
313326 useEffect ( ( ) => {
314- if ( ! vidRef . current || isAutoplayAllowed === false ) {
327+ console . log (
328+ `autoplay useeffect - isRestoredFromBFCache: ${ isRestoredFromBFCache } . isAutoplayAllowed: ${ isAutoplayAllowed } . playerState: ${ playerState } . isInView: ${ isInView } ` ,
329+ ) ;
330+
331+ if ( ! vidRef . current || ! isPlayable ) {
315332 return ;
316333 }
317334
335+ /**
336+ * Stops playback when the video is scrolled out of view.
337+ */
338+ const isNoLongerInView =
339+ playerState === 'PLAYING' && hasBeenInView && isInView === false ;
340+ if ( isNoLongerInView ) {
341+ pauseVideo ( 'PAUSED_BY_INTERSECTION_OBSERVER' ) ;
342+ return ;
343+ }
344+
345+ /**
346+ * Autoplay/resume playback when the player comes into view or when
347+ * the page has been restored from the BFCache.
348+ */
318349 if (
350+ isAutoplayAllowed &&
319351 isInView &&
320- isPlayable &&
321352 ( playerState === 'NOT_STARTED' ||
322- playerState === 'PAUSED_BY_INTERSECTION_OBSERVER' )
353+ playerState === 'PAUSED_BY_INTERSECTION_OBSERVER' ||
354+ ( isRestoredFromBFCache && playerState === 'PAUSED_BY_BROWSER' ) )
323355 ) {
324356 /**
325357 * Check if the video has not been in view before tracking the play.
@@ -329,8 +361,14 @@ export const LoopVideo = ({
329361 ophanTrackerWeb ( atomId , 'loop' ) ( 'play' ) ;
330362 }
331363
364+ console . log (
365+ 'autoplay useeffect - Playing video!' ,
366+ isAutoplayAllowed ,
367+ ) ;
368+ setIsRestoredFromBFCache ( false ) ;
332369 void playVideo ( ) ;
333370 }
371+ // eslint-disable-next-line react-hooks/exhaustive-deps -- Logs
334372 } , [
335373 isAutoplayAllowed ,
336374 isInView ,
@@ -341,31 +379,6 @@ export const LoopVideo = ({
341379 atomId ,
342380 ] ) ;
343381
344- /**
345- * Stops playback when the video is scrolled out of view.
346- * Resumes playback when the video is back in the viewport.
347- */
348- useEffect ( ( ) => {
349- if ( ! vidRef . current || ! hasBeenInView ) return ;
350-
351- const isNoLongerInView =
352- playerState === 'PLAYING' && isInView === false ;
353- if ( isNoLongerInView ) {
354- pauseVideo ( 'PAUSED_BY_INTERSECTION_OBSERVER' ) ;
355- }
356-
357- /**
358- * If a user action paused the video, they have indicated
359- * that they don't want to watch the video. Therefore, don't
360- * resume the video when it comes back in view.
361- */
362- const isBackInView =
363- playerState === 'PAUSED_BY_INTERSECTION_OBSERVER' && isInView ;
364- if ( isBackInView ) {
365- void playVideo ( ) ;
366- }
367- } , [ isInView , hasBeenInView , playerState , playVideo ] ) ;
368-
369382 /**
370383 * Show the play icon when the video is not playing, except for when it is scrolled
371384 * out of view. In this case, the intersection observer will resume playback and
@@ -404,6 +417,32 @@ export const LoopVideo = ({
404417 setPreloadPartialData ( isAutoplayAllowed === false || ! ! isInView ) ;
405418 } , [ isAutoplayAllowed , isInView ] ) ;
406419
420+ useEffect ( ( ) => {
421+ window . addEventListener ( 'pageshow' , function ( event ) {
422+ if ( event . persisted ) {
423+ // The page was restored from the bfcache. Rerender the component to ensure video can autoplay.
424+ console . log (
425+ 'BFCache useEffect - playerState' ,
426+ 'playerState' ,
427+ playerState ,
428+ 'isAutoplayAllowed' ,
429+ isAutoplayAllowed ,
430+ ) ;
431+
432+ // Reset the state to allow the video to autoplay again.
433+ setIsAutoplayAllowed ( null ) ;
434+ setPlayerState ( 'NOT_STARTED' ) ;
435+ setIsRestoredFromBFCache ( true ) ;
436+ } else {
437+ console . log (
438+ 'BFCache useEffect - setting isRestoredFromBFCache to false' ,
439+ ) ;
440+ setIsRestoredFromBFCache ( false ) ;
441+ }
442+ } ) ;
443+ // eslint-disable-next-line react-hooks/exhaustive-deps -- logs
444+ } , [ ] ) ;
445+
407446 if ( renderingTarget !== 'Web' ) return null ;
408447
409448 if ( adapted ) {
@@ -412,7 +451,10 @@ export const LoopVideo = ({
412451
413452 const handleCanPlay = ( ) => {
414453 if ( ! isPlayable ) {
454+ console . log ( 'canPlay event fired - Setting video as playable' ) ;
415455 setIsPlayable ( true ) ;
456+ } else {
457+ console . log ( 'canPlay event fired - Video is already playable' ) ;
416458 }
417459 } ;
418460
@@ -448,6 +490,8 @@ export const LoopVideo = ({
448490 return ;
449491 }
450492
493+ console . log ( 'handlePause - Pausing video due to browser conditions' ) ;
494+
451495 pauseVideo ( 'PAUSED_BY_BROWSER' ) ;
452496 } ;
453497
0 commit comments