Skip to content

Commit

Permalink
Gallery Block: Add Media Library button to the upload new image area (#…
Browse files Browse the repository at this point in the history
…12367)

Fixes: #8309
Supersedes: #9682

This PR adds a media library button in the upload new image are of the gallery block.
Trying to follow the design 2 proposed in #9682 (comment) by @kjellr and approved by @karmatosed.

A new functionality that allows the gallery to open in library/add frame instead of the edit frame was added to MediaUpload, so when the user pressed the media library button in the add zone the user goes directly to the add to library section when using the edit gallery button on the toolbar the user goes to the edit gallery section.

## Description
I added a gallery;
I added some images;
I selected the gallery;
I checked that a new media library button exists in the add to gallery zone.
If I click on it I go directly to a frame that allows the addition of images from the library to the gallery.

## How has this been tested?

## Screenshot
<img width="997" alt="screenshot 2018-11-27 at 15 35 14" src="https://user-images.githubusercontent.com/11271197/49093136-64176280-f25b-11e8-82de-ff44cee4ab47.png">
  • Loading branch information
jorgefilipecosta authored Mar 25, 2019
1 parent d718a97 commit 3c1fe58
Show file tree
Hide file tree
Showing 11 changed files with 320 additions and 188 deletions.
7 changes: 7 additions & 0 deletions packages/block-editor/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
## 2.0.0 (Unreleased)

### New Features

- Added the `addToGallery` property to the `MediaUpload` interface. The property allows users to open the media modal in the `gallery-library`instead of `gallery-edit` state.
- Added the `addToGallery` property to the `MediaPlaceholder` component. The component passes the property to the `MediaUpload` component used inside the placeholder.
- Added the `isAppender` property to the `MediaPlaceholder` component. The property changes the look of the placeholder to be adequate to scenarios where new files are added to an already existing set of files, e.g., adding files to a gallery.
- Added the `dropZoneUIOnly` property to the `MediaPlaceholder` component. The property makes the `MediaPlaceholder` only render a dropzone without any other additional UI.

### Breaking Changes

- `CopyHandler` will now only catch cut/copy events coming from its `props.children`, instead of from anywhere in the `document`.
Expand Down
288 changes: 213 additions & 75 deletions packages/block-editor/src/components/media-placeholder/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
/**
* External dependencies
*/
import { every, get, noop, startsWith, defaultTo } from 'lodash';
import {
defaultTo,
every,
get,
isArray,
noop,
startsWith,
} from 'lodash';
import classnames from 'classnames';

