UNPKG

@gravityforms/components

Version:

UI components for use in Gravity Forms development. Both React and vanilla js flavors.

171 lines (154 loc) 5.3 kB
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;