Skip to content

Commit

Permalink
Separate out MediaAddButton
Browse files Browse the repository at this point in the history
  • Loading branch information
obenland committed Sep 15, 2020
1 parent 12a76a5 commit 0ed3f1d
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 144 deletions.
152 changes: 8 additions & 144 deletions packages/block-library/src/gallery/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,36 +22,27 @@ import {
PanelBody,
SelectControl,
ToggleControl,
ToolbarButton,
ToolbarGroup,
withNotices,
RangeControl,
Dropdown,
NavigableMenu,
MenuItem,
FormFileUpload,
} from '@wordpress/components';
import {
BlockControls,
MediaPlaceholder,
InspectorControls,
MediaUpload,
MediaUploadCheck,
} from '@wordpress/block-editor';
import { Component, createRef, Platform } from '@wordpress/element';
import { Component, Platform } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { media as mediaIcon, upload } from '@wordpress/icons';
import { getBlobByURL, isBlobURL, revokeBlobURL } from '@wordpress/blob';
import { withSelect } from '@wordpress/data';
import { withViewportMatch } from '@wordpress/viewport';
import { DOWN } from '@wordpress/keycodes';

/**
* Internal dependencies
*/
import { sharedIcon } from './shared-icon';
import { defaultColumnsNumber, pickRelevantMediaFiles } from './shared';
import Gallery from './gallery';
import MediaAddButton from './media-add';

const MAX_COLUMNS = 8;
const linkOptions = [
Expand Down Expand Up @@ -352,7 +343,6 @@ class GalleryEdit extends Component {
attributes,
className,
isSelected,
mediaUpload,
noticeUI,
insertBlocksAfter,
} = this.props;
Expand Down Expand Up @@ -400,138 +390,12 @@ class GalleryEdit extends Component {
<>
<BlockControls>
{ hasImages && (
<Dropdown
popoverProps={ {
isAlternate: true,
} }
contentClassName="block-editor-media-replace-flow__options"
renderToggle={ ( { isOpen, onToggle } ) => (
<ToolbarGroup className="media-replace-flow">
<ToolbarButton
ref={ createRef() }
aria-expanded={ isOpen }
onClick={ onToggle }
onKeyDown={ ( event ) => {
if ( event.keyCode === DOWN ) {
event.preventDefault();
event.stopPropagation();
event.target.click();
}
} }
>
{ __( 'Add' ) }
</ToolbarButton>
</ToolbarGroup>
) }
renderContent={ ( { onClose } ) => (
<NavigableMenu className="block-editor-media-replace-flow__media-upload-menu">
<MediaUpload
multiple
gallery
addToGallery
title={ __( 'Add image' ) }
onSelect={ this.onSelectImages }
onError={ this.onUploadError }
allowedTypes={ ALLOWED_MEDIA_TYPES }
value={ ids }
render={ ( { open } ) => (
<MenuItem
icon={ mediaIcon }
onClick={ open }
>
{ __( 'Open Media Library' ) }
</MenuItem>
) }
/>
<MediaUploadCheck>
<FormFileUpload
onChange={ ( event ) => {
const { files } = event.target;

// 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 = [];
const setMedia = ( newMedia ) => {
// Remove any images this upload group is responsible for (lastMediaPassed).
// Their replacements are contained in newMedia.
const filteredMedia = (
images ?? []
).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.
this.onSelectImages(
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,
};
}
);
};

mediaUpload( {
allowedTypes: ALLOWED_MEDIA_TYPES,
filesList: files,
onFileChange: setMedia,
onError: this.onUploadError,
} );

onClose();
} }
accept={ ALLOWED_MEDIA_TYPES }
render={ ( { openFileDialog } ) => (
<MenuItem
icon={ upload }
onClick={ () => {
openFileDialog();
} }
>
{ __( 'Upload' ) }
</MenuItem>
) }
/>
</MediaUploadCheck>
</NavigableMenu>
) }
<MediaAddButton
allowedTypes={ ALLOWED_MEDIA_TYPES }
images={ images }
onError={ this.onUploadError }
onSelect={ this.onSelectImages }
value={ ids }
/>
) }
</BlockControls>
Expand Down
146 changes: 146 additions & 0 deletions packages/block-library/src/gallery/media-add.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/**
* WordPress dependencies
*/
import { MediaUpload, MediaUploadCheck } from '@wordpress/block-editor';
import {
Dropdown,
FormFileUpload,
MenuItem,
NavigableMenu,
ToolbarButton,
ToolbarGroup,
} from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { createRef } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { media as mediaIcon, upload } from '@wordpress/icons';
import { DOWN } from '@wordpress/keycodes';

export default function MediaAddButton( props ) {
const { allowedTypes, images, onError, onSelect, value } = props;

const mediaUpload = useSelect(
( select ) => select( 'core/block-editor' ).getSettings().mediaUpload,
[]
);

const onKeyDown = ( event ) => {
if ( event.keyCode === DOWN ) {
event.preventDefault();
event.stopPropagation();
event.target.click();
}
};

const mediaLibraryButton = ( { open } ) => (
<MenuItem icon={ mediaIcon } onClick={ open }>
{ __( 'Open Media Library' ) }
</MenuItem>
);

const mediaUploadButton = ( { openFileDialog } ) => (
<MenuItem icon={ upload } onClick={ openFileDialog }>
{ __( 'Upload' ) }
</MenuItem>
);

const onFileUpload = ( event, onClose ) => {
// 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 = [];
const setMedia = ( newMedia ) => {
// Remove any images this upload group is responsible for (lastMediaPassed).
// Their replacements are contained in newMedia.
const filteredMedia = ( images ?? [] ).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,
};
} );
};

mediaUpload( {
allowedTypes,
filesList: event.target.files,
onFileChange: setMedia,
onError,
} );

onClose();
};

const dropdownToggle = ( { isOpen, onToggle } ) => (
<ToolbarGroup className="media-add">
<ToolbarButton
ref={ createRef() }
aria-expanded={ isOpen }
onClick={ onToggle }
onKeyDown={ onKeyDown }
>
{ __( 'Add' ) }
</ToolbarButton>
</ToolbarGroup>
);

const dropdownContent = ( { onClose } ) => (
<NavigableMenu className="block-editor-media-add__media-upload-menu">
<MediaUpload
multiple
gallery
addToGallery
title={ __( 'Add image' ) }
onSelect={ onSelect }
onError={ onError }
allowedTypes={ allowedTypes }
value={ value }
render={ mediaLibraryButton }
/>
<MediaUploadCheck>
<FormFileUpload
onChange={ ( event ) => onFileUpload( event, onClose ) }
accept={ allowedTypes }
render={ mediaUploadButton }
/>
</MediaUploadCheck>
</NavigableMenu>
);

return (
<Dropdown
popoverProps={ {
isAlternate: true,
} }
contentClassName="block-editor-media-add__options"
renderToggle={ dropdownToggle }
renderContent={ dropdownContent }
/>
);
}

0 comments on commit 0ed3f1d

Please sign in to comment.