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

VideoPress: Add video settings to the VideoPress-enhanced video block #13134

Merged
merged 5 commits into from
Aug 7, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions extensions/blocks/videopress/deprecated/v1/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* Internal dependencies
*/
import save from './save';

export default {
attributes: {
autoplay: {
type: 'boolean',
},
caption: {
type: 'string',
source: 'html',
selector: 'figcaption',
},
controls: {
type: 'boolean',
default: true,
},
guid: {
type: 'string',
},
id: {
type: 'number',
},
loop: {
type: 'boolean',
},
muted: {
type: 'boolean',
},
poster: {
type: 'string',
},
preload: {
type: 'string',
default: 'metadata',
},
src: {
type: 'string',
},
},
support: {
reusable: false,
},
save,
isDeprecation: true,
};
25 changes: 25 additions & 0 deletions extensions/blocks/videopress/deprecated/v1/save.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* External dependencies
*/
import { RichText } from '@wordpress/editor';

export default function VideoPressSave( { attributes } ) {
const { caption, guid } = attributes;

if ( ! guid ) {
return null;
}

const url = `https://videopress.com/v/${ guid }`;

return (
<figure className="wp-block-embed is-type-video is-provider-videopress">
<div className="wp-block-embed__wrapper">
{ `\n${ url }\n` /* URL needs to be on its own line. */ }
</div>
{ ! RichText.isEmpty( caption ) && (
<RichText.Content tagName="figcaption" value={ caption } />
) }
</figure>
);
}
182 changes: 159 additions & 23 deletions extensions/blocks/videopress/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,39 @@
* External dependencies
*/
import apiFetch from '@wordpress/api-fetch';
import classnames from 'classnames';
import { __ } from '@wordpress/i18n';
import { BlockControls, RichText } from '@wordpress/editor';
import { Component, createRef, Fragment } from '@wordpress/element';
import { compose, createHigherOrderComponent } from '@wordpress/compose';
import { Disabled, IconButton, SandBox, Toolbar } from '@wordpress/components';
import { get } from 'lodash';
import { isBlobURL } from '@wordpress/blob';
import {
BaseControl,
Button,
Disabled,
IconButton,
PanelBody,
SandBox,
SelectControl,
ToggleControl,
Toolbar,
} from '@wordpress/components';
import { compose, createHigherOrderComponent, withInstanceId } from '@wordpress/compose';
import { withSelect } from '@wordpress/data';
import {
BlockControls,
InspectorControls,
MediaUpload,
MediaUploadCheck,
RichText,
} from '@wordpress/editor';
import { Component, createRef, Fragment } from '@wordpress/element';
import { __, _x, sprintf } from '@wordpress/i18n';
import classnames from 'classnames';
import { get } from 'lodash';

/**
* Internal dependencies
*/
import Loading from './loading';
import { getVideoPressUrl } from './url';

const VIDEO_POSTER_ALLOWED_MEDIA_TYPES = [ 'image' ];

const VideoPressEdit = CoreVideoEdit =>
class extends Component {
Expand Down Expand Up @@ -90,52 +109,161 @@ const VideoPressEdit = CoreVideoEdit =>
} );
};

onSelectPoster = image => {
const { setAttributes } = this.props;
setAttributes( { poster: image.url } );
};

onRemovePoster = () => {
this.props.setAttributes( { poster: '' } );
const { setAttributes } = this.props;
setAttributes( { poster: '' } );

// Move focus back to the Media Upload button.
this.posterImageButton.current.focus();
};

toggleAttribute = attribute => {
return newValue => {
this.props.setAttributes( { [ attribute ]: newValue } );
};
};

getAutoplayHelp = checked => {
return checked
? __( 'Note: Autoplaying videos may cause usability issues for some visitors.', 'jetpack' )
: null;
};

