Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Media Placeholder: make component easier to read and reduce required … #35482

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/**
* WordPress dependencies
*/
import { useSelect } from '@wordpress/data';

/**
* Internal dependencies
*/
import { store as blockEditorStore } from '../../../store';

export default function useFilesUpload( {
addToGallery,
handleUpload,
onSelect,
multiple,
onFilesPreUpload,
value,
allowedTypes,
onError,
} ) {
const mediaUpload = useSelect( ( select ) => {
const { getSettings } = select( blockEditorStore );
return getSettings().mediaUpload;
}, [] );

return [
mediaUpload,
( files ) => {
if ( ! handleUpload ) {
return onSelect( files );
}
onFilesPreUpload( files );
let setMedia;
if ( multiple ) {
if ( addToGallery ) {
// Since the setMedia function runs multiple times per upload group
// and is passed newMedia containing every item in its group each time, we must
// filter out whatever this upload group had previously returned to the
// gallery before adding and returning the image array with replacement newMedia
// values.

// Define an array to store urls from newMedia between subsequent function calls.
let lastMediaPassed = [];
setMedia = ( newMedia ) => {
// Remove any images this upload group is responsible for (lastMediaPassed).
// Their replacements are contained in newMedia.
const filteredMedia = ( value ?? [] ).filter(
( item ) => {
// If Item has id, only remove it if lastMediaPassed has an item with that id.
if ( item.id ) {
return ! lastMediaPassed.some(
// Be sure to convert to number for comparison.
( { id } ) =>
Number( id ) === Number( item.id )
);
}
// Compare transient images via .includes since gallery may append extra info onto the url.
return ! lastMediaPassed.some(
( { urlSlug } ) =>
item.url.includes( urlSlug )
);
}
);
// Return the filtered media array along with newMedia.
onSelect( filteredMedia.concat( newMedia ) );
// Reset lastMediaPassed and set it with ids and urls from newMedia.
lastMediaPassed = newMedia.map( ( media ) => {
// Add everything up to '.fileType' to compare via .includes.
const cutOffIndex = media.url.lastIndexOf( '.' );
const urlSlug = media.url.slice( 0, cutOffIndex );
return { id: media.id, urlSlug };
} );
};
} else {
setMedia = onSelect;
}
} else {
setMedia = ( [ media ] ) => onSelect( media );
}
mediaUpload( {
allowedTypes,
filesList: files,
onFileChange: setMedia,
onError,
} );
},
];
}
73 changes: 11 additions & 62 deletions packages/block-editor/src/components/media-placeholder/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { useState, useEffect } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
import deprecated from '@wordpress/deprecated';
import { keyboardReturn } from '@wordpress/icons';

Expand All @@ -26,7 +25,7 @@ import { keyboardReturn } from '@wordpress/icons';
import MediaUpload from '../media-upload';
import MediaUploadCheck from '../media-upload/check';
import URLPopover from '../url-popover';
import { store as blockEditorStore } from '../../store';
import useFilesUpload from './hooks/use-files-upload';

const InsertFromURLPopover = ( { src, onChange, onSubmit, onClose } ) => (
<URLPopover onClose={ onClose }>
Expand Down Expand Up @@ -79,10 +78,16 @@ export function MediaPlaceholder( {
mediaLibraryButton,
placeholder,
} ) {
const mediaUpload = useSelect( ( select ) => {
const { getSettings } = select( blockEditorStore );
return getSettings().mediaUpload;
}, [] );
const [ mediaUpload, onFilesUpload ] = useFilesUpload( {
addToGallery,
handleUpload,
onSelect,
multiple,
onFilesPreUpload,
value,
allowedTypes,
onError,
} );
const [ src, setSrc ] = useState( '' );
const [ isURLInputVisible, setIsURLInputVisible ] = useState( false );

Expand Down Expand Up @@ -120,62 +125,6 @@ export function MediaPlaceholder( {
}
};

const onFilesUpload = ( files ) => {
if ( ! handleUpload ) {
return onSelect( files );
}
onFilesPreUpload( files );
let setMedia;
if ( multiple ) {
if ( addToGallery ) {
// Since the setMedia function runs multiple times per upload group
// and is passed newMedia containing every item in its group each time, we must
// filter out whatever this upload group had previously returned to the
// gallery before adding and returning the image array with replacement newMedia
// values.

// Define an array to store urls from newMedia between subsequent function calls.
let lastMediaPassed = [];
setMedia = ( newMedia ) => {
// Remove any images this upload group is responsible for (lastMediaPassed).
// Their replacements are contained in newMedia.
const filteredMedia = ( value ?? [] ).filter( ( item ) => {
// If Item has id, only remove it if lastMediaPassed has an item with that id.
if ( item.id ) {
return ! lastMediaPassed.some(
// Be sure to convert to number for comparison.
( { id } ) => Number( id ) === Number( item.id )
);
}
// Compare transient images via .includes since gallery may append extra info onto the url.
return ! lastMediaPassed.some( ( { urlSlug } ) =>
item.url.includes( urlSlug )
);
} );
// Return the filtered media array along with newMedia.
onSelect( filteredMedia.concat( newMedia ) );
// Reset lastMediaPassed and set it with ids and urls from newMedia.
lastMediaPassed = newMedia.map( ( media ) => {
// Add everything up to '.fileType' to compare via .includes.
const cutOffIndex = media.url.lastIndexOf( '.' );
const urlSlug = media.url.slice( 0, cutOffIndex );
return { id: media.id, urlSlug };
} );
};
} else {
setMedia = onSelect;
}
} else {
setMedia = ( [ media ] ) => onSelect( media );
}
mediaUpload( {
allowedTypes,
filesList: files,
onFileChange: setMedia,
onError,
} );
};

const onUpload = ( event ) => {
onFilesUpload( event.target.files );
};
Expand Down