<!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>[BuddyPress][10839] trunk/src: Activity: Introduce media into embed template.</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 { 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://buddypress.trac.wordpress.org/changeset/10839">10839</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"http://buddypress.trac.wordpress.org/changeset/10839","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>r-a-y</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2016-05-31 07:40:36 +0000 (Tue, 31 May 2016)</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'>Activity: Introduce media into embed template.

This commit displays media from an activity item into the embed template.

Specifically, if an activity item contains an oEmbed item from a
WordPress whitelisted oEmbed provider and that oEmbed item contains a
thumbnail, we will display that thumbnail along with a caption.  One thing
to note is we only display the first oEmbed item to prevent cluttering up
the embed template.

If an oEmbed item isn't found, we will attempt to find the first inline
video or audio item.  If such an item is found, we will embed that item
using the browser's native HTML5 player.

Props r-a-y, imath.

See <a href="http://buddypress.trac.wordpress.org/ticket/6772">#6772</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcbpactivitybpactivityembedsphp">trunk/src/bp-activity/bp-activity-embeds.php</a></li>
<li><a href="#trunksrcbptemplatesbplegacybuddypressassetsembedsactivityphp">trunk/src/bp-templates/bp-legacy/buddypress/assets/embeds/activity.php</a></li>
<li><a href="#trunksrcbptemplatesbplegacybuddypressassetsembedscssactivityphp">trunk/src/bp-templates/bp-legacy/buddypress/assets/embeds/css-activity.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcbpactivitybpactivityembedsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-activity/bp-activity-embeds.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-activity/bp-activity-embeds.php      2016-05-31 07:29:30 UTC (rev 10838)
+++ trunk/src/bp-activity/bp-activity-embeds.php        2016-05-31 07:40:36 UTC (rev 10839)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -167,3 +167,192 @@
</span><span class="cx" style="display: block; padding: 0 10px">                 */
</span><span class="cx" style="display: block; padding: 0 10px">                return apply_filters( 'bp_activity_get_embed_excerpt', $content, $GLOBALS['activities_template']->activity->content );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+/**
+ * Outputs the first embedded item in the activity oEmbed template.
+ *
+ * @since 2.6.0
+ */
+function bp_activity_embed_media() {
+       // Bail if oEmbed request explicitly hides media.
+       if ( isset( $_REQUEST['hide_media'] ) && true == wp_validate_boolean( $_REQUEST['hide_media'] ) ) {
+               /**
+                * Do something after media is rendered for an activity oEmbed item.
+                *
+                * @since 2.6.0
+                */
+               do_action( 'bp_activity_embed_after_media' );
+
+               return;
+       }
+
+       /**
+        * Should we display media in the oEmbed template?
+        *
+        * @since 2.6.0
+        *
+        * @param bool $retval Defaults to true.
+        */
+       $allow_media = apply_filters( 'bp_activity_embed_display_media', true );
+
+       // Find oEmbeds from only WP registered providers.
+       bp_remove_all_filters( 'oembed_providers' );
+       $media = bp_core_extract_media_from_content( $GLOBALS['activities_template']->activity->content, 'embeds' );
+       bp_restore_all_filters( 'oembed_providers' );
+
+       // oEmbeds have precedence over inline video / audio.
+       if ( isset( $media['embeds'] ) && true === $allow_media ) {
+               // Autoembed first URL.
+               $oembed_defaults = wp_embed_defaults();
+               $oembed_args = array(
+                       'width'    => $oembed_defaults['width'],
+                       'height'   => $oembed_defaults['height'],
+                       'discover' => true
+               );
+               $url      = $media['embeds'][0]['url'];
+               $cachekey = '_oembed_response_' . md5( $url . serialize( $oembed_args ) );
+
+               // Try to fetch oEmbed response from meta.
+               $oembed = bp_activity_get_meta( bp_get_activity_id(), $cachekey );
+
+               // No cache, so fetch full oEmbed response now!
+               if ( '' === $oembed ) {
+                       $o = _wp_oembed_get_object();
+                       $oembed = $o->fetch( $o->get_provider( $url, $oembed_args ), $url, $oembed_args );
+
+                       // Cache oEmbed response.
+                       bp_activity_update_meta( bp_get_activity_id(), $cachekey, $oembed );
+               }
+
+               $content = '';
+
+               /**
+                * Filters the default embed display max width.
+                *
+                * This is used if the oEmbed response does not return a thumbnail width.
+                *
+                * @since 2.6.0
+                *
+                * @param int $width.
+                */
+               $width = (int) apply_filters( 'bp_activity_embed_display_media_width', 550 );
+
+               // Set thumbnail.
+               if ( 'photo' === $oembed->type ) {
+                       $thumbnail = $oembed->url;
+               } elseif ( isset( $oembed->thumbnail_url ) ) {
+                       $thumbnail = $oembed->thumbnail_url;
+
+               /* Non-oEmbed standard attributes */
+               // Mixcloud
+               } elseif ( isset( $oembed->image ) ) {
+                       $thumbnail = $oembed->image;
+               // ReverbNation
+               } elseif ( isset( $oembed->{'thumbnail-url'} ) ) {
+                       $thumbnail = $oembed->{'thumbnail-url'};
+               }
+
+               // Display thumb and related oEmbed meta.
+               if ( true === isset ( $thumbnail ) ) {
+                       $play_icon = $caption = '';
+
+                       // Add play icon for non-photos.
+                       if ( 'photo' !== $oembed->type ) {
+                               /**
+                                * ion-play icon from Ionicons.
+                                *
+                                * @link    http://ionicons.com/
+                                * @license MIT
+                                */
+                               $play_icon = <<<EOD
+<svg id="Layer_1" style="enable-background:new 0 0 512 512;" version="1.1" viewBox="0 0 512 512" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M405.2,232.9L126.8,67.2c-3.4-2-6.9-3.2-10.9-3.2c-10.9,0-19.8,9-19.8,20H96v344h0.1c0,11,8.9,20,19.8,20  c4.1,0,7.5-1.4,11.2-3.4l278.1-165.5c6.6-5.5,10.8-13.8,10.8-23.1C416,246.7,411.8,238.5,405.2,232.9z"/></svg>
+EOD;
+
+                               $play_icon = sprintf( '<a rel="nofollow" class="play-btn" href="%1$s" onclick="top.location.href=\'%1$s\'">%2$s</a>', esc_url( $url ), $play_icon );
+                       }
+
+                       // Thumb width
+                       $thumb_width = isset( $oembed->thumbnail_width ) && 'photo' !== $oembed->type && (int) $oembed->thumbnail_width < 550 ? (int) $oembed->thumbnail_width : $width;
+
+                       $float_width = 350;
+
+                       // Set up thumb.
+                       $content = sprintf( '<div class="thumb" style="max-width:%1$spx">%2$s<a href="%3$s" rel="nofollow" onclick="top.location.href=\'%3$s\'"><img src="%4$s" /></a></div>', $thumb_width, $play_icon, esc_url( $url ), esc_url( $thumbnail ) );
+
+                       // Show title.
+                       if ( isset( $oembed->title ) ) {
+                               $caption .= sprintf( '<p class="caption-title"><strong>%s</strong></p>', apply_filters( 'single_post_title', $oembed->title ) );
+                       }
+
+                       // Show description (non-oEmbed standard)
+                       if ( isset( $oembed->description ) ) {
+                               $caption .= sprintf( '<div class="caption-description">%s</div>', apply_filters( 'bp_activity_get_embed_excerpt', $oembed->description ) );
+                       }
+
+                       // Show author info.
+                       if ( isset( $oembed->provider_name ) && isset( $oembed->author_name ) ) {
+                               /* translators: By [oEmbed author] on [oEmbed provider]. eg. By BuddyPress on YouTube. */
+                               $anchor_text = sprintf( __( 'By %1$s on %2$s', 'buddypress' ), $oembed->author_name, $oembed->provider_name );
+
+                       } elseif ( isset( $oembed->provider_name ) ) {
+                               $anchor_text = sprintf( __( 'View on %s', 'buddypress' ), $oembed->provider_name );
+                       }
+
+                       if ( true === isset( $anchor_text ) )  {
+                               $caption .= sprintf( '<a rel="nofollow" href="%1$s" onclick="top.location.href=\'%1$s\'">%2$s</a>', esc_url( $url ), apply_filters( 'the_title', $anchor_text ) );
+                       }
+
+                       // Set up caption.
+                       if ( '' !== $caption ) {
+                               $css_class = isset( $oembed->provider_name ) ? sprintf( ' provider-%s', sanitize_html_class( strtolower( $oembed->provider_name ) ) ) : '';
+                               $caption = sprintf( '<div class="caption%1$s" style="width:%2$s">%3$s</div>',
+                                       $css_class,
+                                       $thumb_width > $float_width ? 100 . '%' : round( ( $width - (int) $thumb_width ) / $width * 100 ) . '%',
+                                       $caption
+                               );
+
+                               $content .= $caption;
+                       }
+               }
+
+               // Print rich content.
+               if ( '' !== $content ) {
+                       printf( '<div class="bp-activity-embed-display-media %s" style="max-width:%spx">%s</div>',
+                               $thumb_width < $float_width ? 'two-col' : 'one-col',
+                               $thumb_width < $float_width ? $width : $thumb_width,
+                               $content
+                       );
+               }
+
+       // Video / audio.
+       } elseif ( true === $allow_media ) {
+               // Call BP_Embed if it hasn't already loaded.
+               bp_embed_init();
+
+               // Run shortcode and embed routine.
+               $content = buddypress()->embed->run_shortcode( $GLOBALS['activities_template']->activity->content );
+               $content = buddypress()->embed->autoembed( $content );
+
+               // Try to find inline video / audio.
+               $media = bp_core_extract_media_from_content( $content, 96 );
+
+               // Video takes precedence. HTML5-only.
+               if ( isset( $media['videos'] ) && 'shortcodes' === $media['videos'][0]['source'] ) {
+                       printf( '<video controls preload="metadata"><source src="%1$s"><p>%2$s</p></video>',
+                               esc_url( $media['videos'][0]['url'] ),
+                               esc_html__( 'Your browser does not support HTML5 video', 'buddypress' )
+                       );
+
+               // No video? Try audio. HTML5-only.
+               } elseif ( isset( $media['audio'] ) && 'shortcodes' === $media['audio'][0]['source'] ) {
+                       printf( '<audio controls preload="metadata"><source src="%1$s"><p>%2$s</p></audio>',
+                               esc_url( $media['audio'][0]['url'] ),
+                               esc_html__( 'Your browser does not support HTML5 audio', 'buddypress' )
+                       );
+               }
+
+       }
+
+       /** This hook is documented in /bp-activity/bp-activity-embeds.php */
+       do_action( 'bp_activity_embed_after_media' );
+}
</ins></span></pre></div>
<a id="trunksrcbptemplatesbplegacybuddypressassetsembedsactivityphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-templates/bp-legacy/buddypress/assets/embeds/activity.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-templates/bp-legacy/buddypress/assets/embeds/activity.php    2016-05-31 07:29:30 UTC (rev 10838)
+++ trunk/src/bp-templates/bp-legacy/buddypress/assets/embeds/activity.php      2016-05-31 07:40:36 UTC (rev 10839)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3,7 +3,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        <?php while ( bp_activities() ) : bp_the_activity(); ?>
</span><span class="cx" style="display: block; padding: 0 10px">                                <div class="bp-embed-excerpt"><?php bp_activity_embed_excerpt(); ?></div>
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+                               <?php bp_activity_embed_media(); ?>
+
</ins><span class="cx" style="display: block; padding: 0 10px">                         <?php endwhile; ?>
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                <?php endif; ?>
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
</del></span></pre></div>
<a id="trunksrcbptemplatesbplegacybuddypressassetsembedscssactivityphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-templates/bp-legacy/buddypress/assets/embeds/css-activity.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-templates/bp-legacy/buddypress/assets/embeds/css-activity.php        2016-05-31 07:29:30 UTC (rev 10838)
+++ trunk/src/bp-templates/bp-legacy/buddypress/assets/embeds/css-activity.php  2016-05-31 07:40:36 UTC (rev 10839)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -53,4 +53,100 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> span.bp-embed-timestamp {
</span><span class="cx" style="display: block; padding: 0 10px">        font-size: .9em;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+}
+
+video {
+       width: 100%;
+       height: auto;
+}
+
+.bp-activity-embed-display-media {
+       border: 1px solid #ccc;
+       border-radius: 6px;
+}
+
+.bp-activity-embed-display-media.one-col,
+.bp-activity-embed-display-media.one-col .thumb,
+.bp-activity-embed-display-media.one-col .thumb img {
+       width: 100%;
+}
+
+.bp-activity-embed-display-media.two-col .thumb,
+.bp-activity-embed-display-media.two-col .caption {
+       display: table-cell;
+}
+
+.bp-activity-embed-display-media.two-col .thumb {
+       background: #000;
+       vertical-align: middle;
+}
+
+.bp-activity-embed-display-media.two-col .caption {
+       vertical-align: top;
+}
+
+.bp-activity-embed-display-media.two-col .thumb img {
+       border-right: 1px solid #ccc;
+       display: block;
+       width: 100%;
+}
+
+.bp-activity-embed-display-media .thumb {
+       position: relative;
+}
+
+.bp-activity-embed-display-media .caption {
+       padding: .2em .5em .5em .5em;
+}
+
+a.play-btn {
+       background: rgba(0, 0, 0, 0.75);
+       border-radius: 50%;
+       height: 50px;
+       left: 50%;
+       margin: 0;
+       padding: 1em;
+       position: absolute;
+       text-indent: 0.25em;
+       top: 50%;
+       transform: translateY(-50%) translateX(-50%);
+       -webkit-transform: translateY(-50%) translateX(-50%);
+       transition: all 0.2s ease-out;
+       width: 50px;
+}
+
+.bp-activity-embed-display-media.two-col a.play-btn {
+       height: 35px;
+       width: 35px;
+}
+
+a.play-btn:hover {
+       background: rgba(0, 0, 0, 0.95);
+       transform: translateY(-50%) translateX(-50%) scale(1.05);
+       -webkit-transform: translateY(-50%) translateX(-50%) scale(1.05);
+       transition: all 0.2s ease-out;
+}
+
+.bp-activity-embed-display-media .thumb svg {
+       fill: #fff;
+       overflow: hidden;
+}
+
+.bp-activity-embed-display-media .caption-description {
+       font-size: 90%;
+       margin: .4em 0;
+}
+
+@media only screen and (max-width: 480px) {
+       .bp-activity-embed-display-media.two-col .thumb {
+               border-bottom: 1px solid #ccc;
+               border-right: 0;
+               display: block;
+               max-width: none !important;
+       }
+
+       a.play-btn {
+               height: 35px;
+               width: 35px;
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span></span></pre>
</div>
</div>

</body>
</html>