Skip to content

Instantly share code, notes, and snippets.

@kwhinnery
Created October 14, 2011 17:23
Show Gist options
  • Save kwhinnery/1287727 to your computer and use it in GitHub Desktop.
Save kwhinnery/1287727 to your computer and use it in GitHub Desktop.
(function() {
var RUN_TESTS = false;
if (RUN_TESTS) {
Ti.include('tests/tests.js');
} else {
var accessTokenKey = Ti.App.Properties.getString('twitterAccessTokenKey'),
accessTokenSecret = Ti.App.Properties.getString('twitterAccessTokenSecret');
var Twitter = require('twitter').Twitter;
var client = Twitter({
consumerKey: "h2teRPJOuxrFK6jYScfFbg",
consumerSecret: "QAJGe0vEIMh9rmGBFkaPUdzHx82zmNuxW7RsoxBlY",
accessTokenKey: accessTokenKey,
accessTokenSecret: accessTokenSecret
});
var win = Ti.UI.createWindow({backgroundColor: 'white'}),
tableView = Ti.UI.createTableView();
win.add(tableView);
win.open();
client.addEventListener('login', function(e) {
if (e.success) {
Ti.App.Properties.setString('twitterAccessTokenKey', e.accessTokenKey);
Ti.App.Properties.setString('twitterAccessTokenSecret', e.accessTokenSecret);
client.request("1/statuses/home_timeline.json", {count: 100}, 'GET', function(e) {
if (e.success) {
var json = JSON.parse(e.result.text),
tweets = json.map(function(tweet) {
return {title: tweet.text};
});
tableView.setData(tweets);
} else {
alert(e.error);
}
});
} else {
alert(e.error);
}
});
client.authorize();
}
})(this);
var exports = exports || this;
exports.Twitter = (function(global) {
var K = function(){}, isAndroid = Ti.Platform.osname === "android", jsOAuth = require('jsOAuth-1.3.1');
/**
* Twitter constructor function
*
* var client = Twitter({
* consumerKey: "INSERT YOUR KEY HERE",
* consumerSecret: "INSERT YOUR SECRET HERE"
* });
*
* Can be used with or without `new` keyword.
*
* @constructor
* @requires jsOAuth: http://github.com/bytespider/jsOAuth
* @param options {Object} Configuration object
* @param options.consumerKey {String} Application consumer key
* @param options.consumerSecret {String} Application consumer secret
* @param options.accessTokenKey {String} (optional) The user's access token key
* @param options.accessTokenSecret {String} (optional) The user's access token secret
* @param [options.windowTitle="Twitter Authorization"] {String} (optional) The title to display in the authentication window
*/
var Twitter = function(options) {
var self;
if (this instanceof Twitter) {
self = this;
} else {
self = new K();
}
if (!options) { options = {}; }
self.windowTitle = options.windowTitle || "Twitter Authorization";
self.consumerKey = options.consumerKey;
self.consumerSecret = options.consumerSecret;
self.authorizeUrl = "https://api.twitter.com/oauth/authorize";
self.accessTokenKey = options.accessTokenKey;
self.accessTokenSecret = options.accessTokenSecret;
self.authorized = false;
if (self.accessTokenKey && self.accessTokenSecret) {
self.authorized = true;
}
options.requestTokenUrl = options.requestTokenUrl || "https://api.twitter.com/oauth/request_token";
self.oauthClient = jsOAuth.OAuth(options);
return self;
};
K.prototype = Twitter.prototype;
function createAuthWindow() {
var self = this,
oauth = this.oauthClient,
webViewWindow = Ti.UI.createWindow({title: this.windowTitle}),
webView = Ti.UI.createWebView(),
loadingOverlay = Ti.UI.createView({
backgroundColor: 'black',
opacity: 0.7,
zIndex: 1
}),
actInd = Titanium.UI.createActivityIndicator({
height: 50,
width: 10,
message: 'Loading...',
color: 'white'
}),
closeButton = Ti.UI.createButton({
title: "Close"
}),
backButton = Ti.UI.createButton({
title: "Back"
});
this.webView = webView;
webViewWindow.leftNavButton = closeButton;
actInd.show();
loadingOverlay.add(actInd);
webViewWindow.add(loadingOverlay);
webViewWindow.open({modal: true});
webViewWindow.add(webView);
closeButton.addEventListener('click', function(e) {
webViewWindow.close();
});
backButton.addEventListener('click', function(e) {
webView.goBack();
});
webView.addEventListener('beforeload', function(e) {
if (!isAndroid) { webViewWindow.add(loadingOverlay); }
actInd.show();
});
webView.addEventListener('load', function(event) {
// If we're not on the Twitter authorize page
if (event.url.indexOf(self.authorizeUrl) === -1) {
webViewWindow.remove(loadingOverlay);
actInd.hide(); // Required for Android
// Switch out close button for back button
if (webViewWindow.leftNavButton !== backButton) {
webViewWindow.leftNavButton = backButton;
}
} else {
// Switch out back button for close button
if (webViewWindow.leftNavButton !== closeButton) {
webViewWindow.leftNavButton = closeButton;
}
// Grab the PIN code out of the DOM
var pin = event.source.evalJS("document.getElementById('oauth_pin').getElementsByTagName('code')[0].innerText");
if (!pin) {
// We're here when:
// - "No thanks" button clicked
// - Bad username/password
webViewWindow.remove(loadingOverlay);
actInd.hide();
} else {
if (!isAndroid) { // on iOS we can close the modal window right away
webViewWindow.close();
}
oauth.accessTokenUrl = "https://api.twitter.com/oauth/access_token?oauth_verifier=" + pin;
oauth.fetchAccessToken(function(data) {
var returnedParams = oauth.parseTokenRequest(data.text);
self.fireEvent('login', {
success: true,
error: false,
accessTokenKey: returnedParams.oauth_token,
accessTokenSecret: returnedParams.oauth_token_secret
});
if (isAndroid) { // we have to wait until now to close the modal window on Android: http://developer.appcelerator.com/question/91261/android-probelm-with-httpclient
webViewWindow.close();
}
}, function(data) {
self.fireEvent('login', {
success: false,
error: "Failure to fetch access token, please try again.",
result: data
});
});
}
}
});
}
/*
* Requests the user to authorize via Twitter through a modal WebView.
*/
Twitter.prototype.authorize = function() {
var self = this;
if (this.authorized) {
// TODO: verify access tokens are still valid?
this.fireEvent('login', {
success: true,
error: false,
accessTokenKey: this.accessTokenKey,
accessTokenSecret: this.accessTokenSecret
});
} else {
createAuthWindow.call(this);
this.oauthClient.fetchRequestToken(
function(requestParams) {
var authorizeUrl = self.authorizeUrl + requestParams;
self.webView.url = authorizeUrl;
},
function(data) {
self.fireEvent('login', {
success: false,
error: "Failure to fetch access token, please try again.",
result: data
});
}
);
}
};
/*
* Make an authenticated Twitter API request.
*
* @param {String} path the Twitter API path without leading forward slash. For example: `1/statuses/home_timeline.json`
* @param {Object} params the parameters to send along with the API call
* @param {String} [httpVerb="GET"] the HTTP verb to use
* @param {Function} callback
*/
Twitter.prototype.request = function(path, params, httpVerb, callback) {
var self = this, oauth = this.oauthClient, url = "https://api.twitter.com/" + path;
oauth.request({
method: httpVerb,
url: url,
data: params,
success: function(data) {
callback.call(self, {
success: true,
error: false,
result: data
});
},
error: function(data) {
callback.call(self, {
success: false,
error: "Request failed",
result: data
});
}
});
};
/*
* Add an event listener
*/
Twitter.prototype.addEventListener = function(eventName, callback) {
this.listeners = this.listeners || {};
this.listeners[eventName] = this.listeners[eventName] || [];
this.listeners[eventName].push(callback);
};
/*
* Fire an event
*/
Twitter.prototype.fireEvent = function(eventName, data) {
this.listeners = this.listeners || {};
if (this.listeners[eventName]) {
for (var i = 0; i < this.listeners[eventName].length; i++) {
this.listeners[eventName][i].call(this, data);
}
}
};
return Twitter;
})(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment