-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,16 +58,22 @@ const blockAttributes = { | |
customOverlayColor: { | ||
type: 'string', | ||
}, | ||
backgroundType: { | ||
type: 'string', | ||
default: 'image', | ||
}, | ||
}; | ||
|
||
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>, | ||
|
||
|
@@ -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: [ | ||
{ | ||
|
@@ -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, | ||
|
@@ -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, | ||
} ) | ||
), | ||
}, | ||
], | ||
}, | ||
|
||
|
@@ -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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's weird that the object shape is different between the 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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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, | ||
}; | ||
|
||
|
@@ -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 } | ||
/> | ||
|
@@ -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 && ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 } | ||
|
@@ -235,7 +310,7 @@ export const settings = { | |
onChange={ setTitle } | ||
inlineToolbar | ||
/> | ||
) : __( 'Cover Image' ); | ||
) : __( 'Cover' ); | ||
|
||
return ( | ||
<Fragment> | ||
|
@@ -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' ), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should have a
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 } | ||
|
@@ -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 } | ||
|
@@ -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; | ||
} | ||
|
@@ -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: { | ||
|
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes we should 👍