Skip to content

Instantly share code, notes, and snippets.

@nitrag
Created December 3, 2015 22:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nitrag/57514857e78bb71bdf23 to your computer and use it in GitHub Desktop.
Save nitrag/57514857e78bb71bdf23 to your computer and use it in GitHub Desktop.
/**
* twitter: @aaronksaunders
*
* See more Appcelerator Information on Company Blog
*
* blog.clearlyinnovative.com
*
*/
/**
* Edits to the parse library to work with this helper file
*
* Add this to line 1348
*<pre>
* // Import Parse's local copy of underscore.
* if (Titanium !== "undefined") {
* console.log("Using titanium");
*
* Parse._ = exports._.noConflict();
* exports.Parse = Parse;
* } else
*</pre>
*
* Replace line 8576
* <pre>
* Parse.User._registerAuthenticationProvider(FB.provider);
* </pre>
*/
/**
* saveEventually features by Nitrag, credit goes to francimedia
* https://github.com/francimedia/parse-js-local-storage
**/
var TiParse = function(options) {
// UPDATED TO LATEST PARSE LIBRARY
require("parse-1.3.2");
//
// Override the Facebook object on Appcelerator
//
// Create the provider and the other methods the Parse Library is looking for
//
TiFacebook = require('facebook');
TiFacebook.appid = options.facebookAppId;
FB = {
provider : {
authenticate : function(options) {
var self = this;
TiFacebook.forceDialogAuth = false;
TiFacebook.authorize();
TiFacebook.addEventListener('login', function(response) {
if (response.success) {
if (options.success) {
options.success(self, {
id : JSON.parse(response.data).id,
access_token : TiFacebook.accessToken,
expiration_date : (new Date(TiFacebook.expirationDate)).toJSON()
});
}
} else {
if (options.error) {
options.error(self, response);
}
}
});
},
restoreAuthentication : function(authData) {
var authResponse;
if (authData) {
authResponse = {
userID : authData.id,
accessToken : authData.access_token,
expiresIn : (Parse._parseDate(authData.expiration_date).getTime() - (new Date()).getTime()) / 1000
};
} else {
authResponse = {
userID : null,
accessToken : null,
expiresIn : null
};
}
//FB.Auth.setAuthResponse(authResponse);
if (!authData) {
TiFacebook.logout();
}
return true;
},
getAuthType : function() {
return "facebook";
},
deauthenticate : function() {
this.restoreAuthentication(null);
}
},
init : function() {
Ti.API.debug("called FB.init()");
},
login : function() {
Ti.API.debug("called FB.login()");
},
logout : function() {
Ti.API.debug("called FB.logout()");
}
};
/**
* over write the local storage so it works on Appcelerator
*/
Parse.localStorage = {
getItem : function(key) {
return Ti.App.Properties.getObject(Parse.localStorage.fixKey(key));
},
setItem : function(key, value) {
return Ti.App.Properties.setObject(Parse.localStorage.fixKey(key), value);
},
removeItem : function(key, value) {
return Ti.App.Properties.removeProperty(Parse.localStorage.fixKey(key));
},
//Fix Parse Keys. Parse uses a Key containing slashes "/". This is invalid for Titanium Android
//We'll replace those slashes with underscores ""
fixKey : function(key) {
return key.split("/").join("");
}
};
//
// Save Eventually
// Credits to: https://github.com/francimedia/parse-js-local-storage
Parse.saveEventually = {
localStorageKey: "Parse.saveEventually.Queue",
initialize: function () {
},
save: function (objectType, object) {
this.addToQueue('save', objectType, object);
},
addToQueue: function (action, objectType, object) {
var queueData = this.getQueue();
// create queueId to avoid duplicates. Maintain previously saved data.
var queueId = ([objectType, object.id, object.get('hash')]).join('_');
var i = this.queueItemExists(queueData, queueId);
if(i > -1) {
for (var prop in queueData[i].data) {
if(object.get(prop) == 'undefined') {
object.set(prop, queueData[i].data[prop]);
}
}
} else {
i = queueData.length;
}
queueData[i] = {
queueId: queueId,
type: objectType,
action: action,
id: object.id,
hash: object.get('hash'),
createdAt: new Date(),
data: object
};
this.setQueue(queueData);
},
getQueue: function () {
var q = Parse.localStorage.getItem(this.localStorageKey) || null;
if(q && (typeof JSON.parse(q) == 'object'))
return JSON.parse(q);
else
return [];
},
setQueue: function (queueData) {
Parse.localStorage.setItem(this.localStorageKey, JSON.stringify(queueData));
},
clearQueue: function () {
Parse.localStorage.setItem(this.localStorageKey, JSON.stringify([]));
},
queueItemExists: function(queueData, queueId) {
for (var i = 0; i < queueData.length; i++) {
if(queueData[i].queueId == queueId) {
return i;
}
};
return -1;
},
countQueue: function(){
return this.getQueue().length;
},
sendQueue: function () {
var queueData = this.getQueue();
if(queueData.length < 1)
return false;
for (var i = 0; i < queueData.length; i++) {
var myObjectType = Parse.Object.extend(queueData[i].type);
// if object has a parse data id, update existing object
if (queueData[i].id) {
this.reprocess.byId(myObjectType, queueData[i]);
}
// if object has no id but a unique identifier, look for existing object, update or create new
else if (queueData[i].hash) {
this.reprocess.byHash(myObjectType, queueData[i]);
}
// else create a new object
else {
this.reprocess.create(myObjectType, queueData[i]);
}
}
return true;
// empty queue - 2do: verify queue has been sent
// this.clearQueue();
},
sendQueueCallback: function (myObject, queueObject) {
switch (queueObject.action) {
case 'save':
// queued update was overwritten by other request > do not save
if (typeof myObject.updatedAt != 'undefined' && myObject.updatedAt > new Date(queueObject.createdAt)) {
return false;
}
myObject.save(queueObject.data, {
success: function (object) {
console.log(object);
},
error: function (model, error) {
console.log(error);
}
});
break;
case 'delete':
// 2do: code to delete queued objects
break;
}
},
reprocess: {
create: function (myObjectType, queueObject) {
var myObject = new myObjectType();
Parse.saveEventually.sendQueueCallback(myObject, queueObject);
},
byId: function (myObjectType, queueObject) {
var query = new Parse.Query(myObjectType);
query.get(queueObject.id, {
success: function (myObject) {
// The object was retrieved successfully.
Parse.saveEventually.sendQueueCallback(myObject, queueObject);
},
error: function (myObject, error) {
// The object was not retrieved successfully.
// error is a Parse.Error with an error code and description.
}
});
},
byHash: function (myObjectType, queueObject) {
var query = new Parse.Query(myObjectType);
query.equalTo("hash", queueObject.hash);
query.find({
success: function (results) {
// The object was retrieved successfully.
if(results.length > 0) {
Parse.saveEventually.sendQueueCallback(results[0], queueObject);
}
// The object was not found, create a new one
else {
Parse.saveEventually.reprocess.create(myObjectType, queueObject);
}
},
error: function (myObject, error) {
// The object was not retrieved successfully.
// error is a Parse.Error with an error code and description.
}
});
}
}
};
//
// Enter appropriate parameters for initializing Parse
//
// options.applicationId, options.javascriptkey);
//
Parse.initialize(options.applicationId, options.javascriptkey);
/**
* Over write the _ajax function to use titanium httpclient
*
* @TODO Still looking for way to clean this up better
*
* @param {Object} method
* @param {Object} url
* @param {Object} data
* @param {Object} success
* @param {Object} error
*/
Parse._ajax = function(method, url, data, success, error) {
var options = {
success : success,
error : error
};
var promise = new Parse.Promise();
var handled = !1;
var xhr = Ti.Network.createHTTPClient({
timeout : 5e3
});
xhr.onreadystatechange = function() {
if (4 === xhr.readyState) {
if (handled)
return;
handled = !0;
if (xhr.status >= 200 && 300 > xhr.status) {
var response;
try {
response = JSON.parse(xhr.responseText);
} catch (e) {
promise.reject(e);
}
response && promise.resolve(response, xhr.status, xhr);
} else
promise.reject(xhr);
}
};
xhr.open(method, url, !0);
xhr.setRequestHeader("Content-Type", "text/plain");
xhr.send(data);
return promise._thenRunCallbacks(options);
};
//
// IF the appid was set for facebook then initialize facebook. if you are going
// to use Facebook, set the appid at the top of this file
//
if (TiFacebook.appid) {
Parse.FacebookUtils.init({
appId : TiFacebook.appid, // Facebook App ID
channelUrl : '//sigep.eagledevelopers.net/channel.php', // Channel File - USE YOUR DOMAIN HERE !!
status : false, // check login status
cookie : true, // enable cookies to allow Parse to access the session
xfbml : true // parse XFBML
});
}
};
module.exports = TiParse;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment