Return to Snippet

Revision: 17032
at August 21, 2009 06:53 by jonniespratley


Initial Code
/**
 * @author Jonnie Spratley
 * @classDescription - Full jQuery wrapper for Twitter API. This plugin requires
 * TwitterService.php for anything to work, files must be in same location. Or
 * specified in the options of the plugin.
 * @version - 0.9
 * @projectDescription - http://code.google.com/p/jquery-jtwitter/
 * @type - defaultTimeline: 'public' - String - The default timeline to recieve. public | friends | user
 * @type - autoFetch: true,
 * @type - showActions: false,
 * @type - tweetarea: null - the id of the textarea for updating status, works well with replies
 * @type - user: null - Object - A user object holding propertys username and/or password.
 * @type - 		username: null - String - The twitter username
 * @type - 		password: null - String - The twitter user password
 * @type - search: null - Object - The next and prev link ids for paging search results.
 * @type -		next: null,
 * @type -		prev: null,
 * @type - resultLocations: - null - Object - A object containing all of the result locations.
 * @type - debug: null,
 * @type - success: null,
 * @type - error: null,
 * @type - currentUser: null,
 * @type - rateStatus: null,
 * @type - deleteTweet: null,
 * @type - getFollowing: null,
 * @type - getFollowers: null,
 * @type - getFriendsFollowers: null,
 * @type - getFriendsTimeline: null,
 * @type - getPublicTimeline: null,
 * @type - getUserTimeline: null,
 * @type - getReplies: null,
 * @type - showTweet: null,
 * @type - postTweet: null,
 * @type - getMessages: null,
 * @type - deleteMessage: null,
 * @type - createMessage: null,
 * @type - getSentMessages: null,
 * @type - getFavorites: null,
 * @type - createFavorite: null,
 * @type - deleteFavorite: null,
 * @type - followMember: null,
 * @type - unfollowMember: null,
 * @type - confirmFollow: null,
 * @type - blockMember: null,
 * @type - unblockMember: null,
 * @type - getAllFollowers: null,
 * @type - getAllFriends: null,
 * @type - getRateLimit: null,
 * @type - endSession: null,
 * @type - verifyCredentials: null,
 * @type - updateDevice: null,
 * @type - updateLocation: null,
 * @type - updateProfile: null,
 * @type - updateProfileImage: null,
 * @type - updateBackgroundImage: null,
 * @type - updateProfileColors: null,
 * @type - searchKeywords: null,
 * @type - searchTrends: null
 */
