]> git.wh0rd.org Git - tt-rss.git/commitdiff
add article prefetching, remove history tracking
authorAndrew Dolgov <fox@madoka.spb.ru>
Tue, 15 May 2007 05:03:35 +0000 (06:03 +0100)
committerAndrew Dolgov <fox@madoka.spb.ru>
Tue, 15 May 2007 05:03:35 +0000 (06:03 +0100)
backend.php
feedlist.js
functions.js
functions.php
tt-rss.js
viewfeed.js

index a71b649e44e1b10dc1ee270663f054d6edc194ba..39324673239cb34d9c1b30f19f690f086d05d813 100644 (file)
@@ -43,7 +43,7 @@
 
        $print_exec_time = false;
 
-       if ((!$op || $op == "rpc" || $op == "rss" || $op == "digestSend" ||
+       if ((!$op || $op == "rpc" || $op == "rss" || $op == "view" || $op == "digestSend" ||
                        $op == "globalUpdateFeeds") && !$_REQUEST["noxml"]) {
                header("Content-Type: application/xml; charset=utf-8");
        } else {
 
        }
 
-       if ($op == "view") {
+       function outputArticleXML($link, $id, $feed_id, $mark_as_read = true) {
 
-               $id = db_escape_string($_GET["id"]);
-               $feed_id = db_escape_string($_GET["feed"]);
+               print "<article id='$id'><![CDATA[";
 
                $result = db_query($link, "SELECT rtl_content FROM ttrss_feeds
                        WHERE id = '$feed_id' AND owner_uid = " . $_SESSION["uid"]);
                        $rtl_class = "";
                }
 
-               $result = db_query($link, "UPDATE ttrss_user_entries 
-                       SET unread = false,last_read = NOW() 
-                       WHERE ref_id = '$id' AND owner_uid = " . $_SESSION["uid"]);
+               if ($mark_as_read) {
+                       $result = db_query($link, "UPDATE ttrss_user_entries 
+                               SET unread = false,last_read = NOW() 
+                               WHERE ref_id = '$id' AND owner_uid = " . $_SESSION["uid"]);
+               }
 
                $result = db_query($link, "SELECT title,link,content,feed_id,comments,int_id,
                        SUBSTRING(updated,1,16) as updated,
                        print "</div>";
 
                }
+
+               print "]]></article>";
+
+       }
+
+       if ($op == "view") {
+
+               $id = db_escape_string($_GET["id"]);
+               $feed_id = db_escape_string($_GET["feed"]);
+               $cids = split(",", db_escape_string($_GET["cids"]));
+               $mode = db_escape_string($_GET["mode"]);
+
+               print "<reply>";
+
+               // in prefetch mode we only output requested cids, main article 
+               // just gets marked as read (it already exists in client cache)
+
+               if ($mode != "prefetch") {
+                       outputArticleXML($link, $id, $feed_id);
+               } else {
+                       catchupArticleById($link, $id, 0);
+               }
+
+               foreach ($cids as $cid) {
+                       if ($cid) {
+                               outputArticleXML($link, $cid, $feed_id, false);
+                       }
+               }
+
+               print "</reply>";
        }
 
        if ($op == "viewfeed") {
index 77a31302fc5ca1501537f02c2d427cabb743203e..f5a675772fddffb3f7d7e0024cb85e0ebf4ba2ea 100644 (file)
@@ -46,10 +46,10 @@ function viewfeed(feed, subop, is_cat, subop_param, skip_history, offset) {
 
                enableHotkeys();
 
-               if (!skip_history) {
+/*             if (!skip_history) {
                        history_push('FEED:' + feed + ':' + subop + ':' + is_cat +
                                ':' + subop_param);
-               }
+               } */
 
                var toolbar_query = Form.serialize("main_toolbar_form");
                var toolbar_form = document.forms["main_toolbar_form"];
index 3a67b183728ec3178bb8854193a0397aa4180960..09f430096830e88e5433c900d318eec0ccac0db0 100644 (file)
@@ -1667,3 +1667,34 @@ function logoutUser() {
                exception_error("logoutUser", e);
        }
 }
+
+// this only searches loaded headlines list, not in CDM
+function getRelativePostIds(id) {
+
+       debug("getRelativePostIds: " + id);
+
+       var ids = new Array();
+       var container = document.getElementById("headlinesList");
+
+       if (container) {
+               var rows = container.rows;
+
+               for (var i = 0; i < rows.length; i++) {
+                       var r_id = rows[i].id.replace("RROW-", "");
+
+                       if (r_id == id) {
+                               if (i > 0) ids.push(rows[i-1].id.replace("RROW-", ""));
+                               if (i > 1) ids.push(rows[i-2].id.replace("RROW-", ""));
+                               if (i > 2) ids.push(rows[i-3].id.replace("RROW-", ""));
+
+                               if (i < rows.length) ids.push(rows[i+1].id.replace("RROW-", ""));
+                               if (i < rows.length-1) ids.push(rows[i+2].id.replace("RROW-", ""));
+                               if (i < rows.length-2) ids.push(rows[i+3].id.replace("RROW-", ""));
+
+                               return ids;
+                       }
+               }
+       }
+
+       return false;
+}
index cdf592f7027323674c65347914ada18106d2448e..6188e38d935ced36d607df3f36343c9e0b55543d 100644 (file)
                }
        }
 
+       function catchupArticleById($link, $id, $cmode) {
+
+               if ($cmode == 0) {
+                       db_query($link, "UPDATE ttrss_user_entries SET 
+                       unread = false,last_read = NOW()
+                       WHERE ref_id = '$id' AND owner_uid = " . $_SESSION["uid"]);
+               } else if ($cmode == 1) {
+                       db_query($link, "UPDATE ttrss_user_entries SET 
+                       unread = true
+                       WHERE ref_id = '$id' AND owner_uid = " . $_SESSION["uid"]);
+               } else {
+                       db_query($link, "UPDATE ttrss_user_entries SET 
+                       unread = NOT unread,last_read = NOW()
+                       WHERE ref_id = '$id' AND owner_uid = " . $_SESSION["uid"]);
+               }
+       }
+
        function escape_for_form($s) {
                return htmlspecialchars(db_unescape_string($s));
        }
index b46c859acccfd3b1f30ab0a84000d1107bc2295b..d22aa1fba3ae6df2bbc52c46f971acecb162f148 100644 (file)
--- a/tt-rss.js
+++ b/tt-rss.js
@@ -21,7 +21,7 @@ var xmlhttp_ctr = Ajax.getTransport();
 
 var init_params = new Object();
 
-var op_history = new Array();
+//var op_history = new Array();
 
 function tagsAreDisplayed() {
        return display_tags;
@@ -696,7 +696,7 @@ function feedEditSave() {
                exception_error("feedEditSave (main)", e);
        } 
 }
-
+/*
 function localHotkeyHandler(e) {
 
        var keycode;
@@ -756,7 +756,7 @@ function localHotkeyHandler(e) {
        }       
 
        debug("LKP=" + keycode);
-}
+} 
 
 function history_push(op) {
        debug("history_push: " + op);
@@ -776,4 +776,4 @@ function history_pop() {
 function history_clear() {
        debug("history_clear");
        op_history.clear();
-}
+} */
index 8a35180532b6230b6d7b1a852d0b9a6ca60fbea6..f5791eaf7f21ed7e9f0f998618eb959a3ceb57ad 100644 (file)
@@ -16,6 +16,8 @@ var _reload_feedlist_after_view = false;
 var _cdm_wd_timeout = false;
 var _cdm_wd_vishist = new Array();
 
+var article_cache = new Array();
+
 function catchup_callback() {
        if (xmlhttp_rpc.readyState == 4) {
                try {
@@ -66,14 +68,49 @@ function headlines_callback() {
        }
 }
 
-function article_callback() {
-       if (xmlhttp.readyState == 4) {
-               debug("article_callback");
+function render_article(article) {
+       try {
                var f = document.getElementById("content-frame");
                try {
                        f.scrollTop = 0;
                } catch (e) { };
-               f.innerHTML = xmlhttp.responseText;
+
+               f.innerHTML = article;
+
+       } catch (e) {
+               exception_error("render_article", e);
+       }
+}
+
+function article_callback() {
+       if (xmlhttp.readyState == 4) {
+               debug("article_callback");
+
+               try {
+                       if (xmlhttp.responseXML) {
+                               var reply = xmlhttp.responseXML.firstChild.firstChild;
+
+                               var articles = xmlhttp.responseXML.getElementsByTagName("article");
+
+                               for (var i = 0; i < articles.length; i++) {
+                                       var a_id = articles[i].getAttribute("id");
+
+                                       debug("found id: " + a_id);
+
+                                       if (a_id == active_post_id) {
+                                               debug("active article, rendering...");                                  
+                                               render_article(articles[i].firstChild.nodeValue);
+                                       }
+
+                                       cache_inject(a_id, articles[i].firstChild.nodeValue);
+                               }
+                       
+                       } else {
+                               debug("article_callback: returned no XML object");
+                       }
+               } catch (e) {
+                       exception_error("article_callback", e);
+               }
 
                var date = new Date();
                last_article_view = date.getTime() / 1000;
@@ -100,9 +137,13 @@ function view(id, feed_id, skip_history) {
 
                active_real_feed_id = feed_id;
 
-               if (!skip_history) {
+               var cached_article = cache_find(id);
+
+               debug("cache check result: " + (cached_article != false));
+
+/*             if (!skip_history) {
                        history_push("ARTICLE:" + id + ":" + feed_id);
-               }
+               } */
        
                enableHotkeys();
        
@@ -119,11 +160,15 @@ function view(id, feed_id, skip_history) {
                        xmlhttp.abort();
                }
 
-               if (xmlhttp_ready(xmlhttp)) {
+               if (cached_article || xmlhttp_ready(xmlhttp)) {
 
                        cleanSelected("headlinesList");
 
                        var crow = document.getElementById("RROW-" + active_post_id);
+
+                       var article_is_unread = crow.className.match("Unread");
+                       debug("article is unread: " + article_is_unread);                       
+
                        crow.className = crow.className.replace("Unread", "");
 
                        var upd_img_pic = document.getElementById("FUPDPIC-" + active_post_id);
@@ -135,15 +180,55 @@ function view(id, feed_id, skip_history) {
                        selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', false);
                        markHeadline(active_post_id);
 
+                       var neighbor_ids = getRelativePostIds(active_post_id);
+
+                       /* only request uncached articles */
+
+                       var cids_to_request = Array();
+
+                       for (var i = 0; i < neighbor_ids.length; i++) {
+                               if (!cache_check(neighbor_ids[i])) {
+                                       cids_to_request.push(neighbor_ids[i]);
+                               }
+                       }
+
+                       debug("additional ids: " + cids_to_request.toString());                 
+
                        var date = new Date();
                        var timestamp = Math.round(date.getTime() / 1000);
                        query = query + "&ts=" + timestamp;
 
-                       notify_progress("Loading, please wait...");
+                       query = query + "&cids=" + cids_to_request.toString();
+
+                       if (!cached_article) {
+
+                               notify_progress("Loading, please wait...");
+
+                               debug(query);
+
+                               xmlhttp.open("GET", query, true);
+                               xmlhttp.onreadystatechange=article_callback;
+                               xmlhttp.send(null);
+                       } else if (cached_article && article_is_unread) {
+
+                               query = query + "&mode=prefetch";
+
+                               debug(query);
+
+                               xmlhttp.open("GET", query, true);
+                               xmlhttp.onreadystatechange=article_callback;
+                               xmlhttp.send(null);
+
+                               render_article(cached_article);
+
+                       } else if (cached_article) {
+
+                               render_article(cached_article);
+
+                       }
+
+                       cache_expire();
 
-                       xmlhttp.open("GET", query, true);
-                       xmlhttp.onreadystatechange=article_callback;
-                       xmlhttp.send(null);
                } else {
                        debug("xmlhttp busy (@view)");
                        printLockingError();
@@ -650,3 +735,37 @@ function cdmWatchdog() {
        }
 
 }
+
+
+function cache_inject(id, article) {
+       if (!article_cache[id]) {
+               debug("cache_article: miss: " + id);
+
+               var cache_obj = new Array();
+
+               var d = new Date();
+               cache_obj["entered"] = d.getTime() / 1000;
+               cache_obj["data"] = article;
+
+               article_cache[id] = cache_obj;
+
+       } else {
+               debug("cache_article: hit: " + id);
+       }
+}
+
+function cache_find(id) {
+       if (typeof article_cache[id] != 'undefined') {
+               return article_cache[id]["data"];
+       } else {
+               return false;
+       }
+}
+
+function cache_check(id) {
+       return typeof article_cache[id] != 'undefined';
+}
+
+function cache_expire() {
+       /* TODO */
+}