From c07f8cefeea266a4e449d0b0d250d673c8f8b8cd Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Sat, 28 Sep 2024 20:58:09 +0200 Subject: [PATCH 1/3] Openverse: prevent multiple insertions during upload --- .../inserter/media-tab/media-preview.js | 39 ++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/packages/block-editor/src/components/inserter/media-tab/media-preview.js b/packages/block-editor/src/components/inserter/media-tab/media-preview.js index 070a850d430cca..44c7fbcb14a374 100644 --- a/packages/block-editor/src/components/inserter/media-tab/media-preview.js +++ b/packages/block-editor/src/components/inserter/media-tab/media-preview.js @@ -20,7 +20,7 @@ import { __experimentalVStack as VStack, } from '@wordpress/components'; import { __, sprintf } from '@wordpress/i18n'; -import { useMemo, useCallback, useState } from '@wordpress/element'; +import { useMemo, useCallback, useState, useRef } from '@wordpress/element'; import { cloneBlock } from '@wordpress/blocks'; import { moreVertical, external } from '@wordpress/icons'; import { useSelect, useDispatch } from '@wordpress/data'; @@ -127,6 +127,7 @@ export function MediaPreview( { media, onClick, category } ) { useState( false ); const [ isHovered, setIsHovered ] = useState( false ); const [ isInserting, setIsInserting ] = useState( false ); + const hasInsertedBlock = useRef( false ); const [ block, preview ] = useMemo( () => getBlockAndPreviewFromMedia( media, category.mediaType ), [ media, category.mediaType ] @@ -134,6 +135,7 @@ export function MediaPreview( { media, onClick, category } ) { const { createErrorNotice, createSuccessNotice } = useDispatch( noticesStore ); const { getSettings } = useSelect( blockEditorStore ); + const { updateBlockAttributes } = useDispatch( blockEditorStore ); const onMediaInsert = useCallback( ( previewBlock ) => { @@ -180,18 +182,34 @@ export function MediaPreview( { media, onClick, category } ) { if ( isBlobURL( img.url ) ) { return; } - onClick( { - ...clonedBlock, - attributes: { + + if ( ! hasInsertedBlock.current ) { + // Ensure the block is only inserted once. + onClick( { + ...clonedBlock, + attributes: { + ...clonedBlock.attributes, + id: img.id, + url: img.url, + }, + } ); + + // TODO: Move to a new onSuccess callback as part of #61447. + createSuccessNotice( + __( 'Image uploaded and inserted.' ), + { type: 'snackbar', id: 'inserter-notice' } + ); + + hasInsertedBlock.current = true; + } else { + // For subsequent calls, update the existing block. + updateBlockAttributes( clonedBlock.clientId, { ...clonedBlock.attributes, id: img.id, url: img.url, - }, - } ); - createSuccessNotice( - __( 'Image uploaded and inserted.' ), - { type: 'snackbar', id: 'inserter-notice' } - ); + } ); + } + setIsInserting( false ); }, allowedTypes: ALLOWED_MEDIA_TYPES, @@ -214,6 +232,7 @@ export function MediaPreview( { media, onClick, category } ) { getSettings, onClick, createSuccessNotice, + updateBlockAttributes, createErrorNotice, ] ); From fdb976af7f761b9e63c7f28d0846243dab4eb8b6 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Mon, 30 Sep 2024 12:43:52 +0200 Subject: [PATCH 2/3] Use `getBlock` instead of ref --- .../src/components/inserter/media-tab/media-preview.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/block-editor/src/components/inserter/media-tab/media-preview.js b/packages/block-editor/src/components/inserter/media-tab/media-preview.js index 44c7fbcb14a374..11f1f11d5216cf 100644 --- a/packages/block-editor/src/components/inserter/media-tab/media-preview.js +++ b/packages/block-editor/src/components/inserter/media-tab/media-preview.js @@ -20,7 +20,7 @@ import { __experimentalVStack as VStack, } from '@wordpress/components'; import { __, sprintf } from '@wordpress/i18n'; -import { useMemo, useCallback, useState, useRef } from '@wordpress/element'; +import { useMemo, useCallback, useState } from '@wordpress/element'; import { cloneBlock } from '@wordpress/blocks'; import { moreVertical, external } from '@wordpress/icons'; import { useSelect, useDispatch } from '@wordpress/data'; @@ -127,14 +127,13 @@ export function MediaPreview( { media, onClick, category } ) { useState( false ); const [ isHovered, setIsHovered ] = useState( false ); const [ isInserting, setIsInserting ] = useState( false ); - const hasInsertedBlock = useRef( false ); const [ block, preview ] = useMemo( () => getBlockAndPreviewFromMedia( media, category.mediaType ), [ media, category.mediaType ] ); const { createErrorNotice, createSuccessNotice } = useDispatch( noticesStore ); - const { getSettings } = useSelect( blockEditorStore ); + const { getSettings, getBlock } = useSelect( blockEditorStore ); const { updateBlockAttributes } = useDispatch( blockEditorStore ); const onMediaInsert = useCallback( @@ -183,7 +182,7 @@ export function MediaPreview( { media, onClick, category } ) { return; } - if ( ! hasInsertedBlock.current ) { + if ( ! getBlock( clonedBlock.clientId ) ) { // Ensure the block is only inserted once. onClick( { ...clonedBlock, @@ -199,8 +198,6 @@ export function MediaPreview( { media, onClick, category } ) { __( 'Image uploaded and inserted.' ), { type: 'snackbar', id: 'inserter-notice' } ); - - hasInsertedBlock.current = true; } else { // For subsequent calls, update the existing block. updateBlockAttributes( clonedBlock.clientId, { @@ -234,6 +231,7 @@ export function MediaPreview( { media, onClick, category } ) { createSuccessNotice, updateBlockAttributes, createErrorNotice, + getBlock, ] ); From e08e13d7ce741e9b8606df014a80fcc98dad19bf Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Mon, 30 Sep 2024 12:55:04 +0200 Subject: [PATCH 3/3] Remove comment --- .../src/components/inserter/media-tab/media-preview.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/block-editor/src/components/inserter/media-tab/media-preview.js b/packages/block-editor/src/components/inserter/media-tab/media-preview.js index 11f1f11d5216cf..319c25c01831c8 100644 --- a/packages/block-editor/src/components/inserter/media-tab/media-preview.js +++ b/packages/block-editor/src/components/inserter/media-tab/media-preview.js @@ -193,7 +193,6 @@ export function MediaPreview( { media, onClick, category } ) { }, } ); - // TODO: Move to a new onSuccess callback as part of #61447. createSuccessNotice( __( 'Image uploaded and inserted.' ), { type: 'snackbar', id: 'inserter-notice' }