/* 	Twitter Friends v1.0
	Blog : http://www.moretechtips.net
	Project: http://code.google.com/p/twitter-friends-widget/
	Copyright 2009 [Mike @ moretechtips.net] 
	Licensed under the Apache License, Version 2.0 
	(the "License"); you may not use this file except in compliance with the License. 
	You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
*/

(function ($) { $.fn.twitterFriends = function (allOptions) { var defaults = { debug: 0, username: '', friends: 0, users: 20, loop: 0, user_link: 0, user_image: 48, user_animate: 'opacity', user_change: 200, user_swap: 5000, user_append: 1, header: '', tweet: 0, tweet_avatar: 1, tweet_author: 0, tweet_date: 1, tweet_source: 1, tweet_image: 48, tweet_stay: 5000, tweet_change: 200, tweet_animate: 'opacity', info: '<div class="twitter-title"></div><a href="http://twitter.com/ASPRobot" rel="external nofollow" target="_blank"><img class="imgFollowme" src="../img/follow-me.jpg" alt="Follow ASP.NET Robot on Twitter" title="Follow ASP.NET Robot on Twitter" /></a>' }; allOptions = $.extend({}, defaults, allOptions); return this.each(function () { var wasOutput = 0; var rs = []; var vp = -1, ai = -1, si = -1; var div = $(this), usrsDiv = null, stsDiv = null, hdDiv = null; var op = allOptions; if (div.attr('options')) { try { op = eval('(' + div.attr('options') + ')'); } catch (e) { div.html('<b style="color:red">' + e + '</b>'); return; }; op = $.extend({}, defaults, op); }; var requestUsers = function () { var url = op.friends ? 'http://twitter.com/statuses/friends.json' : 'http://twitter.com/statuses/followers.json'; var data = { screen_name: op.username, cursor: -1 }; $.ajax({ url: url, data: data, success: requestedUsers, dataType: 'jsonp', cache: true }); }; var requestedUsers = function (json) { if (!json.users) { if (op.debug) div.html('<b style="color:red">Error:' + (json.error ? json.error : 'unkown') + '</b>'); return; }; rs = json.users.reverse(); if (rs.length == 0) return; output(); vp = -1; addUsers(); }; var addUsers = function () { if ((vp + 1) * op.users >= rs.length) { if (op.loop) vp = -1; else return; }; usrsDiv.html(''); vp++; for (var i = vp * op.users; i < (vp + 1) * op.users; i++) { if (i >= rs.length) break; addUser(rs[i], i); }; ai = op.user_append ? -1 : $('a', usrsDiv).length; showUser(); si = -1; if (op.tweet) hideStatus(); }; var addUser = function (x, i) { var u = op.user_link && x.url ? x.url : 'http://twitter.com/' + x.screen_name; var t = x.name + (x.status && op.tweet ? ': ' + x.status.text : ''); t = t.replace(/"/g, '&quot;').replace(/'/g, '&#39;'); $('<a style="display:none;height:' + op.user_image + 'px" href="' + u + '" title="' + t + '">' + '<img src="' + x.profile_image_url + '" border="0" height="' + op.user_image + '" width="' + op.user_image + '"/>' + '</a>').appendTo(usrsDiv); }; var showUser = function () { ai = op.user_append ? ai + 1 : ai - 1; var x = $('a:eq(' + ai + ')', usrsDiv); if (!x.length) { if (!op.tweet) usrsDiv.animate({ opacity: 1 }, op.user_swap, "linear", addUsers); return; }; var effect = new Object; effect[op.user_animate] = 'show'; x.animate(effect, op.user_change, "linear", showUser); }; var addStatus = function (x, s) { var u = op.user_link && x.url ? x.url : 'http://twitter.com/' + x.screen_name; var t = x.name; stsDiv.html('<div style="display:none;">' + (op.tweet_avatar ? '<span class="tf-avatar">' + '<a href="' + u + '" title="' + t + '">' + '<img src="' + x.profile_image_url + '" height="' + op.tweet_image + '" width="' + op.tweet_image + '" border="0"/>' + '</a>' + '</span>' : '') + '<span class="tf-body">' + (op.tweet_author ? '<strong>' + '<a href="' + u + '" title="' + t + '">' + x.screen_name + '</a>' + '</strong>' : '') + '<span class="tf-content">' + linkify(s.text) + '</span>' + '<span class="tf-meta">' + (op.tweet_date ? '<a class="tf-date" href="http://twitter.com/' + x.screen_name + '/status/' + s.id + '">' + formatDate(s.created_at) + '</a>' : '') + (op.tweet_source ? '<span class="tf-source"> from ' + decodeHTML(s.source) + '</span>' : '') + '</span>' + '</span>' + '</div>'); }; var hideStatus = function () { if (si > -1) $('div', stsDiv).fadeOut(op.tweet_change, showStatus); else showStatus(); }; var showStatus = function () { var x = null, s = null; while (!s) { si++; if (si >= $('a', usrsDiv).length) { addUsers(); return; }; x = rs[vp * op.users + si]; s = x.status; }; addStatus(x, s); var effect = new Object; effect[op.tweet_animate] = 'show'; $('div', stsDiv).animate(effect, op.tweet_change, "linear", stayStatus); }; var stayStatus = function () { $('div', stsDiv).animate({ opacity: 1 }, op.tweet_stay, "linear", hideStatus); }; var linkify = function (d) { return d.replace(/\bhttps?\:\/\/\S+/gi, function (b) { var c = ''; b = b.replace(/(\.*|\?*|\!*)$/, function (m, a) { c = a; return '' }); return '<a class="tf-link" href="' + b + '">' + ((b.length > 25) ? b.substr(0, 24) + '...' : b) + '</a>' + c; }).replace(/\B\@([A-Z0-9_]{1,15})/gi, '@<a class="tf-at" href="http://twitter.com/$1">$1</a>').replace(/\B\#([A-Z0-9_]+)/gi, '<a class="tf-hashtag" href="http://search.twitter.com/search?q=%23$1">#$1</a>') }; var decodeHTML = function (s) { return s.replace(/&lt;/gi, '<').replace(/&gt;/gi, '>').replace(/&quot;/gi, '"'); }; var formatDate = function (s) { if (/^(\w\w\w) (\w\w\w) (\d\d?) (\d\d?:\d\d?:\d\d?) ([\+\-]\d+) (\d\d\d\d)$/i.test(s)) s = s.replace(/^(\w\w\w) (\w\w\w) (\d\d?) (\d\d?:\d\d?:\d\d?) ([\+\-]\d+) (\d\d\d\d)$/i, '$1, $3 $2 $6 $4 $5'); var dat = new Date(), tody = new Date(); dat.setTime(Date.parse(s)); var td = tody.getDate(), tm = tody.getMonth() + 1, ty = tody.getFullYear(), th = tody.getHours(), tmn = tody.getMinutes(), ts = tody.getSeconds(); var d = dat.getDate(), m = dat.getMonth() + 1, y = dat.getFullYear(), h = dat.getHours(), mn = dat.getMinutes(), s = dat.getSeconds(); if (y == ty && m == tm && d == td) { var dh = th - h; if (dh > 0) return dh + ' hour' + (dh > 1 ? 's' : '') + ' ago'; var dmn = tmn - mn; if (dmn > 0) return dmn + ' minute' + (dmn > 1 ? 's' : '') + ' ago'; var ds = ts - s; return ds + ' second' + (ds > 1 ? 's' : '') + ' ago'; } else return m + '/' + d + '/' + y; }; var requestMe = function () { $.ajax({ url: 'http://twitter.com/users/show.json', data: { screen_name: op.username }, success: requestedMe, dataType: 'jsonp', cache: true }); }; var requestedMe = function (j) { output(); if (!j.screen_name) { if (op.debug) hdDiv.html('<b style="color:red">Error:' + (j.error ? j.error : 'unkown') + '</b>'); return; }; hdDiv.html(op.header.replace(/_tp_/g, 'http://twitter.com/' + j.screen_name).replace(/_fr_/g, j.friends_count).replace(/_fo_/g, j.followers_count).replace(/_ti_/g, j.profile_image_url)) }; var init = function () { if (op.header) requestMe(); requestUsers(); }; var output = function () { if (wasOutput) return; else wasOutput = 1; div.html(''); if (op.info) div.append(op.info); if (op.header) hdDiv = $('<div class="tf-header"></div>').appendTo(div); usrsDiv = $('<div class="tf-users"></div>').appendTo(div); if (op.tweet) stsDiv = $('<div class="tf-tweet"></div>').appendTo(div); }; init(); }); } })(jQuery); jQuery(document).ready(function () { jQuery('div.twitter-friends').twitterFriends(); });
