From dd58d4b95852e8488ecfc60b2eeaf3649dbd2506 Mon Sep 17 00:00:00 2001 From: thelovekesh Date: Mon, 8 Jan 2024 14:00:48 +0530 Subject: [PATCH] Update withMediaLibraryNotice component to use logic from MediaUplod class --- .../components/with-media-library-notice.js | 276 +++++++++--------- 1 file changed, 134 insertions(+), 142 deletions(-) diff --git a/assets/src/block-editor/components/with-media-library-notice.js b/assets/src/block-editor/components/with-media-library-notice.js index 6cf12c91f34..e380d0a5a0b 100644 --- a/assets/src/block-editor/components/with-media-library-notice.js +++ b/assets/src/block-editor/components/with-media-library-notice.js @@ -1,23 +1,12 @@ /** * External dependencies */ -import { isFunction } from 'lodash'; - -/** - * WordPress dependencies - */ -import { dispatch } from '@wordpress/data'; +import { isFunction, get } from 'lodash'; /** * Internal dependencies */ -import { - FeaturedImageToolbarSelect, - getSelectMediaFrame, -} from '../../common/components/select-media-frame'; -import { setImageFromURL } from '../../common/helpers'; - -const { wp } = window; +import { FeaturedImageToolbarSelect } from '../../common/components/select-media-frame'; /** * Gets a wrapped version of MediaUpload to display a notice for small images. @@ -37,146 +26,149 @@ export default (InitialMediaUpload, minImageDimensions) => { minImageDimensions; /** - * Mostly copied from customize-controls.js, with slight changes. + * Prepares the Featured Image toolbars and frames. * - * @see https://github.com/WordPress/wordpress-develop/blob/c80325658f85d24ff82295dd2d55bfdf789f4163/src/js/_enqueues/wp/customize/controls.js#L4695 - * @see wp.media.HeaderControl + * @return {window.wp.media.view.MediaFrame.Select} The default media workflow. */ - return class FeaturedImageMediaUpload extends InitialMediaUpload { - /** - * Constructs the class. - * - * @param {*} args Constructor arguments. - */ - constructor(...args) { - super(...args); - - // @todo This should be a different event. - // This class should only be present in the MediaUpload for the Featured Image. - if ( - 'editor-post-featured-image__media-modal' === - this.props.modalClass - ) { - this.initFeaturedImage = this.initFeaturedImage.bind(this); - this.initFeaturedImage(); - } else { - // Restore the original`onOpen` callback as it will be overridden by the parent class. - this.frame.off('open', this.onOpen); - this.frame.on('open', super.onOpen.bind(this)); - } - } - - /** - * Initialize. - * - * Mainly copied from customize-controls.js, like most of this class. - * - * Overwrites the Media Library frame, this.frame. - * Adds a suggested width and height. - */ - initFeaturedImage() { - const FeaturedImageSelectMediaFrame = getSelectMediaFrame( - FeaturedImageToolbarSelect - ); - - const FeaturedImageLibrary = - wp.media.controller.FeaturedImage.extend({ - defaults: { - ...wp.media.controller.FeaturedImage.prototype.defaults, - date: false, - filterable: false, - // Note: These suggestions are shown in the media library image browser. - suggestedWidth: EXPECTED_WIDTH, - suggestedHeight: EXPECTED_HEIGHT, - }, + const getFeaturedImageMediaFrame = () => { + const { wp } = window; + + return wp.media.view.MediaFrame.Select.extend({ + /** + * Create select toolbar. + * + * The only reason for this method is to override the select toolbar view class. + * + * @param {Object} toolbar + * @param {Object} [options={}] + * @this {wp.media.controller.Region} + */ + createSelectToolbar(toolbar, options) { + options = options || this.options.button || {}; + options.controller = this; + options = { + ...options, + allowedTypes: get(this, ['options', 'allowedTypes'], null), + }; + + toolbar.view = new FeaturedImageToolbarSelect(options); + }, + + /** + * Enables the Set Featured Image Button. + * + * @param {Object} toolbar toolbar for featured image state + * @return {void} + */ + featuredImageToolbar(toolbar) { + this.createSelectToolbar(toolbar, { + text: wp.media.view.l10n.setFeaturedImage, + state: this.options.state, }); - - this.frame = new FeaturedImageSelectMediaFrame({ - allowedTypes: this.props.allowedTypes, - state: 'featured-image', - states: [ - new FeaturedImageLibrary(), - new wp.media.controller.EditImage(), - ], - }); - - this.frame.on( - 'toolbar:create:featured-image', - function (toolbar) { - /** - * @this {wp.media.view.MediaFrame.Select} - */ - this.createSelectToolbar(toolbar, { - text: wp.media.view.l10n.setFeaturedImage, - state: this.options.state, + }, + + /** + * Handle the edit state requirements of selected media item. + * + * @return {void} + */ + editState() { + const selection = this.state('featured-image').get('selection'); + const view = new wp.media.view.EditImage({ + model: selection.single(), + controller: this, + }).render(); + + // Set the view to the EditImage frame using the selected image. + this.content.set(view); + + // After bringing in the frame, load the actual editor via an ajax call. + view.loadEditor(); + }, + + /** + * Create the default states. + * + * @return {void} + */ + createStates: function createStates() { + this.on( + 'toolbar:create:featured-image', + this.featuredImageToolbar, + this + ); + this.on('content:render:edit-image', this.editState, this); + + const FeaturedImageLibrary = + wp.media.controller.FeaturedImage.extend({ + defaults: { + ...wp.media.controller.FeaturedImage.prototype + .defaults, + date: false, + filterable: false, + // Note: These suggestions are shown in the media library image browser. + suggestedWidth: EXPECTED_WIDTH, + suggestedHeight: EXPECTED_HEIGHT, + }, }); - }, - this.frame - ); - this.frame.on('open', this.onOpen); - - this.frame - .state('featured-image') - .on('select', this.onSelectImage, this); + this.states.add([ + new FeaturedImageLibrary(), + new wp.media.controller.EditImage({ + model: this.options.editImage, + }), + ]); + }, + }); + }; - // See wp.media() for this. - wp.media.frame = this.frame; - } + /** + * Get attachment collection. + * + * @param {Array} ids Attachment IDs. + * @return {Object} The attachment collection. + */ + const getAttachmentsCollection = (ids) => { + const { wp } = window; + + return wp.media.query({ + order: 'ASC', + orderby: 'post__in', + post__in: ids, + posts_per_page: -1, + query: true, + type: 'image', + }); + }; + /** + * Extends the MediaUpload component to display a notice for small images. + */ + return class FeaturedImageMediaUpload extends InitialMediaUpload { /** - * Ensure the selected image is the first item in the collection. + * Initializes the Media Library requirements for the featured image flow. * - * @see https://github.com/WordPress/gutenberg/blob/c58b32266f8c950c5b9927d286608343078aee02/packages/media-utils/src/components/media-upload/index.js#L401-L417 - */ - onOpen() { - const frameContent = this.frame.content.get(); - if (frameContent && frameContent.collection) { - const collection = frameContent.collection; - - // Clean all attachments we have in memory. - collection - .toArray() - .forEach((model) => model.trigger('destroy', model)); - - // Reset has more flag, if library had small amount of items all items may have been loaded before. - collection.mirroring._hasMore = true; - - // Request items. - collection.more(); - } - } - - /** - * Handles image selection. + * @override + * @description Overrides the media upload component's initialize method for featured image. + * @see {@link https://github.com/WordPress/gutenberg/blob/debddee2ace15263c08c66b5f5a43a9e17bf5d0c/packages/media-utils/src/components/media-upload/index.js#L301} Original MediaUpload buildAndSetFeatureImageFrame method. + * + * @return {void} */ - onSelectImage() { - const attachment = this.frame - .state('featured-image') - .get('selection') - .first() - .toJSON(); - const dispatchImage = (attachmentId) => { - dispatch('core/editor').editPost({ - featured_media: attachmentId, - }); - }; - const { onSelect } = this.props; - const { url, id, width, height } = attachment; - setImageFromURL({ - url, - id, - width, - height, - onSelect, - dispatchImage, + buildAndSetFeatureImageFrame() { + const { wp } = window; + const featuredImageFrame = getFeaturedImageMediaFrame(); + const attachments = getAttachmentsCollection(this.props.value); + const selection = new wp.media.model.Selection(attachments.models, { + props: attachments.props.toJSON(), }); - - if (!wp.media.view.settings.post.featuredImageId) { - return; - } - - wp.media.featuredImage.set(attachment ? attachment.id : -1); + this.frame = new featuredImageFrame({ + mimeType: this.props.allowedTypes, + state: 'featured-image', + multiple: this.props.multiple, + selection, + editing: this.props.value ? true : false, + }); + wp.media.frame = this.frame; } }; };