Skip to content

Instantly share code, notes, and snippets.

@lfreneda
Created June 13, 2016 14:46
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 lfreneda/62db7e91b0fb3c576b74afaf8cbba6ab to your computer and use it in GitHub Desktop.
Save lfreneda/62db7e91b0fb3c576b74afaf8cbba6ab to your computer and use it in GitHub Desktop.
Http Offline Cache Ionic Module with Lokijs
(function () {
'use strict';
angular.module('app.offline')
.factory('httpOfflineCacheStorage', httpOfflineCacheStorage);
function httpOfflineCacheStorage(Loki) {
var _cacheDb = null;
var _requests = null;
return {
initialize: initialize,
get: get,
set: set
};
function initialize() {
var adapter = new LokiCordovaFSAdapter({"prefix": "loki"});
_cacheDb = new Loki('cacheDb', {
autosave: true,
autosaveInterval: 5000,
adapter: adapter
});
_cacheDb.loadDatabase({}, function () {
_requests = _cacheDb.getCollection('requests');
if (!_requests) {
_requests = _cacheDb.addCollection('requests', { indices: ['url'], clone: true });
}
purgeOldRequests();
});
}
function purgeOldRequests() {
var requests = _requests.find({});
requests.forEach(function(request) {
var today = new Date();
var createdAt = new Date(request.meta.created);
var diffMs = (today - createdAt); // milliseconds between now & Christmas
var diffDays = Math.round(diffMs / 86400000); // days
var totalHours = Math.round(diffMs / 3600000); // hours
var totalMinutes = Math.round(diffMs / 60000); // hours
var diffHrs = Math.round((diffMs % 86400000) / 3600000); // hours
var diffMins = Math.round(((diffMs % 86400000) % 3600000) / 60000); // minutes
if (diffDays > 0) {
_requests.remove(request);
}
});
}
function get(url) {
return _requests.findOne({url:url});
}
function set(url, response) {
var request = get(url);
if (request) {
request.url = url;
request.response = response;
_requests.update(request);
}
else {
_requests.insert({
url: url,
response: response
});
}
}
}
}).call(this);
--
(function () {
'use strict';
angular.module('app.offline')
.factory('httpOfflineCache', httpOfflineCache);
function httpOfflineCache($http, httpOfflineCacheStorage, $q) {
return {
get: get
};
function get(url, config) {
config = config || { timeout: 10000 };
return $http.get(url, config).then(function(response) {
return persistResponse(url, response);
}).catch(function(response) {
var isOffline = !response.status;
if (isOffline) {
return getCachedRequest(url);
} else {
return $q.reject(response);
}
});
}
function persistResponse(url, response) {
httpOfflineCacheStorage.set(url, response);
return response;
}
function getCachedRequest(url) {
var cachedRequest = httpOfflineCacheStorage.get(url);
if (cachedRequest) {
return cachedRequest.response;
}
else {
return $q.reject({
status: 0,
data: '',
headers: function () { return ''; },
config: null,
statusText: ''
});
}
}
}
}).call(this);
--
(function () {
'use strict';
angular.module('app.offline', ['lokijs']);
})();
--
(function () {
'use strict';
angular.module('app.offline')
.factory('networkConnection', networkConnection);
function networkConnection($http, EnvironmentConfig, $ionicPopup) {
return {
testConnectionBefore: testConnectionBefore,
testConnection: testConnection,
alertOffline: alertOffline
};
function testConnectionBefore(callbackIfOnline, callbackIfOffline) {
testConnection(function(stats) {
if (stats.isOnline) {
callbackIfOnline();
}
else {
var alert = alertOffline();
alert.then(function() {
if (callbackIfOffline) {
callbackIfOffline();
}
});
}
});
}
function alertOffline() {
return $ionicPopup.alert({
title: 'Sem conexão com a Internet',
template: 'Verifique o status da sua conexão e tente novamente.'
});
}
function testConnection(callback) {
return $http.get(EnvironmentConfig.baseUrl, { timeout: 10000 }).then(function (response) {
callback({ isOnline: response.status !== 0, isOffline: response.status === 0, response: response });
}).catch(function(response){
callback({ isOnline: response.status !== 0, isOffline: response.status === 0, response: response });
});
}
}
})();
--
(function () {
'use strict';
angular.module('app.offline')
.factory('hasher', hasher);
function hasher() {
return {
sha1: sha1
};
function sha1(obj) {
var objectJson = JSON.stringify(obj);
return binToHex(coreFunction(fillString(objectJson)));
}
function fillString(str) {
var blockAmount = ((str.length + 8) >> 6) + 1,
blocks = [],
i;
for (i = 0; i < blockAmount * 16; i++) {
blocks[i] = 0;
}
for (i = 0; i < str.length; i++) {
blocks[i >> 2] |= str.charCodeAt(i) << (24 - (i & 3) * 8);
}
blocks[i >> 2] |= 0x80 << (24 - (i & 3) * 8);
blocks[blockAmount * 16 - 1] = str.length * 8;
return blocks;
}
function binToHex(binArray) {
var hexString = "0123456789abcdef",
str = "",
i;
for (i = 0; i < binArray.length * 4; i++) {
str += hexString.charAt((binArray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF) +
hexString.charAt((binArray[i >> 2] >> ((3 - i % 4) * 8 )) & 0xF);
}
return str;
}
function coreFunction(blockArray) {
var w = [],
a = 0x67452301,
b = 0xEFCDAB89,
c = 0x98BADCFE,
d = 0x10325476,
e = 0xC3D2E1F0,
olda,
oldb,
oldc,
oldd,
olde,
t,
i,
j;
for (i = 0; i < blockArray.length; i += 16) { //每次处理512位 16*32
olda = a;
oldb = b;
oldc = c;
oldd = d;
olde = e;
for (j = 0; j < 80; j++) { //对每个512位进行80步操作
if (j < 16) {
w[j] = blockArray[i + j];
} else {
w[j] = cyclicShift(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
}
t = modPlus(modPlus(cyclicShift(a, 5), ft(j, b, c, d)), modPlus(modPlus(e, w[j]), kt(j)));
e = d;
d = c;
c = cyclicShift(b, 30);
b = a;
a = t;
}
a = modPlus(a, olda);
b = modPlus(b, oldb);
c = modPlus(c, oldc);
d = modPlus(d, oldd);
e = modPlus(e, olde);
}
return [a, b, c, d, e];
}
function ft(t, b, c, d) {
if (t < 20) {
return (b & c) | ((~b) & d);
} else if (t < 40) {
return b ^ c ^ d;
} else if (t < 60) {
return (b & c) | (b & d) | (c & d);
} else {
return b ^ c ^ d;
}
}
function kt(t) {
return (t < 20) ? 0x5A827999 :
(t < 40) ? 0x6ED9EBA1 :
(t < 60) ? 0x8F1BBCDC : 0xCA62C1D6;
}
function modPlus(x, y) {
var low = (x & 0xFFFF) + (y & 0xFFFF),
high = (x >> 16) + (y >> 16) + (low >> 16);
return (high << 16) | (low & 0xFFFF);
}
function cyclicShift(num, k) {
return (num << k) | (num >>> (32 - k));
}
}
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment