Skip to content
Merged
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
15 changes: 14 additions & 1 deletion packages/block-editor/src/components/provider/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { BlockRefsProvider } from './block-refs-provider';
import { unlock } from '../../lock-unlock';
import KeyboardShortcuts from '../keyboard-shortcuts';
import useMediaUploadSettings from './use-media-upload-settings';
import useUploadSaveLock from './use-upload-save-lock';

/** @typedef {import('@wordpress/data').WPDataRegistry} WPDataRegistry */

Expand Down Expand Up @@ -121,7 +122,7 @@ export const ExperimentalBlockEditorProvider = withRegistryProvider(
settings={ mediaUploadSettings }
useSubRegistry={ false }
>
{ children }
<UploadSaveLockWrapper>{ children }</UploadSaveLockWrapper>
</MediaUploadProvider>
);
}
Expand All @@ -130,6 +131,18 @@ export const ExperimentalBlockEditorProvider = withRegistryProvider(
}
);

/**
* Wrapper component that manages post save locks based on upload state.
* Must be rendered inside MediaUploadProvider to access the upload-media store.
*
* @param {Object} props Component props.
* @param {Object} props.children Children elements.
*/
function UploadSaveLockWrapper( { children } ) {
useUploadSaveLock();
return children;
}

export const BlockEditorProvider = ( props ) => {
return (
<ExperimentalBlockEditorProvider { ...props } stripExperimentalSettings>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* WordPress dependencies
*/
import { useSelect, useRegistry } from '@wordpress/data';
import { useEffect } from '@wordpress/element';
import { store as uploadStore } from '@wordpress/upload-media';

const LOCK_NAME = 'upload-in-progress';

/**
* A hook that locks post saving and autosaving while media uploads are in progress.
* This prevents users from publishing or saving while files are still uploading.
*
* Note: This hook dynamically accesses the editor store to avoid creating a
* circular dependency between block-editor and editor packages. The lock
* functionality only activates when the editor store is available.
*/
export default function useUploadSaveLock() {
const registry = useRegistry();

const { isUploading, hasEditorStore } = useSelect( ( select ) => {
// Check if the editor store is registered to avoid errors
// in contexts where it's not available (e.g., standalone block editor).
const stores = registry.stores;
const editorStoreExists = !! stores[ 'core/editor' ];

return {
isUploading: select( uploadStore ).isUploading(),
hasEditorStore: editorStoreExists,
};
}, [] );

useEffect( () => {
if ( ! hasEditorStore ) {
return;
}

const { dispatch } = registry;
const editorDispatch = dispatch( 'core/editor' );

if ( isUploading ) {
editorDispatch.lockPostSaving( LOCK_NAME );
editorDispatch.lockPostAutosaving( LOCK_NAME );
} else {
editorDispatch.unlockPostSaving( LOCK_NAME );
editorDispatch.unlockPostAutosaving( LOCK_NAME );
}
}, [ isUploading, hasEditorStore, registry ] );
}
Loading