From: Michael J. Rubinsky Date: Thu, 1 Jul 2010 21:14:57 +0000 (-0400) Subject: Break out the javascript for the twitter client. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=814018ccddfbb77ed98f18513cac2312c25b15a5;p=horde.git Break out the javascript for the twitter client. --- diff --git a/horde/js/twitterclient.js b/horde/js/twitterclient.js new file mode 100644 index 000000000..9096ad517 --- /dev/null +++ b/horde/js/twitterclient.js @@ -0,0 +1,158 @@ +/** + * Javascript based Twitter client for Horde. + * + * See the enclosed file COPYING for license information (GPL). If you + * did not receive this file, see http://www.fsf.org/copyleft/gpl.html. + * + * @author Michael J. Rubinsky + * @package Horde + */ +var Horde_Twitter = Class.create({ + inReplyTo: '', + page: 1, + + /** + * Const'r + * + * opts.input The domid of the input form element. + * opts.spinner The domid of the spinner element. + * opts.content The main content area, where the tweets are placed. + * opts.endpoint The url endpoint for horde/servcies/twitter.php + * opts.inreplyto + * opts.strings.inreplyto + * opts.strings.defaultText + * opts.strings.justnow + */ + initialize: function(opts) { + this.opts = opts; + $(this.opts.input).observe('focus', function() {this.clearInput()}.bind(this)); + $(this.opts.input).observe('blur', function() { + if (!$(this.opts.input).value.length) { + $(this.opts.input).value = this.opts.strings.defaultText; + } + }.bind(this)); + + /* Get the first page */ + this.updateStream(1); + + }, + + /** + * Post a new tweet. + * + */ + updateStatus: function(statusText) { + $(this.opts.input).stopObserving('blur'); + $(this.opts.spinner).toggle(); + params = { + actionID: 'updateStatus', + statusText: statusText, + params: { 'in_reply_to_status_id': this.inReplyTo } + }; + + new Ajax.Request(this.opts.endpoint, { + method: 'post', + parameters: params, + onComplete: function(response) { + this.updateCallback(response.responseJSON); + }.bind(this), + onFailure: function() { + $(this.opts.spinner).toggle(); + this.inReplyTo = ''; + } + }); + }, + + /** + * Retweet the specifed tweet id. + * + */ + retweet: function(id) { + $(this.opts.spinner).toggle(); + params = { + actionID: 'retweet', + tweetId: id + }; + new Ajax.Request(this.opts.endpoint, { + method: 'post', + parameters: params, + onComplete: function(response) { + this.updateCallback(response.responseJSON); + }.bind(this), + onFailure: function() { + $(this.opts.spinner).toggle(); + this.inReplyTo = ''; + } + }); + }, + + /** + * Update the timeline stream. + * + * @param integer page The page number to retrieve. + */ + updateStream: function(page) { + new Ajax.Request(this.opts.endpoint, { + method: 'post', + parameters: { actionID: 'getPage', 'page': page }, + onComplete: function(response) { + var h = $(this.opts.content).scrollHeight + $(this.opts.content).insert(response.responseText); + // Don't scroll if it's the first request. + if (page != 1) { + $(this.opts.content).scrollTop = h; + } else { + $(this.opts.content).scrollTop = 0; + } + }.bind(this), + onFailure: function() { + $(this.opts.spinner).toggle(); + } + }); + }, + + /** + * Build the reply structure + */ + buildReply: function(id, userid, usertext) { + this.inReplyTo = id; + $(this.opts.input).focus(); + $(this.opts.input).value = '@' + userid + ' '; + $(this.opts.inreplyto).update(this.opts.strings.inreplyto + usertext); + }, + + /** + * Callback for after a new tweet is posted. + */ + updateCallback: function(response) { + this.buildNewTweet(response); + $(this.opts.input).value = this.opts.strings.defaultText; + $(this.opts.spinner).toggle(); + this.inReplyTo = ''; + $(this.opts.inreplyto).update(''); + }, + + /** + * Build adnd display the node for a new tweet. + */ + 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( + 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(this.opts.strings.justnow)); + tweet.appendChild(tPic); + tweet.appendChild(tBody); + $(this.opts.content).insert({top:tweet}); + }, + + /** + * Clear the input field. + */ + clearInput: function() { + $(this.opts.input).value = ''; + } +}); \ No newline at end of file diff --git a/horde/lib/Block/twitter_timeline.php b/horde/lib/Block/twitter_timeline.php index 1ac248566..4b22c6d7c 100644 --- a/horde/lib/Block/twitter_timeline.php +++ b/horde/lib/Block/twitter_timeline.php @@ -104,6 +104,7 @@ class Horde_Block_Horde_twitter_timeline extends Horde_Block { global $conf; + /* Get the twitter driver */ try { $twitter = $this->_getTwitterObject(); } catch (Horde_Exception $e) { @@ -127,11 +128,38 @@ class Horde_Block_Horde_twitter_timeline extends Horde_Block } } + /* Build values to pass to the javascript twitter client */ + $defaultText = _("What are you working on now?"); + $endpoint = Horde::url('services/twitter.php', true); + $spinner = $instance . '_loading'; + $inputNode = $instance . '_newStatus'; + $inReplyToNode = $instance . '_inReplyTo'; + $inReplyToText = _("In reply to:"); + $contentNode = 'twitter_body' . $instance; + $justNowText = _("Just now..."); + + /* Add the client javascript / initialize it */ + Horde::addScriptFile('twitterclient.js'); + $script = <<_profile->status->text, ENT_COMPAT, Horde_Nls::getCharset()); // Bring in the Facebook CSS $csslink = $GLOBALS['registry']->get('themesuri', 'horde') . '/facebook.css'; - $defaultText = _("What are you working on now?"); + + /* Build the UI */ $html = ''; $html .= '
' . '' @@ -140,147 +168,10 @@ class Horde_Block_Horde_twitter_timeline extends Horde_Block $html .= '
' . 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"))) . '
'; $html .= '
'; $filter = Horde_Text_Filter::factory('Text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO)); - $html .= '
'; $html .= ''; - $endpoint = Horde::url('services/twitter.php', true); - $spinner = '$(\'' . $instance . '_loading\')'; - $inputNode = '$(\'' . $instance . '_newStatus\')'; - $inReplyToNode = '$(\'' . $instance . '_inReplyTo\')'; - $inReplyToText = _("In reply to:"); - $contentNode = 'twitter_body' . $instance; - $justNowText = _("Just now..."); - - $html .= << - var Horde = window.Horde || {}; - Horde.twitter = { - inReplyTo: '', - page: 1, - updateStatus: function(statusText) { - {$inputNode}.stopObserving('blur'); - {$spinner}.toggle(); - params = new Object(); - params.actionID = 'updateStatus'; - params.statusText = statusText; - params.params = { 'in_reply_to_status_id': this.inReplyTo }; - new Ajax.Request('$endpoint', { - method: 'post', - parameters: params, - onComplete: function(response) { - this.updateCallback(response.responseJSON); - }.bind(this), - onFailure: function() { - {$spinner}.toggle(); - this.inReplyTo = ''; - } - }); - }, - - retweet: function(id) { - {$spinner}.toggle(); - params = { - actionID: 'retweet', - tweetId: id - }; - new Ajax.Request('$endpoint', { - method: 'post', - parameters: params, - onComplete: function(response) { - this.updateCallback(response.responseJSON); - }.bind(this), - onFailure: function() { - {$spinner}.toggle(); - this.inReplyTo = ''; - } - }); - }, - - 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 h = $('{$contentNode}').scrollHeight - $('{$contentNode}').insert(content); - // Don't scroll if it's the first request. - if (page != 1) { - $('{$contentNode}').scrollTop = h; - } else { - $('{$contentNode}').scrollTop = 0; - } - }, - onFailure: function() { - {$spinner}.toggle(); - } - }); - }, - - buildReply: function(id, userid, usertext) { - this.inReplyTo = id; - {$inputNode}.focus(); - {$inputNode}.value = '@' + userid + ' '; - {$inReplyToNode}.update(' {$inReplyToText} ' + usertext); - }, - - updateCallback: function(response) { - this.buildNewTweet(response); - {$inputNode}.value = '{$defaultText}'; - {$spinner}.toggle(); - this.inReplyTo = ''; - {$inReplyToNode}.update(''); - }, - - 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( - 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({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 = ''; - } - }; - - document.observe('dom:loaded', function() { - {$inputNode}.observe('focus', function() {Horde.twitter.clearInput()}); - {$inputNode}.observe('blur', function() { - if (!{$inputNode}.value.length) { - {$inputNode}.value = '{$defaultText}'; - } - }); - - /* Get the first page */ - Horde.twitter.updateStream(1); - }); - -EOF; $html .= '
'; + return $html; }