(function($){
	var defaultSettings = {
		defaultTimeline: 'public',
		autoFetch: true,
		loader: null,
		showActions: false,
		user: {
			username: null,
			password: null
		},
		search: {
			next: null,
			prev: null,
		},
		tweetarea: null,
		resultLocations: {
			debug: null,
			success: null,
			error: null,
			currentUser: null,
			rateStatus: null,
			deleteTweet: null,
			getFollowing: null,
			getFollowers: null,
			getFriendsFollowers: null,
			getFriendsTimeline: null,
			getPublicTimeline: null,
			getUserTimeline: null,
			getReplies: null,
			showTweet: null,
			postTweet: null,
			getMessages: null,
			deleteMessage: null,
			createMessage: null,
			getSentMessages: null,
			getFavorites: null,
			createFavorite: null,
			deleteFavorite: null,
			followMember: null,
			unfollowMember: null,
			confirmFollow: null,
			blockMember: null,
			unblockMember: null,
			getAllFollowers: null,
			getAllFriends: null,
			getRateLimit: null,
			endSession: null,
			verifyCredentials: null,
			updateDevice: null,
			updateLocation: null,
			updateProfile: null,
			updateProfileImage: null,
			updateBackgroundImage: null,
			updateProfileColors: null,
			searchKeywords: null,
			searchTrends: null
		}
	};
	var thisWrap = '';
	var inCall = false;
	var jtwitterUserObject = {
		created_at: new Date(),
		description: '',
		favourites_count: 0,
		followers_count: 0,
		following: 0,
		id: 0,
		location: '',
		name: '',
		notifications: true,
		profile_background_color: '000000',
		profile_background_image_url: '',
		profile_background_tile: true,
		profile_image_url: '',
		profile_link_color: '000000',
		profile_sidebar_fill_color: '000000',
		profile_sidebar_border_color: '000000',
		isprotected: false,
		screen_name: '',
		statuses_count: 0,
		time_zone: '',
		url: '',
		utc_offset: 0,
		verified: false
	};
	
	var jtwitterMessageObject = {
		id: 0,
		text: '',
		created_at: new Date(),
		recipient_id: 0,
		recipient_screen_name: '',
		recipient: jtwitterUserObject,
		sender_id: 0,
		sender_screen_name: '',
		sender: jtwitterUserObject
	};
	
	var jtwitterTweetObject = {
		id: 0,
		text: '',
		created_at: new Date(),
		source: '',
		truncated: false,
		favorited: false,
		in_reply_to_screen_name: null,
		in_reply_to_status_id: null,
		in_reply_to_user_id: null,
		user: jtwitterTweetObject
	};
	
	var jtwitterRateObject = {
		reset_time_in_seconds: 0,
		reset_time: new Date(),
		remaining_hits: 0,
		hourly_limit: 0
	};
	
	var jtwitterTrendObject = {
		as_of: new Date(),
		trends: {
			name: '',
			url: ''
		}
	};
	
	var jtwitterSearchObject = {
		completed_in: 0,
		max_id: 0,
		next_page: '',
		page: 0,
		query: '',
		refresh_url: '',
		results: {
			created_at: new Date(),
			from_user: '',
			from_user_id: 0,
			id: 0,
			iso_language_code: '',
			profile_image_url: '',
			source: '',
			text: '',
			to_user_id: 0
		}
	};
	
	$.fn.jtwitter = function(url, options){
	
		thisWrap = $(this);
		
		var defaultOptions = $.extend(true, {}, defaultSettings, options);
		
		$.jtwitter = {
			jtwitterMethods: ["deleteTweet", "getFollowing", "getFollowers", "getFriendsFollowers", "getFriendsTimeline", "getPublicTimeline", "getUserTimeline", "getReplies", "showTweet", "postTweet", "showProfile", "getMessages", "deleteMessage", "createMessage", "getSentMessages", "followMember", "unfollowMember", "confirmFollow", "getFavorites", "createFavorite", "deleteFavorite", "blockMember", "unBlockMember", "getAllFriends", "getAllFollowers", "getRateLimit", "endSession", "verifyCredentials", "updateDevice", "updateLocation", "updateProfile", "updateBackgroundImage", "updateProfileColors", "updateProfileImage", "notification_turnOn", "notification_turnOff", "search_keywords", "search_trends", "help_test"],
			
			/**
			 * I make a get call to the proxy which then calls on the twitter api.
			 * @param {Object} method - the method to invoke
			 * @param {Object} params - the parameter object to send with the call
			 * @param {Object} callback - the callback to execute once result is recieved
			 */
			_get: function(method, params, callback){
				$.extend(params, {
					m: method
				});
				
				//@TODO: Check this 
				//if ( method != 'verifyCredentials' || method != 'getPublicTimeline' || method != 'searchKeywords' || method != 'searchTrends' ){
				
				if (defaultOptions.user.username) {
					$.extend(params, {
						u: defaultOptions.user.username
					});
				}
				
				if (defaultOptions.user.password) {
					$.extend(params, {
						p: defaultOptions.user.password
					});
				}
				
				//}
				
				//Set loading to true
				defaultOptions.loader(true);
				
				$.get(url, params, function(result){
					defaultOptions.loader(false);
					
					var resultArray = eval('(' + result + ')');
					if (callback) {
						callback(resultArray);
					}
					//return resultArray;
				});
			},
			
			/**
			 * I post data to the proxy which then posts to twitter.com
			 *
			 * @param {Object} method - the method to invoke
			 * @param {Object} params - the parameter object to send with the call
			 * @param {Object} callback - the callback to execute once result is recieved
			 */
			_post: function(method, params, callback){
				$.extend(params, {
					m: method,
					u: defaultOptions.user.username,
					p: defaultOptions.user.password
				});
				
				//Set the loader
				defaultOptions.loader(true);
				
				$.post(url, params, function(result){
					defaultOptions.loader(false);
					
					var resultArray = eval('(' + result + ')');
					if (callback) {
						callback(resultArray);
					}
				});
			},
			
			
			/**
			 * I am the methods object, I hold all of the methods that are available on the proxy.
			 * I then call upon the _get function passing all required parameters, and then handle
			 * the result by passing the result and the method called to the build function. Which
			 * then populates the specified jquery object with the formatted and build data.
			 */
			getPublicTimeline: function(callback){
				$.jtwitter._get('getPublicTimeline', {}, function(data){
					(defaultOptions.resultLocations.getPublicTimeline) ? $(defaultOptions.resultLocations.getPublicTimeline).html($.jtwitter._builders.build('tweet', data)) : (callback(data));
				});
			},
			
			getFollowers: function( page, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._get('getFollowers', {
						page: page
					}, function(data){
						(defaultOptions.resultLocations.getFollowers) ? $(defaultOptions.resultLocations.getFollowers).html($.jtwitter._builders.build('follower', data)) : (callback(data));
					});
				}
			},
			
			getFollowing: function(count, page, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._get('getFollowing', {
						count: count,
						page: page
					}, function(data){
						(defaultOptions.resultLocations.getFollowing) ? $(defaultOptions.resultLocations.getFollowing).html($.jtwitter._builders.build('follower', data)) : (callback(data));
					});
				}
			},
			
			getFriendsFollowers: function(callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._get('getFriendsFollowers', {}, function(data){
						(defaultOptions.resultLocations.getFriendsFollowers) ? $(defaultOptions.resultLocations.getFriendsFollowers).html($.jtwitter._builders.build('tweet', data)) : (callback(data));
					});
				}
			},
			
			getFriendsTimeline: function(count, page, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._get('getFriendsTimeline', {
						count: count,
						page: page
					}, function(data){
						(defaultOptions.resultLocations.getFriendsTimeline) ? $(defaultOptions.resultLocations.getFriendsTimeline).html($.jtwitter._builders.build('tweet', data)) : (callback(data));
					});
				}
				
			},
			
			getUserTimeline: function(user, count, page, callback){
			
				$.jtwitter._get('getUserTimeline', {
					user: user,
					count: count,
					page: page
				}, function(data){
					(defaultOptions.resultLocations.getUserTimeline) ? $(defaultOptions.resultLocations.getUserTimeline).html($.jtwitter._builders.build('tweet', data)) : (callback(data));
				});
				
			},
			
			getReplies: function(count, page, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._get('getReplies', {
						count: count,
						page: page
					}, function(data){
						(defaultOptions.resultLocations.getReplies) ? $(defaultOptions.resultLocations.getReplies).html($.jtwitter._builders.build('tweet', data)) : (callback(data));
					});
				}
			},
			
			showTweet: function(id, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._get('showTweet', {
						id: id
					}, function(data){
					
						(callback(data));
					});
				}
			},
			
			postTweet: function(text, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._post('postTweet', {
						status: text
					}, function(data){
						(defaultOptions.resultLocations.getFriendsTimeline) ? $(defaultOptions.resultLocations.getFriendsTimeline).prepend($.jtwitter._builders.build('singletweet', data)) : (callback(data));
					});
				}
			},
			
			getMessages: function(count, page, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._get('getMessages', {
						count: count,
						page: page
					}, function(data){
						(defaultOptions.resultLocations.getMessages) ? $(defaultOptions.resultLocations.getMessages).html($.jtwitter._builders.build('message', data)) : (callback(data));
					});
				}
			},
			
			getSentMessages: function(count, page, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._get('getSentMessages', {
						count: count,
						page: page
					}, function(data){
						(defaultOptions.resultLocations.getPublicTimeline) ? $(defaultOptions.resultLocations.getPublicTimeline).html($.jtwitter._builders.build(1, data)) : (callback(data));
					});
				}
			},
			
			createMessage: function(userid, text, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._post('createMessage', {
						id: userid,
						text: text
					}, function(data){
						(defaultOptions.resultLocations.createMessage) ? $(defaultOptions.resultLocations.createMessage).html($.jtwitter._builders.build('message', data)) : (callback(data));
					});
				}
			},
			
			deleteMessage: function(msgid, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._post('deleteMessage', {
						id: msgid
					}, function(data){
						(defaultOptions.resultLocations.deleteMessage) ? $(defaultOptions.resultLocations.deleteMessage).html($.jtwitter._builders.build('message', data)) : (callback(data));
					});
				}
			},
			
			getFavorites: function(count, page, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._get('getFavorites', {
						count: count,
						page: page
					}, function(data){
						(defaultOptions.resultLocations.getFavorites) ? $(defaultOptions.resultLocations.getFavorites).html($.jtwitter._builders.build('tweet', data)) : (callback(data));
					});
				}
			},
			
			createFavorite: function(msgid, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._post('createFavorite', {
						id: msgid
					}, function(data){
						(defaultOptions.resultLocations.createFavorite) ? $(defaultOptions.resultLocations.createFavorite).html($.jtwitter._builders.build('tweet', data)) : (callback(data));
					});
				}
			},
			
			deleteFavorite: function(msgid, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._post('deleteFavorite', {
						id: msgid
					}, function(data){
						(defaultOptions.resultLocations.deleteFavorite) ? $(defaultOptions.resultLocations.deleteFavorite).html($.jtwitter._builders.build('tweet', data)) : (callback(data));
					});
				}
			},
			
			deleteTweet: function(id, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._post('deleteTweet', {
						id: id
					}, function(data){
						(defaultOptions.resultLocations.deleteTweet) ? $(defaultOptions.resultLocations.deleteTweet).html($.jtwitter._builders.build('tweet', data)) : (callback(data));
					});
				}
			},
			
			followMember: function(userid, follow, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._post('followMember', {
						id: userid,
						follow: follow
					}, function(data){
						(defaultOptions.resultLocations.followMember) ? $(defaultOptions.resultLocations.followMember).html($.jtwitter._builders.build('user', data)) : (callback(data));
					});
				}
			},
			
			unfollowMember: function(userid, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._post('unfollowMember', {
						id: userid
					}, function(data){
						(defaultOptions.resultLocations.unfollowMember) ? $(defaultOptions.resultLocations.unfollowMember).html($.jtwitter._builders.build('user', data)) : (callback(data));
					});
				}
			},
			
			confirmFollow: function(usera, userb, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._get('confirmFollow', {
						a: usera,
						b: userb
					}, function(data){
						(defaultOptions.resultLocations.confirmFollow) ? $(defaultOptions.resultLocations.confirmFollow).html($.jtwitter._builders.build('user', data)) : (callback(data));
					});
				}
			},
			
			blockMember: function(userid, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._post('blockMember', {
						id: userid
					}, function(data){
						(defaultOptions.resultLocations.blockMember) ? $(defaultOptions.resultLocations.blockMember).html($.jtwitter._builders.build('user', data)) : (callback(data));
					});
				}
			},
			
			unblockMember: function(userid, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._post('unblockMember', {
						id: userid
					}, function(data){
						(defaultOptions.resultLocations.unblockMember) ? $(defaultOptions.resultLocations.unblockMember).html($.jtwitter._builders.build('user', data)) : (callback(data));
					});
				}
			},
			
			getAllFollowers: function(callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._get('getAllFollowers', {}, function(data){
						(defaultOptions.resultLocations.getAllFollowers) ? $(defaultOptions.resultLocations.getAllFollowers).html($.jtwitter._builders.build('countfriends', data)) : (callback(data));
					});
				}
			},
			
			getAllFriends: function(callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._get('getAllFriends', {}, function(data){
						(defaultOptions.resultLocations.getAllFriends) ? $(defaultOptions.resultLocations.getAllFriends).html($.jtwitter._builders.build('countfriends', data)) : (callback(data));
					});
				}
			},
			
			getRateLimit: function(callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._get('getRateLimit', {}, function(data){
						(defaultOptions.resultLocations.getRateLimit) ? $(defaultOptions.resultLocations.getRateLimit).html($.jtwitter._builders.build('rate', data)) : (callback(data));
					});
				}
			},
			
			endSession: function(callback){
				$.jtwitter._post('endSession', {}, function(data){
					(defaultOptions.resultLocations.endSession) ? $(defaultOptions.resultLocations.endSession).html($.jtwitter._builders.build('user', data)) : (callback(data));
				});
			},
			
			verifyCredentials: function(user, pass, callback){
				$.extend(defaultOptions.user, {
					username: user,
					password: pass
				});
				$.jtwitter._get('verifyCredentials', {
					u: user,
					p: pass
				}, function(data){
					(defaultOptions.resultLocations.verifyCredentials) ? $(defaultOptions.resultLocations.verifyCredentials).html($.jtwitter._builders.build('user', data)) : (callback(data));
				});
			},
			
			updateDevice: function(device, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._post('updateDevice', {
						device: device
					}, function(data){
						(defaultOptions.resultLocations.updateDevice) ? $(defaultOptions.resultLocations.updateDevice).html($.jtwitter._builders.build('user', data)) : (callback(data));
					});
				}
			},
			
			updateLocation: function(location, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._post('updateLocation', {
						location: location
					}, function(data){
						(defaultOptions.resultLocations.updateLocation) ? $(defaultOptions.resultLocations.updateLocation).html($.jtwitter._builders.build('user', data)) : (callback(data));
					});
				}
			},
			
			updateProfile: function(name, email, url, location, desc, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._post('updateProfile', {
						n: name,
						e: email,
						url: url,
						l: location,
						d: desc
					}, function(data){
						(defaultOptions.resultLocations.updateProfile) ? $(defaultOptions.resultLocations.updateProfile).html($.jtwitter._builders.build('user', data)) : (callback(data));
					});
				}
			},
			
			updateProfileImage: function(img, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._post('updateProfileImage', {
						image: img
					}, function(data){
						(defaultOptions.resultLocations.updateProfileImage) ? $(defaultOptions.resultLocations.updateProfileImage).html($.jtwitter._builders.build('user', data)) : (callback(data));
					});
				}
			},
			
			updateBackgroundImage: function(img, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._post('updateBackgroundImage', {
						image: img
					}, function(data){
						(defaultOptions.resultLocations.updateBackgroundImage) ? $(defaultOptions.resultLocations.updateBackgroundImage).html($.jtwitter._builders.build('user', data)) : (callback(data));
					});
				}
			},
			
			updateProfileColors: function(bg, text, link, sidebg, sideborder, callback){
				if ($.jtwitter._utils.checkUser()) {
					$.jtwitter._post('updateProfileColors', {
						bg: bg,
						t: text,
						sbg: sidebg,
						sb: sideborder
					}, function(data){
						(defaultOptions.resultLocations.updateProfileColors) ? $(defaultOptions.resultLocations.updateProfileColors).html($.jtwitter._builders.build('user', data)) : (callback(data));
					});
				}
			},
			
			searchKeywords: function(q, page, since, sinceid, maxid, callback){
				$.jtwitter._get('searchKeywords', {
					q: q,
					page: page,
					since: since,
					sinceid: sinceid,
					maxid: maxid
				
				}, function(data){
					(defaultOptions.resultLocations.searchKeywords) ? $(defaultOptions.resultLocations.searchKeywords).html($.jtwitter._builders.build('search', data)) : (callback(data));
				});
			},
			
			searchTrends: function(callback){
				$.jtwitter._get('searchTrends', {}, function(data){
					(defaultOptions.resultLocations.searchTrends) ? $(defaultOptions.resultLocations.searchTrends).html($.jtwitter._builders.build('trends', data)) : (callback(data));
				});
			},
			
			
			
			/**
			 * I hold all of the functions that build the html from the result of a service call
			 */
			_builders: {
				/**
				 * I evaluate and prep each build depending on what method was invoked
				 * @param {Object} mode - what method that was called
				 * @param {Object} data - the result object from that method
				 */
				build: function(mode, data){
					var html = '';
					
					switch (mode) {
						case 'tweet'://Timelines, Replies, Favorites,
							$.each(data, function(i, obj){
								$.extend(jtwitterTweetObject, obj);
								html += $.jtwitter._builders.buildTweets(jtwitterTweetObject);
							});
						break;
						case 'singletweet'://Timelines, Replies, Favorites,
							$.extend(jtwitterTweetObject, data);
							
							html += $.jtwitter._builders.buildTweets(jtwitterTweetObject);
							
						break;
							
						case 'message'://Messages, Sent Messages
							$.each(data, function(i, obj){
								$.extend(jtwitterMessageObject, obj);
								html += $.jtwitter._builders.buildMessages(jtwitterMessageObject);
							});
						break;
							
						case 'follower'://Followers Image List
							$.each(data, function(i, obj){
								$.extend(jtwitterUserObject, obj);
								html += $.jtwitter._builders.buildImages(jtwitterUserObject);
							});
						break;
							
						case 'user'://User Update Status, Profile changes, etc user 						 
							$.extend(jtwitterUserObject, data);
							html += $.jtwitter._builders.buildUser(jtwitterUserObject);
						break;
							
						case 'search'://User Update Status, Profile changes, etc user 
							$.extend(jtwitterSearchObject, data);
							$.each(jtwitterSearchObject.results, function(i, obj){
								html += $.jtwitter._builders.buildSearch(obj);
							});
						break;
							
						case 'trends'://User Update Status, Profile changes, etc user 
							$.extend(jtwitterTrendObject, data);
							$.each(jtwitterTrendObject.trends, function(i, obj){
								html += $.jtwitter._builders.buildTrends(obj);
							});
						break;
							
						case 'rate': //Rate Status 
							$.extend(jtwitterRateObject, data);
							html += $.jtwitter._builders.buildRateStatus(jtwitterRateObject);
						break;
					}
					return html;
				},
				
				buildTweets: function(tweetObj){
				
					var html = '';
					var altUser = '';
					
					altUser = (defaultOptions.user.username === tweetObj.user.screen_name ? 'alt' : '');
					
					html += '<li class="jtwitter-tweet ' + altUser + '" id="jtweet_' + tweetObj.id + '">';
					html += '<ul>';
					if (defaultOptions.showActions === true) {
						html += $.jtwitter._builders.buildActions(tweetObj);
					}
					html += '<li class="jtwitter-profile-image"><img src="' + tweetObj.user.profile_image_url + '" alt="Photo of ' + tweetObj.user.name + '"/></li>';
					html += '<li class="jtwitter-screen-name">';
					html += '<a class="jtwitter-url" href="http://twitter.com/' + tweetObj.user.screen_name + '" title="' + tweetObj.user.screen_name + '" rel="bookmark" target="_blank">';
					html += tweetObj.user.screen_name + '</a></li>';
					html += '<li class="jtwitter-text">' + tweetObj.text + '</li>';
					html += '<li class="jtwitter-time">';
					html += '<span class="jtwitter-created-at">' + $.jtwitter._utils.prettifyDate(tweetObj.created_at) + ' </span>';
					html += '<span class="jtwitter-source">via ' + tweetObj.source + '</span>';
					html += '</li>';
					html += '<li class="jtwitter-meta" style="display:none;">';
					html += '<span class="jtwitter-friends">' + tweetObj.user.friends_count + ' following</span> / ';
					html += '<span class="jtwitter-followers">' + tweetObj.user.followers_count + ' followers</span> / ';
					html += '<span class="jtwitter-updates">' + tweetObj.user.statuses_count + ' tweets</span>';
					//html += '<span class="jtwitter-favorites">' + tweetObj.user.favourites_count + ' favorites</span>';
					html += '</li>';
					html += '<li class="jtwitter-clear"></li>';
					html += '</ul>';
					html += '</li>';
					
					return html;
				},
				buildMessages: function(msgObj){
					var html = '';
					html += '<li class="jtwitter-tweet" id="jtwitter-' + msgObj.id + '"><ul>';
					html += '<li class="jtwitter-profile-image"><img src="' + msgObj.sender.profile_image_url + '" alt="Photo of ' + msgObj.sender.name + '"/></li>';
					html += '<li class="jtwitter-screen-name"><a class="jtwitter-url" href="http://twitter.com/' + msgObj.sender.screen_name + '" title="' + msgObj.sender.screen_name + '" rel="bookmark" target="_blank">' + msgObj.sender.screen_name + '</a></li>';
					html += '<li class="jtwitter-text">' + msgObj.text + '</li>';
					html += '<li class="jtwitter-time"><span class="jtwitter-created-at">' + $.jtwitter._utils.prettifyDate(msgObj.created_at) + ' </span></li>';
					html += '</ul></li>';
					
					return html;
				},
				buildImages: function(userObj){
					var html = '<li id="jtwitter-user-' + userObj.id + '" class="jtwitter-profile-image">';
					html += '<a class="jtwitter-url" href="http://twitter.com/' + userObj.screen_name + '" title="' + userObj.screen_name + '" rel="bookmark" target="_blank">';
					html += '<img src="' + userObj.profile_image_url + '" alt="Photo of ' + userObj.name + '"/></a></li>';
					
					return html;
				},
				buildTrends: function(trendObj){
					var html = '';
					html += '<li class="jtwitter-trend"><a href="' + trendObj.url + '">' + trendObj.name + '</a></li>';
					
					return html;
				},
				buildSearch: function(searchObj){
					var html = '';
					html += '<li class="jtwitter-search">' + searchObj.text + '</li>';
					
					return html;
				},
				buildActions: function(tweetObj){
					var html = '';
					html += '<li class="jtwitter-actions">';
					html += '<ul class="jtwitter-actions">';
					if (tweetObj.user.screen_name == defaultOptions.user.username) {
						html += '<li class="ui-state-default ui-corner-all"><a href="#" title="' + tweetObj.user.screen_name + '" class="jtwitter-action-delete" rel="' + tweetObj.id + '"><span class="ui-icon ui-icon-trash">delete</span></a></li>';
					} else {
						html += '<li class="ui-state-default ui-corner-all"><a href="#" title="' + tweetObj.user.screen_name + '" class="jtwitter-action-reply" rel="' + tweetObj.id + '"><span class="ui-icon ui-icon-arrowreturnthick-1-w">reply</span></a></li>';
					}
					
					//html += '<li class="ui-state-default ui-corner-all"><a href="#" title="' + tweetObj.user.screen_name + '" class="jtwitter-action-message" rel="' + tweetObj.user.id + '"><span class="ui-icon ui-icon-mail-closed">message</span></a></li>';
					
					var favUnfav1 = (tweetObj.favorited == true) ? 'active' : 'default';
					var favUnfav2 = (tweetObj.favorited == true) ? 'unfavorite' : 'favorite';
					
					
					
					html += '<li class="ui-state-' + favUnfav1 + ' ui-corner-all"><a href="#" title="' + favUnfav2 + ' tweet" class="jtwitter-action-' + favUnfav2 + '" rel="' + tweetObj.id + '"><span class="ui-icon ui-icon-star">favorite</span></a></li>';
					//html += '<li><a href="#" class="jtwitter-action-block" rel="' + tweetObj.user.id + '">block</a></li>';
					html += '</ul>';
					html += '</li>';
					//html += '<li class="jtwitter-clear"></li>';
					
					return html;
				},
				buildUser: function(userObj){
					var html = '';
					html += '<li class="jtwitter-tweet" id="jtwitter-user-' + userObj.id + '">';
					html += '<ul>';
					html += '<li class="jtwitter-profile-image"><img src="' + userObj.profile_image_url + '" alt="Photo of ' + userObj.name + '"/></li>';
					html += '<li class="jtwitter-screen-name">';
					html += '<a class="jtwitter-url" href="http://twitter.com/' + userObj.screen_name + '" title="' + userObj.screen_name + '" rel="bookmark" target="_blank">';
					html += userObj.screen_name + '</a></li>';
					html += '<li class="jtwitter-meta">';
					html += '<span class="jtwitter-friends">' + userObj.friends_count + ' following</span> / ';
					html += '<span class="jtwitter-followers">' + userObj.followers_count + ' followers</span> / ';
					html += '<span class="jtwitter-updates">' + userObj.statuses_count + ' tweets</span>';
					//html += '<span class="jtwitter-favorites">' + userObj.favourites_count + ' favorites</span>';
					html += '</li>';
					html += '</ul>';
					html += '</li>';
					
					return html;
				},
				buildRateStatus: function(statusObj){
					var html = '';
					html += '<li>API Hits: ' + statusObj.remaining_hits + '</li>';
					html += '<li>Hourly Limit: ' + statusObj.hourly_limit + '</li>';
					html += '<li>Reset Time: ' + statusObj.reset_time + '</li>';
					return html;
				}
			},
			_utils: {
				prettifyDate: function(time){
					var values = time.split(" ");
					time = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
					
					var parsed_date = Date.parse(time);
					
					var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
					
					var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
					delta = delta + (relative_to.getTimezoneOffset() * 60);
					
					var out = '';
					
					if (delta < 60) {
						out = 'a minute ago';
					} else if (delta < 120) {
						out = 'couple of minutes ago';
					} else if (delta < (45 * 60)) {
						out = (parseInt(delta / 60)).toString() + ' minutes ago';
					} else if (delta < (90 * 60)) {
						out = 'an hour ago';
					} else if (delta < (24 * 60 * 60)) {
						out = '' + (parseInt(delta / 3600)).toString() + ' hours ago';
					} else if (delta < (48 * 60 * 60)) {
						out = '1 day ago';
					} else {
						out = (parseInt(delta / 86400)).toString() + ' days ago';
					}
					
					return out;
				},
				checkUser: function(){
					if (defaultOptions.user.username === null && defaultOptions.user.password === null) {
						alert('You must login for this .');
						return false;
					} else {
						return true;
					}
				},
				handleActions: function(){
				
					/***************************Favorite Actions**************************/
					//Add
					$('.jtwitter-action-favorite').live('click', function(){
						var link = this;
						//var confirm = confirm('You want to favorite tweet ' + $(this).attr('rel'));
						var confirm = true;
						if (confirm == true) {
							$.jtwitter.createFavorite($(this).attr('rel'), function(result){
								//Set it highlighted
								$(link).parent().removeClass('ui-state-default').addClass('ui-state-active');
								$(link).removeClass('jtwitter-action-favorite').addClass('jtwitter-action-unfavorite');
							});
						} else {
							return false;
						}
						return false;
					});
					//Remove
					$('.jtwitter-action-unfavorite').live('click', function(){
						var link = $(this);
						//var confirm = confirm('You want to un-favorite tweet ' + $(this).attr('rel'));
						var confirm = true;
						if (confirm == true) {
							$.jtwitter.deleteFavorite($(this).attr('rel'), function(result){
								//Set it un-highlighted
								$(link).parent().removeClass('ui-state-active').addClass('ui-state-default');
								$(link).removeClass('jtwitter-action-unfavorite').addClass('jtwitter-action-favorite');
								return false;
							});
						} else {
							return false;
						}
					});
					
					/***************************Message Actions**************************/
					$('.jtwitter-action-message').bind('click', function(event){
						alert('Message to user id: ' + $(this).attr('rel'));
					});
					
					/***************************Block Actions**************************/
					$('.jtwitter-action-block').live('click', function(){
						alert('Block user id: ' + $(this).attr('rel'));
					});
					
					/***************************Reply Actions**************************/
					$('.jtwitter-action-reply').live('click', function(){
						$(defaultOptions.tweetarea).val('@' + $(this).attr('title'))
						//alert( 'Reply to tweet id: ' + $(this).attr('rel'));
					});
					
					/***************************Follow Actions**************************/
					$('.jtwitter-action-follow').live('click', function(){
						alert('Follow user id: ' + $(this).attr('rel'));
					});
					/***************************Delete Actions**************************/
					$('.jtwitter-action-delete').live('click', function(){
						var confirmCheck = confirm('Are you sure?');
						var id = $(this).attr('rel');
						if (confirmCheck == true) {
							$.jtwitter.deleteTweet($(this).attr('rel'), function(result){
								$('#jtweet_' + id).remove('slow');
							});
						}
						
					});
					
					$(defaultOptions.search.next).bind('click', function(){
					
						//alert('You clicked next. Current Page: ' + jtwitterSearchObject.page + ' Next Page: ' + (jtwitterSearchObject.page + 1) + ' Prev Page: ' + (jtwitterSearchObject.page - 1) + 'Max ID: ' + jtwitterSearchObject.max_id );
						$.jtwitter.searchKeywords(jtwitterSearchObject.query, (jtwitterSearchObject.page + 1), 0, 0, jtwitterSearchObject.max_id);
					});
					
					$(defaultOptions.search.prev).bind('click', function(){
						$.jtwitter.searchKeywords(jtwitterSearchObject.query, (jtwitterSearchObject.page - 1), 0, 0, jtwitterSearchObject.max_id);
						//alert('You clicked prev'); 
					});
					
				}
			}
		
		};//ends jTwitterObject
		//If auto load data is true
		if (defaultOptions.autoFetch) {
			if (defaultOptions.defaultTimeline == 'public') {
				$.jtwitter.getPublicTimeline();
			} else if (defaultOptions.defaultTimeline == 'user') {
				$.jtwitter.getUserTimeline();
			} else if (defaultOptions.defaultTimeline == 'friends') {
				$.jtwitter.getFriendsTimeline();
			}
		}
		
		if (defaultOptions.showActions) {
			$.jtwitter._utils.handleActions();
		}
		
		return thisWrap;
		
	};
})(jQuery);

Initial URL
http://code.google.com/p/jquery-jtwitter/

Initial Description
http://code.google.com/p/jquery-jtwitter/ for examples.

Initial Title
jQuery jTwitter

Initial Tags
plugin, jquery, twitter

Initial Language
jQuery