<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[8506] sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks: Blocks: Add FeaturedImage component.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="http://meta.trac.wordpress.org/changeset/8506">8506</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"http://meta.trac.wordpress.org/changeset/8506","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>vedjain</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2019-03-25 09:44:44 +0000 (Mon, 25 Mar 2019)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Blocks: Add FeaturedImage component.

This adds a featured image component, which allows to display and control sizes of multiple featured images rendered inside blocks. Note that there is still some work left to be done in this component.

props vedjain</pre>

<h3>Added Paths</h3>
<ul>
<li>sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/featured-image/</li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentmupluginsblocksassetssrcsharedfeaturedimageindexjs">sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/featured-image/index.js</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentmupluginsblocksassetssrcsharedfeaturedimageinspectorcontroljs">sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/featured-image/inspector-control.js</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentmupluginsblocksassetssrcsharedfeaturedimagestylescss">sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/featured-image/style.scss</a></li>
<li>sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/view/shared/</li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentmupluginsblocksviewsharedfeaturedimagephp">sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/view/shared/featured-image.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentmupluginsblocksassetssrcsharedfeaturedimageindexjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/featured-image/index.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/featured-image/index.js                               (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/featured-image/index.js 2019-03-25 09:44:44 UTC (rev 8506)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,86 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * External dependencies
+ */
+import classnames from 'classnames';
+
+/**
+ * WordPress dependencies.
+ */
+const { Component } = wp.element;
+
+/**
+ * Displays featured image, can be linked with block control for size.
+ */
+export default class FeaturedImage extends Component {
+
+       /**
+        * @param props Props for function.
+        * @param props.wpMediaDetails Available sizes of images in the format as returned by WP API. This is the `sizes` object inside `media_details` inside `wp:featuredMedia` object.
+        * @param props.height Height in pixels for image.
+        * @param props.width Width in pixels for image.
+        * @param props.className Classname for image element
+        * @param props.alt Alt text for image
+        */
+       constructor( props ) {
+               super( props );
+               this.state = {};
+       }
+
+       /**
+        * Get 'full' size image to be displayed in editor. Or get the widest one.
+        */
+       getFullImage() {
+
+               const availableSizes = this.props.wpMediaDetails;
+
+               const { selectedImage } = this.state;
+
+               if ( selectedImage && selectedImage.hasOwnProperty( 'source_url' ) ) {
+                       return selectedImage;
+               }
+
+               if ( availableSizes.hasOwnProperty( 'full' ) && availableSizes['full'].hasOwnProperty( 'source_url' ) ) {
+                       this.setState( { selectedImage: availableSizes['full'] } );
+                       return availableSizes[ 'full' ];
+               }
+
+               let widestImage = { source_url : '' };
+
+               for ( const size in availableSizes ) {
+                       if ( ! availableSizes.hasOwnProperty( size ) ) {
+                               continue;
+                       }
+
+                       if ( availableSizes[ size ]['width'] > ( widestImage[ 'width '] || 0 ) && availableSizes[ size ].hasOwnProperty( 'source_url' ) ) {
+                               widestImage = availableSizes[ size ];
+                       }
+               }
+
+               this.setState( { selectedImage: widestImage } );
+
+               return widestImage;
+       }
+
+       /**
+        * Renders FeaturedImage component.
+        *
+        * @returns {*}
+        */
+       render() {
+               const { className, alt, attributes } = this.props;
+
+               const { featured_image_width } = attributes;
+               const image = this.getFullImage();
+
+               const width = featured_image_width || 150 ;
+
+               return(
+                       <img
+                               className={ classnames( 'wordcamp-featured-image', className ) }
+                               src = { image['source_url'] }
+                               alt = { alt }
+                               width = { width + 'px' }
+                       />
+               )
+       }
+}
</ins></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentmupluginsblocksassetssrcsharedfeaturedimageinspectorcontroljs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/featured-image/inspector-control.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/featured-image/inspector-control.js                           (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/featured-image/inspector-control.js     2019-03-25 09:44:44 UTC (rev 8506)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,93 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * WordPress dependencies.
+ */
+const { Component } = wp.element;
+const { PanelBody, PanelRow, TextControl, BaseControl, SelectControl, ToggleControl } = wp.components;
+const { __ } = wp.i18n;
+import './style.scss';
+
+/**
+ * Not sure if these sizes are actually useful.
+ */
+const sizePresets = [
+       {
+               label : __( 'Thumbnail', 'wordcamporg' ),
+               value : '150',
+       },
+       {
+               label : __( 'Thumbnail - Large', 'wordcamporg' ),
+               value : '926',
+       },
+       {
+               label : __( 'Medium', 'wordcamporg' ),
+               value : '300',
+       },
+       {
+               label : __( 'Medium - Large', 'wordcamporg' ),
+               value : '768',
+       },
+       {
+               label : __( 'Large', 'wordcamporg' ),
+               value : '1024',
+       },
+       {
+               label : __( '(Custom)', 'wordcamporg' ),
+               value : '',
+       }
+];
+
+/**
+ * Implements inspector control for FeaturedImage component defined in ./index.js. Uses and sets attribute `featured_image_height` and `featured_image_width`.
+ */
+class FeaturedImageInspectorControls extends Component {
+
+       componentWillMount() {
+               this.availableSizes = sizePresets.map( (size) => size.value );
+       }
+
+       onPresetSizeSelect( size ) {
+               if ( size === '' ) {
+                       return;
+               }
+               const { setAttributes } = this.props;
+               setAttributes( { featured_image_width: Number( size ) } );
+       }
+
+       render() {
+
+               const { attributes, setAttributes, title, help, selectLabel, cropLabel } = this.props;
+               const { featured_image_width } = attributes;
+               const selectedValue = this.availableSizes.indexOf( featured_image_width.toString() ) === -1 ? '' : featured_image_width.toString();
+               return (
+                       <PanelBody
+                               title = { title }
+                               initialopen = { false }
+                       >
+                               <PanelRow>
+                                       <BaseControl
+                                               help = { help }
+                                       >
+                                               <PanelRow>
+                                                       <SelectControl
+                                                               label={ selectLabel }
+                                                               value={ selectedValue }
+                                                               options={ sizePresets }
+                                                               onChange={ ( size ) => this.onPresetSizeSelect( size ) }
+                                                       />
+                                               </PanelRow>
+                                               <PanelRow>
+                                                       <TextControl
+                                                               label = { __('Width (in px)', 'wordcamporg' ) }
+                                                               type = 'number'
+                                                               value = { featured_image_width }
+                                                               onChange = { ( width ) => setAttributes( { featured_image_width: Number( width ) } ) }
+                                                       />
+                                               </PanelRow>
+                                       </BaseControl>
+                               </PanelRow>
+                       </PanelBody>
+               );
+       }
+}
+
+export default FeaturedImageInspectorControls;
</ins></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentmupluginsblocksassetssrcsharedfeaturedimagestylescss"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/featured-image/style.scss</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/featured-image/style.scss                             (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/assets/src/shared/featured-image/style.scss       2019-03-25 09:44:44 UTC (rev 8506)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,6 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+img.wordcamp-featured-image {
+       height: auto;
+       max-width: 100%;
+       max-height: 100%;
+
+}
</ins></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentmupluginsblocksviewsharedfeaturedimagephp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/view/shared/featured-image.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/view/shared/featured-image.php                          (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/blocks/view/shared/featured-image.php    2019-03-25 09:44:44 UTC (rev 8506)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,37 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+namespace WordCamp\Blocks\Shared\Components;
+
+/**
+ * Provides render backend for FeaturedImage component.
+ *
+ * @param array    $class_names        Additional classes to add inside <img> tag.
+ * @param \WP_Post $post               Current post object. This will be used to calculate srcset attribute.
+ * @param string   $selected_image_url URL for selected sized image.
+ * @param int      $height             Height of the image
+ * @param int      $width              Width of the image
+ *
+ * @return string Output markup for featured image.
+ */
+function render_featured_image( $class_names, $post, $height, $width ) {
+       $class_names[] = 'wordcamp-featured-image';
+       $class_names[] = 'wordcamp-featured-image-' . $post->post_name;
+       $class_names = implode( ' ', $class_names );
+       $attachment_id = get_post_thumbnail_id( $post->ID );
+       $image_data = wp_get_attachment_metadata( $attachment_id );
+       $size = 'post-thumbnail';
+       if ( is_array( $image_data ) && isset( $image_data['sizes'] ) && isset( $image_data['sizes']['full'] ) ) {
+               $aspect_ratio = $image_data['sizes']['full']['height'] / $image_data['sizes']['full']['width'];
+               $height = $aspect_ratio * $width;
+               $size = array( $width, $height );
+       }
+
+       return get_the_post_thumbnail(
+               $post,
+               $size,
+               array(
+                       'class' => esc_attr( $class_names ),
+                       'alt'   => esc_attr( $post->post_name ),
+               )
+       );
+}
</ins></span></pre>
</div>
</div>

</body>
</html>