From e2386c5d4aea564a1e03d90be88ea578afe7c25b Mon Sep 17 00:00:00 2001 From: Addison Stavlo Date: Fri, 8 May 2020 16:12:42 -0400 Subject: [PATCH] Gallery block / media-placeholder - Preserve changes made while upload in progress. (#19134) * added optional prop to pass by reference instead of value * currentValue updated on adding/removing * comment update * fixed multiple upload bug * removed stuff for trying to keep loaders that werent part of the upload group * updates comments and naming * updated galleryValue to fallback to empty array * renamed values to be more semantic * removed dynamicAlteration prop * refactored to compare last pass of newMedia * added comments, changed variable name * simplified setting lastMediaPassed * compare via includes instead * added id check as first priority in filter * edited comments * rebased * changed to soft equal for int/string ID comparison * added unchanging reference for image array * re-added fallback value for currentMedia, fixed linter == problem * updated comment * re-added addToGallery check, forced 'true' for our gallery * refactored to use a getValue instead * updated comment * Remove getValue and use a reference to this.props.value * comment update Co-authored-by: Jorge --- .../src/components/media-placeholder/index.js | 42 +++++++++++++++++-- packages/block-library/src/gallery/edit.js | 5 +-- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/packages/block-editor/src/components/media-placeholder/index.js b/packages/block-editor/src/components/media-placeholder/index.js index 505464b7264b2e..5e62dfd47ea782 100644 --- a/packages/block-editor/src/components/media-placeholder/index.js +++ b/packages/block-editor/src/components/media-placeholder/index.js @@ -116,14 +116,50 @@ export class MediaPlaceholder extends Component { multiple, onError, onSelect, - value = [], } = this.props; let setMedia; if ( multiple ) { if ( addToGallery ) { - const currentValue = value; + // To allow changes to a gallery to be made while uploads are in progress + // (including trigging multiple upload groups and removing already in place images), + // we must be able to add newMedia based on the current value of the Gallery + // whenever the setMedia function runs (not destructuring 'value' from props). + // Additionally, since the setMedia function runs multiple times per upload group + // and is passed newMedia containing every item in its group each time, we must + // also filter out whatever this upload group had previously returned to the + // gallery before adding and returning the image array with replacement newMedia + // values. + + // Define an array to store urls from newMedia between subsequent function calls. + let lastMediaPassed = []; setMedia = ( newMedia ) => { - onSelect( currentValue.concat( newMedia ) ); + // Remove any images this upload group is responsible for (lastMediaPassed). + // Their replacements are contained in newMedia. + const filteredMedia = ( this.props.value || [] ).filter( + ( item ) => { + // If Item has id, only remove it if lastMediaPassed has an item with that id. + if ( item.id ) { + return ! lastMediaPassed.some( + // Be sure to convert to number for comparison. + ( { id } ) => + Number( id ) === Number( item.id ) + ); + } + // Compare transient images via .includes since gallery may append extra info onto the url. + return ! lastMediaPassed.some( ( { urlSlug } ) => + item.url.includes( urlSlug ) + ); + } + ); + // Return the filtered media array along with newMedia. + onSelect( filteredMedia.concat( newMedia ) ); + // Reset lastMediaPassed and set it with ids and urls from newMedia. + lastMediaPassed = newMedia.map( ( media ) => { + // Add everything up to '.fileType' to compare via .includes. + const cutOffIndex = media.url.lastIndexOf( '.' ); + const urlSlug = media.url.slice( 0, cutOffIndex ); + return { id: media.id, urlSlug }; + } ); }; } else { setMedia = onSelect; diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 3f77212f71990a..cac649205b0b72 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -355,11 +355,10 @@ class GalleryEdit extends Component { } = attributes; const hasImages = !! images.length; - const hasImagesWithId = hasImages && some( images, ( { id } ) => id ); const mediaPlaceholder = (