import { isEqual } from 'includes/utility'; const { __ } = wp.i18n; const { debounce } = lodash; const { addQueryArgs } = wp.url; const apiFetch = wp.apiFetch; const { Component, RawHTML } = wp.element; const { Placeholder, Spinner } = wp.components; export default class TemplateRender extends Component { constructor(props) { super(props); this.state = { response: null, }; this.fetchSuccessEvent = new Event( 'jetMenu/editor/templateRenderer/renderSuccess' ); this.placeholderRef = React.createRef(); } componentDidMount() { this.isStillMounted = true; this.fetch(); // 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) { if (!isEqual(prevProps, this.props)) { this.fetch(); } } fetch() { if (!this.isStillMounted) return; if (null !== this.state.response) this.setState({ response: null }); const path = this.rendererPath(); const { onSuccess = () => { }, onError = () => { } } = this.props // 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 = apiFetch({ path }) .then((response) => { if ( this.isStillMounted && fetchRequest === this.currentFetchRequest && response ) { this.setState({ response: response.rendered }); window.dispatchEvent( this.fetchSuccessEvent ); //setTimeout(onSuccess(window.ReactDOM.findDOMNode(this)), 100); } }) .catch((error) => { if ( this.isStillMounted && fetchRequest === this.currentFetchRequest ) { this.setState({ response: { error: true, errorMsg: error.message, }, }); onError(); } })); return fetchRequest; } rendererPath() { const { block, attributes = null, } = this.props; return addQueryArgs(`/wp/v2/block-renderer/${block}`, { context: 'edit', ...(null !== attributes ? { attributes } : {}), }); } EmptyResponsePlaceholder() { return ( {__('Block rendered as empty.')} ) } ErrorResponsePlaceholder(response) { const errorMessage = sprintf( // translators: %s: error message describing the problem __('Error loading block: %s'), response.errorMsg ); return ( {errorMessage} ); } LoadingResponsePlaceholder() { return ( ); } render() { const response = this.state.response; const { EmptyResponsePlaceholder, ErrorResponsePlaceholder, LoadingResponsePlaceholder } = this; if (response === '') { return ( ); } else if (!response) { return ( ); } else if (response.error) { return ( ); } return ( {response} ); } }