Skip to content

Commit

Permalink
Image: Reflect media deletion in the editor (#35973)
Browse files Browse the repository at this point in the history
* initial commit. listening out for changes to the attachments collection and passing to onRemove prop.

* Removing console.log

* Reverting component changes

* Adding a store to media utils

* Rolling back historical experimental commits.
Now relying on the `onClose` event of the media upload, and the media object to test if the media has been "destroyed."

* Testing setting a temporary media object so we can keep track of uploaded media

* Winding this back to check if an image exists when the editor loads.
This removes the `isSelected` check, but also removes a bunch of code as well.
We could run the same check on `isSelected`... TBC

* Removed the onerror listener and relying on the error handler already added to the Image props

* Fixed grammatical mistake.

* Check if the media has been destroyed when the image is selected

* Only delete image source URL and ID when detecting a destroyed image. That way the caption, title and alt values persist in case the user deletes, then replaces.
  • Loading branch information
ramonjd authored Dec 14, 2021
1 parent 07fb2b7 commit ee07bbf
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export function MediaPlaceholder( {
onDoubleClick,
onFilesPreUpload = noop,
onHTMLDrop = noop,
onClose = noop,
children,
mediaLibraryButton,
placeholder,
Expand Down Expand Up @@ -328,6 +329,7 @@ export function MediaPlaceholder( {
gallery={ multiple && onlyAllowsImages() }
multiple={ multiple }
onSelect={ onSelect }
onClose={ onClose }
allowedTypes={ allowedTypes }
value={
Array.isArray( value )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const MediaReplaceFlow = ( {
onSelect,
onSelectURL,
onFilesUpload = noop,
onCloseModal = noop,
name = __( 'Replace' ),
createNotice,
removeNotice,
Expand Down Expand Up @@ -136,6 +137,7 @@ const MediaReplaceFlow = ( {
value={ mediaId }
onSelect={ ( media ) => selectMedia( media ) }
allowedTypes={ allowedTypes }
onClose={ onCloseModal }
render={ ( { open } ) => (
<MenuItem icon={ mediaIcon } onClick={ open }>
{ __( 'Open Media Library' ) }
Expand Down
44 changes: 44 additions & 0 deletions packages/block-library/src/image/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,20 @@ function hasDefaultSize( image, defaultSize ) {
);
}

/**
* Checks if a media attachment object has been "destroyed",
* that is, removed from the media library. The core Media Library
* adds a `destroyed` property to a deleted attachment object in the media collection.
*
* @param {number} id The attachment id.
*
* @return {boolean} Whether the image has been destroyed.
*/
export function isMediaDestroyed( id ) {
const attachment = wp?.media?.attachment( id ) || {};
return attachment.destroyed;
}

export function ImageEdit( {
attributes,
setAttributes,
Expand Down Expand Up @@ -127,6 +141,33 @@ export function ImageEdit( {
return pick( getSettings(), [ 'imageDefaultSize', 'mediaUpload' ] );
}, [] );

// A callback passed to MediaUpload,
// fired when the media modal closes.
function onCloseModal() {
if ( isMediaDestroyed( attributes?.id ) ) {
setAttributes( {
url: undefined,
id: undefined,
} );
}
}

/*
Runs an error callback if the image does not load.
If the error callback is triggered, we infer that that image
has been deleted.
*/
function onImageError( isReplaced = false ) {
// If the image block was not replaced with an embed,
// clear the attributes and trigger the placeholder.
if ( ! isReplaced ) {
setAttributes( {
url: undefined,
id: undefined,
} );
}
}

function onUploadError( message ) {
noticeOperations.removeAllNotices();
noticeOperations.createErrorNotice( message );
Expand Down Expand Up @@ -324,6 +365,8 @@ export function ImageEdit( {
containerRef={ ref }
context={ context }
clientId={ clientId }
onCloseModal={ onCloseModal }
onImageLoadError={ onImageError }
/>
) }
{ ! url && (
Expand All @@ -340,6 +383,7 @@ export function ImageEdit( {
onSelectURL={ onSelectURL }
notices={ noticeUI }
onError={ onUploadError }
onClose={ onCloseModal }
accept="image/*"
allowedTypes={ ALLOWED_MEDIA_TYPES }
value={ { id, src } }
Expand Down
17 changes: 14 additions & 3 deletions packages/block-library/src/image/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import { store as coreStore } from '@wordpress/core-data';
*/
import { createUpgradedEmbedBlock } from '../embed/util';
import useClientWidth from './use-client-width';
import { isExternalImage } from './edit';
import { isExternalImage, isMediaDestroyed } from './edit';

/**
* Module constants
Expand Down Expand Up @@ -72,12 +72,14 @@ export default function Image( {
isSelected,
insertBlocksAfter,
onReplace,
onCloseModal,
onSelectImage,
onSelectURL,
onUploadError,
containerRef,
context,
clientId,
onImageLoadError,
} ) {
const imageRef = useRef();
const captionRef = useRef();
Expand Down Expand Up @@ -213,11 +215,16 @@ export default function Image( {
}

function onImageError() {
// Check if there's an embed block that handles this URL.
// Check if there's an embed block that handles this URL, e.g., instagram URL.
// See: https://github.com/WordPress/gutenberg/pull/11472
const embedBlock = createUpgradedEmbedBlock( { attributes: { url } } );
if ( undefined !== embedBlock ) {
const shouldReplace = undefined !== embedBlock;

if ( shouldReplace ) {
onReplace( embedBlock );
}

onImageLoadError( shouldReplace );
}

function onSetHref( props ) {
Expand Down Expand Up @@ -289,6 +296,9 @@ export default function Image( {
if ( ! isSelected ) {
setIsEditingImage( false );
}
if ( isSelected && isMediaDestroyed( id ) ) {
onImageLoadError();
}
}, [ isSelected ] );

const canEditImage = id && naturalWidth && naturalHeight && imageEditing;
Expand Down Expand Up @@ -352,6 +362,7 @@ export default function Image( {
onSelect={ onSelectImage }
onSelectURL={ onSelectURL }
onError={ onUploadError }
onCloseModal={ onCloseModal }
/>
</BlockControls>
) }
Expand Down

0 comments on commit ee07bbf

Please sign in to comment.