// Import block dependencies and components
import isEqual from 'lodash/isEqual';
import debounce from 'lodash/debounce';
// Components
const {
__,
sprintf
} = wp.i18n;
const {
Placeholder,
Spinner
} = wp.components;
const {
Component,
RawHTML,
} = wp.element;
const { addQueryArgs } = wp.url;
/**
* Create an AIOVGServerSideRender Component.
*/
export function AIOVGRendererPath( block, attributes = null, urlQueryArgs = {} ) {
return addQueryArgs( `/wp/v2/block-renderer/${ block }`, {
context: 'edit',
...( null !== attributes ? { attributes } : {} ),
...urlQueryArgs,
} );
}
export class AIOVGServerSideRender extends Component {
constructor( props ) {
super( props );
this.state = {
response: null,
};
}
componentDidMount() {
this.isStillMounted = true;
this.fetch( this.props );
// Only debounce once the initial fetch occurs to ensure that the first
// renders show data as soon as possible.
this.fetch = debounce( this.fetch, 500 );
}
componentWillUnmount() {
this.isStillMounted = false;
}
componentDidUpdate( prevProps, prevState ) {
if ( ! isEqual( prevProps, this.props ) ) {
this.fetch( this.props );
}
if ( this.state.response !== prevState.response ) {
if ( this.props.onChange ) {
this.props.onChange();
}
}
}
fetch( props ) {
if ( ! this.isStillMounted ) {
return;
}
if ( null !== this.state.response ) {
this.setState( { response: null } );
}
const { block, attributes = null, urlQueryArgs = {} } = props;
const path = AIOVGRendererPath( block, attributes, urlQueryArgs );
// Store the latest fetch request so that when we process it, we can
// check if it is the current request, to avoid race conditions on slow networks.
const fetchRequest = this.currentFetchRequest = wp.apiFetch( { path } )
.then( ( response ) => {
if ( this.isStillMounted && fetchRequest === this.currentFetchRequest && response && response.rendered ) {
this.setState( { response: response.rendered } );
}
} )
.catch( ( error ) => {
if ( this.isStillMounted && fetchRequest === this.currentFetchRequest ) {
this.setState( { response: {
error: true,
errorMsg: error.message,
} } );
}
} );
return fetchRequest;
}
render() {
const response = this.state.response;
if ( ! response ) {
return (
);
} else if ( response.error ) {
// translators: %s: error message describing the problem
const errorMessage = sprintf( __( 'Error loading block: %s' ), response.errorMsg );
return (
{ errorMessage }
);
} else if ( ! response.length ) {
return (
{ __( 'No results found.' ) }
);
}
return (
{ response }
);
}
}
export default AIOVGServerSideRender;