diff --git a/src/components/send-button/index.js b/src/components/send-button/index.js index 4ff6bc0c..e8df44af 100644 --- a/src/components/send-button/index.js +++ b/src/components/send-button/index.js @@ -18,8 +18,9 @@ import { get } from 'lodash'; * Internal dependencies */ import { getServiceProvider } from '../../service-providers'; -import { refreshEmailHtml, validateNewsletter } from '../../newsletter-editor/utils'; +import { validateNewsletter } from '../../newsletter-editor/utils'; import { useNewsletterData } from '../../newsletter-editor/store'; +import { refreshEmailHtml } from '../../editor/mjml'; import './style.scss'; function PreviewHTML() { diff --git a/src/editor/mjml/index.js b/src/editor/mjml/index.js index 95d8d4ed..0defa8cf 100644 --- a/src/editor/mjml/index.js +++ b/src/editor/mjml/index.js @@ -3,19 +3,52 @@ /** * WordPress dependencies */ +import { __ } from '@wordpress/i18n'; import apiFetch from '@wordpress/api-fetch'; import { useSelect, useDispatch } from '@wordpress/data'; import { useEffect } from '@wordpress/element'; -import { refreshEmailHtml, usePrevious } from '../../newsletter-editor/utils'; +import { usePrevious } from '../../newsletter-editor/utils'; /** * Internal dependencies */ -import { fetchNewsletterData, fetchSyncErrors, updateNewsletterDataError, updateIsRefreshingHtml, useIsRefreshingHtml } from '../../newsletter-editor/store'; import { getServiceProvider } from '../../service-providers'; +import { + fetchNewsletterData, + fetchSyncErrors, + updateIsRefreshingHtml, +} from '../../newsletter-editor/store'; + +/** + * External dependencies + */ +import mjml2html from 'mjml-browser'; + +/** + * Refresh the email-compliant HTML for a post. + * + * @param {number} postId The current post ID. + * @param {string} postTitle The current post title. + * @param {string} postContent The current post content. + * @return {Promise} The refreshed email HTML. + */ +export const refreshEmailHtml = async ( postId, postTitle, postContent ) => { + const mjml = await apiFetch( { + path: `/newspack-newsletters/v1/post-mjml`, + method: 'POST', + data: { + post_id: postId, + title: postTitle, + content: postContent, + }, + } ); + + // Once received MJML markup, convert it to email-compliant HTML and save as post meta. + const { html } = mjml2html( mjml, { keepComments: false, minify: true } ); + return html; +}; function MJML() { - const isRefreshingHTML = useIsRefreshingHtml(); const { saveSucceeded, isPublishing, @@ -54,7 +87,7 @@ function MJML() { isAutosaveLocked: isPostAutosavingLocked(), }; } ); - + const { createNotice } = useDispatch( 'core/notices' ); const { lockPostAutosaving, lockPostSaving, unlockPostSaving, editPost } = useDispatch( 'core/editor' ); @@ -79,42 +112,43 @@ function MJML() { ! isSaving && ! isAutosaving && ! isPublishing && - ! isRefreshingHTML && ! isSent && saveSucceeded ) { - updateIsRefreshingHtml( true ); - lockPostSaving( 'newspack-newsletters-refresh-html' ); - refreshEmailHtml( postId, postTitle, postContent ) - .then( refreshedHtml => { - updateMetaValue( newspack_email_editor_data.email_html_meta, refreshedHtml ); - return apiFetch( { - data: { meta: { [ newspack_email_editor_data.email_html_meta ]: refreshedHtml } }, - method: 'POST', - path: `/wp/v2/${ postType }/${ postId }`, - } ); - } ).then( () => { - // Rehydrate ESP newsletter data after completing sync. - if ( isSupportedESP ) { - return fetchNewsletterData( postId ); - } - return true; - } ).then ( () => { - // Check for sync errors after refreshing the HTML. - if ( isSupportedESP ) { - return fetchSyncErrors( postId ); - } - return true; - } ) - .catch( e => { - updateNewsletterDataError( e ); - } ) - .finally( () => { - unlockPostSaving( 'newspack-newsletters-refresh-html' ); - updateIsRefreshingHtml( false ); - } ); + refreshHtml(); } }, [ isSaving, isAutosaving ] ); + + const refreshHtml = async () => { + try { + lockPostSaving( 'newspack-newsletters-refresh-html' ); + if ( isSupportedESP ) { + updateIsRefreshingHtml( true ); + } + const refreshedHtml = await refreshEmailHtml( postId, postTitle, postContent ); + updateMetaValue( newspack_email_editor_data.email_html_meta, refreshedHtml ); + + // Save the refreshed HTML to post meta. + await apiFetch( { + data: { meta: { [ newspack_email_editor_data.email_html_meta ]: refreshedHtml } }, + method: 'POST', + path: `/wp/v2/${ postType }/${ postId }`, + } ); + + // Rehydrate ESP newsletter data after completing sync. + if ( isSupportedESP ) { + await fetchNewsletterData( postId ); + await fetchSyncErrors( postId ); + updateIsRefreshingHtml( false ); + } + unlockPostSaving( 'newspack-newsletters-refresh-html' ); + } catch ( e ) { + createNotice( 'error', e?.message || __( 'Error refreshing email HTML.', 'newspack-newsletters' ), { + id: 'newspack-newsletters-mjml-error', + isDismissible: true, + } ); + } + } } export default MJML; diff --git a/src/newsletter-editor/index.js b/src/newsletter-editor/index.js index 1cd70f6b..93866232 100644 --- a/src/newsletter-editor/index.js +++ b/src/newsletter-editor/index.js @@ -90,7 +90,7 @@ function NewsletterEdit( { apiFetchWithErrorHandling, setInFlightForAsync, inFli // Handle error messages from retrieve/sync requests with connected ESP. useEffect( () => { if ( newsletterDataError ) { - createNotice( 'error', newsletterDataError?.message || __( 'Error communicating with service provider.', 'newspack-newseltters' ), { + createNotice( 'error', newsletterDataError?.message || __( 'Error communicating with service provider.', 'newspack-newsletters' ), { id: 'newspack-newsletters-newsletter-data-error', isDismissible: true, } ); diff --git a/src/newsletter-editor/utils.js b/src/newsletter-editor/utils.js index db306da3..137dd4bd 100644 --- a/src/newsletter-editor/utils.js +++ b/src/newsletter-editor/utils.js @@ -3,15 +3,9 @@ /** * WordPress dependencies */ -import apiFetch from '@wordpress/api-fetch'; import { useEffect, useRef } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; -/** - * External dependencies - */ -import mjml2html from 'mjml-browser'; - /** * Internal dependencies */ @@ -61,30 +55,6 @@ export const validateNewsletter = ( meta = {} ) => { */ export const hasValidEmail = string => /\S+@\S+/.test( string ); -/** - * Refresh the email-compliant HTML for a post. - * - * @param {number} postId The current post ID. - * @param {string} postTitle The current post title. - * @param {string} postContent The current post content. - * @return {Promise} The refreshed email HTML. - */ -export const refreshEmailHtml = async ( postId, postTitle, postContent ) => { - const mjml = await apiFetch( { - path: `/newspack-newsletters/v1/post-mjml`, - method: 'POST', - data: { - post_id: postId, - title: postTitle, - content: postContent, - }, - } ); - - // Once received MJML markup, convert it to email-compliant HTML and save as post meta. - const { html } = mjml2html( mjml, { keepComments: false, minify: true } ); - return html; -}; - /** * Custom hook to fetch a previous state or prop value. *