diff --git a/packages/media-utils/src/components/media-upload/index.js b/packages/media-utils/src/components/media-upload/index.js index 91de011869ad38..ed0a59ddbc684a 100644 --- a/packages/media-utils/src/components/media-upload/index.js +++ b/packages/media-utils/src/components/media-upload/index.js @@ -70,6 +70,46 @@ const getFeaturedImageMediaFrame = () => { } ); }; +/** + * Prepares the default frame for selecting a single media item. + * + * @return {window.wp.media.view.MediaFrame.Select} The default media workflow. + */ +const getSingleMediaFrame = () => { + const { wp } = window; + + // Extend the default Select frame, and use the same `createStates` method as in core, + // but with the addition of `filterable: 'uploaded'` to the Library state, so that + // the user can filter the media library by uploaded media. + return wp.media.view.MediaFrame.Select.extend( { + /** + * Create the default states on the frame. + */ + createStates() { + const options = this.options; + + if ( this.options.states ) { + return; + } + + // Add the default states. + this.states.add( [ + // Main states. + new wp.media.controller.Library( { + library: wp.media.query( options.library ), + multiple: options.multiple, + title: options.title, + priority: 20, + filterable: 'uploaded', // Allow filtering by uploaded images. + } ), + new wp.media.controller.EditImage( { + model: options.editImage, + } ), + ] ); + }, + } ); +}; + /** * Prepares the Gallery toolbars and frames. * @@ -324,6 +364,47 @@ class MediaUpload extends Component { }; } + /** + * Initializes the Media Library requirements for the single image flow. + * + * @return {void} + */ + buildAndSetSingleMediaFrame() { + const { wp } = window; + const { + allowedTypes, + multiple = false, + title = __( 'Select or Upload Media' ), + value, + } = this.props; + + const frameConfig = { + title, + multiple, + }; + if ( !! allowedTypes ) { + frameConfig.library = { type: allowedTypes }; + } + + // If a frame already exists, remove it. + if ( this.frame ) { + this.frame.remove(); + } + + const singleImageFrame = getSingleMediaFrame(); + const attachments = getAttachmentsCollection( value ); + const selection = new wp.media.model.Selection( attachments.models, { + props: attachments.props.toJSON(), + } ); + this.frame = new singleImageFrame( { + mimeType: allowedTypes, + multiple, + selection, + ...frameConfig, + } ); + wp.media.frame = this.frame; + } + componentWillUnmount() { this.frame?.remove(); } @@ -424,27 +505,15 @@ class MediaUpload extends Component { openModal() { const { - allowedTypes, gallery = false, unstableFeaturedImageFlow = false, modalClass, - multiple = false, - title = __( 'Select or Upload Media' ), } = this.props; - const { wp } = window; if ( gallery ) { this.buildAndSetGalleryFrame(); } else { - const frameConfig = { - title, - multiple, - }; - if ( !! allowedTypes ) { - frameConfig.library = { type: allowedTypes }; - } - - this.frame = wp.media( frameConfig ); + this.buildAndSetSingleMediaFrame(); } if ( modalClass ) {