From 61a7a30d4c9fd1f305d281d4caff777a50b88523 Mon Sep 17 00:00:00 2001 From: arunshenoy99 Date: Thu, 8 Feb 2024 13:03:54 +0530 Subject: [PATCH 1/4] Block Render and Screenshots --- includes/RestApi/BlockRenderController.php | 88 ++++++++++++++++++ includes/RestApi/RestApi.php | 1 + .../LivePreview/BlockPreview/index.js | 6 +- .../steps/SiteGen/Editor/Header/index.js | 93 +++++++++++++++++-- .../steps/SiteGen/Editor/index.js | 1 + src/OnboardingSPA/utils/api/blockRender.js | 18 ++++ 6 files changed, 199 insertions(+), 8 deletions(-) create mode 100644 includes/RestApi/BlockRenderController.php create mode 100644 src/OnboardingSPA/utils/api/blockRender.js diff --git a/includes/RestApi/BlockRenderController.php b/includes/RestApi/BlockRenderController.php new file mode 100644 index 000000000..413984a5a --- /dev/null +++ b/includes/RestApi/BlockRenderController.php @@ -0,0 +1,88 @@ +namespace, + $this->rest_base . '/screenshot', + array( + 'methods' => \WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'generate_screenshot' ), + 'permission_callback' => array( Permissions::class, 'rest_is_authorized_admin' ), + 'args' => $this->generate_screenshot_args(), + ) + ); + } + + /** + * Args for Generating the screenshot. + * + * @return array + */ + public function generate_screenshot_args() { + return array( + 'width' => array( + 'required' => true, + 'type' => 'integer', + ), + 'height' => array( + 'required' => true, + 'type' => 'integer', + ), + 'content' => array( + 'required' => true, + 'type' => 'string', + ), + ); + } + + /** + * Generates a PNG screenshot of the HTML block render. + * + * @param \WP_REST_Request $request The incoming request. + * @return \WP_REST_Response|\WP_Error + */ + public function generate_screenshot( \WP_REST_Request $request ) { + $width = $request->get_param( 'width' ); + $height = $request->get_param( 'height' ); + $content = $request->get_param( 'content' ); + + $screenshot = BlockRenderService::generate_screenshot( $width, $height, $content ); + if ( is_wp_error( $screenshot ) ) { + return $screenshot; + } + + return new \WP_REST_Response( + $screenshot, + 201 + ); + } +} diff --git a/includes/RestApi/RestApi.php b/includes/RestApi/RestApi.php index e3bfb7dd3..c0b8caebf 100644 --- a/includes/RestApi/RestApi.php +++ b/includes/RestApi/RestApi.php @@ -30,6 +30,7 @@ final class RestApi { 'NewfoldLabs\WP\\Module\\Onboarding\\RestApi\\Themes\\ThemeColorsController', 'NewfoldLabs\\WP\\Module\\Onboarding\\RestApi\\SiteClassificationController', 'NewfoldLabs\\WP\\Module\\Onboarding\\RestApi\\SiteGenController', + 'NewfoldLabs\\WP\\Module\\Onboarding\\RestApi\\BlockRenderController', ); /** diff --git a/src/OnboardingSPA/components/LivePreview/BlockPreview/index.js b/src/OnboardingSPA/components/LivePreview/BlockPreview/index.js index 936fe7ff9..bc1c19762 100644 --- a/src/OnboardingSPA/components/LivePreview/BlockPreview/index.js +++ b/src/OnboardingSPA/components/LivePreview/BlockPreview/index.js @@ -10,6 +10,7 @@ import { store as nfdOnboardingStore } from '../../../store'; import Animate from '../../Animate'; const BlockPreview = ( { + slug = '', blockGrammer, viewportWidth = 1300, styling = 'large', @@ -122,7 +123,10 @@ const BlockPreview = ( { }; return ( -
+
{ loading && getSkeleton() } { blocks && settings && ( { const [ homepage, setHomepage ] = useState(); const [ isSaving, setIsSaving ] = useState( false ); const [ isRegenerating, setIsRegenerating ] = useState( false ); + const [ globalStyles, setGlobalStyles ] = useState( false ); const isLargeViewport = useViewportMatch( 'medium' ); @@ -102,11 +107,13 @@ const StepSiteGenEditorHeader = () => { setIsSidebarOpened( true ); }; - const handleCustomize = () => { + const handleCustomize = async () => { const isSidebarOpenedNew = sideBarView === 'Customize' ? ! isSidebarOpened : isSidebarOpened; setSidebarActiveView( 'Customize' ); setIsSidebarOpened( isSidebarOpenedNew ); + const globalStylesResponse = await getGlobalStyles(); + setGlobalStyles( globalStylesResponse.body ); }; const handleRename = ( title ) => { @@ -116,8 +123,80 @@ const StepSiteGenEditorHeader = () => { setCurrentOnboardingData( currentData ); }; + const buildLivePreviews = ( homepages, activeHomepage ) => { + return ( +
+ { Object.keys( homepages ).map( ( slug, idx ) => { + const data = homepages[ slug ]; + if ( ! data.isFavorite && slug !== activeHomepage.slug ) { + return false; + } + const newPreviewSettings = cloneDeep( globalStyles[ 0 ] ); + newPreviewSettings.settings.color.palette = + data.color.palette; + let blockGrammar = ''; + [ 'header', 'content', 'footer' ].forEach( ( part ) => { + if ( part in data ) { + blockGrammar += data[ part ]; + } + } ); + return ( + + ); + } ) } +
+ ); + }; + const saveAndContinue = async () => { setIsSaving( true ); + const homepages = currentData.sitegen.homepages.data; + const activeHomepage = currentData.sitegen.homepages.active; + const finalPreviews = buildLivePreviews( homepages, activeHomepage ); + const ele = document.querySelector( + '.nfd-onboarding-screenshot-container' + ); + render( finalPreviews, ele ); + const delay = ( ms ) => new Promise( ( res ) => setTimeout( res, ms ) ); + await delay( 5000 ); + + const stuff = await Promise.all( + Object.keys( homepages ).map( ( slug ) => { + const data = homepages[ slug ]; + if ( ! data.isFavorite && slug !== activeHomepage.slug ) { + return false; + } + + const iframe = ele.querySelector( + `div > div[data-slug="nfd-onboarding-block-preview-${ slug }"] > .block-editor-block-preview__container > div > iframe` + ); + const html = iframe.contentWindow.document.querySelector( + '.block-editor-block-preview__content-iframe' + ); + return blockRenderScreenshot( html.innerHTML ); + } ) + ); + + Object.keys( homepages ).forEach( ( slug, idx ) => { + if ( stuff[ idx ]?.body?.screenshot ) { + homepages[ slug ].screenshot = stuff[ idx ].body.screenshot; + if ( slug === activeHomepage.slug ) { + activeHomepage.screenshot = stuff[ idx ].body.screenshot; + } + } + } ); + + currentData.sitegen.homepages.data = homepages; + currentData.sitegen.homepages.active = activeHomepage; + setCurrentOnboardingData( currentData ); + await setFlow( currentData ); await completeFlow(); window.location.replace( pluginDashboardPage ); diff --git a/src/OnboardingSPA/steps/SiteGen/Editor/index.js b/src/OnboardingSPA/steps/SiteGen/Editor/index.js index 9ddbba8bd..a2bc319d0 100644 --- a/src/OnboardingSPA/steps/SiteGen/Editor/index.js +++ b/src/OnboardingSPA/steps/SiteGen/Editor/index.js @@ -122,6 +122,7 @@ const StepSiteGenEditor = () => {
{ buildPreview() }
+
); }; diff --git a/src/OnboardingSPA/utils/api/blockRender.js b/src/OnboardingSPA/utils/api/blockRender.js new file mode 100644 index 000000000..9390623f2 --- /dev/null +++ b/src/OnboardingSPA/utils/api/blockRender.js @@ -0,0 +1,18 @@ +import apiFetch from '@wordpress/api-fetch'; + +import { onboardingRestURL } from './common'; +import { resolve } from './resolve.js'; + +export async function blockRenderScreenshot( content ) { + return await resolve( + apiFetch( { + url: onboardingRestURL( 'block-render/screenshot' ), + method: 'POST', + data: { + width: 1200, + height: 900, + content, + }, + } ).then() + ); +} From d9d028891144aa8b812ff565b53142ec8a6328d2 Mon Sep 17 00:00:00 2001 From: arunshenoy99 Date: Thu, 8 Feb 2024 13:26:35 +0530 Subject: [PATCH 2/4] SPA lint fixes --- .../components/LivePreview/BlockPreview/index.js | 12 ++++++------ .../steps/SiteGen/Editor/Header/index.js | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/OnboardingSPA/components/LivePreview/BlockPreview/index.js b/src/OnboardingSPA/components/LivePreview/BlockPreview/index.js index bc1c19762..b09a1e8a8 100644 --- a/src/OnboardingSPA/components/LivePreview/BlockPreview/index.js +++ b/src/OnboardingSPA/components/LivePreview/BlockPreview/index.js @@ -96,13 +96,13 @@ const BlockPreview = ( {

{ skeletonShouldWait ? __( - 'Regenerating Site', - 'wp-module-onboarding' - ) + 'Regenerating Site', + 'wp-module-onboarding' + ) : __( - 'Generating Site', - 'wp-module-onboarding' - ) } + 'Generating Site', + 'wp-module-onboarding' + ) }

diff --git a/src/OnboardingSPA/steps/SiteGen/Editor/Header/index.js b/src/OnboardingSPA/steps/SiteGen/Editor/Header/index.js index e1de561be..2f1c01d36 100644 --- a/src/OnboardingSPA/steps/SiteGen/Editor/Header/index.js +++ b/src/OnboardingSPA/steps/SiteGen/Editor/Header/index.js @@ -289,9 +289,9 @@ const StepSiteGenEditorHeader = () => { > { isLargeViewport ? __( - 'Save & Continue', - 'wp-module-onboarding' - ) + 'Save & Continue', + 'wp-module-onboarding' + ) : __( 'Next', 'wp-module-onboarding' ) }
{ isSaving ? ( From 24b66879111729266d04c2d0bb47f52007c3d296 Mon Sep 17 00:00:00 2001 From: arunshenoy99 Date: Fri, 9 Feb 2024 23:43:38 +0530 Subject: [PATCH 3/4] Minor refactor --- .../steps/SiteGen/Editor/Header/index.js | 79 +++++++++++-------- 1 file changed, 45 insertions(+), 34 deletions(-) diff --git a/src/OnboardingSPA/steps/SiteGen/Editor/Header/index.js b/src/OnboardingSPA/steps/SiteGen/Editor/Header/index.js index 2f1c01d36..9fc345c64 100644 --- a/src/OnboardingSPA/steps/SiteGen/Editor/Header/index.js +++ b/src/OnboardingSPA/steps/SiteGen/Editor/Header/index.js @@ -123,7 +123,7 @@ const StepSiteGenEditorHeader = () => { setCurrentOnboardingData( currentData ); }; - const buildLivePreviews = ( homepages, activeHomepage ) => { + const buildPreviewsForScreenshot = ( homepages, activeHomepage ) => { return (
{ Object.keys( homepages ).map( ( slug, idx ) => { @@ -157,46 +157,57 @@ const StepSiteGenEditorHeader = () => { const saveAndContinue = async () => { setIsSaving( true ); + const homepages = currentData.sitegen.homepages.data; const activeHomepage = currentData.sitegen.homepages.active; - const finalPreviews = buildLivePreviews( homepages, activeHomepage ); + const finalPreviews = buildPreviewsForScreenshot( + homepages, + activeHomepage + ); const ele = document.querySelector( '.nfd-onboarding-screenshot-container' ); - render( finalPreviews, ele ); - const delay = ( ms ) => new Promise( ( res ) => setTimeout( res, ms ) ); - await delay( 5000 ); + if ( ele ) { + render( finalPreviews, ele ); - const stuff = await Promise.all( - Object.keys( homepages ).map( ( slug ) => { - const data = homepages[ slug ]; - if ( ! data.isFavorite && slug !== activeHomepage.slug ) { - return false; - } + const delay = ( ms ) => + new Promise( ( res ) => setTimeout( res, ms ) ); + await delay( 5000 ); - const iframe = ele.querySelector( - `div > div[data-slug="nfd-onboarding-block-preview-${ slug }"] > .block-editor-block-preview__container > div > iframe` - ); - const html = iframe.contentWindow.document.querySelector( - '.block-editor-block-preview__content-iframe' - ); - return blockRenderScreenshot( html.innerHTML ); - } ) - ); + const screenshots = await Promise.all( + Object.keys( homepages ).map( ( slug ) => { + const data = homepages[ slug ]; + if ( ! data.isFavorite && slug !== activeHomepage.slug ) { + return false; + } - Object.keys( homepages ).forEach( ( slug, idx ) => { - if ( stuff[ idx ]?.body?.screenshot ) { - homepages[ slug ].screenshot = stuff[ idx ].body.screenshot; - if ( slug === activeHomepage.slug ) { - activeHomepage.screenshot = stuff[ idx ].body.screenshot; - } - } - } ); + const iframe = ele.querySelector( + `div > div[data-slug="nfd-onboarding-block-preview-${ slug }"] > .block-editor-block-preview__container > div > iframe` + ); + const html = iframe.contentWindow.document.querySelector( + '.block-editor-block-preview__content-iframe' + ); - currentData.sitegen.homepages.data = homepages; - currentData.sitegen.homepages.active = activeHomepage; - setCurrentOnboardingData( currentData ); + return blockRenderScreenshot( html.innerHTML ); + } ) + ); + Object.keys( homepages ).forEach( ( slug, idx ) => { + if ( screenshots[ idx ]?.body?.screenshot ) { + homepages[ slug ].screenshot = + screenshots[ idx ].body.screenshot; + if ( slug === activeHomepage.slug ) { + activeHomepage.screenshot = + screenshots[ idx ].body.screenshot; + } + } + } ); + + currentData.sitegen.homepages.data = homepages; + currentData.sitegen.homepages.active = activeHomepage; + setCurrentOnboardingData( currentData ); + return currentData; + } await setFlow( currentData ); await completeFlow(); window.location.replace( pluginDashboardPage ); @@ -289,9 +300,9 @@ const StepSiteGenEditorHeader = () => { > { isLargeViewport ? __( - 'Save & Continue', - 'wp-module-onboarding' - ) + 'Save & Continue', + 'wp-module-onboarding' + ) : __( 'Next', 'wp-module-onboarding' ) }
{ isSaving ? ( From 8b316546982df63608375dbdff7f0c47e8df9bc9 Mon Sep 17 00:00:00 2001 From: arunshenoy99 Date: Fri, 9 Feb 2024 23:46:02 +0530 Subject: [PATCH 4/4] Lint fix --- .../components/LivePreview/BlockPreview/index.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/OnboardingSPA/components/LivePreview/BlockPreview/index.js b/src/OnboardingSPA/components/LivePreview/BlockPreview/index.js index b09a1e8a8..bc1c19762 100644 --- a/src/OnboardingSPA/components/LivePreview/BlockPreview/index.js +++ b/src/OnboardingSPA/components/LivePreview/BlockPreview/index.js @@ -96,13 +96,13 @@ const BlockPreview = ( {

{ skeletonShouldWait ? __( - 'Regenerating Site', - 'wp-module-onboarding' - ) + 'Regenerating Site', + 'wp-module-onboarding' + ) : __( - 'Generating Site', - 'wp-module-onboarding' - ) } + 'Generating Site', + 'wp-module-onboarding' + ) }