import { PagePatternModal, PatternDefinition } from '@automattic/page-pattern-modal'; import { useSelect, useDispatch } from '@wordpress/data'; import { useCallback } from '@wordpress/element'; import { addFilter, removeFilter } from '@wordpress/hooks'; import { __ } from '@wordpress/i18n'; import { pageLayoutStore } from './store'; import '@wordpress/nux'; const INSERTING_HOOK_NAME = 'isInsertingPagePattern'; const INSERTING_HOOK_NAMESPACE = 'automattic/full-site-editing/inserting-pattern'; interface PagePatternsPluginProps { patterns: PatternDefinition[]; } type CoreEditorPlaceholder = { getBlocks: ( ...args: unknown[] ) => Array< { name: string; clientId: string } >; getEditedPostAttribute: ( ...args: unknown[] ) => unknown; }; type CoreEditPostPlaceholder = { isFeatureActive: ( ...args: unknown[] ) => boolean; }; type CoreNuxPlaceholder = { areTipsEnabled: ( ...args: unknown[] ) => boolean; }; export function PagePatternsPlugin( props: PagePatternsPluginProps ) { const { setOpenState } = useDispatch( pageLayoutStore ); const { setUsedPageOrPatternsModal } = useDispatch( 'automattic/wpcom-welcome-guide' ); const { replaceInnerBlocks } = useDispatch( 'core/block-editor' ); const { editPost } = useDispatch( 'core/editor' ); const { toggleFeature } = useDispatch( 'core/edit-post' ); const { disableTips } = useDispatch( 'core/nux' ); const selectProps = useSelect( ( select ) => { const { isOpen, isPatternPicker } = select( pageLayoutStore ); return { isOpen: isOpen(), isWelcomeGuideActive: ( select( 'core/edit-post' ) as CoreEditPostPlaceholder ).isFeatureActive( 'welcomeGuide' ) as boolean, // Gutenberg 7.2.0 or higher areTipsEnabled: select( 'core/nux' ) ? ( ( select( 'core/nux' ) as CoreNuxPlaceholder ).areTipsEnabled() as boolean ) : false, // Gutenberg 7.1.0 or lower ...( isPatternPicker() && { title: __( 'Choose a Pattern', 'full-site-editing' ), description: __( 'Pick a pre-defined layout or continue with a blank page', 'full-site-editing' ), } ), }; }, [] ); const { getMeta, postContentBlock } = useSelect( ( select ) => { const getMeta = () => ( select( 'core/editor' ) as CoreEditorPlaceholder ).getEditedPostAttribute( 'meta' ); const currentBlocks = ( select( 'core/editor' ) as CoreEditorPlaceholder ).getBlocks(); return { getMeta, postContentBlock: currentBlocks.find( ( block ) => block.name === 'a8c/post-content' ), }; }, [] ); const savePatternChoice = useCallback( ( name: string, selectedCategory: string | null ) => { // Save selected pattern slug in meta. const currentMeta = getMeta() as Record< string, unknown >; const currentCategory = ( Array.isArray( currentMeta._wpcom_template_layout_category ) && currentMeta._wpcom_template_layout_category ) || []; editPost( { meta: { ...currentMeta, _starter_page_template: name, _wpcom_template_layout_category: [ ...currentCategory, selectedCategory ], }, } ); }, [ editPost, getMeta ] ); const insertPattern = useCallback( ( title: string | null, blocks: unknown[] ) => { // Add filter to let the tracking library know we are inserting a template. addFilter( INSERTING_HOOK_NAME, INSERTING_HOOK_NAMESPACE, () => true ); // Set post title. if ( title ) { editPost( { title } ); } // Replace blocks. replaceInnerBlocks( postContentBlock ? postContentBlock.clientId : '', blocks, false ); // Remove filter. removeFilter( INSERTING_HOOK_NAME, INSERTING_HOOK_NAMESPACE ); }, [ editPost, postContentBlock, replaceInnerBlocks ] ); const { isWelcomeGuideActive, areTipsEnabled } = selectProps; const hideWelcomeGuide = useCallback( () => { if ( isWelcomeGuideActive ) { // Gutenberg 7.2.0 or higher. toggleFeature( 'welcomeGuide' ); } else if ( areTipsEnabled ) { // Gutenberg 7.1.0 or lower. disableTips(); } }, [ areTipsEnabled, disableTips, isWelcomeGuideActive, toggleFeature ] ); const handleClose = useCallback( () => { setOpenState( 'CLOSED' ); setUsedPageOrPatternsModal?.(); }, [ setOpenState, setUsedPageOrPatternsModal ] ); return ( ); }