]> git.wh0rd.org - tt-rss.git/commitdiff
implement automatic precaching for next normal and unread feeds
authorAndrew Dolgov <fox@madoka.volgo-balt.ru>
Wed, 31 Aug 2011 11:25:42 +0000 (15:25 +0400)
committerAndrew Dolgov <fox@madoka.volgo-balt.ru>
Wed, 31 Aug 2011 12:15:01 +0000 (16:15 +0400)
allow opening cached next_unread_feed on f-q if available
tweak getRelativeArticles() to scan forward only
reenable prefetch_old server requests

backend.php
feedlist.js
functions.php
modules/backend-rpc.php
tt-rss.js
viewfeed.js

index d039740b33f6703603812a29f080c9589dbb1192..e3260739fde70d64ac0e68f59a2bd0b9fbb8ba0f 100644 (file)
                        $subop = db_escape_string($_REQUEST["subop"]);
                        $view_mode = db_escape_string($_REQUEST["view_mode"]);
                        $limit = (int) get_pref($link, "DEFAULT_ARTICLE_LIMIT");
-                       @$cat_view = db_escape_string($_REQUEST["cat"]);
+                       @$cat_view = db_escape_string($_REQUEST["cat"]) == "true";
                        @$next_unread_feed = db_escape_string($_REQUEST["nuf"]);
                        @$offset = db_escape_string($_REQUEST["skip"]);
                        @$vgroup_last_feed = db_escape_string($_REQUEST["vgrlf"]);
index ab21a30fb4b7ac40573affd8a39b551be97c3d77..fc3bcd9c73685d6362f8b333f99b23af1ebe9360 100644 (file)
@@ -48,7 +48,7 @@ function loadMoreHeadlines() {
 }
 
 
