Skip to content

Commit

Permalink
Pattern block: avoid fetching all reusable blocks on mount (#60310)
Browse files Browse the repository at this point in the history
Co-authored-by: ellatrix <[email protected]>
Co-authored-by: jsnajdr <[email protected]>
  • Loading branch information
3 people authored Apr 11, 2024
1 parent 05926aa commit c75c5bd
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 58 deletions.
103 changes: 74 additions & 29 deletions packages/block-editor/src/store/private-selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,38 +290,83 @@ export const hasAllowedPatterns = createRegistrySelector( ( select ) =>
)
);

function mapUserPattern(
userPattern,
__experimentalUserPatternCategories = []
) {
return {
name: `core/block/${ userPattern.id }`,
id: userPattern.id,
type: INSERTER_PATTERN_TYPES.user,
title: userPattern.title.raw,
categories: userPattern.wp_pattern_category.map( ( catId ) => {
const category = __experimentalUserPatternCategories.find(
( { id } ) => id === catId
);
return category ? category.slug : catId;
} ),
content: userPattern.content.raw,
syncStatus: userPattern.wp_pattern_sync_status,
};
}

export const getPatternBySlug = createRegistrySelector( ( select ) =>
createSelector(
( state, patternName ) => {
// Only fetch reusable blocks if we know we need them. To do: maybe
// use the entity record API to retrieve the block by slug.
if ( patternName?.startsWith( 'core/block/' ) ) {
const _id = parseInt(
patternName.slice( 'core/block/'.length ),
10
);
const block = unlock( select( STORE_NAME ) )
.getReusableBlocks()
.find( ( { id } ) => id === _id );

if ( ! block ) {
return null;
}

return mapUserPattern(
block,
state.settings.__experimentalUserPatternCategories
);
}

return [
// This setting is left for back compat.
...( state.settings.__experimentalBlockPatterns ?? [] ),
...( state.settings[ selectBlockPatternsKey ]?.( select ) ??
[] ),
].find( ( { name } ) => name === patternName );
},
( state, patternName ) =>
patternName?.startsWith( 'core/block/' )
? [
unlock( select( STORE_NAME ) ).getReusableBlocks(),
state.settings.__experimentalReusableBlocks,
]
: [
state.settings.__experimentalBlockPatterns,
state.settings[ selectBlockPatternsKey ]?.( select ),
]
)
);

export const getAllPatterns = createRegistrySelector( ( select ) =>
createSelector( ( state ) => {
// This setting is left for back compat.
const {
__experimentalBlockPatterns = [],
__experimentalUserPatternCategories = [],
__experimentalReusableBlocks = [],
} = state.settings;
const reusableBlocksSelect = state.settings[ reusableBlocksSelectKey ];
const userPatterns = (
reusableBlocksSelect
? reusableBlocksSelect( select )
: __experimentalReusableBlocks ?? []
).map( ( userPattern ) => {
return {
name: `core/block/${ userPattern.id }`,
id: userPattern.id,
type: INSERTER_PATTERN_TYPES.user,
title: userPattern.title.raw,
categories: userPattern.wp_pattern_category.map( ( catId ) => {
const category = (
__experimentalUserPatternCategories ?? []
).find( ( { id } ) => id === catId );
return category ? category.slug : catId;
} ),
content: userPattern.content.raw,
syncStatus: userPattern.wp_pattern_sync_status,
};
} );
return [
...userPatterns,
...__experimentalBlockPatterns,
...unlock( select( STORE_NAME ) )
.getReusableBlocks()
.map( ( userPattern ) =>
mapUserPattern(
userPattern,
state.settings.__experimentalUserPatternCategories
)
),
// This setting is left for back compat.
...( state.settings.__experimentalBlockPatterns ?? [] ),
...( state.settings[ selectBlockPatternsKey ]?.( select ) ?? [] ),
].filter(
( x, index, arr ) =>
Expand Down
61 changes: 32 additions & 29 deletions packages/block-editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -2280,36 +2280,39 @@ export function __experimentalGetDirectInsertBlock(

export const __experimentalGetParsedPattern = createRegistrySelector(
( select ) =>
createSelector( ( state, patternName ) => {
const { getAllPatterns } = unlock( select( STORE_NAME ) );
const patterns = getAllPatterns();
const pattern = patterns.find(
( { name } ) => name === patternName
);
if ( ! pattern ) {
return null;
}
const blocks = parse( pattern.content, {
__unstableSkipMigrationLogs: true,
} );
if ( blocks.length === 1 ) {
blocks[ 0 ].attributes = {
...blocks[ 0 ].attributes,
metadata: {
...( blocks[ 0 ].attributes.metadata || {} ),
categories: pattern.categories,
patternName: pattern.name,
name:
blocks[ 0 ].attributes.metadata?.name ||
pattern.title,
},
createSelector(
( state, patternName ) => {
const pattern = unlock( select( STORE_NAME ) ).getPatternBySlug(
patternName
);
if ( ! pattern ) {
return null;
}
const blocks = parse( pattern.content, {
__unstableSkipMigrationLogs: true,
} );
if ( blocks.length === 1 ) {
blocks[ 0 ].attributes = {
...blocks[ 0 ].attributes,
metadata: {
...( blocks[ 0 ].attributes.metadata || {} ),
categories: pattern.categories,
patternName: pattern.name,
name:
blocks[ 0 ].attributes.metadata?.name ||
pattern.title,
},
};
}
return {
...pattern,
blocks,
};
}
return {
...pattern,
blocks,
};
}, getAllPatternsDependants( select ) )
},
( state, patternName ) => [
unlock( select( STORE_NAME ) ).getPatternBySlug( patternName ),
]
)
);

const getAllowedPatternsDependants = ( select ) => ( state, rootClientId ) => [
Expand Down

0 comments on commit c75c5bd

Please sign in to comment.