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,91 @@ const StepSiteGenEditorHeader = () => { setCurrentOnboardingData( currentData ); }; + const buildPreviewsForScreenshot = ( 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 = buildPreviewsForScreenshot( + homepages, + activeHomepage + ); + const ele = document.querySelector( + '.nfd-onboarding-screenshot-container' + ); + if ( ele ) { + render( finalPreviews, ele ); + + const delay = ( ms ) => + new Promise( ( res ) => setTimeout( res, ms ) ); + await delay( 5000 ); + + const screenshots = 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 ( 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 ); 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() + ); +}