/**
Expand Down Expand Up @@ -103,8 +110,28 @@ export class MediaPlaceholder extends Component {
}

onFilesUpload( files ) {
const { onSelect, multiple, onError, allowedTypes, mediaUpload } = this.props;
const setMedia = multiple ? onSelect : ( [ media ] ) => onSelect( media );
const {
addToGallery,
allowedTypes,
mediaUpload,
multiple,
onError,
onSelect,
value = [],
} = this.props;
let setMedia;
if ( multiple ) {
if ( addToGallery ) {
const currentValue = value;
setMedia = ( newMedia ) => {
onSelect( currentValue.concat( newMedia ) );
};
} else {
setMedia = onSelect;
}
} else {
setMedia = ( [ media ] ) => onSelect( media );
}
mediaUpload( {
allowedTypes,
filesList: files,
Expand All @@ -121,42 +148,32 @@ export class MediaPlaceholder extends Component {
this.setState( { isURLInputVisible: false } );
}

render() {
renderPlaceholder( content, onClick ) {
const {
accept,
icon,
allowedTypes = [],
className,
hasUploadPermissions,
icon,
isAppender,
labels = {},
onSelect,
value = {},
onSelectURL,
onHTMLDrop = noop,
multiple = false,
notices,
allowedTypes = [],
hasUploadPermissions,
mediaUpload,
onSelectURL,
} = this.props;

const {
isURLInputVisible,
src,
} = this.state;

let instructions = labels.instructions || '';
let title = labels.title || '';
let instructions = labels.instructions;
let title = labels.title;

if ( ! hasUploadPermissions && ! onSelectURL ) {
instructions = __( 'To edit this block, you need permission to upload media.' );
}

if ( ! instructions || ! title ) {
if ( instructions === undefined || title === undefined ) {
const isOneType = 1 === allowedTypes.length;
const isAudio = isOneType && 'audio' === allowedTypes[ 0 ];
const isImage = isOneType && 'image' === allowedTypes[ 0 ];
const isVideo = isOneType && 'video' === allowedTypes[ 0 ];

if ( ! instructions ) {
if ( instructions === undefined ) {
if ( hasUploadPermissions ) {
instructions = __( 'Drag a media file, upload a new one or select a file from your library.' );

Expand All @@ -180,7 +197,7 @@ export class MediaPlaceholder extends Component {
}
}

if ( ! title ) {
if ( title === undefined ) {
title = __( 'Media' );

if ( isAudio ) {
Expand All @@ -193,70 +210,191 @@ export class MediaPlaceholder extends Component {
}
}

const placeholderClassName = classnames(
'block-editor-media-placeholder',
'editor-media-placeholder',
className,
{ 'is-appender': isAppender }
);

return (
<Placeholder
icon={ icon }
label={ title }
instructions={ instructions }
className={ classnames( 'editor-media-placeholder block-editor-media-placeholder', className ) }
className={ placeholderClassName }
notices={ notices }
onClick={ onClick }
>
<MediaUploadCheck>
{ !! mediaUpload && (
<Fragment>
<DropZone
onFilesDrop={ this.onFilesUpload }
onHTMLDrop={ onHTMLDrop }
/>
<FormFileUpload
isLarge
className="editor-media-placeholder__button block-editor-media-placeholder__button"
onChange={ this.onUpload }
accept={ accept }
multiple={ multiple }
>
{ __( 'Upload' ) }
</FormFileUpload>
</Fragment>
) }
<MediaUpload
gallery={ multiple && this.onlyAllowsImages() }
multiple={ multiple }
onSelect={ onSelect }
allowedTypes={ allowedTypes }
value={ value.id }
render={ ( { open } ) => (
<Button
isLarge
className="editor-media-placeholder__button block-editor-media-placeholder__button"
onClick={ open }
>
{ __( 'Media Library' ) }
</Button>
) }
{ content }
</Placeholder>
);
}

renderDropZone() {
const { onHTMLDrop = noop } = this.props;
return (
<DropZone
onFilesDrop={ this.onFilesUpload }
onHTMLDrop={ onHTMLDrop }
/>
);
}

renderUrlSelectionUI() {
const {
onSelectURL,
} = this.props;
if ( ! onSelectURL ) {
return null;
}
const {
isURLInputVisible,
src,
} = this.state;
return (
<div className="editor-media-placeholder__url-input-container block-editor-media-placeholder__url-input-container">
<Button
className="editor-media-placeholder__button block-editor-media-placeholder__button"
onClick={ this.openURLInput }
isToggled={ isURLInputVisible }
isLarge
>
{ __( 'Insert from URL' ) }
</Button>
{ isURLInputVisible && (
<InsertFromURLPopover
src={ src }
onChange={ this.onChangeSrc }
onSubmit={ this.onSubmitSrc }
onClose={ this.closeURLInput }
/>
</MediaUploadCheck>
{ onSelectURL && (
<div className="editor-media-placeholder__url-input-container block-editor-media-placeholder__url-input-container">
) }
</div>
);
}

renderMediaUploadChecked() {
const {
accept,
addToGallery,
allowedTypes = [],
isAppender,
mediaUpload,
multiple = false,
onSelect,
value = {},
} = this.props;

const mediaLibraryButton = (
<MediaUpload
addToGallery={ addToGallery }
gallery={ multiple && this.onlyAllowsImages() }
multiple={ multiple }
onSelect={ onSelect }
allowedTypes={ allowedTypes }
value={
isArray( value ) ?
value.map( ( { id } ) => id ) :
value.id
}
render={ ( { open } ) => {
return (
<Button
className="editor-media-placeholder__button block-editor-media-placeholder__button"
onClick={ this.openURLInput }
isToggled={ isURLInputVisible }
isLarge
className={ classnames(
'editor-media-placeholder__button',
'editor-media-placeholder__media-library-button'
) }
onClick={ ( event ) => {
event.stopPropagation();
open();
} }
>
{ __( 'Insert from URL' ) }
{ __( 'Media Library' ) }
</Button>
{ isURLInputVisible && (
<InsertFromURLPopover
src={ src }
onChange={ this.onChangeSrc }
onSubmit={ this.onSubmitSrc }
onClose={ this.closeURLInput }
/>
);
} }
/>
);

if ( mediaUpload && isAppender ) {
return (
<Fragment>
{ this.renderDropZone() }
<FormFileUpload
onChange={ this.onUpload }
accept={ accept }
multiple={ multiple }
render={ ( { openFileDialog } ) => {
const content = (
<Fragment>
<IconButton
isLarge
className={ classnames(
'block-editor-media-placeholder__button',
'editor-media-placeholder__button',
'block-editor-media-placeholder__upload-button'
) }
icon="upload"
>
{ __( 'Upload' ) }
</IconButton>
{ mediaLibraryButton }
{ this.renderUrlSelectionUI() }
</Fragment>
);
return this.renderPlaceholder( content, openFileDialog );
} }
/>
</Fragment>
);
}
if ( mediaUpload ) {
const content = (
<Fragment>
{ this.renderDropZone() }
<FormFileUpload
isLarge
className={ classnames(
'block-editor-media-placeholder__button',
'editor-media-placeholder__button',
'block-editor-media-placeholder__upload-button'
) }
</div>
) }
</Placeholder>
onChange={ this.onUpload }
accept={ accept }
multiple={ multiple }
>
{ __( 'Upload' ) }
</FormFileUpload>
{ mediaLibraryButton }
{ this.renderUrlSelectionUI() }
</Fragment>
);
return this.renderPlaceholder( content );
}
return this.renderPlaceholder( mediaLibraryButton );
}

render() {
const {
dropZoneUIOnly,
} = this.props;

if ( dropZoneUIOnly ) {
return (
<MediaUploadCheck>
{ this.renderDropZone() }
</MediaUploadCheck>
);
}

return (
<MediaUploadCheck
fallback={ this.renderPlaceholder( this.renderUrlSelectionUI() ) }
>
{ this.renderMediaUploadChecked() }
</MediaUploadCheck>
);
}
}
Expand Down
27 changes: 27 additions & 0 deletions packages/block-editor/src/components/media-placeholder/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,30 @@
.components-form-file-upload .block-editor-media-placeholder__button {
margin-right: $grid-size-small;
}

.block-editor-media-placeholder.is-appender {
min-height: 100px;
outline: $border-width dashed $dark-gray-150;

&:hover {
outline: $border-width dashed $dark-gray-500;
cursor: pointer;
}

.is-dark-theme & {

&:hover {
outline: $border-width dashed $white;
}
}

.block-editor-media-placeholder__upload-button {
margin-right: $grid-size-small;
&.components-button:hover,
&.components-button:focus {
box-shadow: none;
border: $border-width solid $dark-gray-500;
}
}

}
Loading

0 comments on commit 3c1fe58

Please sign in to comment.