Implement paging
authorMichael J. Rubinsky <mrubinsk@horde.org>
Thu, 1 Jul 2010 19:32:16 +0000 (15:32 -0400)
committerMichael J. Rubinsky <mrubinsk@horde.org>
Thu, 1 Jul 2010 19:42:49 +0000 (15:42 -0400)
horde/lib/Block/twitter_timeline.php
horde/services/twitter.php
horde/themes/facebook.css

index 788375e..7cdf7fe 100644 (file)
@@ -87,7 +87,12 @@ class Horde_Block_Horde_twitter_timeline extends Horde_Block
      */
     function _params()
     {
-        return null;
+        return array(
+            'height' => array(
+                 'name' => _("Height of map (width automatically adjusts to block)"),
+                 'type' => 'int',
+                 'default' => 250)
+        );
     }
 
     /**
@@ -142,7 +147,7 @@ class Horde_Block_Horde_twitter_timeline extends Horde_Block
            . '<div><a class="button" onclick="Horde.twitter.updateStatus($F(\'' . $instance . '_newStatus\'));" href="#">' . _("Update") . '</a><span id="' . $instance . '_inReplyTo"></span></div>'
            . Horde::img('loading.gif', '', array('id' => $instance . '_loading', 'style' => 'display:none;'));
         $html .= '<div id="currentStatus" class="fbemptystatus" style="margin-left:10px;margin-top:10px;">' . sprintf(_("Latest: %s - %s"), $latestStatus, Horde_Date_Utils::relativeDateTime(strtotime($this->_profile->status->created_at), $GLOBALS['prefs']->getValue('date_format'), ($GLOBALS['prefs']->getValue('twentyFour') ? "%H:%M %P" : "%I %M %P"))) . '</div>';
-        $html .= '<div id="twitter_body' . $instance . '">';
+        $html .= '<div style="height:' . $this->_params['height'] . 'px;overflow-y:auto;" id="twitter_body' . $instance . '">';
         $filter = Horde_Text_Filter::factory('Text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO));
         foreach ($stream as $tweet) {
             /* links */
@@ -182,6 +187,7 @@ class Horde_Block_Horde_twitter_timeline extends Horde_Block
             $html .= '</div><div class="clear">&nbsp;</div></div></div>';
         }
         $html .= '</div>';
+        $html .= '<div class="control fbgetmore"><a href="#" onclick="Horde.twitter.updateStream(++Horde.twitter.page);">' . _("Get More") . '</a></div>';
         $endpoint = Horde::url('services/twitter.php', true);
         $spinner = '$(\'' . $instance . '_loading\')';
         $inputNode = '$(\'' . $instance . '_newStatus\')';
@@ -195,7 +201,7 @@ class Horde_Block_Horde_twitter_timeline extends Horde_Block
         var Horde = window.Horde || {};
         Horde.twitter = {
             inReplyTo: '',
-
+            page: 1,
             updateStatus: function(statusText) {
                 {$inputNode}.stopObserving('blur');
                 {$spinner}.toggle();
@@ -235,6 +241,25 @@ class Horde_Block_Horde_twitter_timeline extends Horde_Block
                 });
             },
 
+            updateStream: function(page) {
+                new Ajax.Request('$endpoint', {
+                    method: 'post',
+                    parameters: { actionID: 'getPage', 'page': page },
+                    onComplete: function(response) {
+                        var content = new Element('div').update(response.responseText);
+                        //var cHeight = $('{contentNode}').scrollHeight;
+                        //console.log(cHeight);
+                        var h = $('{$contentNode}').scrollHeight
+                        $('{$contentNode}').insert(content);
+                        //console.log($('{$contentNode}').scrollTop);
+                        $('{$contentNode}').scrollTop = h;
+                    },
+                    onFailure: function() {
+                        {$spinner}.toggle();
+                    }
+                });
+            },
+
             buildReply: function(id, userid, usertext) {
                 this.inReplyTo = id;
                 {$inputNode}.focus();
@@ -243,14 +268,14 @@ class Horde_Block_Horde_twitter_timeline extends Horde_Block
             },
 
             updateCallback: function(response) {
-               this.buildTweet(response);
+               this.buildNewTweet(response);
                {$inputNode}.value = '{$defaultText}';
                {$spinner}.toggle();
                this.inReplyTo = '';
                {$inReplyToNode}.update('');
             },
 
-            buildTweet: function(response) {
+            buildNewTweet: function(response) {
                 var tweet = new Element('div', {'class':'fbstreamstory'});
                 var tPic = new Element('div', {'style':'float:left'}).update(
                     new Element('a', {'href': 'http://twitter.com/' + response.user.screen_name}).update(
@@ -265,6 +290,21 @@ class Horde_Block_Horde_twitter_timeline extends Horde_Block
                 $('{$contentNode}').insert({top:tweet});
             },
 
+            buildTweet: function(response) {
+                var tweet = new Element('div', {'class':'fbstreamstory'});
+                var tPic = new Element('div', {'style':'float:left'}).update(
+                    new Element('a', {'href': 'http://twitter.com/' + response.user.screen_name}).update(
+                        new Element('img', {'src':response.user.profile_image_url})
+                    )
+                );
+                var tBody = new Element('div', {'class':'fbstreambody'}).update(response.text);
+                tBody.appendChild(new Element('div', {'class':'fbstreaminfo'}).update('{$justNowText}'));
+                tweet.appendChild(tPic);
+                tweet.appendChild(tBody);
+
+                $('{$contentNode}').insert(tweet);
+            },
+
             clearInput: function() {
                 {$inputNode}.value = '';
             }
index 67b9939..2a4b59e 100644 (file)
@@ -49,6 +49,49 @@ case 'retweet':
     header('Content-Type: application/json');
     echo $result;
     exit;
+
+case 'getPage':
+    $stream = Horde_Serialize::unserialize($twitter->statuses->homeTimeline(array('page' => Horde_Util::getPost('page'))), Horde_Serialize::JSON);
+    $html = '';
+    foreach ($stream as $tweet) {
+        /* links */
+        $body = Horde_Text_Filter::filter($tweet->text, 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO_LINKURL));
+        $body = preg_replace("/[@]+([A-Za-z0-9-_]+)/", "<a href=\"http://twitter.com/\\1\" target=\"_blank\">\\0</a>", $body);
+
+        /* If this is a retweet, use the original author's profile info */
+        if (!empty($tweet->retweeted_status)) {
+            $tweetObj = $tweet->retweeted_status;
+        } else {
+            $tweetObj = $tweet;
+        }
+
+        /* These are all referencing the *original* tweet */
+        $profileLink = Horde::externalUrl('http://twitter.com/' . htmlspecialchars($tweetObj->user->screen_name), true);
+        $profileImg = $tweetObj->user->profile_image_url;
+        $authorName = htmlspecialchars($tweetObj->user->screen_name, ENT_COMPAT, Horde_Nls::getCharset());
+        $authorFullname = htmlspecialchars($tweetObj->user->name, ENT_COMPAT, Horde_Nls::getCharset());
+        $createdAt = $tweetObj->created_at;
+
+        $appText = Horde_Text_Filter::filter($tweet->source, 'xss', array());
+        $html .= '<div class="fbstreamstory">';
+        $html .= '<div style="float:left;text-align:center;width:70px;margin-right:5px;">' . $profileLink
+            . '<img src="' . $profileImg . '" alt="' . $authorName . '" title="' . $authorFullname . '" />'
+            . '</a><div style="overflow:hidden;">' . $profileLink . $authorName . '</a></div></div>';
+        $html .= ' <div class="fbstreambody">';
+        $html .=  $body;
+        $html .= '<div class="fbstreaminfo">' . sprintf(_("Posted %s via %s"), Horde_Date_Utils::relativeDateTime(strtotime($createdAt), $GLOBALS['prefs']->getValue('date_format')), $appText) . '</div>';
+
+        /* Specify the retweeted status */
+        if (!empty($tweet->retweeted_status)) {
+            $html .= '<div class="fbstreaminfo">' . sprintf(_("Retweeted by %s"), Horde::externalUrl('http://twitter.com/' . htmlspecialchars($tweet->user->screen_name), true)) . htmlspecialchars($tweet->user->screen_name) . '</a></div>';
+        }
+
+        $html .= '<div class="fbstreaminfo">' . Horde::link('#', '', '', '', 'Horde.twitter.buildReply(\'' . $tweet->id . '\', \'' . $tweet->user->screen_name . '\', \'' . $tweet->user->name . '\')') .  _("Reply") . '</a>';
+        $html .= '&nbsp;|&nbsp;' . Horde::link('#', '', '', '', 'Horde.twitter.retweet(\'' . $tweet->id . '\')') . _("Retweet") . '</a>';
+        $html .= '</div><div class="clear">&nbsp;</div></div></div>';
+    }
+    echo $html;
+    exit;
 }
 
 /* No requested action, check to see if we have a valid token */
index 9c161fc..a551cda 100644 (file)
 .fbemptystatus {
     font-style: italic;
     color: gray;
+}
+
+.fbgetmore {
+    text-align: center;
+    font-style: italic;
 }
\ No newline at end of file