Skip to content

Commit

Permalink
Merge pull request #6 from washingtonstateuniversity/features/block-d…
Browse files Browse the repository at this point in the history
…ocument-select

Features/block document select
  • Loading branch information
admturner authored Jul 14, 2020
2 parents 4bb43ea + 73e5cd4 commit e3c9dc8
Show file tree
Hide file tree
Showing 18 changed files with 469 additions and 1 deletion.
1 change: 1 addition & 0 deletions build/editor.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions build/index.asset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?php return array('dependencies' => array('wp-element', 'wp-polyfill'), 'version' => '98fe2af9193e60b8fbbb9eb9731c4d9b');
6 changes: 6 additions & 0 deletions build/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions inc/class-documents-post-type.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ public function action_register_post_types() {
),
'rewrite' => array( 'slug' => admin\get_plugin_info( 'slug' ) ),
'show_in_rest' => true,
'template' => array( array( 'hrswp/document-select' ) ),
'template_lock' => 'all',
);

register_post_type( admin\get_plugin_info( 'post_type' ), $documents_args );
Expand Down
50 changes: 50 additions & 0 deletions lib/client-assets.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php
/**
* Functions to register and manage client assets (scripts and styles).
*
* @package HrswpTheme
* @since 1.0.0
*/

namespace HrswpDocuments\lib\client_assets;

use HrswpDocuments as admin;

if ( ! defined( 'ABSPATH' ) ) {
die( 'Silence is golden.' );
}

/**
* Enqueues the plugin editor scripts.
*
* @since 1.0.0
*/
function action_enqueue_block_editor_assets() {
$slug = admin\get_plugin_info( 'slug' );
$path = admin\get_plugin_info( 'plugin_file_uri' );
$version = admin\get_plugin_info( 'version' );

wp_enqueue_script(
$slug . '-script',
plugins_url( 'build/index.js', $path ),
array(
'wp-blob',
'wp-block-editor',
'wp-components',
'wp-compose',
'wp-data',
'wp-element',
'wp-i18n',
),
$version,
true
);

wp_enqueue_style(
$slug . 'editor-style',
plugins_url( 'build/editor.css', $path ),
array(),
$version
);
}
add_action( 'enqueue_block_editor_assets', __NAMESPACE__ . '\action_enqueue_block_editor_assets' );
1 change: 1 addition & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
die( 'Silence is golden.' );
}

require dirname( __FILE__ ) . '/client-assets.php';
require dirname( __FILE__ ) . '/data.php';

require dirname( __DIR__ ) . '/inc/class-documents-post-type.php';
Expand Down
36 changes: 35 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"@wordpress/eslint-plugin": "^7.0.0",
"@wordpress/npm-package-json-lint-config": "3.1.0",
"babel-loader": "^8.1.0",
"classnames": "^2.2.6",
"cssnano": "^4.1.10",
"eslint": "^7.3.1",
"eslint-plugin-jest": "^23.18.0",
Expand Down
9 changes: 9 additions & 0 deletions src/blocks/document-select/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "hrswp/document-select",
"category": "media",
"supports": {
"inserter": false,
"reusable": false,
"html": false
}
}
208 changes: 208 additions & 0 deletions src/blocks/document-select/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
const { getBlobByURL, isBlobURL, revokeBlobURL } = wp.blob;
const { Animate, ClipboardButton, Disabled, withNotices } = wp.components;
const { compose } = wp.compose;
const { withSelect, withDispatch } = wp.data;
const {
BlockControls,
BlockIcon,
MediaPlaceholder,
MediaReplaceFlow,
RichText,
} = wp.blockEditor;
const { Component } = wp.element;
const { __ } = wp.i18n;

/**
* Internal dependencies
*/
import { file as icon } from './icons';

/**
* Constants
*/
const MEDIA_ID_META_NAME = '_hrswp_document_file_id';
const MEDIA_HREF_META_NAME = '_hrswp_document_file_href';

