Skip to content

Commit

Permalink
Continue requesting the preview until its ready to render
Browse files Browse the repository at this point in the history
  • Loading branch information
jhnstn committed Apr 12, 2023
1 parent 30cf32e commit af17d54
Showing 1 changed file with 63 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
* WordPress dependencies
*/
import { SandBox } from '@wordpress/components';
import { useState, useEffect } from '@wordpress/element';
import { store as coreStore } from '@wordpress/core-data';
import { useDispatch } from '@wordpress/data';
import { useState, useEffect, useRef, useCallback } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
/**
* External dependencies
Expand All @@ -17,6 +19,11 @@ import { usePreview } from '../../../../hooks/use-preview';
import addTokenIntoIframeSource from '../../../../utils/add-token-iframe-source';
import style from './style.scss';

const VIDEO_PREVIEW_ATTEMPTS_LIMIT = 10;

// The preview is ready when it has a height property
const isPreviewReady = preview => !! preview?.height;

/**
* VideoPlayer react component
*
Expand All @@ -39,7 +46,10 @@ export default function Player( { isSelected, attributes } ) {
seekbarPlayedColor,
} = attributes;

const [ isPlayerLoaded, setIsPlayerLoaded ] = useState( false );
const [ token, setToken ] = useState();
const [ previewCheckAttempts, setPreviewCheckAttempts ] = useState( 0 );
const previewCheckInterval = useRef();

// Fetch token for a VideoPress GUID
useEffect( () => {
Expand All @@ -63,19 +73,64 @@ export default function Player( { isSelected, attributes } ) {
poster,
} );

const { preview } = usePreview( videoPressUrl );
const html = addTokenIntoIframeSource( preview?.html, token );
// Helper to invalidate the preview cache.
const invalidateResolution = useDispatch( coreStore ).invalidateResolution;
const invalidatePreview = useCallback( () => {
invalidateResolution( 'getEmbedPreview', [ videoPressUrl ] );
}, [ videoPressUrl, invalidateResolution ] );

const renderEmbed = () => {
if ( ! html ) {
return <SandBox html={ html } />;
const { preview = {}, isRequestingEmbedPreview } = usePreview( videoPressUrl );
const html = addTokenIntoIframeSource( preview.html, token );

const cancelPreviewCheckInterval = useCallback( () => {
clearInterval( previewCheckInterval.current );
}, [ previewCheckInterval ] );

// Fetch the preview until it's ready
useEffect( () => {
// Wait for the client player to load
if ( ! isPlayerLoaded ) {
return;
}
previewCheckInterval.current = setInterval( () => {
// if the preview is ready or we reached the max attempts, clear the interval
if ( isPreviewReady( preview ) || previewCheckAttempts > VIDEO_PREVIEW_ATTEMPTS_LIMIT ) {
return cancelPreviewCheckInterval();
}

// Avoid lapping any prior request
if ( isRequestingEmbedPreview ) {
return;
}

// Invalidate the cache and wait for the next interval since the preview is not ready yet
setPreviewCheckAttempts( previewCheckAttempts + 1 );
invalidatePreview();
}, 1000 );

return cancelPreviewCheckInterval;
}, [ preview, isPlayerLoaded ] );

const onSandboxMessage = useCallback( message => {
if ( message.event === 'videopress_loading_state' && message.state === 'loaded' ) {
setIsPlayerLoaded( true );
}
}, [] );

return <Text style={ { height: 250 } }>{ __( 'Loading…', 'jetpack-videopress-pkg' ) }</Text>;
const loadingStyle = {};
if ( ! isPreviewReady( preview ) ) {
loadingStyle.height = 250;
}

const renderEmbed = () => {
if ( html ) {
return <SandBox html={ html } onWindowEvents={ { message: onSandboxMessage } } />;
}
return <Text>{ __( 'Loading…', 'jetpack-videopress-pkg' ) }</Text>;
};

return (
<View style={ style[ 'videopress-player' ] }>
<View style={ [ style[ 'videopress-player' ], loadingStyle ] }>
{ ! isSelected && <View style={ style[ 'videopress-player__overlay' ] } /> }
{ renderEmbed() }
</View>
Expand Down

0 comments on commit af17d54

Please sign in to comment.