Add basic optimization for usePreviewTemplates to improve render performance

MAILPOET-5949
This commit is contained in:
Oluwaseun Olorunsola
2024-12-05 22:42:19 +01:00
committed by Oluwaseun Olorunsola
parent bc0ce09d61
commit 8661a169b3

View File

@ -1,4 +1,4 @@
// import { useMemo } from '@wordpress/element';
import { useMemo } from '@wordpress/element';
import { parse } from '@wordpress/blocks';
import { BlockInstance } from '@wordpress/blocks/index';
import { useSelect } from '@wordpress/data';
@ -89,84 +89,87 @@ function generateTemplateCssTheme(
export function usePreviewTemplates(
customEmailContent = ''
): TemplatePreview[][] {
const { templates, patterns, emailPosts } = useSelect( ( select ) => {
const contentBlockId =
// @ts-expect-error getBlocksByName is not defined in types
select( blockEditorStore ).getBlocksByName(
'core/post-content'
)?.[ 0 ];
return {
templates: select( storeName ).getEmailTemplates(),
patterns:
// @ts-expect-error getPatternsByBlockTypes is not defined in types
select( blockEditorStore ).getPatternsByBlockTypes(
[ 'core/post-content' ],
contentBlockId
),
emailPosts: select( storeName ).getSentEmailEditorPosts(),
};
}, [] );
if ( ! templates || ( ! patterns.length && ! customEmailContent ) ) {
return [ [] ];
}
let contentPatternBlocksGeneral = null;
let contentPatternBlocks = null;
const parsedCustomEmailContent =
customEmailContent && parse( customEmailContent );
// If there is a custom email content passed from outside we use it as email content for preview
// otherwise we pick first suitable from patterns
if ( parsedCustomEmailContent ) {
contentPatternBlocksGeneral = parsedCustomEmailContent;
contentPatternBlocks = parsedCustomEmailContent;
} else {
// Pick first pattern that comes from mailpoet and is for general email template
contentPatternBlocksGeneral = patterns.find(
( pattern ) =>
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
pattern?.templateTypes?.includes( 'email-general-template' )
)?.blocks as BlockInstance[];
// Pick first pattern that comes from mailpoet and is for template with header and footer content separated
contentPatternBlocks = patterns.find(
( pattern ) =>
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
pattern?.templateTypes?.includes( 'email-template' )
)?.blocks as BlockInstance[];
}
const allTemplates = templates.map(
( template: EmailTemplatePreview ): TemplatePreview => {
let parsedTemplate = parse( template.content?.raw );
parsedTemplate = setPostContentInnerBlocks(
parsedTemplate,
template.slug === 'email-general'
? contentPatternBlocksGeneral
: contentPatternBlocks
);
): [ TemplatePreview[], TemplatePreview[], boolean ] {
const { templates, patterns, emailPosts, hasEmailPosts } = useSelect(
( select ) => {
const contentBlockId =
// @ts-expect-error getBlocksByName is not defined in types
select( blockEditorStore ).getBlocksByName(
'core/post-content'
)?.[ 0 ];
const rawEmailPosts = select( storeName ).getSentEmailEditorPosts();
return {
id: template.id,
slug: template.slug,
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
previewContentParsed: parsedTemplate,
emailParsed:
template.slug === 'email-general'
? contentPatternBlocksGeneral
: contentPatternBlocks,
template,
category: 'basic', // TODO: This will be updated once template category is implemented
type: template.type,
templates: select( storeName ).getEmailTemplates(),
patterns:
// @ts-expect-error getPatternsByBlockTypes is not defined in types
select( blockEditorStore ).getPatternsByBlockTypes(
[ 'core/post-content' ],
contentBlockId
),
emailPosts: rawEmailPosts,
hasEmailPosts: !! ( rawEmailPosts && rawEmailPosts?.length ),
};
}
},
[]
);
return [
allTemplates,
emailPosts?.map( ( post: EmailEditorPostType ) => {
const allTemplates = useMemo( () => {
let contentPatternBlocksGeneral = null;
let contentPatternBlocks = null;
const parsedCustomEmailContent =
customEmailContent && parse( customEmailContent );
// If there is a custom email content passed from outside we use it as email content for preview
// otherwise we pick first suitable from patterns
if ( parsedCustomEmailContent ) {
contentPatternBlocksGeneral = parsedCustomEmailContent;
contentPatternBlocks = parsedCustomEmailContent;
} else {
// Pick first pattern that comes from mailpoet and is for general email template
contentPatternBlocksGeneral = patterns.find(
( pattern ) =>
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
pattern?.templateTypes?.includes( 'email-general-template' )
)?.blocks as BlockInstance[];
// Pick first pattern that comes from mailpoet and is for template with header and footer content separated
contentPatternBlocks = patterns.find(
( pattern ) =>
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
pattern?.templateTypes?.includes( 'email-template' )
)?.blocks as BlockInstance[];
}
return templates?.map(
( template: EmailTemplatePreview ): TemplatePreview => {
let parsedTemplate = parse( template.content?.raw );
parsedTemplate = setPostContentInnerBlocks(
parsedTemplate,
template.slug === 'email-general'
? contentPatternBlocksGeneral
: contentPatternBlocks
);
return {
id: template.id,
slug: template.slug,
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
previewContentParsed: parsedTemplate,
emailParsed:
template.slug === 'email-general'
? contentPatternBlocksGeneral
: contentPatternBlocks,
template,
category: 'basic', // TODO: This will be updated once template category is implemented
type: template.type,
};
}
);
}, [ templates, patterns, customEmailContent ] );
const allEmailPosts = useMemo( () => {
return emailPosts?.map( ( post: EmailEditorPostType ) => {
const parsedPostContent = parse( post.content?.raw );
const cssThemeData = generateTemplateCssTheme( post, allTemplates );
return {
@ -186,6 +189,8 @@ export function usePreviewTemplates(
category: 'recent',
type: post.type,
};
} ) as unknown as TemplatePreview[],
];
} ) as unknown as TemplatePreview[];
}, [ emailPosts, allTemplates ] );
return [ allTemplates || [], allEmailPosts || [], hasEmailPosts ];
}