class FileEdit extends Component {
constructor() {
super( ...arguments );

this.onSelectFile = this.onSelectFile.bind( this );
this.confirmCopyURL = this.confirmCopyURL.bind( this );
this.resetCopyConfirmation = this.resetCopyConfirmation.bind( this );
this.onUploadError = this.onUploadError.bind( this );

this.state = {
hasError: false,
showCopyConfirmation: false,
};
}

componentDidMount() {
const { mediaHref, mediaUpload, noticeOperations } = this.props;

// Upload a file drag-and-dropped into the editor
if ( isBlobURL( mediaHref ) ) {
const file = getBlobByURL( mediaHref );

mediaUpload( {
filesList: [ file ],
onFileChange: ( [ media ] ) => this.onSelectFile( media ),
onError: ( message ) => {
this.setState( { hasError: true } );
noticeOperations.createErrorNotice( message );
},
} );

revokeBlobURL( mediaHref );
}
}

componentDidUpdate( prevProps ) {
// Reset copy confirmation state when block is deselected
if ( prevProps.isSelected && ! this.props.isSelected ) {
this.setState( { showCopyConfirmation: false } );
}
}

onSelectFile( media ) {
if ( media && media.url ) {
this.setState( { hasError: false } );
this.props.updateMeta( media.id, MEDIA_ID_META_NAME );
this.props.updateMeta( media.url, MEDIA_HREF_META_NAME );
}
}

onUploadError( message ) {
const { noticeOperations } = this.props;
noticeOperations.removeAllNotices();
noticeOperations.createErrorNotice( message );
}

confirmCopyURL() {
this.setState( { showCopyConfirmation: true } );
}

resetCopyConfirmation() {
this.setState( { showCopyConfirmation: false } );
}

render() {
const {
className,
isSelected,
noticeUI,
mediaId,
mediaHref,
} = this.props;
const { hasError, showCopyConfirmation } = this.state;

if ( ! mediaHref || hasError ) {
return (
<MediaPlaceholder
icon={ <BlockIcon icon={ icon } /> }
labels={ {
title: __( 'File' ),
instructions: __(
'Upload a file or pick one from your media library.'
),
} }
onSelect={ this.onSelectFile }
notices={ noticeUI }
onError={ this.onUploadError }
accept="*"
/>
);
}

const classes = classnames( className, {
'is-transient': isBlobURL( mediaHref ),
} );

return (
<>
<BlockControls>
<MediaReplaceFlow
mediaId={ mediaId }
mediaURL={ mediaHref }
accept="*"
onSelect={ this.onSelectFile }
onError={ this.onUploadError }
/>
</BlockControls>
<Animate type={ isBlobURL( mediaHref ) ? 'loading' : null }>
{ ( { className: animateClassName } ) => (
<div
className={ classnames(
classes,
animateClassName
) }
>
<p>
<strong>Selected file:</strong>
</p>
<Disabled>
<RichText tagName="div" value={ mediaHref } />
</Disabled>
{ isSelected && (
<ClipboardButton
isSecondary
text={ mediaHref }
className={
'wp-block-file__copy-url-button'
}
onCopy={ this.confirmCopyURL }
onFinishCopy={ this.resetCopyConfirmation }
disabled={ isBlobURL( mediaHref ) }
>
{ showCopyConfirmation
? __( 'Copied!' )
: __( 'Copy URL' ) }
</ClipboardButton>
) }
</div>
) }
</Animate>
</>
);
}
}

export default compose( [
withDispatch( ( dispatch ) => {
return {
updateMeta: ( value, metaField ) => {
dispatch( 'core/editor' ).editPost( {
meta: { [ metaField ]: value },
} );
},
};
} ),
withSelect( ( select ) => {
const { getMedia } = select( 'core' );
const { getSettings } = select( 'core/block-editor' );
const { mediaUpload } = getSettings();
const mediaId = select( 'core/editor' ).getEditedPostAttribute(
'meta'
)[ MEDIA_ID_META_NAME ];

return {
media: mediaId === undefined ? undefined : getMedia( mediaId ),
postType: select( 'core/editor' ).getCurrentPostType(),
mediaId,
mediaHref: select( 'core/editor' ).getEditedPostAttribute( 'meta' )[
MEDIA_HREF_META_NAME
],
mediaUpload,
};
} ),
withNotices,
] )( FileEdit );
8 changes: 8 additions & 0 deletions src/blocks/document-select/editor.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.wp-block[data-type="hrswp/document-select"] {
padding: 0;
transition: padding 0.15s cubic-bezier(0.4, 0, 0.2, 1);
}

.wp-block[data-type="hrswp/document-select"].is-selected {
padding: 0 8px 8px;
}
10 changes: 10 additions & 0 deletions src/blocks/document-select/icons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* WordPress dependencies
*/
const { SVG, Path } = wp.components;

export const file = (
<SVG viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<Path d="M19 6.2h-5.9l-.6-1.1c-.3-.7-1-1.1-1.8-1.1H5c-1.1 0-2 .9-2 2v11.8c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V8.2c0-1.1-.9-2-2-2zm.5 11.6c0 .3-.2.5-.5.5H5c-.3 0-.5-.2-.5-.5V6c0-.3.2-.5.5-.5h5.8c.2 0 .4.1.4.3l1 2H19c.3 0 .5.2.5.5v9.5z" />
</SVG>
);
Loading

0 comments on commit e3c9dc8

Please sign in to comment.