From 661ab4b3388f3dde3213bcdeb97bdae49da81578 Mon Sep 17 00:00:00 2001 From: erqan Date: Fri, 9 May 2014 12:27:48 +0300 Subject: [PATCH 1/2] following's followings and known followers are cached in localStorage instead of session... and added a simple adaptive updating method for following's followings to reduce rpc requests.. --- js/interface_common.js | 23 +++--- js/interface_home.js | 34 ++------ js/twister_following.js | 172 ++++++++++++++++++++++++++++++++-------- js/twister_io.js | 20 ++--- 4 files changed, 169 insertions(+), 80 deletions(-) diff --git a/js/interface_common.js b/js/interface_common.js index eaea170..a38f7fe 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -256,25 +256,26 @@ function refreshWhoToFollow(e) { function fillWhoToFollowModal(list, hlist, start) { var i; for (i = 0; i < followingUsers.length && list.length < start + 20; i++) { - if (typeof(followingsFollowings[followingUsers[i]]) !== 'undefined') { - for (var j = 0; j < followingsFollowings[followingUsers[i]].length && list.length < start + 25; j++) { + if (typeof(twisterFollowingO.followingsFollowings[followingUsers[i]]) !== 'undefined') { + for (var j = 0; j < twisterFollowingO.followingsFollowings[followingUsers[i]]["following"].length && list.length < start + 25; j++) { - if (followingUsers.indexOf(followingsFollowings[followingUsers[i]][j]) < 0 && - list.indexOf(followingsFollowings[followingUsers[i]][j]) < 0) { - list.push(followingsFollowings[followingUsers[i]][j]); + var utf = twisterFollowingO.followingsFollowings[followingUsers[i]]["following"][j]; + if (followingUsers.indexOf(utf) < 0 && + list.indexOf(utf) < 0) { + list.push(utf); var item = $("#follow-suggestion-template").clone(true); item.removeAttr("id"); - item.find(".twister-user-info").attr("data-screen-name", followingsFollowings[followingUsers[i]][j]); + item.find(".twister-user-info").attr("data-screen-name", utf); - item.find(".twister-user-name").attr("href", $.MAL.userUrl(followingsFollowings[followingUsers[i]][j])); + item.find(".twister-user-name").attr("href", $.MAL.userUrl(utf)); item.find(".twister-by-user-name").attr("href", $.MAL.userUrl(followingUsers[i])); - item.find(".twister-user-tag").text("@" + followingsFollowings[followingUsers[i]][j]); + item.find(".twister-user-tag").text("@" + utf); - getAvatar(followingsFollowings[followingUsers[i]][j], item.find(".twister-user-photo")); - getFullname(followingsFollowings[followingUsers[i]][j], item.find(".twister-user-full")); - getBio(followingsFollowings[followingUsers[i]][j], item.find(".bio")); + getAvatar(utf, item.find(".twister-user-photo")); + getFullname(utf, item.find(".twister-user-full")); + getBio(utf, item.find(".bio")); var $spanFollowedBy = item.find(".followed-by"); $spanFollowedBy.text(followingUsers[i]); diff --git a/js/interface_home.js b/js/interface_home.js index 4b61dc3..8020b2a 100644 --- a/js/interface_home.js +++ b/js/interface_home.js @@ -22,13 +22,13 @@ var InterfaceFunctions = function() $.MAL.getStreamPostsParent().empty(); requestTimelineUpdate("latestFirstTime",postsPerRefresh,followingUsers,promotedPostsOnly); }); - + initInterfaceCommon(); initUserSearch(); initInterfaceDirectMsg(); initUser(initHome); - } + }; function initHome(cbFunc, cbArg) { checkNetworkStatusAndAskRedirect(); @@ -56,7 +56,7 @@ var InterfaceFunctions = function() twisterRpc("gettrendinghashtags", [10], function(args, ret) { for( var i = 0; i < ret.length; i++ ) { - + var $li = $("
  • "); var hashtagLinkTemplate = $("#hashtag-link-template").clone(true); hashtagLinkTemplate.removeAttr("id"); @@ -68,7 +68,7 @@ var InterfaceFunctions = function() }, {}, function(args, ret) { console.log("Error with gettrendinghashtags. Older twister daemon?"); - }, {}); + }, {}); } else { @@ -97,34 +97,16 @@ var InterfaceFunctions = function() } }); - loadFollowingSessionData(); - //geting followings of following... - for(var i = 0; i < followingUsers.length; i++) { - if (typeof(followingsFollowings[followingUsers[i]]) === 'undefined') { - loadFollowingFromDht(followingUsers[i], 1, [], 0, function (args, following, seqNum) { - if (following.indexOf(defaultScreenName) > -1) { - if (knownFollowers.indexOf(args) < 0) - knownFollowers.push(args); - } else { - if (notFollowers.indexOf(args) < 0) - notFollowers.push(args); - } - $(".open-followers").attr("title", knownFollowers.length.toString()); - - followingsFollowings[args] = following; - }, followingUsers[i]); - } - } - storeFollowingSessionData(); + twisterFollowingO = TwisterFollowing(defaultScreenName); setTimeout("getRandomFollowSuggestion(processSuggestion)", 1000); setTimeout("getRandomFollowSuggestion(processSuggestion)", 1000); setTimeout("getRandomFollowSuggestion(processSuggestion)", 1000); - + twisterRpc("gettrendinghashtags", [10], function(args, ret) { for( var i = 0; i < ret.length; i++ ) { - + var $li = $("
  • "); var hashtagLinkTemplate = $("#hashtag-link-template").clone(true); hashtagLinkTemplate.removeAttr("id"); @@ -143,7 +125,7 @@ var InterfaceFunctions = function() }, {cbFunc:cbFunc, cbArg:cbArg}); } } -} +}; //*********************************************** //******************* INIT ************** diff --git a/js/twister_following.js b/js/twister_following.js index 2899b42..8ed6272 100644 --- a/js/twister_following.js +++ b/js/twister_following.js @@ -5,9 +5,6 @@ // Provides random user suggestions to follow. var followingUsers = []; -var knownFollowers = []; -var notFollowers = []; -var followingsFollowings = {}; var _isFollowPublic = {}; var _followsPerPage = 200; var _maxFollowingPages = 50; @@ -18,6 +15,135 @@ var _searchKeypressTimer = undefined; var _lastSearchUsersResults = []; var _lastLoadFromDhtTime = 0; +var twisterFollowingO = undefined; + +var TwisterFollowing = function (user) { + if (!(this instanceof TwisterFollowing)) + return new TwisterFollowing(user); + + this.init(user); +}; + +TwisterFollowing.minUpdateInterval = 43200; // 1/2 day +TwisterFollowing.maxUpdateInterval = 691200; // 8 days + +TwisterFollowing.prototype = { + user: undefined, + init: function (user) { + this.user = user; + this.load(); + this.update(); + }, + knownFollowers: [], + knownFollowersResetTime: new Date().getTime() / 1000, + notFollowers: [], + /* + followinsFollowings = { + "username": { + "lastUpdate": , + "updateInterval": , + "following": [] + } + } + */ + followingsFollowings: {}, + + load: function () { + var ns = $.initNamespaceStorage(this.user); + + if (ns.localStorage.isSet("followingsFollowings")) + this.followingsFollowings = ns.localStorage.get("followingsFollowings"); + + if (ns.localStorage.isSet("knownFollowersResetTime")) + this.knownFollowersResetTime = ns.localStorage.get("knownFollowersResetTime"); + + var ctime = new Date().getTime() / 1000; + if (ctime - this.knownFollowersResetTime < TwisterFollowing.maxUpdateInterval && + ns.localStorage.isSet("knownFollowers")) { + this.knownFollowers = ns.localStorage.get("knownFollowers"); + } else { + this.knownFollowers = []; + this.knownFollowersResetTime = ctime; + ns.localStorage.set("knownFollowersResetTime", this.knownFollowersResetTime); + } + + if (ns.sessionStorage.isSet("notFollowers")) + this.notFollowers = ns.sessionStorage.get("notFollowers"); + }, + + save: function () { + var ns = $.initNamespaceStorage(this.user); + ns.localStorage.set("followingsFollowings", this.followingsFollowings); + ns.sessionStorage.set("notFollowers", this.notFollowers); + ns.localStorage.set("knownFollowers", this.knownFollowers); + ns.localStorage.set("knownFollowersResetTime", this.knownFollowersResetTime); + }, + + update: function (username) { + var oneshot = false; + var i = 0; + if (typeof(username) !== 'undefined') { + i = followingUsers[username]; + + if (i > -1) + oneshot = true; + else + i = 0; + } + + for (; i < followingUsers.length; i++) { + var ctime = new Date().getTime() / 1000; + + if (typeof(this.followingsFollowings[followingUsers[i]]) === 'undefined' || + ctime - this.followingsFollowings[followingUsers[i]]["lastUpdate"] >= this.followingsFollowings[followingUsers[i]]["updateInterval"]) { + + loadFollowingFromDht(followingUsers[i], 1, [], 0, function (args, following, seqNum) { + if (following.indexOf(args.tf.user) > -1) { + if (args.tf.knownFollowers.indexOf(args.fu) < 0) + args.tf.knownFollowers.push(args.fu); + } else { + if (args.tf.notFollowers.indexOf(args.fu) < 0) + args.tf.notFollowers.push(args.fu); + var tmpi = args.tf.knownFollowers.indexOf(args.fu); + if (tmpi > -1) + args.tf.knownFollowers.splice(tmpi, 1); + } + $(".open-followers").attr("title", args.tf.knownFollowers.length.toString()); + + var ctime = new Date().getTime() / 1000; + if (typeof(args.tf.followingsFollowings[args.fu]) === 'undefined' || + typeof(args.tf.followingsFollowings[args.fu]["following"]) === 'undefined') { + args.tf.followingsFollowings[args.fu] = {}; + args.tf.followingsFollowings[args.fu]["lastUpdate"] = ctime; + args.tf.followingsFollowings[args.fu]["updateInterval"] = TwisterFollowing.minUpdateInterval; + args.tf.followingsFollowings[args.fu]["following"] = following; + + args.tf.save(); + } else { + var diff = []; + var ff = args.tf.followingsFollowings[args.fu]["following"]; + + for (var j = 0; j < following.length; j++) { + if (ff.indexOf(following[j]) === -1) { + diff.push(following[j]); + ff.push(following[j]); + } + } + + if (diff.length > 0) { + args.tf.followingsFollowings[args.fu]["updateInterval"] = TwisterFollowing.minUpdateInterval; + args.tf.followingsFollowings[args.fu]["lastUpdate"] = ctime; + args.tf.save(); + } else if (args.tf.followingsFollowings[args.fu]["updateInterval"] < TwisterFollowing.maxUpdateInterval) { + args.tf.followingsFollowings[args.fu]["updateInterval"] *= 2; + } + } + }, {"tf": this, "fu": followingUsers[i]}); + } + } + } +}; + // load followingUsers from localStorage function loadFollowingFromStorage() { var ns=$.initNamespaceStorage(defaultScreenName); @@ -44,28 +170,6 @@ function saveFollowingToStorage() { ns.localStorage.set("lastLoadFromDhtTime", _lastLoadFromDhtTime); } -// load followers & following's followings from sessionStorage -function loadFollowingSessionData() { - var ns = $.initNamespaceStorage(defaultScreenName); - - if (ns.sessionStorage.isSet("followingsFollowings")) - followingsFollowings = ns.sessionStorage.get("followingsFollowings"); - - if (ns.sessionStorage.isSet("followers")) - knownFollowers = ns.sessionStorage.get("followers"); - - if (ns.sessionStorage.isSet("notFollowers")) - notFollowers = ns.sessionStorage.get("notFollowers"); -} - -// save list of followers & following's followings to sessionStorage -function storeFollowingSessionData() { - var ns = $.initNamespaceStorage(defaultScreenName); - ns.sessionStorage.set("followingsFollowings", followingsFollowings); - ns.sessionStorage.set("followers", knownFollowers); - ns.sessionStorage.set("notFollowers", notFollowers); -} - // load public list of following users from dht resources // "following1", "following2" etc. // it will stop loading when resource is empty @@ -284,7 +388,7 @@ function getRandomFollowSuggestion(cbFunc, cbArg) { var i = parseInt( Math.random() * followingUsers.length ); if ( (i < followingUsers.length && followingUsers[i] == defaultScreenName) || - typeof(followingsFollowings[followingUsers[i]]) === 'undefined') { + typeof(twisterFollowingO.followingsFollowings[followingUsers[i]]) === 'undefined') { setTimeout(getRandomFollowSuggestion, 500, cbFunc, cbArg); return; @@ -292,12 +396,12 @@ function getRandomFollowSuggestion(cbFunc, cbArg) { if( i < followingUsers.length ) { var suggested = false; - var j = parseInt( Math.random() * followingsFollowings[followingUsers[i]].length ); - for( ; j < followingsFollowings[followingUsers[i]].length; j++ ) { - if( followingUsers.indexOf(followingsFollowings[followingUsers[i]][j]) < 0 && - _followSuggestions.indexOf(followingsFollowings[followingUsers[i]][j]) < 0 ) { - cbFunc(cbArg, followingsFollowings[followingUsers[i]][j], followingUsers[i]); - _followSuggestions.push(followingsFollowings[followingUsers[i]][j]); + var j = parseInt( Math.random() * twisterFollowingO.followingsFollowings[followingUsers[i]]["following"].length ); + for( ; j < twisterFollowingO.followingsFollowings[followingUsers[i]]["following"].length; j++ ) { + if( followingUsers.indexOf(twisterFollowingO.followingsFollowings[followingUsers[i]]["following"][j]) < 0 && + _followSuggestions.indexOf(twisterFollowingO.followingsFollowings[followingUsers[i]]["following"][j]) < 0 ) { + cbFunc(cbArg, twisterFollowingO.followingsFollowings[followingUsers[i]]["following"][j], followingUsers[i]); + _followSuggestions.push(twisterFollowingO.followingsFollowings[followingUsers[i]]["following"][j]); suggested = true; break; } @@ -313,8 +417,8 @@ function getRandomFollowSuggestion(cbFunc, cbArg) { function whoFollows(username) { var list = []; - for (var following in followingsFollowings) { - if (followingsFollowings[following].indexOf(username) > -1) { + for (var following in twisterFollowingO.followingsFollowings) { + if (twisterFollowingO.followingsFollowings[following]["following"].indexOf(username) > -1) { list.push(following); } } diff --git a/js/twister_io.js b/js/twister_io.js index 93a7beb..b20d564 100644 --- a/js/twister_io.js +++ b/js/twister_io.js @@ -212,30 +212,32 @@ function getFullname( username, item ){ args.item.text(value); } }, {item: item} ); - if ($.Options.getIsFollowingMeOpt() === 'everywhere' || item.hasClass('profile-name')) { - if (knownFollowers.indexOf(username) > -1) { + if (typeof(twisterFollowingO) !== 'undefined' && + ($.Options.getIsFollowingMeOpt() === 'everywhere' || item.hasClass('profile-name'))) { + if (twisterFollowingO.knownFollowers.indexOf(username) > -1) { item.addClass('isFollowing'); item.attr("title", polyglot.t("follows you")); - } else if (notFollowers.indexOf(username) > -1) + } else if (twisterFollowingO.notFollowers.indexOf(username) > -1) item.addClass("notFollowing"); else { loadFollowingFromDht(username, 1, [], 0, function (args, following, seqNum) { if (following.indexOf(args.user) > -1) { item.addClass('isFollowing'); item.attr("title", polyglot.t("follows you")); - if (knownFollowers.indexOf(args.username) < 0) - knownFollowers.push(args.username); + if (twisterFollowingO.knownFollowers.indexOf(args.username) < 0) + twisterFollowingO.knownFollowers.push(args.username); } else { item.addClass('notFollowing'); - if (notFollowers.indexOf(args.username) < 0) - notFollowers.push(args.username); + if (twisterFollowingO.notFollowers.indexOf(args.username) < 0) + twisterFollowingO.notFollowers.push(args.username); } - storeFollowingSessionData(); + //storeFollowingSessionData(); + twisterFollowingO.save(); }, {"user": defaultScreenName, "item": item, "username": username}); } - $(".open-followers").attr("title", knownFollowers.length.toString()); + $(".open-followers").attr("title", twisterFollowingO.knownFollowers.length.toString()); } } From bdab2c116bc7c4009231b925879608977e7e5526 Mon Sep 17 00:00:00 2001 From: erqan Date: Fri, 9 May 2014 16:19:46 +0300 Subject: [PATCH 2/2] fixed TwisterFollowing issue on following.html --- js/twister_following.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/js/twister_following.js b/js/twister_following.js index 8ed6272..95d33cd 100644 --- a/js/twister_following.js +++ b/js/twister_following.js @@ -725,6 +725,8 @@ function initInterfaceFollowing() { loadFollowing( function(args) { showFollowingUsers(); requestSwarmProgress(); + + twisterFollowingO = TwisterFollowing(defaultScreenName); }); initMentionsCount(); initDMsCount();