modules_Videos_VidyardVideo_index.js
import { classnames, PropTypes, React } from '@gravityforms/libraries';
import { useScript } from '@gravityforms/react-utils';
import { trigger } from '@gravityforms/utils';
import Video from '../Video';
const { forwardRef, useRef, useEffect, useState } = React;
const VIDYARD_LIBRARY_SRC = 'https://play.vidyard.com/embed/v4.js';
const videoDefaultOptions = {
vidyard: {
aspect: '16:10',
type: 'inline',
},
};
/**
* @module VidyardVideo
* @description A vidyard video player component.
*
* @since 1.2.2
*
* @param {object} props Component props.
* @param {object} props.customAttributes Custom attributes for the component.
* @param {string|Array|object} props.customClasses Custom classes for the component.
* @param {object} props.videoOptions Video options for player type from consumer. See https://knowledge.vidyard.com/hc/en-us/articles/360009879754-Use-query-strings-to-override-player-settings.
* @param {object|null} ref Ref to the component.
*
* @return {JSX.Element} A vidyard video component.
*
* @example
* import VidyardVideo from '@gravityforms/components/react/admin/modules/Videos/VidyardVideo';
*
* return (
* <VidyardVideo
* customClasses={ [ 'example-class' ] }
* videoOptions={ { uuid: 'example-id' } }
* />
* );
*
*/
const VidyardVideo = forwardRef( ( {
customAttributes = {},
customClasses = [],
videoCustomAttributes = {},
videoOptions = {},
}, ref ) => {
const videoRef = useRef( null );
const [ loading, error ] = useScript( { src: VIDYARD_LIBRARY_SRC } );
const [ rendered, setRendered ] = useState( false );
useEffect( () => {
// if we are loading, errored, don't have a vidref, or weren't supplied uuid for video, no point in going on.
if ( loading || error || ! videoRef.current || ! videoOptions.uuid ) {
return;
}
// get the vidyard api from the loaded script.
const { api: vidyardApi } = window.VidyardV4;
// create the final video options.
const options = Object.assign( {}, videoDefaultOptions.vidyard, videoOptions, {
container: videoRef.current,
} );
/**
* @function controlPlayer
* @description Listen on document for custom events to either play or pause the player using the vidyard api.
*
* @since 1.2.2
*
* @param {CustomEvent} e The event object.
*
* @return {void}
*/
const controlPlayer = ( e ) => {
if ( e.type !== 'gform/video/pauseAll' && e.detail.uuid !== videoOptions.uuid ) {
return;
}
const player = vidyardApi.getPlayersByUUID( videoOptions.uuid )[ 0 ];
let eventType = '';
if ( e.type === 'gform/video/play' ) {
player.play();
eventType = 'playing';
} else if ( e.type === 'gform/video/pause' || e.type === 'gform/video/pauseAll' ) {
player.pause();
eventType = 'paused';
}
trigger( { event: `gform/video/${ eventType }`, native: false, data: {
options,
player,
} } );
};
// render the player into the dom on the react ref.
vidyardApi
.renderPlayer( options ).then( ( player ) => {
// set rendered state
setRendered( true );
// after player render bind listeners in promise.
document.addEventListener( 'gform/video/pause', controlPlayer );
document.addEventListener( 'gform/video/pauseAll', controlPlayer );
document.addEventListener( 'gform/video/play', controlPlayer );
// trigger an event for consumers with instance.
trigger( { event: 'gform/video/rendered', native: false, data: {
options,
player,
} } );
} );
return () => {
// on unmount clean up listeners and destroy player.
const player = vidyardApi.getPlayersByUUID( videoOptions.uuid )[ 0 ];
vidyardApi.destroyPlayer( player );
document.removeEventListener( 'gform/video/pause', controlPlayer );
document.removeEventListener( 'gform/video/pauseAll', controlPlayer );
document.removeEventListener( 'gform/video/play', controlPlayer );
};
}, [ loading, error, videoOptions ] );
if ( loading ) {
return <h3>Loading Vidyard API...</h3>;
}
if ( error ) {
return <h3>Failed to load Vidyard API: { error.message }</h3>;
}
const style = {
display: rendered ? 'block' : 'none',
};
const componentProps = {
className: classnames( {
'gform-video': true,
'gform-video--type-vidyard': true,
}, customClasses ),
...customAttributes,
style,
};
const player = <div ref={ videoRef } { ...componentProps } />;
const videoProps = {
...videoCustomAttributes,
player,
placeholderButtonProps: {
...videoCustomAttributes.placeholderButtonProps,
onClick: () => {
if ( typeof videoCustomAttributes.placeholderButtonProps.onClick === 'function' ) {
videoCustomAttributes.placeholderButtonProps.onClick();
}
trigger( { event: 'gform/video/play', native: false, data: { uuid: videoOptions.uuid } } );
},
},
};
return <Video { ...videoProps } ref={ ref } />;
} );
VidyardVideo.propTypes = {
customAttributes: PropTypes.object,
customClasses: PropTypes.oneOfType( [
PropTypes.string,
PropTypes.array,
PropTypes.object,
] ),
videoCustomAttributes: PropTypes.object,
videoOptions: PropTypes.object,
};
VidyardVideo.displayName = 'Videos/VidyardVideo';
export default VidyardVideo;