diff --git a/docs/reference-guides/data/data-core-block-editor.md b/docs/reference-guides/data/data-core-block-editor.md index 38a93552bcbef..817a9d5400dee 100644 --- a/docs/reference-guides/data/data-core-block-editor.md +++ b/docs/reference-guides/data/data-core-block-editor.md @@ -251,6 +251,19 @@ _Returns_ - `string`: Root client ID +### getBlockImage + +Returns the list of the block images. + +_Parameters_ + +- _state_ `Record`: Current state. +- _clientId_ `string`: Client Id of the block. + +_Returns_ + +- `Record`: Block images. + ### getBlockIndex Returns the index at which the block corresponding to the specified client ID occurs within the block order, or `-1` if the block does not exist. @@ -1638,6 +1651,15 @@ _Returns_ - `Object`: Action object. +### setBlockImage + +Action that sets block image. + +_Parameters_ + +- _clientId_ `string`: A block client ID. +- _images_ `string|string[]`: Block images. + ### setBlockMovingClientId Action that enables or disables the block moving mode. diff --git a/packages/block-editor/src/components/list-view/block-select-button.js b/packages/block-editor/src/components/list-view/block-select-button.js index 6b9de943ea0bf..a1a494b9b0c06 100644 --- a/packages/block-editor/src/components/list-view/block-select-button.js +++ b/packages/block-editor/src/components/list-view/block-select-button.js @@ -291,9 +291,9 @@ function ListViewBlockSelectButton( { images.map( ( image, index ) => ( diff --git a/packages/block-editor/src/components/list-view/use-list-view-images.js b/packages/block-editor/src/components/list-view/use-list-view-images.js index 97633349b6b02..e5011f8031062 100644 --- a/packages/block-editor/src/components/list-view/use-list-view-images.js +++ b/packages/block-editor/src/components/list-view/use-list-view-images.js @@ -12,48 +12,6 @@ import { store as blockEditorStore } from '../../store'; // Maximum number of images to display in a list view row. const MAX_IMAGES = 3; -function getImage( block ) { - if ( block.name !== 'core/image' ) { - return; - } - - if ( block.attributes?.url ) { - return { - url: block.attributes.url, - alt: block.attributes.alt, - clientId: block.clientId, - }; - } -} - -function getImagesFromGallery( block ) { - if ( block.name !== 'core/gallery' || ! block.innerBlocks ) { - return []; - } - - const images = []; - - for ( const innerBlock of block.innerBlocks ) { - const img = getImage( innerBlock ); - if ( img ) { - images.push( img ); - } - if ( images.length >= MAX_IMAGES ) { - return images; - } - } - - return images; -} - -function getImagesFromBlock( block, isExpanded ) { - const img = getImage( block ); - if ( img ) { - return [ img ]; - } - return isExpanded ? [] : getImagesFromGallery( block ); -} - /** * Get a block's preview images for display within a list view row. * @@ -67,17 +25,15 @@ function getImagesFromBlock( block, isExpanded ) { * @return {Array} Images. */ export default function useListViewImages( { clientId, isExpanded } ) { - const { block } = useSelect( + const images = useSelect( ( select ) => { - const _block = select( blockEditorStore ).getBlock( clientId ); - return { block: _block }; + return select( blockEditorStore ).getBlockImage( clientId ) || []; }, [ clientId ] ); - - const images = useMemo( () => { - return getImagesFromBlock( block, isExpanded ); - }, [ block, isExpanded ] ); - - return images; + const filteredImages = useMemo( + () => images.slice( 0, MAX_IMAGES ), + [ images ] + ); + return isExpanded ? [] : filteredImages; } diff --git a/packages/block-editor/src/store/actions.js b/packages/block-editor/src/store/actions.js index b21436161cb8c..ca6acfc2ff0eb 100644 --- a/packages/block-editor/src/store/actions.js +++ b/packages/block-editor/src/store/actions.js @@ -1678,6 +1678,20 @@ export function setBlockVisibility( updates ) { }; } +/** + * Action that sets block image. + * + * @param {string} clientId A block client ID. + * @param {string|string[]} images Block images. + */ +export function setBlockImage( clientId, images ) { + return { + type: 'SET_BLOCK_IMAGE', + images: castArray( images ), + clientId, + }; +} + /** * Action that sets whether a block is being temporaritly edited as blocks. * diff --git a/packages/block-editor/src/store/reducer.js b/packages/block-editor/src/store/reducer.js index 11811afd83f6f..0374437eced14 100644 --- a/packages/block-editor/src/store/reducer.js +++ b/packages/block-editor/src/store/reducer.js @@ -1285,6 +1285,26 @@ export function blockVisibility( state = {}, action ) { return state; } +/** + * Reducer tracking the block images. + * + * @param {Record} state Current state. + * @param {Object} action Dispatched action. + * + * @return {Record} Block images. + */ +export function blockImage( state = {}, action ) { + if ( action.type === 'SET_BLOCK_IMAGE' ) { + const { clientId, images } = action; + return { + ...state, + [ clientId ]: images, + }; + } + + return state; +} + /** * Internal helper reducer for selectionStart and selectionEnd. Can hold a block * selection, represented by an object with property clientId. @@ -2026,6 +2046,7 @@ const combinedReducers = combineReducers( { temporarilyEditingAsBlocks, blockVisibility, blockEditingModes, + blockImage, styleOverrides, removalPromptData, blockRemovalRules, diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index b6d455333c7a5..7d0675232e56f 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -2709,6 +2709,17 @@ export function isBlockVisible( state, clientId ) { return state.blockVisibility?.[ clientId ] ?? true; } +/** + * Returns the list of the block images. + * + * @param {Record} state Current state. + * @param {string} clientId Client Id of the block. + * @return {Record} Block images. + */ +export function getBlockImage( state, clientId ) { + return state?.blockImage?.[ clientId ]; +} + /** * Returns the list of all hidden blocks. * diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 371a13b1bf5ad..c88bff950a8fd 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -91,6 +91,7 @@ function GalleryEdit( props ) { const { columns, imageCrop, linkTarget, linkTo, sizeSlug } = attributes; const { + setBlockImage, __unstableMarkNextChangeAsNotPersistent, replaceInnerBlocks, updateBlockAttributes, @@ -169,6 +170,11 @@ function GalleryEdit( props ) { } ); }, [ newImages ] ); + useEffect( () => { + const imageUrls = images.map( ( { url } ) => url ); + setBlockImage( clientId, imageUrls ); + }, [ images, clientId, setBlockImage ] ); + const imageSizeOptions = useImageSizes( imageData, isSelected, diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index d189af32efcbe..b274edec7f761 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -124,7 +124,7 @@ export function ImageEdit( { captionRef.current = caption; }, [ caption ] ); - const { __unstableMarkNextChangeAsNotPersistent } = + const { setBlockImage, __unstableMarkNextChangeAsNotPersistent } = useDispatch( blockEditorStore ); useEffect( () => { @@ -139,6 +139,10 @@ export function ImageEdit( { } }, [ align ] ); + useEffect( () => { + setBlockImage( clientId, url ); + }, [ url, clientId, setBlockImage ] ); + const ref = useRef(); const { imageDefaultSize, mediaUpload } = useSelect( ( select ) => { const { getSettings } = select( blockEditorStore );