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

Rename cover image to cover; Add video in cover block; #10659

Merged
merged 4 commits into from
Oct 18, 2018
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions assets/stylesheets/_z-index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ $z-layers: (
".edit-post-header": 30,
".block-library-button__inline-link .editor-url-input__suggestions": 6, // URL suggestions for button block above sibling inserter
".block-library-image__resize-handlers": 1, // Resize handlers above sibling inserter
".wp-block-cover.has-background-dim::before": 1, // Overlay area inside block cover need to be higher than the video background.
".wp-block-cover__video-background": 0, // Video background inside cover block.

// Side UI active buttons
".editor-block-mover__control": 1,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.wp-block-cover-image {
.wp-block-cover-image,
.wp-block-cover {
.editor-rich-text__tinymce[data-is-empty="true"]::before {
position: inherit;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,22 @@ const blockAttributes = {
customOverlayColor: {
type: 'string',
},
backgroundType: {
type: 'string',
default: 'image',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use the constant here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes we should 👍

},
};

export const name = 'core/cover-image';
export const name = 'core/cover';

const ALLOWED_MEDIA_TYPES = [ 'image' ];
const ALLOWED_MEDIA_TYPES = [ 'image', 'video' ];
const IMAGE_BACKGROUND_TYPE = 'image';
const VIDEO_BACKGROUND_TYPE = 'video';

export const settings = {
title: __( 'Cover Image' ),
title: __( 'Cover' ),

description: __( 'Add a full-width image, and layer text over it — great for headers.' ),
description: __( 'Add a full-width image or video, and layer text over it — great for headers.' ),

icon: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 4h7V2H4c-1.1 0-2 .9-2 2v7h2V4zm6 9l-4 5h12l-3-4-2.03 2.71L10 13zm7-4.5c0-.83-.67-1.5-1.5-1.5S14 7.67 14 8.5s.67 1.5 1.5 1.5S17 9.33 17 8.5zM20 2h-7v2h7v7h2V4c0-1.1-.9-2-2-2zm0 18h-7v2h7c1.1 0 2-.9 2-2v-7h-2v7zM4 13H2v7c0 1.1.9 2 2 2h7v-2H4v-7z" /><path d="M0 0h24v24H0z" fill="none" /></svg>,

Expand All @@ -81,21 +87,34 @@ export const settings = {
type: 'block',
blocks: [ 'core/heading' ],
transform: ( { content } ) => (
createBlock( 'core/cover-image', { title: content } )
createBlock( 'core/cover', { title: content } )
),
},
{
type: 'block',
blocks: [ 'core/image' ],
transform: ( { caption, url, align, id } ) => (
createBlock( 'core/cover-image', {
createBlock( 'core/cover', {
title: caption,
url,
align,
id,
} )
),
},
{
type: 'block',
blocks: [ 'core/video' ],
transform: ( { caption, src, align, id } ) => (
createBlock( 'core/cover', {
title: caption,
url: src,
align,
id,
backgroundType: VIDEO_BACKGROUND_TYPE,
} )
),
},
],
to: [
{
Expand All @@ -108,6 +127,9 @@ export const settings = {
{
type: 'block',
blocks: [ 'core/image' ],
isMatch: ( { backgroundType, url } ) => {
return ! url || backgroundType === IMAGE_BACKGROUND_TYPE;
},
transform: ( { title, url, align, id } ) => (
createBlock( 'core/image', {
caption: title,
Expand All @@ -117,6 +139,21 @@ export const settings = {
} )
),
},
{
type: 'block',
blocks: [ 'core/video' ],
isMatch: ( { backgroundType, url } ) => {
return ! url || backgroundType === VIDEO_BACKGROUND_TYPE;
},
transform: ( { title, url, align, id } ) => (
createBlock( 'core/video', {
caption: title,
src: url,
id,
align,
} )
),
},
],
},

Expand All @@ -132,21 +169,57 @@ export const settings = {
withNotices,
] )(
( { attributes, setAttributes, isSelected, className, noticeOperations, noticeUI, overlayColor, setOverlayColor } ) => {
const { url, title, align, contentAlign, id, hasParallax, dimRatio } = attributes;
const {
align,
backgroundType,
contentAlign,
dimRatio,
hasParallax,
id,
title,
url,
} = attributes;
const updateAlignment = ( nextAlign ) => setAttributes( { align: nextAlign } );
const onSelectImage = ( media ) => {
const onSelectMedia = ( media ) => {
if ( ! media || ! media.url ) {
setAttributes( { url: undefined, id: undefined } );
return;
}
setAttributes( { url: media.url, id: media.id } );
let mediaType;
// for media selections originated from a file upload.
if ( media.media_type ) {
if ( media.media_type === IMAGE_BACKGROUND_TYPE ) {
mediaType = IMAGE_BACKGROUND_TYPE;
} else {
// only images and videos are accepted so if the media_type is not an image we can assume it is a video.
// Videos contain the media type of 'file' in the object returned from the rest api.
mediaType = VIDEO_BACKGROUND_TYPE;
}
} else { // for media selections originated from existing files in the media library.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's weird that the object shape is different between the MediaLibrary component and the file upload. We should probably normalize one of them. (I think we should use the REST API shape in all cases for now).

This can be done in a separate PR to avoid blocking this though and it has other consequences potentially.

if (
media.type !== IMAGE_BACKGROUND_TYPE &&
media.type !== VIDEO_BACKGROUND_TYPE
) {
return;
}
mediaType = media.type;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What other types are there coming from the library, and why should we trust that media.type is valid for this block? Shouldn't we screen for IMAGE and VIDEO?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We set as the allowed media type for the media library video and image so another type being passed would probably be an indicator of a bug in another place. But to be on safe side I added a check that makes sure the type is image or video.

}
setAttributes( {
url: media.url,
id: media.id,
backgroundType: mediaType,
} );
};
const toggleParallax = () => setAttributes( { hasParallax: ! hasParallax } );
const setDimRatio = ( ratio ) => setAttributes( { dimRatio: ratio } );
const setTitle = ( newTitle ) => setAttributes( { title: newTitle } );

const style = {
...backgroundImageStyles( url ),
...(
backgroundType === IMAGE_BACKGROUND_TYPE ?
backgroundImageStyles( url ) :
{}
),
backgroundColor: overlayColor.color,
};

Expand Down Expand Up @@ -177,13 +250,13 @@ export const settings = {
/>
<Toolbar>
<MediaUpload
onSelect={ onSelectImage }
onSelect={ onSelectMedia }
allowedTypes={ ALLOWED_MEDIA_TYPES }
value={ id }
render={ ( { open } ) => (
<IconButton
className="components-toolbar__control"
label={ __( 'Edit image' ) }
label={ __( 'Edit media' ) }
icon="edit"
onClick={ open }
/>
Expand All @@ -195,12 +268,14 @@ export const settings = {
</BlockControls>
{ !! url && (
<InspectorControls>
<PanelBody title={ __( 'Cover Image Settings' ) }>
<ToggleControl
label={ __( 'Fixed Background' ) }
checked={ hasParallax }
onChange={ toggleParallax }
/>
<PanelBody title={ __( 'Cover Settings' ) }>
{ IMAGE_BACKGROUND_TYPE === backgroundType && (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great if we could support this for videos at some point.

<ToggleControl
label={ __( 'Fixed Background' ) }
checked={ hasParallax }
onChange={ toggleParallax }
/>
) }
<PanelColorSettings
title={ __( 'Overlay' ) }
initialOpen={ true }
Expand Down Expand Up @@ -235,7 +310,7 @@ export const settings = {
onChange={ setTitle }
inlineToolbar
/>
) : __( 'Cover Image' );
) : __( 'Cover' );

return (
<Fragment>
Expand All @@ -245,10 +320,11 @@ export const settings = {
className={ className }
labels={ {
title: label,
name: __( 'an image' ),
/* translators: Fragment of the sentence: "Drag %s, upload a new one or select a file from your library." */
name: __( 'an image or a video' ),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should have a translators: note reading something like

translators: Fragment of the sentence: "Drag %s, upload a new one or select a file from your library."

Aside: the way we interpolate these sentence fragments in MediaPlaceholder is pretty bad i18n.

} }
onSelect={ onSelectImage }
accept="image/*"
onSelect={ onSelectMedia }
accept="image/*,video/*"
allowedTypes={ ALLOWED_MEDIA_TYPES }
notices={ noticeUI }
onError={ noticeOperations.createErrorNotice }
Expand All @@ -265,10 +341,19 @@ export const settings = {
style={ style }
className={ classes }
>
{ VIDEO_BACKGROUND_TYPE === backgroundType && (
<video
className="wp-block-cover__video-background"
autoPlay
muted
loop
src={ url }
/>
) }
{ ( ! RichText.isEmpty( title ) || isSelected ) && (
<RichText
tagName="p"
className="wp-block-cover-image-text"
className="wp-block-cover-text"
placeholder={ __( 'Write title…' ) }
value={ title }
onChange={ setTitle }
Expand All @@ -282,9 +367,21 @@ export const settings = {
),

save( { attributes, className } ) {
const { url, title, hasParallax, dimRatio, align, contentAlign, overlayColor, customOverlayColor } = attributes;
const {
align,
backgroundType,
contentAlign,
customOverlayColor,
dimRatio,
hasParallax,
overlayColor,
title,
url,
} = attributes;
const overlayColorClass = getColorClassName( 'background-color', overlayColor );
const style = backgroundImageStyles( url );
const style = backgroundType === IMAGE_BACKGROUND_TYPE ?
backgroundImageStyles( url ) :
{};
if ( ! overlayColorClass ) {
style.backgroundColor = customOverlayColor;
}
Expand All @@ -303,14 +400,58 @@ export const settings = {

return (
<div className={ classes } style={ style }>
{ VIDEO_BACKGROUND_TYPE === backgroundType && url && ( <video
className="wp-block-cover__video-background"
autoPlay
muted
loop
src={ url }
/> ) }
{ ! RichText.isEmpty( title ) && (
<RichText.Content tagName="p" className="wp-block-cover-image-text" value={ title } />
<RichText.Content tagName="p" className="wp-block-cover-text" value={ title } />
) }
</div>
);
},

deprecated: [ {
attributes: {
...blockAttributes,
},

supports: {
className: false,
},

save( { attributes } ) {
const { url, title, hasParallax, dimRatio, align, contentAlign, overlayColor, customOverlayColor } = attributes;
const overlayColorClass = getColorClassName( 'background-color', overlayColor );
const style = backgroundImageStyles( url );
if ( ! overlayColorClass ) {
style.backgroundColor = customOverlayColor;
}

const classes = classnames(
'wp-block-cover-image',
dimRatioToClass( dimRatio ),
overlayColorClass,
{
'has-background-dim': dimRatio !== 0,
'has-parallax': hasParallax,
[ `has-${ contentAlign }-content` ]: contentAlign !== 'center',
},
align ? `align${ align }` : null,
);

return (
<div className={ classes } style={ style }>
{ ! RichText.isEmpty( title ) && (
<RichText.Content tagName="p" className="wp-block-cover-image-text" value={ title } />
) }
</div>
);
},
}, {
attributes: {
...blockAttributes,
title: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.wp-block-cover-image {
.wp-block-cover-image,
.wp-block-cover {
position: relative;
background-color: $black;
background-size: cover;
Expand All @@ -14,7 +15,8 @@
justify-content: flex-start;

h2,
.wp-block-cover-image-text {
.wp-block-cover-image-text,
.wp-block-cover-text {
margin-left: 0;
text-align: left;
}
Expand All @@ -24,14 +26,16 @@
justify-content: flex-end;

h2,
.wp-block-cover-image-text {
.wp-block-cover-image-text,
.wp-block-cover-text {
margin-right: 0;
text-align: right;
}
}

h2,
.wp-block-cover-image-text {
.wp-block-cover-image-text,
.wp-block-cover-text {
color: $white;
font-size: 2em;
line-height: 1.25;
Expand Down Expand Up @@ -62,6 +66,7 @@
right: 0;
background-color: inherit;
opacity: 0.5;
z-index: z-index(".wp-block-cover.has-background-dim::before");
}

@for $i from 1 through 10 {
Expand All @@ -83,3 +88,14 @@
width: 100%;
}
}

.wp-block-cover__video-background {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
width: 100%;
height: 100%;
z-index: z-index(".wp-block-cover__video-background");
object-fit: fill;
}
Loading