Skip to content

Commit

Permalink
Try integrating unsynced patterns directly into pattern selectors (#5…
Browse files Browse the repository at this point in the history
  • Loading branch information
talldan committed Jun 28, 2023
1 parent d42efb2 commit dfbb15d
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* WordPress dependencies
*/
import { useCallback, useMemo } from '@wordpress/element';
import { cloneBlock, parse } from '@wordpress/blocks';
import { cloneBlock } from '@wordpress/blocks';
import { useDispatch, useSelect } from '@wordpress/data';
import { __, sprintf } from '@wordpress/i18n';
import { store as noticesStore } from '@wordpress/notices';
Expand All @@ -12,6 +12,12 @@ import { store as noticesStore } from '@wordpress/notices';
*/
import { store as blockEditorStore } from '../../../store';

const CUSTOM_CATEGORY = {
name: 'custom',
label: __( 'Custom patterns' ),
description: __( 'Custom patterns add by site users' ),
};

/**
* Retrieves the block patterns inserter state.
*
Expand All @@ -21,45 +27,24 @@ import { store as blockEditorStore } from '../../../store';
* @return {Array} Returns the patterns state. (patterns, categories, onSelect handler)
*/
const usePatternsState = ( onInsert, rootClientId ) => {
const { patternCategories, patterns, unsyncedPatterns } = useSelect(
const { patternCategories, patterns } = useSelect(
( select ) => {
const {
__experimentalGetAllowedPatterns,
getSettings,
getInserterItems,
} = select( blockEditorStore );
const { __experimentalGetAllowedPatterns, getSettings } =
select( blockEditorStore );

return {
patterns: __experimentalGetAllowedPatterns( rootClientId ),
patternCategories:
getSettings().__experimentalBlockPatternCategories,
unsyncedPatterns: getInserterItems( rootClientId, 'unsynced' ),
};
},
[ rootClientId ]
);

const allPatterns = useMemo( () => {
const parsedUnsyncedPatterns = unsyncedPatterns.map(
( syncedPattern ) => ( {
title: syncedPattern.title,
name: syncedPattern.id,
categories: [ 'custom' ],
blocks: parse( syncedPattern.content, {
__unstableSkipMigrationLogs: true,
} ),
} )
);
return [ ...patterns, ...parsedUnsyncedPatterns ];
}, [ unsyncedPatterns, patterns ] );

const allCategories = useMemo( () => {
const customPatternsCategory = {
name: 'custom',
label: __( 'Custom patterns' ),
description: __( 'Custom patterns add by site users' ),
};
return [ ...patternCategories, customPatternsCategory ];
}, [ patternCategories ] );
const allCategories = useMemo(
() => [ ...patternCategories, CUSTOM_CATEGORY ],
[ patternCategories ]
);

const { createSuccessNotice } = useDispatch( noticesStore );
const onClickPattern = useCallback(
Expand All @@ -82,7 +67,7 @@ const usePatternsState = ( onInsert, rootClientId ) => {
[ createSuccessNotice, onInsert ]
);

return [ allPatterns, allCategories, onClickPattern ];
return [ patterns, allCategories, onClickPattern ];
};

export default usePatternsState;
54 changes: 40 additions & 14 deletions packages/block-editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1945,7 +1945,6 @@ const buildBlockTypeItem =
*
* @param {Object} state Editor state.
* @param {?string} rootClientId Optional root client ID of block list.
* @param {?string} syncStatus Optional sync status to filter pattern blocks by.
*
* @return {WPEditorInserterItem[]} Items that appear in inserter.
*
Expand All @@ -1962,7 +1961,7 @@ const buildBlockTypeItem =
* @property {number} frecency Heuristic that combines frequency and recency.
*/
export const getInserterItems = createSelector(
( state, rootClientId = null, syncStatus ) => {
( state, rootClientId = null ) => {
/*
* Matches block comment delimiters amid serialized content.
*
Expand Down Expand Up @@ -2027,25 +2026,22 @@ export const getInserterItems = createSelector(
};
};

const reusableBlockInserterItems = canInsertBlockTypeUnmemoized(
const syncedPatternInserterItems = canInsertBlockTypeUnmemoized(
state,
'core/block',
rootClientId
)
? getReusableBlocks( state )
.filter(
( reusableBlock ) =>
syncStatus === reusableBlock.meta?.sync_status ||
( ! syncStatus &&
reusableBlock.meta?.sync_status === '' )
// Filter to either fully synced patterns (sync_status === 'fully'),
// or old school reusable blocks (sync_status === '').
reusableBlock.meta?.sync_status === 'fully' ||
reusableBlock.meta?.sync_status === ''
)
.map( buildReusableBlockInserterItem )
: [];

if ( syncStatus === 'unsynced' ) {
return reusableBlockInserterItems;
}

const buildBlockTypeInserterItem = buildBlockTypeItem( state, {
buildScope: 'inserter',
} );
Expand Down Expand Up @@ -2086,7 +2082,7 @@ export const getInserterItems = createSelector(
{ core: [], noncore: [] }
);
const sortedBlockTypes = [ ...coreItems, ...nonCoreItems ];
return [ ...sortedBlockTypes, ...reusableBlockInserterItems ];
return [ ...sortedBlockTypes, ...syncedPatternInserterItems ];
},
( state, rootClientId ) => [
state.blockListSettings[ rootClientId ],
Expand Down Expand Up @@ -2310,10 +2306,32 @@ const checkAllowListRecursive = ( blocks, allowedBlockTypes ) => {
return true;
};

function getUnsyncedPatterns( state ) {
const reusableBlocks =
state?.settings?.__experimentalReusableBlocks ?? EMPTY_ARRAY;

return reusableBlocks
.filter(
( reusableBlock ) => reusableBlock.meta?.sync_status === 'unsynced'
)
.map( ( reusableBlock ) => {
return {
name: `core/block/${ reusableBlock.id }`,
title: reusableBlock.title.raw,
categories: [ 'custom' ],
content: reusableBlock.content.raw,
};
} );
}

export const __experimentalGetParsedPattern = createSelector(
( state, patternName ) => {
const patterns = state.settings.__experimentalBlockPatterns;
const pattern = patterns.find( ( { name } ) => name === patternName );
const unsyncedPatterns = getUnsyncedPatterns( state );

const pattern = [ ...patterns, ...unsyncedPatterns ].find(
( { name } ) => name === patternName
);
if ( ! pattern ) {
return null;
}
Expand All @@ -2324,14 +2342,20 @@ export const __experimentalGetParsedPattern = createSelector(
} ),
};
},
( state ) => [ state.settings.__experimentalBlockPatterns ]
( state ) => [
state.settings.__experimentalBlockPatterns,
state.settings.__experimentalReusableBlocks,
]
);

const getAllAllowedPatterns = createSelector(
( state ) => {
const patterns = state.settings.__experimentalBlockPatterns;
const unsyncedPatterns = getUnsyncedPatterns( state );

const { allowedBlockTypes } = getSettings( state );
const parsedPatterns = patterns

const parsedPatterns = [ ...patterns, ...unsyncedPatterns ]
.filter( ( { inserter = true } ) => !! inserter )
.map( ( { name } ) =>
__experimentalGetParsedPattern( state, name )
Expand All @@ -2343,6 +2367,7 @@ const getAllAllowedPatterns = createSelector(
},
( state ) => [
state.settings.__experimentalBlockPatterns,
state.settings.__experimentalReusableBlocks,
state.settings.allowedBlockTypes,
]
);
Expand All @@ -2369,6 +2394,7 @@ export const __experimentalGetAllowedPatterns = createSelector(
},
( state, rootClientId ) => [
state.settings.__experimentalBlockPatterns,
state.settings.__experimentalReusableBlocks,
state.settings.allowedBlockTypes,
state.settings.templateLock,
state.blockListSettings[ rootClientId ],
Expand Down

0 comments on commit dfbb15d

Please sign in to comment.