Skip to content
Closed
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
4 changes: 4 additions & 0 deletions packages/editor/src/components/provider/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import NavigationBlockEditingMode from './navigation-block-editing-mode';
import { useHideBlocksFromInserter } from './use-hide-blocks-from-inserter';
import useCommands from '../commands';
import useUploadSaveLock from './use-upload-save-lock';
import useInvalidateMediaAfterUpload from './use-invalidate-media-after-upload';
import BlockRemovalWarnings from '../block-removal-warnings';
import StartPageOptions from '../start-page-options';
import KeyboardShortcutHelpModal from '../keyboard-shortcut-help-modal';
Expand Down Expand Up @@ -383,6 +384,9 @@ export const ExperimentalEditorProvider = withRegistryProvider(
// Lock post saving when media uploads are in progress (experimental feature).
useUploadSaveLock();

// Invalidate attachment entities after uploads complete so blocks see updated data.
useInvalidateMediaAfterUpload();

if ( ! isReady || ! mode ) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* WordPress dependencies
*/
import { useSelect, useDispatch } from '@wordpress/data';
import { useEffect } from '@wordpress/element';
import { usePrevious } from '@wordpress/compose';
import { store as uploadStore } from '@wordpress/upload-media';
import { store as coreDataStore } from '@wordpress/core-data';

const EMPTY_ARRAY = [];

function getAttachmentIds( items ) {
const ids = new Set();
for ( const item of items ) {
if ( item.attachment?.id ) {
ids.add( item.attachment.id );
}
}
return ids;
}

/**
* After client-side media processing completes, the entity store has stale
* attachment data (empty `media_details.sizes`) because the initial upload
* uses `generate_sub_sizes: false`. This hook watches the upload queue and
* invalidates each attachment's entity record once its item (including any
* sideloads) is removed from the queue, so blocks re-fetch updated data.
*
* When client-side media processing is not enabled, invalidation is handled
* by `receiveEntityRecords` in the `onFileChange` callback of
* `packages/editor/src/utils/media-upload/index.js`.
*/
export default function useInvalidateMediaAfterUpload() {
const items = useSelect( ( select ) => {
if ( ! window.__clientSideMediaProcessing ) {
return EMPTY_ARRAY;
}
return select( uploadStore ).getItems();
}, [] );

const previousItems = usePrevious( items );
const { invalidateResolution } = useDispatch( coreDataStore );

useEffect( () => {
if ( ! window.__clientSideMediaProcessing || ! previousItems ) {
return;
}

const currentIds = getAttachmentIds( items );
const previousIds = getAttachmentIds( previousItems );

for ( const id of previousIds ) {
if ( ! currentIds.has( id ) ) {
// Invalidate with and without the query argument, since
// resolution keys must exactly match the args used by
// each consumer's getEntityRecord() call.
invalidateResolution( 'getEntityRecord', [
'postType',
'attachment',
id,
{ context: 'view' }, // Used by the image block.
] );
invalidateResolution( 'getEntityRecord', [
'postType',
'attachment',
id, // Used by the editor's mediaUpload onFileChange.
] );
}
}
}, [ items, previousItems, invalidateResolution ] );
}
Loading