Created
October 14, 2011 17:23
-
-
Save kwhinnery/1287727 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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