added Cache

This commit is contained in:
Jeena Paradies 2012-12-11 00:46:08 +01:00
parent dacd2ee019
commit c3d1ce7d24
8 changed files with 280 additions and 105 deletions

View file

@ -92,6 +92,9 @@
NSString *index_string = [NSString stringWithContentsOfFile:[NSString stringWithFormat:@"%@index.html", path] encoding:NSUTF8StringEncoding error:nil];
oauthView = [[WebView alloc] init];
WebPreferences* prefs = [oauthView preferences];
[prefs _setLocalStorageDatabasePath:@"~/Library/Application Support/Tentia"];
[prefs setLocalStorageEnabled:YES];
viewDelegate.oauthView = oauthView;
[[oauthView mainFrame] loadHTMLString:index_string baseURL:url];
[oauthView setFrameLoadDelegate:viewDelegate];
@ -110,6 +113,8 @@
if (YES) //viewDelegate.timelineView != timelineView)
{
NSString *localStoragePath = @"~/Library/Application Support/Tentia";
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Webkit/"];
NSURL *url = [NSURL fileURLWithPath:path];
NSString *index_string = [NSString stringWithContentsOfFile:[NSString stringWithFormat:@"%@index.html", path] encoding:NSUTF8StringEncoding error:nil];
@ -120,6 +125,9 @@
[timelineView setPolicyDelegate:viewDelegate];
[timelineView setUIDelegate:viewDelegate];
[[timelineView windowScriptObject] setValue:self forKey:@"controller"];
WebPreferences* prefs = [timelineView preferences];
[prefs _setLocalStorageDatabasePath:localStoragePath];
[prefs setLocalStorageEnabled:YES];
viewDelegate.mentionsView = mentionsView;
[[mentionsView mainFrame] loadHTMLString:index_string baseURL:url];
@ -127,7 +135,9 @@
[mentionsView setPolicyDelegate:viewDelegate];
[mentionsView setUIDelegate:viewDelegate];
[[mentionsView windowScriptObject] setValue:self forKey:@"controller"];
prefs = [mentionsView preferences];
[prefs _setLocalStorageDatabasePath:localStoragePath];
[prefs setLocalStorageEnabled:YES];
viewDelegate.conversationView = conversationView;
[[conversationView mainFrame] loadHTMLString:index_string baseURL:url];
@ -135,6 +145,9 @@
[conversationView setPolicyDelegate:viewDelegate];
[conversationView setUIDelegate:viewDelegate];
[[conversationView windowScriptObject] setValue:self forKey:@"controller"];
prefs = [conversationView preferences];
[prefs _setLocalStorageDatabasePath:localStoragePath];
[prefs setLocalStorageEnabled:YES];
viewDelegate.profileView = profileView;
[[profileView mainFrame] loadHTMLString:index_string baseURL:url];
@ -142,6 +155,10 @@
[profileView setPolicyDelegate:viewDelegate];
[profileView setUIDelegate:viewDelegate];
[[profileView windowScriptObject] setValue:self forKey:@"controller"];
prefs = [profileView preferences];
[prefs _setLocalStorageDatabasePath:localStoragePath];
[prefs setLocalStorageEnabled:YES];
}
else
{

View file

@ -2,10 +2,11 @@ define([
"helper/HostApp",
"helper/Core",
"helper/Paths",
"lib/URI"
"lib/URI",
"helper/Cache"
],
function(HostApp, Core, Paths, URI) {
function(HostApp, Core, Paths, URI, Cache) {
function Conversation() {
@ -66,15 +67,16 @@ function(HostApp, Core, Paths, URI) {
Paths.getURL(URI(server + "/posts/" + id).toString(), "GET", callback, null, false);
}
var profile = JSON.parse(Cache.profiles.getItem(entity));
if (entity == HostApp.stringForKey("entity")) {
var url = URI(Paths.mkApiRootPath("/posts/" + id));
Paths.getURL(url.toString(), "GET", callback, null);
} else if(this.cache.followings[entity]) {
} else if(profile) {
getRemoteStatus(this.cache.followings[entity].profile);
getRemoteStatus(profile);
} else {
@ -82,12 +84,21 @@ function(HostApp, Core, Paths, URI) {
if (profile_url) {
var profile = JSON.parse(Cache.profiles.getItem(entity));
if (profile) {
getRemoteStatus(profile);
} else {
Paths.getURL(profile_url, "GET", function(resp) {
Cache.profiles.setItem(entity, resp.responseText);
getRemoteStatus(JSON.parse(resp.responseText));
}, null, false); // do not send auth-headers
}
}
});
}
}

View file

@ -1,9 +1,10 @@
define([
"helper/HostApp",
"controller/Timeline"
"controller/Timeline",
"helper/Cache"
],
function(HostApp, Timeline) {
function(HostApp, Timeline, Cache) {
function Mentions() {
@ -33,8 +34,9 @@ function(HostApp, Timeline) {
var status = statuses[i];
var name;
if(this.cache.followings[status.entity]) {
name = this.cache.followings[status.entity].profile["https://tent.io/types/info/basic/v0.1.0"].name;
var profile = JSON.parse(Cache.profiles.getItem(status.entity));
if(profile) {
name = profile["https://tent.io/types/info/basic/v0.1.0"].name;
}
HostApp.notificateUserAboutMention(status.content.text, name || status.entity, status.id, status.entity);

View file

@ -2,10 +2,11 @@ define([
"helper/HostApp",
"helper/Core",
"helper/Paths",
"lib/URI"
"lib/URI",
"helper/Cache"
],
function(HostApp, Core, Paths, URI) {
function(HostApp, Core, Paths, URI, Cache) {
function Profile() {
@ -15,6 +16,8 @@ function(HostApp, Core, Paths, URI) {
this.action = "profile";
this.initProfileTemplate();
//setTimeout(Cache.getFollowings, 1000 * 60 * 5);
}
Profile.prototype = Object.create(Core.prototype);
@ -26,7 +29,7 @@ function(HostApp, Core, Paths, URI) {
this.profile_template.entity.innerHTML = this.entity;
this.profile_template.entity.href = this.entity;
this.setFollowingButton(!!this.cache.followings[this.entity]);
this.setFollowingButton(!!Cache.followings.getItem(this.entity));
this.getProfile();
}
@ -153,6 +156,12 @@ function(HostApp, Core, Paths, URI) {
this.profile_template.following_button.style.display = "none";
}
var profile = JSON.parse(Cache.profiles.getItem(this.entity));
if (profile && profile != "null") {
this.showProfile(profile);
} else {
Paths.findProfileURL(this.entity, function(profile_url) {
if (profile_url) {
@ -164,6 +173,8 @@ function(HostApp, Core, Paths, URI) {
}, null, false); // do not send auth-headers
}
});
}
}
Profile.prototype.showProfile = function(profile) {
@ -313,21 +324,26 @@ function(HostApp, Core, Paths, URI) {
Profile.prototype.toggleFollow = function() {
var _this = this;
var callback = function(resp) { _this.cache.getAllFollowings(); debug(resp.responseText) };
if (this.cache.followings[this.entity]) {
var url = URI(Paths.mkApiRootPath("/followings/" + this.cache.followings[this.entity].id));
Paths.getURL(url.toString(), "DELETE", callback);
this.setFollowingButton(false);
delete this.cache.followings[this.entity];
var following = Cache.followings.getItem(this.entity);
if (following) {
var url = URI(Paths.mkApiRootPath("/followings/" + following.id));
Paths.getURL(url.toString(), "DELETE", function(resp) {
if (resp.status >= 200 && resp.status < 300) {
Cache.followings.removeItem(_this.entity);
_this.setFollowingButton(false);
}
});
} else {
var url = URI(Paths.mkApiRootPath("/followings"));
var data = JSON.stringify({"entity": this.entity });
Paths.getURL(url.toString(), "POST", callback, data);
this.setFollowingButton(true);
Paths.getURL(url.toString(), "POST", function(resp) {
debug(resp.responseText)
Cache.followings.setItem(_this.entity, resp.responseText);
_this.setFollowingButton(true);
}, data);
}
}

View file

@ -1,28 +1,23 @@
define([
"helper/Paths",
"lib/URI"
"lib/URI",
"helper/CacheStorage"
],
function(Paths, URI) {
function(Paths, URI, CacheStorage) {
function Cache() {
var Cache = {};
this.timeout = 2 * 60 * 1000;
this.before_id = null;
var timeout = 2 * 60 * 1000;
var followings_before_id = null;
this.followings = {};
Cache.followings = new CacheStorage("followings");
Cache.profiles = new CacheStorage("profiles");
Cache.profile_urls = new CacheStorage("profile_urls");
var _this = this;
this.intervall = setInterval(function() { _this.getAllFollowings(); }, this.timeout);
this.getAllFollowings();
}
Cache.prototype.getAllFollowings = function() {
var _this = this;
var callback = function(resp) {
Cache.getFollowings = function() {
function callback(resp) {
var fs = JSON.parse(resp.responseText)
@ -31,19 +26,25 @@ function(Paths, URI) {
for (var i = 0; i < fs.length; i++) {
var following = fs[i];
_this.before_id = following.id;
_this.followings[following.entity] = following;
followings_before_id = following.id;
Cache.followings.setItem(following.entity, following)
Cache.profiles.setItem(following.entity, following);
}
}
var url = URI(Paths.mkApiRootPath("/followings"));
if (this.before_id) {
url.addSearch("before_id", this.before_id);
var u = Paths.mkApiRootPath("/followings");
var url = URI(u);
if (followings_before_id) {
url.addSearch("before_id", followings_before_id);
}
Paths.getURL(url, "GET", callback);
}
// setTimeout(function(){ Cache.getAllFollowings() }, timeout);
return Cache;
});

View file

@ -0,0 +1,64 @@
define([
],
function() {
function CacheStorage(name) {
this.name = name;
}
CacheStorage.prototype.mkPath = function(key) {
return this.mkInternalPath("") + "-" + key;
}
CacheStorage.prototype.mkInternalPath = function(key) {
return "tentia-cache-" + this.name + key;
};
CacheStorage.prototype.getItem = function(key) {
return localStorage.getItem(this.mkPath(key));
}
CacheStorage.prototype.setItem = function(key, value) {
var item = this.getItem(key);
localStorage.setItem(this.mkPath(key), value);
if (!item) {
var length_path = this.mkInternalPath("_length");
var length = parseInt(localStorage.getItem(length_path), 10) + 1;
localStorage.setItem(length_path, length);
}
}
CacheStorage.prototype.removeItem = function(key) {
var item = this.getItem(key);
localStorage.removeItem(this.mkPath(key));
if (item) {
var length_path = this.mkInternalPath("_length");
var length = parseInt(localStorage.getItem(length_path), 10) - 1;
localStorage.setItem(length_path, length);
}
};
CacheStorage.prototype.clear = function() {
for (var i = 0; i < localStorage.length; i++) {
var key = localStorage.key(i);
if (key.startsWith(this.mkPath(""))) {
localStorage.removeItem(key);
}
}
localStorage.setItem(this.mkInternalPath("_length"), 0);
}
CacheStorage.prototype.length = function() {
return parseInt(localStorage.getItem(this.mkInternalPath("_length")), 10);
}
return CacheStorage;
});

View file

@ -11,8 +11,6 @@ function(jQuery, Paths, URI, HostApp, Cache) {
function Core() {
this.cache = new Cache();
}
Core.prototype.getTemplate = function() {
@ -184,17 +182,17 @@ function(jQuery, Paths, URI, HostApp, Cache) {
}
template.username.innerText = status.entity;
template.username.href = status.entity; // FIXME open profile
template.username.href = status.entity;
template.username.onclick = function() {
HostApp.showProfileForEntity(status.entity);
return false;
}
var profile = function(profile) {
function profile(p) {
var basic = profile["https://tent.io/types/info/basic/v0.1.0"];
var basic = p["https://tent.io/types/info/basic/v0.1.0"];
if (profile && basic) {
if (p && basic) {
if(basic.name) {
template.username.title = template.username.innerText;
template.username.innerText = basic.name;
@ -207,17 +205,25 @@ function(jQuery, Paths, URI, HostApp, Cache) {
}
if (this.cache.followings[status.entity]) {
var p = JSON.parse(Cache.profiles.getItem(status.entity));
profile(this.cache.followings[status.entity].profile);
if (p && p != "null") {
profile(p);
} else {
Paths.findProfileURL(status.entity, function(profile_url) {
if (profile_url) {
Paths.getURL(profile_url, "GET", function(resp) {
var p = JSON.parse(resp.responseText);
profile(p)
if (p && p != "null") {
Cache.profiles.setItem(status.entity, resp.responseText);
profile(p);
}
}, null, false); // do not send auth-headers
}
});
@ -234,15 +240,20 @@ function(jQuery, Paths, URI, HostApp, Cache) {
return false;
}
if (this.cache.followings[status.__repost.entity]) {
var profile = JSON.parse(Cache.profiles.getItem(status.__repost.entity))
if (profile) {
var basic = this.cache.followings[status.__repost.entity].profile["https://tent.io/types/info/basic/v0.1.0"];
var basic = profile["https://tent.io/types/info/basic/v0.1.0"];
template.reposted_by.innerText = basic.name;
} else {
Paths.findProfileURL(status.__repost.entity, function(profile_url) {
if (profile_url) {
Paths.getURL(profile_url, "GET", function(resp) {
Cache.profiles.setItem(status.__repost.entity, resp.responseText);
var p = JSON.parse(resp.responseText);
var profile = p["https://tent.io/types/info/basic/v0.1.0"];
if (profile && profile.name) {
@ -350,12 +361,19 @@ function(jQuery, Paths, URI, HostApp, Cache) {
var _this = this;
var callback = function(resp) {
if (resp.status >= 200 && resp.status < 300) {
var status = JSON.parse(resp.responseText);
status.__repost = repost;
var li = _this.getStatusDOMElement(status);
before_node.parentNode.insertBefore(li, before_node);
}
}
var profile = JSON.parse(Cache.profiles.getItem(repost.content.entity));
if (profile && profile != "null") {
var server = profile["https://tent.io/types/info/core/v0.1.0"].servers[0];
Paths.getURL(URI(server + "/posts/" + repost.content.id).toString(), "GET", callback, null, false);
} else {
Paths.findProfileURL(repost.content.entity, function(profile_url) {
if (profile_url) {
@ -369,6 +387,7 @@ function(jQuery, Paths, URI, HostApp, Cache) {
}
})
}
}
Core.prototype.sendNewMessage = function(content, in_reply_to_status_id, in_reply_to_entity, location, image_file_path, callback) {
@ -583,15 +602,19 @@ function(jQuery, Paths, URI, HostApp, Cache) {
}
}
if (_this.cache.followings[mention.entity]) {
var p = JSON.parse(Cache.profiles.getItem(mention.entity));
if (p) {
profile(_this.cache.followings[mention.entity].profile)
profile(p);
} else {
Paths.findProfileURL(mention.entity, function(profile_url) {
if (profile_url) {
Paths.getURL(profile_url, "GET", function(resp) {
Cache.profiles.setItem(mention.entity, resp.responseText);
var p = JSON.parse(resp.responseText);
profile(p)
}, null, false); // do not send auth-headers

View file

@ -1,10 +1,11 @@
define([
"jquery",
"helper/HostApp",
"helper/Hmac"
"helper/Hmac",
"helper/Cache"
],
function(jQuery, HostApp, Hmac) {
function(jQuery, HostApp, Hmac, Cache) {
var Paths = {};
Paths.getUrlVars = function(url) {
@ -103,23 +104,32 @@ function(jQuery, HostApp, Hmac) {
Paths.findProfileURL = function(entity, callback, errorCallback) {
var profile_url = Cache.profile_urls.getItem(entity);
if (profile_url && profile_url != "null") {
callback(profile_url);
} else {
jQuery.ajax({
url: entity,
type: "HEAD",
complete: function(resp) {
if(resp) {
var headers = resp.getAllResponseHeaders();
var regex = /Link: <([^>]*)>; rel="https:\/\/tent.io\/rels\/profile"/; // FIXME: parse it!
var ret = headers.match(regex);
var profile_urls = Paths.parseHeaderForProfiles(headers);
var profile_url = null;
if(ret && ret.length > 1) {
var profile_url = ret[1];
if (profile_url == "/profile") {
if(profile_urls.length > 0) {
var profile_url = profile_urls[0];
if (!profile_url.startsWith("http")) {
profile_url = entity + "/profile";
}
}
if (profile_url) {
Cache.profile_urls.setItem(entity, profile_url);
callback(profile_url);
} else {
if(errorCallback) errorCallback(entity + " has no profile URL");
@ -132,9 +142,12 @@ function(jQuery, HostApp, Hmac) {
}
});
}
}
Paths.mkApiRootPath = function(path) {
var api_root = HostApp.stringForKey("api_root");
if((api_root.substring(api_root.length - 1, api_root.length) != "/") && (path.substring(0, 1) != "/")) {
api_root += "/";
} else if((api_root.substring(api_root.length - 1, api_root.length) == "/") && (path.substring(0, 1) == "/")) {
@ -143,5 +156,33 @@ function(jQuery, HostApp, Hmac) {
return api_root + path;
}
Paths.parseHeaderForProfiles = function(header_string) {
var headers = header_string.split(/\n/);
var links = [];
for (var i = 0; i < headers.length; i++) {
var header = headers[i];
if (header.match(/^Link:(.*)/i)) {
links.push(header.replace(/\r/, "").substr(5).trim());
}
}
var items = [];
for (var i = 0; i < links.length; i++) {
items = items.concat(links[i].split(","));
}
var profiles = [];
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (item.match(/https:\/\/tent.io\/rels\/profile/i)) {
var n = item.match(/<([^>]*)>/);
if (n) {
profiles.push(n[1]);
}
}
}
return profiles;
}
return Paths;
});