Skip to content

Commit

Permalink
Merge branch 'trunk' into epic/ras-acc
Browse files Browse the repository at this point in the history
  • Loading branch information
laurelfulford committed Nov 6, 2024
2 parents 4f1dc33 + d3f1f37 commit 3cd3e71
Show file tree
Hide file tree
Showing 12 changed files with 98 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1050,7 +1050,7 @@ public function sync( $post ) {
'p[' . $send_list_id . ']' => 1,
'fromemail' => $from_email,
'fromname' => $from_name,
'subject' => $post->post_title,
'subject' => html_entity_decode( $post->post_title ),
],
$message_data
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -490,8 +490,8 @@ public function format_campaign_args( $post_id ) {
}

$args = [
'Subject' => get_the_title( $post_id ),
'Name' => get_the_title( $post_id ) . ' ' . gmdate( 'h:i:s A' ), // Name must be unique.
'Subject' => html_entity_decode( get_the_title( $post_id ) ),
'Name' => html_entity_decode( get_the_title( $post_id ) ) . ' ' . gmdate( 'h:i:s A' ), // Name must be unique.
'FromName' => get_post_meta( $post_id, 'senderName', true ),
'FromEmail' => get_post_meta( $post_id, 'senderEmail', true ),
'ReplyTo' => get_post_meta( $post_id, 'senderEmail', true ),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ public function sender( $post_id, $from_name, $reply_to ) {
$activity = [
'format_type' => 5,
'email_content' => $content,
'subject' => $post->post_title,
'subject' => html_entity_decode( $post->post_title ),
'contact_list_ids' => $campaign->activity->contact_list_ids,
'from_name' => $from_name,
'from_email' => $reply_to,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1004,7 +1004,7 @@ public function get_sync_payload( $post ) {
'type' => 'regular',
'content_type' => 'template',
'settings' => [
'subject_line' => $post->post_title,
'subject_line' => html_entity_decode( $post->post_title ),
'title' => $this->get_campaign_name( $post ),
],
];
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.10.4",
"@wordpress/browserslist-config": "^6.10.0",
"@wordpress/browserslist-config": "^6.11.0",
"eslint": "^8.57.0",
"lint-staged": "^15.2.10",
"newspack-scripts": "^5.5.2",
Expand Down
3 changes: 2 additions & 1 deletion src/components/send-button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
104 changes: 69 additions & 35 deletions src/editor/mjml/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>} 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,
Expand Down Expand Up @@ -54,7 +87,7 @@ function MJML() {
isAutosaveLocked: isPostAutosavingLocked(),
};
} );

const { createNotice } = useDispatch( 'core/notices' );
const { lockPostAutosaving, lockPostSaving, unlockPostSaving, editPost } = useDispatch(
'core/editor'
);
Expand All @@ -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;
2 changes: 1 addition & 1 deletion src/newsletter-editor/editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ const Editor = compose( [
const publishButton = document.getElementsByClassName(
'editor-post-publish-button__button'
)[ 0 ];
publishButton.parentNode.insertBefore( publishEl, publishButton );
publishButton.parentNode.insertBefore( publishEl, publishButton.nextSibling );
}, [] );

// Set color palette option.
Expand Down
2 changes: 1 addition & 1 deletion src/newsletter-editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
} );
Expand Down
17 changes: 15 additions & 2 deletions src/newsletter-editor/sidebar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { __ } from '@wordpress/i18n';
import { compose } from '@wordpress/compose';
import { withSelect, withDispatch } from '@wordpress/data';
import { useEffect } from '@wordpress/element';
import { useEffect, useRef, useState } from '@wordpress/element';
import { Button, Notice, Spinner, TextControl, TextareaControl } from '@wordpress/components';

/**
Expand Down Expand Up @@ -40,11 +40,24 @@ const Sidebar = ( {
stringifiedCampaignDefaults,
postId,
} ) => {
const [ plainTextTitle, setPlainTextTitle ] = useState( title );
const isRetrieving = useIsRetrieving();
const newsletterData = useNewsletterData();
const newsletterDataError = useNewsletterDataError();
const campaign = newsletterData?.campaign;
const updateMeta = ( toUpdate ) => editPost( { meta: toUpdate } );
const entityConverter = useRef( null );

// Create a temp textarea element that we can use to convert HTML entities like &amp; to unicode characters.
useEffect( () => {
if ( entityConverter.current ) {
entityConverter.current.innerHTML = title;
setPlainTextTitle( entityConverter.current.value );
} else {
entityConverter.current = document.createElement( 'textarea' );
}
return () => entityConverter?.current?.remove && entityConverter.current.remove(); // Clean up temp element from DOM on unmount.
}, [ title ] );

// Reconcile stored campaign data with data fetched from ESP.
useEffect( () => {
Expand Down Expand Up @@ -184,7 +197,7 @@ const Sidebar = ( {
<TextControl
label={ __( 'Subject', 'newspack-newsletters' ) }
className="newspack-newsletters__subject-textcontrol"
value={ title }
value={ plainTextTitle }
disabled={ inFlight }
onChange={ value => editPost( { title: value } ) }
/>
Expand Down
30 changes: 0 additions & 30 deletions src/newsletter-editor/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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<string>} 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.
*
Expand Down

0 comments on commit 3cd3e71

Please sign in to comment.