Skip to content

Commit ec4c250

Browse files
glendaviesnzGlen Davies
andcommitted
Move the setting of the default attributes on new blocks to a single useEffect (#29328)
Co-authored-by: Glen Davies <glen.davies@a8c.com>
1 parent 9218e39 commit ec4c250

File tree

3 files changed

+135
-26
lines changed

3 files changed

+135
-26
lines changed

packages/block-library/src/gallery/edit.js

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* External dependencies
33
*/
44
import classnames from 'classnames';
5-
import { isEmpty, concat, differenceBy, some, find } from 'lodash';
5+
import { isEmpty, concat, find } from 'lodash';
66

77
/**
88
* WordPress dependencies
@@ -23,7 +23,6 @@ import {
2323
InspectorControls,
2424
useBlockProps,
2525
} from '@wordpress/block-editor';
26-
import { store as coreStore } from '@wordpress/core-data';
2726
import { Platform, useEffect, useMemo } from '@wordpress/element';
2827
import { __, sprintf } from '@wordpress/i18n';
2928
import { useSelect, useDispatch } from '@wordpress/data';
@@ -51,6 +50,8 @@ import {
5150
} from './constants';
5251
import useImageSizes from './use-image-sizes';
5352
import useShortCodeTransform from './use-short-code-transform';
53+
import useGetNewImages from './use-get-new-images';
54+
import useGetMedia from './use-get-media';
5455

5556
const MAX_COLUMNS = 8;
5657
const linkOptions = [
@@ -122,35 +123,27 @@ function GalleryEdit( props ) {
122123
const images = useMemo(
123124
() =>
124125
innerBlockImages?.map( ( block ) => ( {
126+
clientId: block.clientId,
125127
id: block.attributes.id,
126128
url: block.attributes.url,
127129
attributes: block.attributes,
130+
fromSavedContent: Boolean( block.originalContent ),
128131
} ) ),
129132
[ innerBlockImages ]
130133
);
131134

132-
const imageData = useSelect(
133-
( select ) => {
134-
if (
135-
! innerBlockImages?.length ||
136-
some(
137-
innerBlockImages,
138-
( imageBlock ) => ! imageBlock.attributes.id
139-
)
140-
) {
141-
return imageData;
142-
}
135+
const imageData = useGetMedia( innerBlockImages );
143136

144-
const imageIds = innerBlockImages.map(
145-
( imageBlock ) => imageBlock.attributes.id
146-
);
137+
const newImages = useGetNewImages( images, imageData );
147138

148-
const getMediaItems = select( coreStore ).getMediaItems;
149-
150-
return getMediaItems( { include: imageIds } );
151-
},
152-
[ innerBlockImages ]
153-
);
139+
useEffect( () => {
140+
newImages?.forEach( ( newImage ) => {
141+
updateBlockAttributes( newImage.clientId, {
142+
...buildImageAttributes( false, newImage ),
143+
id: newImage.id,
144+
} );
145+
} );
146+
}, [ newImages ] );
154147

155148
const shortCodeImages = useShortCodeTransform( shortCodeTransforms );
156149

@@ -241,17 +234,22 @@ function GalleryEdit( props ) {
241234
const existingImageBlocks = ! newFileUploads
242235
? innerBlockImages.filter( ( block ) =>
243236
processedImages.find(
244-
( img ) => img.url === block.attributes.url
237+
( img ) => img.id === block.attributes.id
245238
)
246239
)
247240
: innerBlockImages;
248241

249-
const newImages = differenceBy( processedImages, images, 'url' );
242+
const newImageList = processedImages.filter(
243+
( img ) =>
244+
! existingImageBlocks.find(
245+
( existingImg ) => img.id === existingImg.attributes.id
246+
)
247+
);
250248

251-
const newBlocks = newImages.map( ( image ) => {
249+
const newBlocks = newImageList.map( ( image ) => {
252250
return createBlock( 'core/image', {
253-
...buildImageAttributes( false, image ),
254251
id: image.id,
252+
url: image.url,
255253
} );
256254
} );
257255

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import { some } from 'lodash';
5+
6+
/**
7+
* WordPress dependencies
8+
*/
9+
import { useState } from '@wordpress/element';
10+
import { useSelect } from '@wordpress/data';
11+
import { store as coreStore } from '@wordpress/core-data';
12+
13+
export default function useGetMedia( innerBlockImages ) {
14+
const [ currentImageMedia, setCurrentImageMedia ] = useState( [] );
15+
16+
const imageMedia = useSelect(
17+
( select ) => {
18+
if (
19+
! innerBlockImages?.length ||
20+
some(
21+
innerBlockImages,
22+
( imageBlock ) => ! imageBlock.attributes.id
23+
)
24+
) {
25+
return currentImageMedia;
26+
}
27+
28+
const imageIds = innerBlockImages.map(
29+
( imageBlock ) => imageBlock.attributes.id
30+
);
31+
32+
if ( imageIds.length === 0 ) {
33+
return currentImageMedia;
34+
}
35+
const getMedia = select( coreStore ).getMedia;
36+
const newImageMedia = imageIds.map( ( img ) => {
37+
return getMedia( img );
38+
} );
39+
40+
if ( newImageMedia.some( ( img ) => ! img ) ) {
41+
return currentImageMedia;
42+
}
43+
44+
return newImageMedia;
45+
},
46+
[ innerBlockImages ]
47+
);
48+
49+
if ( imageMedia?.length !== currentImageMedia.length ) {
50+
setCurrentImageMedia( imageMedia );
51+
return imageMedia;
52+
}
53+
54+
return currentImageMedia;
55+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* WordPress dependencies
3+
*/
4+
import { useMemo, useState } from '@wordpress/element';
5+
6+
export default function useGetNewImages( images, imageData ) {
7+
const [ currentImages, setCurrentImages ] = useState( [] );
8+
9+
return useMemo( () => getNewImages(), [ images, imageData ] );
10+
11+
function getNewImages() {
12+
let imagesUpdated = false;
13+
14+
// First lets check if any images have been deleted.
15+
const newCurrentImages = currentImages.filter( ( currentImg ) =>
16+
images.find( ( img ) => {
17+
return currentImg.clientId === img.clientId;
18+
} )
19+
);
20+
21+
if ( newCurrentImages.length < currentImages.length ) {
22+
imagesUpdated = true;
23+
}
24+
25+
// Now lets see if we have any images hydrated from saved content and if so
26+
// add them to currentImages state.
27+
images.forEach( ( image ) => {
28+
if (
29+
image.fromSavedContent &&
30+
! newCurrentImages.find(
31+
( currentImage ) => currentImage.id === image.id
32+
)
33+
) {
34+
imagesUpdated = true;
35+
newCurrentImages.push( image );
36+
}
37+
} );
38+
39+
// Now check for any new images that have been added to InnerBlocks and for which
40+
// we have the imageData we need for setting default block attributes.
41+
const newImages = images.filter(
42+
( image ) =>
43+
! newCurrentImages.find(
44+
( currentImage ) => image.id && currentImage.id === image.id
45+
) &&
46+
imageData?.find( ( img ) => img.id === image.id ) &&
47+
! image.fromSavedConent
48+
);
49+
50+
if ( imagesUpdated || newImages?.length > 0 ) {
51+
setCurrentImages( [ ...newCurrentImages, ...newImages ] );
52+
}
53+
54+
return newImages.length > 0 ? newImages : null;
55+
}
56+
}

0 commit comments

Comments
 (0)