-function viewfeed(feed, subop, is_cat, offset) {
+function viewfeed(feed, subop, is_cat, offset, background) {
        try {
                if (is_cat == undefined)
                        is_cat = false;
@@ -57,6 +57,7 @@ function viewfeed(feed, subop, is_cat, offset) {
 
                if (subop == undefined) subop = '';
                if (offset == undefined) offset = 0;
+               if (background == undefined) background = false;
 
                last_requested_article = 0;
 
@@ -72,101 +73,112 @@ function viewfeed(feed, subop, is_cat, offset) {
 
                var force_nocache = false;
 
-               if (getActiveFeedId() != feed || offset == 0) {
-                       active_post_id = 0;
-                       _infscroll_disable = 0;
-               }
+               if (!background) {
+                       if (getActiveFeedId() != feed || offset == 0) {
+                               active_post_id = 0;
+                               _infscroll_disable = 0;
+                       }
 
-               if (!offset && !subop && cached_headlines) {
-                       try {
-                               render_local_headlines(feed, is_cat, JSON.parse(cached_headlines));
-                               return;
-                       } catch (e) {
-                               console.warn("render_local_headlines failed: " + e);
+                       if (!offset && !subop && cached_headlines && !background) {
+                               try {
+                                       render_local_headlines(feed, is_cat, JSON.parse(cached_headlines));
+                                       return;
+                               } catch (e) {
+                                       console.warn("render_local_headlines failed: " + e);
+                               }
                        }
-               }
 
-               if (offset != 0 && !subop) {
-                       var date = new Date();
-                       var timestamp = Math.round(date.getTime() / 1000);
+                       if (offset != 0 && !subop) {
+                               var date = new Date();
+                               var timestamp = Math.round(date.getTime() / 1000);
 
-                       if (_infscroll_request_sent && _infscroll_request_sent + 30 > timestamp) {
-                               //console.log("infscroll request in progress, aborting");
-                               return;
+                               if (_infscroll_request_sent && _infscroll_request_sent + 30 > timestamp) {
+                                       //console.log("infscroll request in progress, aborting");
+                                       return;
+                               }
+
+                               _infscroll_request_sent = timestamp;
                        }
 
-                       _infscroll_request_sent = timestamp;
+                       hideAuxDlg();
                }
 
-               hideAuxDlg();
-
                Form.enable("main_toolbar_form");
 
-               var toolbar_form = document.forms["main_toolbar_form"];
                var toolbar_query = Form.serialize("main_toolbar_form");
 
-               if (toolbar_form.query) {
-                       if (toolbar_form.query.value != "") {
+               var query = "?op=viewfeed&feed=" + feed + "&" +
+                       toolbar_query + "&subop=" + param_escape(subop);
+
+               if (!background) {
+                       if (_search_query) {
                                force_nocache = true;
+                               query = query + "&" + _search_query;
+                               _search_query = false;
                        }
-                       toolbar_form.query.value = "";
-               }
 
-               var query = "?op=viewfeed&feed=" + feed + "&" +
-                       toolbar_query + "&subop=" + param_escape(subop);
+                       if (subop == "MarkAllRead") {
 
-               if (_search_query) {
-                       force_nocache = true;
-                       query = query + "&" + _search_query;
-                       _search_query = false;
-               }
+                               var show_next_feed = getInitParam("on_catchup_show_next_feed") == "1";
 
-               if (subop == "MarkAllRead") {
+                               if (show_next_feed) {
+                                       var nuf = getNextUnreadFeed(feed, is_cat);
 
-                       var show_next_feed = getInitParam("on_catchup_show_next_feed") == "1";
+                                       if (nuf) {
+                                               var cached_nuf = cache_get("feed:" + nuf + ":false");
 
-                       if (show_next_feed) {
-                               var tree = dijit.byId("feedTree");
-                               var nuf = tree.model.getNextUnreadFeed(feed, is_cat);
+                                               if (cached_nuf) {
 
-                               if (nuf) {
-                                       var nuf_id = tree.model.store.getValue(nuf, 'bare_id');
+                                                       render_local_headlines(nuf, false, JSON.parse(cached_nuf));
 
-                                       query = query + "&nuf=" + param_escape(nuf_id);
+                                                       var catchup_query = "?op=rpc&subop=catchupFeed&feed_id=" +
+                                                               feed + "&is_cat=" + is_cat;
+
+                                                       console.log(catchup_query);
+
+                                                       new Ajax.Request("backend.php", {
+                                                               parameters: catchup_query,
+                                                               onComplete: function(transport) {
+                                                                       handle_rpc_json(transport);
+                                                               } });
+
+                                                       return;
+                                               } else {
+                                                       query += "&nuf=" + param_escape(nuf);
+                                               }
+                                       }
                                }
                        }
-               }
 
-               if (is_cat) {
-                       query = query + "&cat=1";
-               }
-
-               if (offset != 0) {
-                       query = query + "&skip=" + offset;
+                       if (offset != 0) {
+                               query = query + "&skip=" + offset;
 
-                       // to prevent duplicate feed titles when showing grouped vfeeds
-                       if (vgroup_last_feed) {
-                               query = query + "&vgrlf=" + param_escape(vgroup_last_feed);
+                               // to prevent duplicate feed titles when showing grouped vfeeds
+                               if (vgroup_last_feed) {
+                                       query = query + "&vgrlf=" + param_escape(vgroup_last_feed);
+                               }
                        }
+
+                       Form.enable("main_toolbar_form");
+
+                       if (!offset)
+                               if (!is_cat) {
+                                       if (!setFeedExpandoIcon(feed, is_cat, 'images/indicator_white.gif'))
+                                               notify_progress("Loading, please wait...", true);
+                               } else {
+                                       notify_progress("Loading, please wait...", true);
+                               }
                }
 
-               Form.enable("main_toolbar_form");
+               query += "&cat=" + is_cat;
 
                console.log(query);
 
-               if (!offset)
-                       if (!is_cat) {
-                               if (!setFeedExpandoIcon(feed, is_cat, 'images/indicator_white.gif'))
-                                       notify_progress("Loading, please wait...", true);
-                       } else {
-                               notify_progress("Loading, please wait...", true);
-                       }
-
                new Ajax.Request("backend.php", {
                        parameters: query,
                        onComplete: function(transport) {
                                setFeedExpandoIcon(feed, is_cat, 'images/blank_icon.gif');
-                               headlines_callback2(transport, offset);
+                               headlines_callback2(transport, offset, background);
                        } });
 
        } catch (e) {
@@ -428,3 +440,17 @@ function setFeedExpandoIcon(feed, is_cat, src) {
        }
        return false;
 }
+
+function getNextUnreadFeed(feed, is_cat) {
+       try {
+               var tree = dijit.byId("feedTree");
+               var nuf = tree.model.getNextUnreadFeed(feed, is_cat);
+
+               if (nuf)
+                       return tree.model.store.getValue(nuf, 'bare_id');
+
+       } catch (e) {
+               exception_error("getNextUnreadFeed", e);
+       }
+}
+
index bb6164d7bc08d1ba32bece776b16ab69a24c2c1d..f0691f209e544683f53f254b0c97a1b8f1a43bed 100644 (file)
 
                        if (!$owner_uid) $owner_uid = $_SESSION['uid'];
 
-                       if (preg_match("/^-?[0-9][0-9]*$/", $feed) != false) {
+                       //if (preg_match("/^-?[0-9][0-9]*$/", $feed) != false) {
 
+                       if (is_numeric($feed)) {
                                if ($cat_view) {
 
                                        if ($feed >= 0) {
                                                }
                                        } else if ($feed == -2) {
 
-
                                                db_query($link, "UPDATE ttrss_user_entries
                                                        SET unread = false,last_read = NOW() WHERE (SELECT COUNT(*)
                                                                FROM ttrss_user_labels2 WHERE article_id = ref_id) > 0
index a89c5ee815910570e657dfb35d861e93dcf6caf0..dff12aa5a3ee5e6dfff67886fd264aa52da57a33 100644 (file)
 
                if ($subop == "catchupFeed") {
                        $feed_id = db_escape_string($_REQUEST['feed_id']);
-                       $is_cat = db_escape_string($_REQUEST['is_cat']);
+                       $is_cat = db_escape_string($_REQUEST['is_cat']) == "true";
 
                        catchup_feed($link, $feed_id, $is_cat);
 
+                       print json_encode(array("message" => "UPDATE_COUNTERS"));
                        return;
                }
 
 
                if ($subop == "regenFeedKey") {
                        $feed_id = db_escape_string($_REQUEST['id']);
-                       $is_cat = (bool) db_escape_string($_REQUEST['is_cat']);
+                       $is_cat = db_escape_string($_REQUEST['is_cat']) == "true";
 
                        $new_key = update_feed_access_key($link, $feed_id, $is_cat);
 
index c8f4ab83e8244bc4e80bd01a3d006036c1915e4c..3e0e95919c413453fb4db532e06f7f205f163525 100644 (file)
--- a/tt-rss.js
+++ b/tt-rss.js
@@ -330,7 +330,9 @@ function init_second_stage() {
 
                loading_set_progress(30);
 
-               cache_clear();
+               // can't use cache_clear() here because viewfeed might not have initialized yet
+               if ('sessionStorage' in window && window['sessionStorage'] !== null)
+                       sessionStorage.clear();
 
                console.log("second stage ok");
 
index c41c49a96e275e63d62453b0fdb127faf2e6fbf9..b040dc1555d6b068fb9e49e24eeb9c5b355d2950 100644 (file)
@@ -11,16 +11,19 @@ var last_requested_article = false;
 
 var catchup_id_batch = [];
 var catchup_timeout_id = false;
+var feed_precache_timeout_id = false;
+
+var cids_requested = [];
 
 var has_storage = 'sessionStorage' in window && window['sessionStorage'] !== null;
 
-function headlines_callback2(transport, offset) {
+function headlines_callback2(transport, offset, background) {
        try {
                handle_rpc_json(transport);
 
                loading_set_progress(25);
 
-               console.log("headlines_callback2 [offset=" + offset + "]");
+               console.log("headlines_callback2 [offset=" + offset + "] B:" + background);
 
                var is_cat = false;
                var feed_id = false;
@@ -38,11 +41,12 @@ function headlines_callback2(transport, offset) {
                        is_cat = reply['headlines']['is_cat'];
                        feed_id = reply['headlines']['id'];
 
-                       setActiveFeedId(feed_id, is_cat);
-
-                       var update_btn = document.forms["main_toolbar_form"].update;
+                       if (background) {
+                               cache_headlines(feed_id, is_cat, reply['headlines']['toolbar'], reply['headlines']['content']);
+                               return;
+                       }
 
-                       update_btn.disabled = !(feed_id >= 0 && !is_cat);
+                       setActiveFeedId(feed_id, is_cat);
 
                        try {
                                if (offset == 0) {
@@ -74,10 +78,6 @@ function headlines_callback2(transport, offset) {
                                var hsp = $("headlines-spacer");
                                if (!hsp) hsp = new Element("DIV", {"id": "headlines-spacer"});
 
-/*                             if (!_infscroll_disable)
-                                       hsp.innerHTML = "<img src='images/indicator_tiny.gif'> " +
-                                               __("Loading, please wait..."); */
-
                                dijit.byId('headlines-frame').domNode.appendChild(hsp);
 
                                initHeadlinesMenu();
@@ -103,10 +103,6 @@ function headlines_callback2(transport, offset) {
 
                                        if (!hsp) hsp = new Element("DIV", {"id": "headlines-spacer"});
 
-/*                                     if (!_infscroll_disable)
-                                               hsp.innerHTML = "<img src='images/indicator_tiny.gif'> " +
-                                                       __("Loading, please wait..."); */
-
                                        fixHeadlinesOrder(getLoadedArticleIds());
 
                                        c.domNode.appendChild(hsp);
@@ -134,7 +130,8 @@ function headlines_callback2(transport, offset) {
                                }
                        }
 
-                       cache_headlines(feed_id, is_cat, reply['headlines']['toolbar'], $("headlines-frame").innerHTML);
+                       if (headlines_count > 0)
+                               cache_headlines(feed_id, is_cat, reply['headlines']['toolbar'], $("headlines-frame").innerHTML);
 
                        if (articles) {
                                for (var i = 0; i < articles.length; i++) {
@@ -247,22 +244,25 @@ function article_callback2(transport, id) {
                var reply = JSON.parse(transport.responseText);
 
                if (reply) {
+
                        var upic = $('FUPDPIC-' + id);
 
                        if (upic) upic.src = 'images/blank_icon.gif';
 
-                       if (id != last_requested_article) {
-                               console.log("requested article id is out of sequence, aborting");
-                               return;
-                       }
-
                        reply.each(function(article) {
                                if (active_post_id == article['id']) {
                                        render_article(article['content']);
                                }
+                               cids_requested.remove(article['id']);
+
                                cache_set("article:" + article['id'], article['content']);
                        });
 
+//                     if (id != last_requested_article) {
+//                             console.log("requested article id is out of sequence, aborting");
+//                             return;
+//                     }
+
                } else {
                        console.warn("article_callback: returned invalid data");
 
@@ -293,16 +293,18 @@ function view(id) {
 
                var query = "?op=view&id=" + param_escape(id);
 
-               var neighbor_ids = getRelativePostIds(active_post_id);
+               var neighbor_ids = getRelativePostIds(id);
 
                /* only request uncached articles */
 
-               var cids_to_request = Array();
+               var cids_to_request = [];
 
                for (var i = 0; i < neighbor_ids.length; i++) {
-                       if (!cache_get("article:" + neighbor_ids[i])) {
-                               cids_to_request.push(neighbor_ids[i]);
-                       }
+                       if (cids_requested.indexOf(neighbor_ids[i]) == -1)
+                               if (!cache_get("article:" + neighbor_ids[i])) {
+                                       cids_to_request.push(neighbor_ids[i]);
+                                       cids_requested.push(neighbor_ids[i]);
+                               }
                }
 
                console.log("additional ids: " + cids_to_request.toString());
@@ -315,6 +317,24 @@ function view(id) {
                active_post_id = id;
                showArticleInHeadlines(id);
 
+               if (!feed_precache_timeout_id) {
+                       feed_precache_timeout_id = window.setTimeout(function() {
+                               var nuf = getNextUnreadFeed(getActiveFeedId(), activeFeedIsCat());
+                               var nf = dijit.byId("feedTree").getNextFeed(getActiveFeedId(), activeFeedIsCat());
+
+                               if (nuf && !cache_get("feed:" + nuf + ":" + activeFeedIsCat()))
+                                       viewfeed(nuf, '', activeFeedIsCat(), 0, true);
+
+                               if (nf && !cache_get("feed:" + nf[0] + ":" + nf[1]))
+                                       viewfeed(nf[0], '', nf[1], 0, true);
+
+                               window.setTimeout(function() {
+                                       feed_precache_timeout_id = false;
+                                       }, 3000);
+
+                       }, 1000);
+               }
+
                if (!cached_article) {
 
                        var upic = $('FUPDPIC-' + id);
@@ -334,8 +354,10 @@ function view(id) {
                        query = query + "&mode=prefetch_old";
                        render_article(cached_article);
 
-                       return; // do not do prefetch_old request
-
+                       // if we don't need to request any relative ids, we might as well skip
+                       // the server roundtrip altogether
+                       if (cids_to_request.length == 0)
+                               return;
                }
 
                last_requested_article = id;
@@ -1083,7 +1105,7 @@ function headlines_scroll_handler(e) {
                }
 
        } catch (e) {
-               exception_error("headlines_scroll_handler", e);
+               console.warn("headlines_scroll_handler: " + e);
        }
 }
 
@@ -1734,14 +1756,14 @@ function getRelativePostIds(id, limit) {
 
        try {
 
-               if (!limit) limit = 3;
+               if (!limit) limit = 6; //3
 
                var ids = getVisibleArticleIds();
 
                for (var i = 0; i < ids.length; i++) {
                        if (ids[i] == id) {
                                for (var k = 1; k <= limit; k++) {
-                                       if (i > k-1) tmp.push(ids[i-k]);
+                                       //if (i > k-1) tmp.push(ids[i-k]);
                                        if (i < ids.length-k) tmp.push(ids[i+k]);
                                }
                                break;
@@ -2029,7 +2051,7 @@ function player(elem) {
 }
 
 function cache_set(id, obj) {
-       console.log("cache_set: " + id);
+       //console.log("cache_set: " + id);
        if (has_storage)
                try {
                        sessionStorage[id] = obj;