render() {
const {
attributes,
className,
instanceId,
isFetchingPreview,
isSelected,
isUploading,
preview,
setAttributes,
} = this.props;
const { fallback, isFetchingMedia } = this.state;
const { autoplay, caption, controls, loop, muted, poster, preload } = attributes;

const videoPosterDescription = `video-block__poster-image-description-${ instanceId }`;

const blockSettings = (
<Fragment>
<BlockControls>
<Toolbar>
<IconButton
className="components-icon-button components-toolbar__control"
label={ __( 'Edit video', 'jetpack' ) }
onClick={ this.switchToEditing }
icon="edit"
/>
</Toolbar>
</BlockControls>
<InspectorControls>
<PanelBody title={ __( 'Video Settings', 'jetpack' ) }>
<ToggleControl
label={ __( 'Autoplay', 'jetpack' ) }
onChange={ this.toggleAttribute( 'autoplay' ) }
checked={ autoplay }
help={ this.getAutoplayHelp }
/>
<ToggleControl
label={ __( 'Loop', 'jetpack' ) }
onChange={ this.toggleAttribute( 'loop' ) }
checked={ loop }
/>
<ToggleControl
label={ __( 'Muted', 'jetpack' ) }
onChange={ this.toggleAttribute( 'muted' ) }
checked={ muted }
/>
<ToggleControl
label={ __( 'Playback Controls', 'jetpack' ) }
onChange={ this.toggleAttribute( 'controls' ) }
checked={ controls }
/>
<SelectControl
label={ __( 'Preload', 'jetpack' ) }
value={ preload }
onChange={ value => setAttributes( { preload: value } ) }
options={ [
{ value: 'auto', label: _x( 'Auto', 'VideoPress preload setting', 'jetpack' ) },
{
value: 'metadata',
label: _x( 'Metadata', 'VideoPress preload setting', 'jetpack' ),
},
{ value: 'none', label: _x( 'None', 'VideoPress preload setting', 'jetpack' ) },
] }
/>
<MediaUploadCheck>
<BaseControl
className="editor-video-poster-control"
label={ __( 'Poster Image', 'jetpack' ) }
simison marked this conversation as resolved.
Show resolved Hide resolved
>
<MediaUpload
title={ __( 'Select Poster Image', 'jetpack' ) }
onSelect={ this.onSelectPoster }
allowedTypes={ VIDEO_POSTER_ALLOWED_MEDIA_TYPES }
render={ ( { open } ) => (
<Button
isDefault
onClick={ open }
ref={ this.posterImageButton }
aria-describedby={ videoPosterDescription }
>
{ ! poster
? __( 'Select Poster Image', 'jetpack' )
: __( 'Replace image', 'jetpack' ) }
</Button>
) }
/>
<p id={ videoPosterDescription } hidden>
{ poster
? sprintf( __( 'The current poster image url is %s', 'jetpack' ), poster )
mmtr marked this conversation as resolved.
Show resolved Hide resolved
: __( 'There is no poster image currently selected', 'jetpack' ) }
</p>
{ !! poster && (
<Button onClick={ this.onRemovePoster } isLink isDestructive>
{ __( 'Remove Poster Image' ) }
</Button>
) }
</BaseControl>
</MediaUploadCheck>
</PanelBody>
</InspectorControls>
</Fragment>
);

if ( isUploading ) {
return <Loading text={ __( 'Uploading…', 'jetpack' ) } />;
return (
<Fragment>
{ blockSettings }
<Loading text={ __( 'Uploading…', 'jetpack' ) } />
</Fragment>
);
}

if ( isFetchingMedia || isFetchingPreview ) {
return <Loading text={ __( 'Embedding…', 'jetpack' ) } />;
return (
<Fragment>
{ blockSettings }
<Loading text={ __( 'Generating preview…', 'jetpack' ) } />
</Fragment>
);
}

if ( fallback || ! preview ) {
return <CoreVideoEdit { ...this.props } />;
}

const { html, scripts } = preview;
const { caption } = attributes;

return (
<Fragment>
<BlockControls>
<Toolbar>
<IconButton
className="components-icon-button components-toolbar__control"
label={ __( 'Edit video', 'jetpack' ) }
onClick={ this.switchToEditing }
icon="edit"
/>
</Toolbar>
</BlockControls>
{ blockSettings }
<figure className={ classnames( className, 'wp-block-embed', 'is-type-video' ) }>
{ /*
Disable the video player so the user clicking on it won't play the
Expand Down Expand Up @@ -164,10 +292,17 @@ const VideoPressEdit = CoreVideoEdit =>
export default createHigherOrderComponent(
compose( [
withSelect( ( select, ownProps ) => {
const { guid, src } = ownProps.attributes;
const { autoplay, controls, guid, loop, muted, poster, preload, src } = ownProps.attributes;
const { getEmbedPreview, isRequestingEmbedPreview } = select( 'core' );

const url = !! guid && `https://videopress.com/v/${ guid }`;
const url = getVideoPressUrl( guid, {
autoplay,
controls,
loop,
muted,
poster,
preload,
} );
const preview = !! url && getEmbedPreview( url );

const isFetchingEmbedPreview = !! url && isRequestingEmbedPreview( url );
Expand All @@ -179,6 +314,7 @@ export default createHigherOrderComponent(
preview,
};
} ),
withInstanceId,
VideoPressEdit,
] ),
'withVideoPressEdit'
Expand Down
26 changes: 18 additions & 8 deletions extensions/blocks/videopress/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@ import { every } from 'lodash';
import withVideoPressEdit from './edit';
import withVideoPressSave from './save';
import getJetpackExtensionAvailability from '../../shared/get-jetpack-extension-availability';
import deprecatedV1 from './deprecated/v1';

const addVideoPressSupport = ( settings, name ) => {
if ( 'core/video' !== name ) {
// Bail if this is not the video block or if the hook has been triggered by a deprecation.
if ( 'core/video' !== name || settings.isDeprecation ) {
return settings;
}

const { attributes, deprecated, edit, save, supports, transforms } = settings;

const { available, unavailableReason } = getJetpackExtensionAvailability( 'videopress' );

// We customize the video block even if VideoPress it not available so we can support videos that were uploaded to
Expand Down Expand Up @@ -52,6 +56,9 @@ const addVideoPressSupport = ( settings, name ) => {
muted: {
type: 'boolean',
},
playsInline: {
type: 'boolean',
},
poster: {
type: 'string',
},
Expand All @@ -65,7 +72,7 @@ const addVideoPressSupport = ( settings, name ) => {
},

transforms: {
...settings.transforms,
...transforms,
from: [
{
type: 'files',
Expand Down Expand Up @@ -95,21 +102,24 @@ const addVideoPressSupport = ( settings, name ) => {
},

supports: {
...settings.supports,
...supports,
reusable: false,
},

edit: withVideoPressEdit( settings.edit ),
edit: withVideoPressEdit( edit ),

save: withVideoPressSave( settings.save ),
save: withVideoPressSave( save ),

deprecated: [
...( deprecated || [] ),
{
attributes: settings.attributes,
save: settings.save,
attributes,
isEligible: attrs => ! attrs.guid,
save,
supports,
isDeprecation: true,
},
...( Array.isArray( settings.deprecated ) ? settings.deprecated : [] ),
deprecatedV1,
],
};
}
Expand Down
Loading