Skip to content

Instantly share code, notes, and snippets.

@devhawk
Created September 23, 2010 20:41
Show Gist options
  • Select an option

  • Save devhawk/594320 to your computer and use it in GitHub Desktop.

Select an option

Save devhawk/594320 to your computer and use it in GitHub Desktop.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<style type="text/css">
.twitter_user
{
font-weight: bold;
}
#tweets
{
width: 600px;
}
.tweet
{
margin: 5px 0px;
}
.profile_image
{
float: left;
}
.profile_image img
{
margin-right: 5px;
}
.tweet_info
{
clear: both;
text-align: right;
}
</style>
</head>
<body>
<button id="btnCancel">
Cancel</button>
<div id="tweets">
<div>
<button id="more">
More</button></div>
</div>
<script src="Scripts/jquery-1.4.2.js" type="text/javascript"></script>
<script src="/Scripts/jquery.tmpl.js" type="text/javascript"></script>
<script id="clientTemplate" type="text/x-jquery-tmpl">
<div class="tweet">
<div class="profile_image">
<img width=48 height=48 src="${user.profile_image_url}"></img>
</div>
<div class="tweet_text">
<a class="twitter_user" href="http://twitter.com/${user.screen_name}">@${user.screen_name}</a>
{{html proctext(text)}}
</div>
<div class="tweet_info">
<a href="http://twitter.com/${user.screen_name}/status/${id}">
${proctime(created_at)}
</a>
via {{html procsource(source)}}
{{if (in_reply_to_status_id != null)}}
in reply to
<a href="http://twitter.com/${in_reply_to_screen_name}/status/${in_reply_to_status_id}">
${in_reply_to_screen_name}
</a>
{{/if}}
</div>
</div>
</script>
<script type="text/javascript">
//jQuery function to replicate IE's outerHTML property
jQuery.fn.outerHTML = function () {
return $('<div>').append(this.eq(0).clone()).html();
};
//helper functions to render tweet time (aka: x seconds ago, y days ago, etc)
var K = function () { var a = navigator.userAgent; return { ie: a.match(/MSIE\s([^;]*)/)} } ();
var proctime = function (a) { var b = new Date(); var c = new Date(a); if (K.ie) { c = Date.parse(a.replace(/( \+)/, ' UTC$1')) } var d = b - c; var e = 1000, minute = e * 60, hour = minute * 60, day = hour * 24, week = day * 7; if (isNaN(d) || d < 0) { return "" } if (d < e * 7) { return "right now" } if (d < minute) { return Math.floor(d / e) + " seconds ago" } if (d < minute * 2) { return "about 1 minute ago" } if (d < hour) { return Math.floor(d / minute) + " minutes ago" } if (d < hour * 2) { return "about 1 hour ago" } if (d < day) { return Math.floor(d / hour) + " hours ago" } if (d > day && d < day * 2) { return "yesterday" } if (d < day * 365) { return Math.floor(d / day) + " days ago" } else { return "over a year ago" } };
//helper function to render tweet text w/ links
function proctext(text) {
text = text.replace(/(http:\/\/\S*)/g, "<a href='$1' target='_blank' rel='nofollow'>$1</a>");
text = text.replace(/@(\w+)/g, "<a href='http://twitter.com/$1' target='_blank' rel='nofollow'>@$1</a>");
text = text.replace(/#(\w+)/g, "<a href='http://twitter.com/search?q=%23$1' target='_blank' rel='nofollow'>#$1</a>");
return text;
}
//helper function to add target and nofollow attributes to tweet source
function procsource(source) {
if (source.search("<a ") == -1)
return source;
return $(source).attr("target", "_blank").attr("rel", "nofollow").outerHTML();
};
</script>
<script src="Scripts/rx.js" type="text/javascript"></script>
<script src="Scripts/rx.jQuery.js" type="text/javascript"></script>
<script type="text/javascript">
//JSONP callback function
function mycallback(data) {
// alert("mycallback: " + data);
window.mydata = data;
}
// Interval based observable to update
var rxTimeUpdate = Rx.Observable.Interval(10000)
.Subscribe(function (count) {
$("div.tweet").each(function (index, element) {
var tweet = $(element).data("tweet");
var newtime = proctime(tweet.created_at) + " " + count;
$("div.tweet_info a:first", element).text(newtime);
});
});
var api_url = "http://api.twitter.com/1/statuses/home_timeline.json?callback=mycallback";
$("#more").click(function (event) {
$("#more").attr("disabled", "disabled");
Rx.Observable.Return(0)
.Select(function () {
var tweet = $("div.tweet:last").data("tweet");
return api_url + "&max_id=" + (tweet.id - 1);
})
.Select(function (url) {
return "/Home/GetOauthSignedUrl?url=" + escape(url);
})
.SelectMany(function (url) {
return $.ajaxAsObservable({ url: url });
})
.Select(function (next) {
return next.data;
})
.SelectMany(function (url) {
return $.getScriptAsObservable(url);
})
.SelectMany(function () {
return Rx.Observable.FromArray(window.mydata);
})
.Select(function (tweet) {
return $("#clientTemplate").tmpl(tweet).data("tweet", tweet);
})
.Subscribe(
function (tweet) {
tweet.hide().insertAfter("div.tweet:last").slideDown();
$("#more").removeAttr("disabled");
},
function (error) {
alert("OnError: " + error);
}
);
});
var rxNewTweets = Rx.Observable.Timer(0, 10000)
// .Do(function(url) { alert(url); })
.Select(function (count) {
if (count === 0) {
return api_url;
}
var tweet = $("div.tweet:first").data("tweet");
return api_url + "&since_id=" + tweet.id;
})
.Select(function (url) {
return "/Home/GetOauthSignedUrl?url=" + escape(url);
})
.SelectMany(function (url) {
return $.ajaxAsObservable({ url: url });
})
.Select(function (next) {
return next.data;
})
.SelectMany(function (url) {
return $.getScriptAsObservable(url);
})
.SelectMany(function () {
return Rx.Observable.FromArray(window.mydata.reverse());
})
.Select(function (tweet) {
return $("#clientTemplate").tmpl(tweet).data("tweet", tweet);
})
.Subscribe(
function (tweet) {
tweet.hide().prependTo("#tweets").slideDown();
},
function (error) {
alert("OnError: " + error);
}
);
$("#btnCancel").click(function () {
$("#btnCancel").slideToggle();
$("#more").slideToggle();
rxNewTweets.Dispose();
rxTimeUpdate.Dispose();
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment