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

Image: Reflect media deletion in the editor #35973

Merged
merged 11 commits into from
Dec 14, 2021
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
58 changes: 50 additions & 8 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.
*/
function isMediaDestroyed( id ) {
const attachment = wp?.media?.attachment( id ) || {};
ramonjd marked this conversation as resolved.
Show resolved Hide resolved
return attachment.destroyed;
}

export function ImageEdit( {
attributes,
setAttributes,
Expand All @@ -109,6 +123,7 @@ export function ImageEdit( {
height,
sizeSlug,
} = attributes;

const [ temporaryURL, setTemporaryURL ] = useState();

const altRef = useRef();
Expand All @@ -127,21 +142,45 @@ export function ImageEdit( {
return pick( getSettings(), [ 'imageDefaultSize', 'mediaUpload' ] );
}, [] );

function clearImageAttributes() {
setAttributes( {
url: undefined,
alt: undefined,
id: undefined,
title: undefined,
caption: undefined,
} );
}

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

/*
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 } ) {
// If the image block was not replaced with an embed,
// clear the attributes and trigger the placeholder.
if ( ! isReplaced ) {
clearImageAttributes();
}
}

function onUploadError( message ) {
noticeOperations.removeAllNotices();
noticeOperations.createErrorNotice( message );
}

function onSelectImage( media ) {
if ( ! media || ! media.url ) {
setAttributes( {
url: undefined,
alt: undefined,
id: undefined,
title: undefined,
caption: undefined,
} );

clearImageAttributes();
return;
}

Expand Down Expand Up @@ -324,6 +363,8 @@ export function ImageEdit( {
containerRef={ ref }
context={ context }
clientId={ clientId }
onCloseModal={ onCloseModal }
onImageLoadError={ onImageError }
/>
) }
{ ! url && (
Expand All @@ -340,6 +381,7 @@ export function ImageEdit( {
onSelectURL={ onSelectURL }
notices={ noticeUI }
onError={ onUploadError }
onClose={ onCloseModal }
accept="image/*"
allowedTypes={ ALLOWED_MEDIA_TYPES }
value={ { id, src } }
Expand Down
14 changes: 12 additions & 2 deletions packages/block-library/src/image/image.js
Original file line number Diff line number Diff line change
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,18 @@ 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 );
}

if ( onImageLoadError ) {
onImageLoadError( { isReplaced: shouldReplace } );
}
}

function onSetHref( props ) {
Expand Down Expand Up @@ -352,6 +361,7 @@ export default function Image( {
onSelect={ onSelectImage }
onSelectURL={ onSelectURL }
onError={ onUploadError }
onCloseModal={ onCloseModal }
/>
</BlockControls>
) }
Expand Down