Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move the setting of the default attributes on new blocks to a single useEffect #29328

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 24 additions & 26 deletions packages/block-library/src/gallery/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* External dependencies
*/
import classnames from 'classnames';
import { isEmpty, concat, differenceBy, some, find } from 'lodash';
import { isEmpty, concat, find } from 'lodash';

/**
* WordPress dependencies
Expand All @@ -23,7 +23,6 @@ import {
InspectorControls,
useBlockProps,
} from '@wordpress/block-editor';
import { store as coreStore } from '@wordpress/core-data';
import { Platform, useEffect, useMemo } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import { useSelect, useDispatch } from '@wordpress/data';
Expand Down Expand Up @@ -51,6 +50,8 @@ import {
} from './constants';
import useImageSizes from './use-image-sizes';
import useShortCodeTransform from './use-short-code-transform';
import useGetNewImages from './use-get-new-images';
import useGetMedia from './use-get-media';

const MAX_COLUMNS = 8;
const linkOptions = [
Expand Down Expand Up @@ -122,35 +123,27 @@ function GalleryEdit( props ) {
const images = useMemo(
() =>
innerBlockImages?.map( ( block ) => ( {
clientId: block.clientId,
id: block.attributes.id,
url: block.attributes.url,
attributes: block.attributes,
fromSavedContent: Boolean( block.originalContent ),
} ) ),
[ innerBlockImages ]
);

const imageData = useSelect(
( select ) => {
if (
! innerBlockImages?.length ||
some(
innerBlockImages,
( imageBlock ) => ! imageBlock.attributes.id
)
) {
return imageData;
}
const imageData = useGetMedia( innerBlockImages );

const imageIds = innerBlockImages.map(
( imageBlock ) => imageBlock.attributes.id
);
const newImages = useGetNewImages( images, imageData );

const getMediaItems = select( coreStore ).getMediaItems;

return getMediaItems( { include: imageIds } );
},
[ innerBlockImages ]
);
useEffect( () => {
newImages?.forEach( ( newImage ) => {
updateBlockAttributes( newImage.clientId, {
...buildImageAttributes( false, newImage ),
id: newImage.id,
} );
} );
}, [ newImages ] );

const shortCodeImages = useShortCodeTransform( shortCodeTransforms );

Expand Down Expand Up @@ -241,17 +234,22 @@ function GalleryEdit( props ) {
const existingImageBlocks = ! newFileUploads
? innerBlockImages.filter( ( block ) =>
processedImages.find(
( img ) => img.url === block.attributes.url
( img ) => img.id === block.attributes.id
)
)
: innerBlockImages;

const newImages = differenceBy( processedImages, images, 'url' );
const newImageList = processedImages.filter(
( img ) =>
! existingImageBlocks.find(
( existingImg ) => img.id === existingImg.attributes.id
)
);

const newBlocks = newImages.map( ( image ) => {
const newBlocks = newImageList.map( ( image ) => {
return createBlock( 'core/image', {
...buildImageAttributes( false, image ),
id: image.id,
url: image.url,
} );
} );

Expand Down
55 changes: 55 additions & 0 deletions packages/block-library/src/gallery/use-get-media.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* External dependencies
*/
import { some } from 'lodash';

/**
* WordPress dependencies
*/
import { useState } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';

export default function useGetMedia( innerBlockImages ) {
const [ currentImageMedia, setCurrentImageMedia ] = useState( [] );

const imageMedia = useSelect(
( select ) => {
if (
! innerBlockImages?.length ||
some(
innerBlockImages,
( imageBlock ) => ! imageBlock.attributes.id
)
) {
return currentImageMedia;
}

const imageIds = innerBlockImages.map(
( imageBlock ) => imageBlock.attributes.id
);

if ( imageIds.length === 0 ) {
return currentImageMedia;
}
const getMedia = select( coreStore ).getMedia;
const newImageMedia = imageIds.map( ( img ) => {
return getMedia( img );
} );

if ( newImageMedia.some( ( img ) => ! img ) ) {
return currentImageMedia;
}

return newImageMedia;
},
[ innerBlockImages ]
);

if ( imageMedia?.length !== currentImageMedia.length ) {
setCurrentImageMedia( imageMedia );
return imageMedia;
}

return currentImageMedia;
}
56 changes: 56 additions & 0 deletions packages/block-library/src/gallery/use-get-new-images.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* WordPress dependencies
*/
import { useMemo, useState } from '@wordpress/element';

export default function useGetNewImages( images, imageData ) {
const [ currentImages, setCurrentImages ] = useState( [] );

return useMemo( () => getNewImages(), [ images, imageData ] );

function getNewImages() {
let imagesUpdated = false;

// First lets check if any images have been deleted.
const newCurrentImages = currentImages.filter( ( currentImg ) =>
images.find( ( img ) => {
return currentImg.clientId === img.clientId;
} )
);

if ( newCurrentImages.length < currentImages.length ) {
imagesUpdated = true;
}

// Now lets see if we have any images hydrated from saved content and if so
// add them to currentImages state.
images.forEach( ( image ) => {
if (
image.fromSavedContent &&
! newCurrentImages.find(
( currentImage ) => currentImage.id === image.id
)
) {
imagesUpdated = true;
newCurrentImages.push( image );
}
} );

// Now check for any new images that have been added to InnerBlocks and for which
// we have the imageData we need for setting default block attributes.
const newImages = images.filter(
( image ) =>
! newCurrentImages.find(
( currentImage ) => image.id && currentImage.id === image.id
) &&
imageData?.find( ( img ) => img.id === image.id ) &&
! image.fromSavedConent
);

if ( imagesUpdated || newImages?.length > 0 ) {
setCurrentImages( [ ...newCurrentImages, ...newImages ] );
}

return newImages.length > 0 ? newImages : null;
}
}