---
 .../all/modules/contrib/heartbeat/heartbeat.module |  23 ++++
 .../plugins/content_types/stream/icon_user.png     | Bin 0 -> 606 bytes
 .../plugins/content_types/stream/stream.inc        | 121 +++++++++++++++++++++
 3 files changed, 144 insertions(+)
 create mode 100644 /heartbeat/plugins/content_types/stream/icon_user.png
 create mode 100644 /heartbeat/plugins/content_types/stream/stream.inc

diff --git a//heartbeat/heartbeat.module b//heartbeat/heartbeat.module
index 199d0db..5f85243 100644
--- a//heartbeat/heartbeat.module
+++ b//heartbeat/heartbeat.module
@@ -595,6 +595,29 @@ function heartbeat_ctools_plugin_api($owner, $api) {
 }
 
 /**
+ * Implements hook_ctools_plugin_directory() to let the system know
+ * where our task and task_handler plugins are.
+ */
+function heartbeat_ctools_plugin_directory($owner, $plugin_type) {
+  if ($owner == 'ctools') {
+    return 'plugins/' . $plugin_type;
+  }
+}
+
+/**
+ * Implements hook_ctools_plugin_type() to inform the plugin system that Page
+ * Manager owns task, task_handler, and page_wizard plugin types.
+ *
+ * All of these are empty because the defaults all work.
+ */
+function heartbeat_ctools_plugin_type() {
+  return array(
+    'content_types' => array(),
+  );
+}
+
+
+/**
  *  Implementation of hook_views_api().
  */
 function heartbeat_views_api() {
diff --git a//heartbeat/plugins/content_types/stream/icon_user.png b//heartbeat/plugins/content_types/stream/icon_user.png
new file mode 100644
index 0000000000000000000000000000000000000000..ab248f3f1bb62536bbf23296a949bfe05cd56bc7
GIT binary patch
literal 606
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl;=8&~`zjDUQ}64!{5
z;QX|b^2DN42FH~Aq*MjZ+{E<Mpwz^a%EFVWHb6y-0(?STjVzs~?LWKw!OuHyzrX+V
z<@x*1-+unO@%p=tq1ET_KUZJAxAfGtjkkWRyL9L3o8NOTecO8P$D(qtb1#2KXI5N%
z^*g_zuPi4yG06GJtGDNtHfNOAzkhV?<kh<;pa1^!;@-*GrKfK^D4)0S!<TP2-u}7!
z;m@b9-&{gcEy9`)Ps#8~t6OyS+llAD4?h0YnP{}J%yrex?@ep==1yGp^7=7Lm*D^Z
z{{x+QzcV)+NST!c`GG`82Mi1Q{R|lx7#TcW978H@B^f+@^fWESgn`Lf!N8Q2LxD|C
zgwZ#+fg$OE=|wiCScMB0FB%$NWC2R#38yK<$NBsFPw(vP^yO7(kdSC(+BK<4VS)C6
z!^_wN90V9`l@%^retI!Im>H;^SvXDBF|$xvxlq}$w$>~eXr@6z;<bwtgpG}aj4v^8
zGO!2)G{m}lF)wj-j`i-oDxuJDfXU~Tl*58`{6Y*s6PzbBG*}5R{QR?qhk=nrC_(7K
zMRq2I`SDGRK+Ac2O-!#|>1k|eY;1PE2-GXVV;X5`X&HLZ!861S#P>0c44v}x#}5~m
smX;J((H2Igj)PZ3BD*&lIy5jc$ag6`Uyzy~2n<aIPgg&ebxsLQ0Lelg8~^|S

literal 0
HcmV?d00001

diff --git a//heartbeat/plugins/content_types/stream/stream.inc b//heartbeat/plugins/content_types/stream/stream.inc
new file mode 100644
index 0000000..22c2055
--- /dev/null
+++ b//heartbeat/plugins/content_types/stream/stream.inc
@@ -0,0 +1,121 @@
+<?php
+
+$plugin = array(
+  'single' => TRUE,
+  'title' => t('Heartbeat stream'),
+  'icon' => 'icon_user.png',
+  'description' => t('Activity steam.'),
+  'required context' => new ctools_context_optional(t('User'), 'user'),
+  'category' => t('Widgets'),
+  'defaults' => array(
+    'stream' => '',
+  ),
+);
+/**
+ * Render the custom content type.
+ */
+function heartbeat_stream_content_type_render($subtype, $conf, $panel_args, $context) {
+  
+  $page = empty($_GET['block']);
+  $heartbeatStream = heartbeat_stream($conf['stream'], $page);
+  $view_mode = $page 
+    ? $heartbeatStream->config->page_view_mode 
+    : $heartbeatStream->config->block_view_mode
+  ;
+
+  if(!$heartbeatStream && heartbeat_stream_has_access($conf['stream'])) {
+    return;
+  }
+
+  if (empty($context) || empty($context->data)) {
+    $account = NULL;
+  }
+  else {
+    $account = $context->data;
+  }
+
+  if (
+    !$page 
+    && is_numeric($account) 
+    && $account > 0 
+    && variable_get('heartbeat_show_user_profile_messages_' . $stream_name, 0)
+  ) {
+    $heartbeatStream->setViewed(user_load($account));
+  }
+  elseif (isset($_GET['uid']) && is_numeric($_GET['uid']) && $_GET['uid'] > 0) {
+    $heartbeatStream->setViewed(user_load($_GET['uid']));
+  }
+
+  if (!empty($heartbeatStream->config->settings['exclude_og'])) {
+    $heartbeatStream->excludeOg(TRUE);
+  }
+
+  if ($offset_time > 0) {
+    $heartbeatStream->setOffsetTime($offset_time);
+  }
+  elseif (!empty($_GET['offset_time'])) {
+    $heartbeatStream->setOffsetTime($_GET['offset_time']);
+  }
+
+  heartbeat_stream_build($heartbeatStream);
+
+  if ($heartbeatStream->hasErrors()) {
+    if (function_exists('dsm')) {
+      dsm($heartbeatStream->getErrors(), $heartbeatStream->name);
+    }
+    else {
+      drupal_set_message(implode('<br />', $heartbeatStream->getErrors()));
+    }
+  }
+
+  $build = heartbeat_stream_view($heartbeatStream, $view_mode);
+
+  $content = array();
+  $content['#theme'] = 'heartbeat_list';
+  $content['#stream'] = $heartbeatStream;
+  $content['#content'] = $build;
+
+  $block->content = $content;
+
+  return $block;
+}
+
+/**
+ * Returns an edit form for custom type settings.
+ */
+function heartbeat_stream_content_type_edit_form($form, &$form_state) {
+  $conf = $form_state['conf'];
+
+  $streams = array();
+  foreach ((array)heartbeat_stream_config_load_all(TRUE) as $stream_name => $stream) {
+    if (!$stream->disabled) {
+      $streams[$stream->class] = $stream->name;
+    }
+  }
+
+  $form['stream'] = array(
+    '#type' => 'select',
+    '#title' => t('Stream'),
+    '#options' => $streams,
+    '#default_value' => $conf['stream'],
+  );
+
+  return $form;
+}
+
+/**
+ * Submit handler for search form.
+ */
+function heartbeat_stream_content_type_edit_form_submit($form, &$form_state) {
+  // Copy everything from our defaults.
+  foreach (array_keys($form_state['plugin']['defaults']) as $key) {
+    $form_state['conf'][$key] = $form_state['values'][$key];
+  }
+}
+
+/**
+ * Returns the administrative title for a type.
+ */
+function heartbeat_stream_content_type_admin_title($subtype, $conf, $context) {
+  return t('Heartbeat stream: @stream', array('@stream' => $conf['stream']));
+}
-- 
