From db2bbc95bfa7c8ebbc0caffd91105cf1c98e0dc0 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Fri, 29 Dec 2023 18:05:49 +0400 Subject: [PATCH 1/5] Block Library: Introduce the 'useUploadMediaFromBlobURL' utility hook --- packages/block-library/src/utils/hooks.js | 57 +++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/packages/block-library/src/utils/hooks.js b/packages/block-library/src/utils/hooks.js index 4b64c529299467..2c4b40eee98a00 100644 --- a/packages/block-library/src/utils/hooks.js +++ b/packages/block-library/src/utils/hooks.js @@ -2,6 +2,9 @@ * WordPress dependencies */ import { useSelect } from '@wordpress/data'; +import { useLayoutEffect, useEffect, useRef } from '@wordpress/element'; +import { getBlobByURL, isBlobURL, revokeBlobURL } from '@wordpress/blob'; +import { store as blockEditorStore } from '@wordpress/block-editor'; import { store as coreStore } from '@wordpress/core-data'; /** @@ -19,6 +22,54 @@ export function useCanEditEntity( kind, name, recordId ) { ); } -export default { - useCanEditEntity, -}; +/** + * Handles uploading a media file from a blob URL on mount. + * + * @param {Object} args Upload media arguments. + * @param {string} args.url Blob URL. + * @param {?Array} args.allowedTypes Array of allowed media types. + * @param {Function} args.onChange Function called when the media is uploaded. + * @param {Function} args.onError Function called when an error happens. + */ +export function useUploadMediaFromBlobURL( args ) { + const latestArgs = useRef( args ); + const { getSettings } = useSelect( blockEditorStore ); + + useLayoutEffect( () => { + latestArgs.current = args; + } ); + + useEffect( () => { + if ( + ! latestArgs.current.url || + ! isBlobURL( latestArgs.current.url ) + ) { + return; + } + + const file = getBlobByURL( latestArgs.current.url ); + if ( ! file ) { + return; + } + + const { url, allowedTypes, onChange, onError } = latestArgs.current; + const { mediaUpload } = getSettings(); + + mediaUpload( { + filesList: [ file ], + allowedTypes, + onFileChange: ( [ media ] ) => { + if ( isBlobURL( media?.url ) ) { + return; + } + + revokeBlobURL( url ); + onChange( media ); + }, + onError: ( message ) => { + revokeBlobURL( url ); + onError( message ); + }, + } ); + }, [ getSettings ] ); +} From 41923af30cbce5f38bd659a384275bc90d384d01 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Sun, 25 Feb 2024 20:33:22 +0400 Subject: [PATCH 2/5] Update the Audio block --- packages/block-library/src/audio/edit.js | 28 ++++++++---------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/packages/block-library/src/audio/edit.js b/packages/block-library/src/audio/edit.js index b50de773a42ce7..e98f845cb56a73 100644 --- a/packages/block-library/src/audio/edit.js +++ b/packages/block-library/src/audio/edit.js @@ -6,7 +6,7 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { getBlobByURL, isBlobURL } from '@wordpress/blob'; +import { isBlobURL } from '@wordpress/blob'; import { Disabled, PanelBody, @@ -21,11 +21,9 @@ import { MediaPlaceholder, MediaReplaceFlow, useBlockProps, - store as blockEditorStore, } from '@wordpress/block-editor'; -import { useEffect } from '@wordpress/element'; import { __, _x } from '@wordpress/i18n'; -import { useDispatch, useSelect } from '@wordpress/data'; +import { useDispatch } from '@wordpress/data'; import { audio as icon } from '@wordpress/icons'; import { store as noticesStore } from '@wordpress/notices'; @@ -33,6 +31,7 @@ import { store as noticesStore } from '@wordpress/notices'; * Internal dependencies */ import { createUpgradedEmbedBlock } from '../embed/util'; +import { useUploadMediaFromBlobURL } from '../utils/hooks'; import { Caption } from '../utils/caption'; const ALLOWED_MEDIA_TYPES = [ 'audio' ]; @@ -47,22 +46,13 @@ function AudioEdit( { } ) { const { id, autoplay, loop, preload, src } = attributes; const isTemporaryAudio = ! id && isBlobURL( src ); - const { getSettings } = useSelect( blockEditorStore ); - useEffect( () => { - if ( ! id && isBlobURL( src ) ) { - const file = getBlobByURL( src ); - - if ( file ) { - getSettings().mediaUpload( { - filesList: [ file ], - onFileChange: ( [ media ] ) => onSelectAudio( media ), - onError: ( e ) => onUploadError( e ), - allowedTypes: ALLOWED_MEDIA_TYPES, - } ); - } - } - }, [] ); + useUploadMediaFromBlobURL( { + url: src, + allowedTypes: ALLOWED_MEDIA_TYPES, + onChange: onSelectAudio, + onError: onUploadError, + } ); function toggleAttribute( attribute ) { return ( newValue ) => { From 352b395e538f8d4f51c366e7bf08376a47831019 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Sun, 25 Feb 2024 22:20:36 +0400 Subject: [PATCH 3/5] Update the Video block --- packages/block-library/src/utils/hooks.js | 1 - packages/block-library/src/video/edit.js | 26 ++++++++--------------- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/packages/block-library/src/utils/hooks.js b/packages/block-library/src/utils/hooks.js index 2c4b40eee98a00..c53d1d538ac8b4 100644 --- a/packages/block-library/src/utils/hooks.js +++ b/packages/block-library/src/utils/hooks.js @@ -67,7 +67,6 @@ export function useUploadMediaFromBlobURL( args ) { onChange( media ); }, onError: ( message ) => { - revokeBlobURL( url ); onError( message ); }, } ); diff --git a/packages/block-library/src/video/edit.js b/packages/block-library/src/video/edit.js index 60c841b18a9318..65a8e952d4b9b0 100644 --- a/packages/block-library/src/video/edit.js +++ b/packages/block-library/src/video/edit.js @@ -6,7 +6,7 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { getBlobByURL, isBlobURL } from '@wordpress/blob'; +import { isBlobURL } from '@wordpress/blob'; import { BaseControl, Button, @@ -24,12 +24,11 @@ import { MediaUploadCheck, MediaReplaceFlow, useBlockProps, - store as blockEditorStore, } from '@wordpress/block-editor'; import { useRef, useEffect } from '@wordpress/element'; import { __, sprintf } from '@wordpress/i18n'; import { useInstanceId } from '@wordpress/compose'; -import { useDispatch, useSelect } from '@wordpress/data'; +import { useDispatch } from '@wordpress/data'; import { video as icon } from '@wordpress/icons'; import { store as noticesStore } from '@wordpress/notices'; @@ -37,6 +36,7 @@ import { store as noticesStore } from '@wordpress/notices'; * Internal dependencies */ import { createUpgradedEmbedBlock } from '../embed/util'; +import { useUploadMediaFromBlobURL } from '../utils/hooks'; import VideoCommonSettings from './edit-common-settings'; import TracksEditor from './tracks-editor'; import Tracks from './tracks'; @@ -75,21 +75,13 @@ function VideoEdit( { const posterImageButton = useRef(); const { id, controls, poster, src, tracks } = attributes; const isTemporaryVideo = ! id && isBlobURL( src ); - const { getSettings } = useSelect( blockEditorStore ); - useEffect( () => { - if ( ! id && isBlobURL( src ) ) { - const file = getBlobByURL( src ); - if ( file ) { - getSettings().mediaUpload( { - filesList: [ file ], - onFileChange: ( [ media ] ) => onSelectVideo( media ), - onError: onUploadError, - allowedTypes: ALLOWED_MEDIA_TYPES, - } ); - } - } - }, [] ); + useUploadMediaFromBlobURL( { + url: src, + allowedTypes: ALLOWED_MEDIA_TYPES, + onChange: onSelectVideo, + onError: onUploadError, + } ); useEffect( () => { // Placeholder may be rendered. From 1a171ed1d7ab8a36535a901bdb923c4ef9c6cf15 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Sun, 25 Feb 2024 23:58:12 +0400 Subject: [PATCH 4/5] Update the File block --- packages/block-library/src/file/edit.js | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/packages/block-library/src/file/edit.js b/packages/block-library/src/file/edit.js index 528a488039acfd..0ce8e107a0074b 100644 --- a/packages/block-library/src/file/edit.js +++ b/packages/block-library/src/file/edit.js @@ -6,7 +6,7 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { getBlobByURL, isBlobURL, revokeBlobURL } from '@wordpress/blob'; +import { isBlobURL } from '@wordpress/blob'; import { __unstableGetAnimateClassName as getAnimateClassName, ResizableBox, @@ -36,6 +36,7 @@ import { store as noticesStore } from '@wordpress/notices'; import FileBlockInspector from './inspector'; import { browserSupportsPdfs } from './utils'; import removeAnchorTag from '../utils/remove-anchor-tag'; +import { useUploadMediaFromBlobURL } from '../utils/hooks'; export const MIN_PREVIEW_HEIGHT = 200; export const MAX_PREVIEW_HEIGHT = 2000; @@ -72,7 +73,6 @@ function FileEdit( { attributes, isSelected, setAttributes, clientId } ) { displayPreview, previewHeight, } = attributes; - const { getSettings } = useSelect( blockEditorStore ); const { media } = useSelect( ( select ) => ( { media: @@ -86,20 +86,13 @@ function FileEdit( { attributes, isSelected, setAttributes, clientId } ) { const { createErrorNotice } = useDispatch( noticesStore ); const { toggleSelection } = useDispatch( blockEditorStore ); - useEffect( () => { - // Upload a file drag-and-dropped into the editor. - if ( isBlobURL( href ) ) { - const file = getBlobByURL( href ); - - getSettings().mediaUpload( { - filesList: [ file ], - onFileChange: ( [ newMedia ] ) => onSelectFile( newMedia ), - onError: onUploadError, - } ); - - revokeBlobURL( href ); - } + useUploadMediaFromBlobURL( { + url: href, + onChange: onSelectFile, + onError: onUploadError, + } ); + useEffect( () => { if ( RichText.isEmpty( downloadButtonText ) ) { setAttributes( { downloadButtonText: _x( 'Download', 'button label' ), From 658b069a29c928a0e5be00d4ad4c53f41b4728ca Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Sun, 25 Feb 2024 23:59:33 +0400 Subject: [PATCH 5/5] Set default argument --- packages/block-library/src/utils/hooks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/utils/hooks.js b/packages/block-library/src/utils/hooks.js index c53d1d538ac8b4..a89031b5f99ce9 100644 --- a/packages/block-library/src/utils/hooks.js +++ b/packages/block-library/src/utils/hooks.js @@ -31,7 +31,7 @@ export function useCanEditEntity( kind, name, recordId ) { * @param {Function} args.onChange Function called when the media is uploaded. * @param {Function} args.onError Function called when an error happens. */ -export function useUploadMediaFromBlobURL( args ) { +export function useUploadMediaFromBlobURL( args = {} ) { const latestArgs = useRef( args ); const { getSettings } = useSelect( blockEditorStore );