]> git.wh0rd.org - tt-rss.git/blobdiff - viewfeed.js
reduce the number of always included libraries
[tt-rss.git] / viewfeed.js
index c41c49a96e275e63d62453b0fdb127faf2e6fbf9..9cb902315a714bb5ca4cd8972551ce09993547d3 100644 (file)
@@ -1,6 +1,4 @@
 var active_post_id = false;
-var last_article_view = false;
-var active_real_feed_id = false;
 
 var article_cache = new Array();
 
@@ -11,21 +9,25 @@ var last_requested_article = false;
 
 var catchup_id_batch = [];
 var catchup_timeout_id = false;
+var feed_precache_timeout_id = false;
+var precache_idle_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, infscroll_req) {
        try {
                handle_rpc_json(transport);
 
                loading_set_progress(25);
 
-               console.log("headlines_callback2 [offset=" + offset + "]");
+               console.log("headlines_callback2 [offset=" + offset + "] B:" + background + " I:" + infscroll_req);
 
                var is_cat = false;
                var feed_id = false;
 
-               var reply;
+               var reply = false;
 
                try {
                        reply = JSON.parse(transport.responseText);
@@ -38,14 +40,21 @@ function headlines_callback2(transport, offset) {
                        is_cat = reply['headlines']['is_cat'];
                        feed_id = reply['headlines']['id'];
 
-                       setActiveFeedId(feed_id, is_cat);
+                       if (background) {
+                               var content = reply['headlines']['content'];
+
+                               if (getInitParam("cdm_auto_catchup") == 1) {
+                                       content = content + "<div id='headlines-spacer'></div>";
+                               }
 
-                       var update_btn = document.forms["main_toolbar_form"].update;
+                               cache_headlines(feed_id, is_cat, reply['headlines']['toolbar'], content);
+                               return;
+                       }
 
-                       update_btn.disabled = !(feed_id >= 0 && !is_cat);
+                       setActiveFeedId(feed_id, is_cat);
 
                        try {
-                               if (offset == 0) {
+                               if (offset == 0 && infscroll_req == false) {
                                        $("headlines-frame").scrollTop = 0;
                                }
                        } catch (e) { };
@@ -62,28 +71,27 @@ function headlines_callback2(transport, offset) {
 
                        var counters = reply['counters'];
                        var articles = reply['articles'];
-                       var runtime_info = reply['runtime-info'];
+                       //var runtime_info = reply['runtime-info'];
 
-                       if (offset == 0) {
+                       if (offset == 0 && infscroll_req == false) {
                                dijit.byId("headlines-frame").attr('content',
                                        reply['headlines']['content']);
 
                                dijit.byId("headlines-toolbar").attr('content',
                                        reply['headlines']['toolbar']);
 
-                               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);
+                               if (getInitParam("cdm_auto_catchup") == 1) {
+                                       var hsp = $("headlines-spacer");
+                                       if (!hsp) hsp = new Element("DIV", {"id": "headlines-spacer"});
+                                       dijit.byId('headlines-frame').domNode.appendChild(hsp);
+                               }
 
                                initHeadlinesMenu();
 
                        } else {
-                               if (headlines_count > 0) {
+
+                               if (headlines_count > 0 && feed_id == getActiveFeedId() && is_cat == activeFeedIsCat()) {
                                        console.log("adding some more headlines...");
 
                                        var c = dijit.byId("headlines-frame");
@@ -97,19 +105,21 @@ function headlines_callback2(transport, offset) {
                                                c.domNode.removeChild(hsp);
 
                                        $$("#headlines-tmp > div").each(function(row) {
-                                               row.style.display = 'none';
-                                               c.domNode.appendChild(row);
+                                               if ($$("#headlines-frame DIV[id="+row.id+"]").length == 0) {
+                                                       row.style.display = 'none';
+                                                       c.domNode.appendChild(row);
+                                               } else {
+                                                       row.parentNode.removeChild(row);
+                                               }
                                        });
 
                                        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);
+                                       if (getInitParam("cdm_auto_catchup") == 1) {
+                                               c.domNode.appendChild(hsp);
+                                       }
 
                                        console.log("restore selected ids: " + ids);
 
@@ -134,7 +144,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++) {
@@ -145,18 +156,22 @@ function headlines_callback2(transport, offset) {
                                console.log("no cached articles received");
                        }
 
+                       // do not precache stuff after fresh feed
+                       if (feed_id != -3)
+                               precache_headlines();
+
                        if (counters)
                                parse_counters(counters);
                        else
                                request_counters();
 
                } else {
-                       console.warn("headlines_callback: returned no XML object");
+                       console.error("Invalid object received: " + transport.responseText);
                        dijit.byId("headlines-frame").attr('content', "<div class='whiteBox'>" +
-                                       __('Could not update headlines (invalid object received)') + "</div>");
+                                       __('Could not update headlines (invalid object received - see error console for details)') +
+                                       "</div>");
                }
 
-               //_feed_cur_page = feed_cur_page;
                _infscroll_request_sent = 0;
 
                notify("");
@@ -244,37 +259,53 @@ function article_callback2(transport, id) {
 
                handle_rpc_json(transport);
 
-               var reply = JSON.parse(transport.responseText);
+               var reply = false;
+
+               try {
+                       reply = JSON.parse(transport.responseText);
+               } catch (e) {
+                       console.error(e);
+               }
 
                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");
+                       console.error("Invalid object received: " + transport.responseText);
 
                        render_article("<div class='whiteBox'>" +
-                                       __('Could not display article (invalid data received)') + "</div>");
+                                       __('Could not display article (invalid object received - see error console for details)') + "</div>");
                }
 
-               var date = new Date();
-               last_article_view = date.getTime() / 1000;
-
                request_counters();
 
+               try {
+                       if (!_infscroll_disable &&
+                                       $$("#headlines-frame > div[id*=RROW]").last().hasClassName("Selected")) {
+
+                               loadMoreHeadlines();
+                       }
+               } catch (e) {
+                       console.warn(e);
+               }
+
                notify("");
        } catch (e) {
                exception_error("article_callback2", e, transport);
@@ -293,16 +324,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 +348,8 @@ function view(id) {
                active_post_id = id;
                showArticleInHeadlines(id);
 
+               precache_headlines();
+
                if (!cached_article) {
 
                        var upic = $('FUPDPIC-' + id);
@@ -334,8 +369,22 @@ 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) {
+
+                               try {
+                                       if (!_infscroll_disable &&
+                                               $$("#headlines-frame > div[id*=RROW]").last().hasClassName("Selected")) {
+
+                                                       loadMoreHeadlines();
+                                       }
+                               } catch (e) {
+                                       console.warn(e);
+                               }
 
+                               return;
+                       }
                }
 
                last_requested_article = id;
@@ -355,14 +404,6 @@ function view(id) {
        }
 }
 
-function tMark(id) {
-       return toggleMark(id);
-}
-
-function tPub(id) {
-       return togglePub(id);
-}
-
 function toggleMark(id, client_only) {
        try {
                var query = "?op=rpc&id=" + id + "&subop=mark";
@@ -382,6 +423,8 @@ function toggleMark(id, client_only) {
                        query = query + "&mark=0";
                }
 
+               cache_headlines(getActiveFeedId(), activeFeedIsCat(), null, $("headlines-frame").innerHTML);
+
                if (!client_only) {
                        new Ajax.Request("backend.php", {
                                parameters: query,
@@ -421,6 +464,8 @@ function togglePub(id, client_only, no_effects, note) {
                        query = query + "&pub=0";
                }
 
+               cache_headlines(getActiveFeedId(), activeFeedIsCat(), null, $("headlines-frame").innerHTML);
+
                if (!client_only) {
                        new Ajax.Request("backend.php", {
                                parameters: query,
@@ -577,7 +622,7 @@ function toggleUnread(id, cmode, effect) {
 function selectionRemoveLabel(id, ids) {
        try {
 
-               if (!ids) var ids = getSelectedArticleIds2();
+               if (!ids) ids = getSelectedArticleIds2();
 
                if (ids.length == 0) {
                        alert(__("No articles are selected."));
@@ -639,7 +684,7 @@ function selectionToggleUnread(set_state, callback, no_error) {
                        return;
                }
 
-               for (i = 0; i < rows.length; i++) {
+               for (var i = 0; i < rows.length; i++) {
                        var row = $("RROW-" + rows[i]);
                        if (row) {
                                if (set_state == undefined) {
@@ -701,7 +746,7 @@ function selectionToggleMarked() {
                        return;
                }
 
-               for (i = 0; i < rows.length; i++) {
+               for (var i = 0; i < rows.length; i++) {
                        toggleMark(rows[i], true, true);
                }
 
@@ -733,7 +778,7 @@ function selectionTogglePublished() {
                        return;
                }
 
-               for (i = 0; i < rows.length; i++) {
+               for (var i = 0; i < rows.length; i++) {
                        togglePub(rows[i], true, true);
                }
 
@@ -834,7 +879,7 @@ function catchupPage() {
        }
 
        selectArticles('all');
-       selectionToggleUnread(false, 'viewCurrentFeed()', true)
+       selectionToggleUnread(false, 'viewCurrentFeed()', true);
        selectArticles('none');
 }
 
@@ -851,7 +896,6 @@ function deleteSelection() {
 
                var fn = getFeedName(getActiveFeedId(), activeFeedIsCat());
                var str;
-               var op;
 
                if (getActiveFeedId() != 0) {
                        str = __("Delete %d selected articles in %s?");
@@ -954,7 +998,7 @@ function catchupSelection() {
                        return;
                }
 
-               selectionToggleUnread(false, 'viewCurrentFeed()', true)
+               selectionToggleUnread(false, 'viewCurrentFeed()', true);
 
        } catch (e) {
                exception_error("catchupSelection", e);
@@ -986,7 +1030,7 @@ function editArticleTags(id) {
                                                var data = JSON.parse(transport.responseText);
 
                                                if (data) {
-                                                       var tags_str = data.tags_str;
+                                                       var tags_str = article.tags;
                                                        var id = tags_str.id;
 
                                                        var tags = $("ATSTR-" + id);
@@ -1050,12 +1094,13 @@ function headlines_scroll_handler(e) {
                        if (hsp && (e.scrollTop + e.offsetHeight > hsp.offsetTop) ||
                                        e.scrollTop + e.offsetHeight > e.scrollHeight - 100) {
 
-                               hsp.innerHTML = "<img src='images/indicator_tiny.gif'> " +
-                                       __("Loading, please wait...");
+                               if (hsp)
+                                       hsp.innerHTML = "<img src='images/indicator_tiny.gif'> " +
+                                               __("Loading, please wait...");
 
                                loadMoreHeadlines();
+                               return;
 
-                               //viewNextFeedPage();
                        }
                } else {
                        if (hsp) hsp.innerHTML = "";
@@ -1072,18 +1117,23 @@ function headlines_scroll_handler(e) {
 
                                                if (catchup_id_batch.indexOf(id) == -1)
                                                        catchup_id_batch.push(id);
+
+                                               //console.log("auto_catchup_batch: " + catchup_id_batch.toString());
                                        }
                                });
 
-                       if (catchup_id_batch.length > 0 && !_infscroll_request_sent) {
+                       if (catchup_id_batch.length > 0) {
                                window.clearTimeout(catchup_timeout_id);
-                               catchup_timeout_id = window.setTimeout('catchupBatchedArticles()',
-                                               1000);
+
+                               if (!_infscroll_request_sent) {
+                                       catchup_timeout_id = window.setTimeout('catchupBatchedArticles()',
+                                               2000);
+                               }
                        }
                }
 
        } catch (e) {
-               exception_error("headlines_scroll_handler", e);
+               console.warn("headlines_scroll_handler: " + e);
        }
 }
 
@@ -1113,12 +1163,13 @@ function catchupBatchedArticles() {
        }
 }
 
-function catchupRelativeToArticle(below) {
+function catchupRelativeToArticle(below, id) {
 
        try {
 
+               if (!id) id = getActiveArticleId();
 
-               if (!getActiveArticleId()) {
+               if (!id) {
                        alert(__("No article is selected."));
                        return;
                }
@@ -1129,7 +1180,7 @@ function catchupRelativeToArticle(below) {
 
                if (!below) {
                        for (var i = 0; i < visible_ids.length; i++) {
-                               if (visible_ids[i] != getActiveArticleId()) {
+                               if (visible_ids[i] != id) {
                                        var e = $("RROW-" + visible_ids[i]);
 
                                        if (e && e.hasClassName("Unread")) {
@@ -1141,7 +1192,7 @@ function catchupRelativeToArticle(below) {
                        }
                } else {
                        for (var i = visible_ids.length-1; i >= 0; i--) {
-                               if (visible_ids[i] != getActiveArticleId()) {
+                               if (visible_ids[i] != id) {
                                        var e = $("RROW-" + visible_ids[i]);
 
                                        if (e && e.hasClassName("Unread")) {
@@ -1226,28 +1277,39 @@ function cdmExpandArticle(id) {
 
                                var query = "?op=rpc&subop=cdmGetArticle&id=" + param_escape(id);
 
-                               //console.log(query);
+                               var neighbor_ids = getRelativePostIds(id);
+
+                               /* only request uncached articles */
+                               var cids_to_request = [];
+
+                               for (var i = 0; i < neighbor_ids.length; i++) {
+                                       if (cids_requested.indexOf(neighbor_ids[i]) == -1)
+                                               if ($("CWRAP-" + neighbor_ids[i]).innerHTML == "") {
+                                                       cids_to_request.push(neighbor_ids[i]);
+                                                       cids_requested.push(neighbor_ids[i]);
+                                               }
+                               }
+
+                               console.log("additional ids: " + cids_to_request.toString());
+
+                               query = query + "&cids=" + cids_to_request.toString();
+
+                               console.log(query);
 
                                new Ajax.Request("backend.php", {
                                        parameters: query,
                                        onComplete: function(transport) {
+
                                                $("FUPDPIC-" + id).src = 'images/blank_icon.gif';
 
                                                handle_rpc_json(transport);
 
                                                var reply = JSON.parse(transport.responseText);
 
-                                               if (reply) {
-                                                       var article = reply['article']['content'];
-                                                       var recv_id = reply['article']['id'];
-
-                                                       if (recv_id == id)
-                                                               $("CWRAP-" + id).innerHTML = article;
-
-                                               } else {
-                                                       $("CWRAP-" + id).innerHTML = __("Unable to load article.");
-
-                                               }
+                                               reply.each(function(article) {
+                                                       $("CWRAP-" + article['id']).innerHTML = article['content'];
+                                                       cids_requested.remove(article['id']);
+                                               });
                                }});
 
                        }
@@ -1296,7 +1358,7 @@ function getArticleUnderPointer() {
 
 function zoomToArticle(event, id) {
        try {
-               var cached_article = cache_find(id);
+               var cached_article = cache_get("article: " + id);
 
                if (dijit.byId("ATAB-" + id))
                        if (!event || !event.shiftKey)
@@ -1595,7 +1657,7 @@ function getVisibleArticleIds() {
 
 function cdmClicked(event, id) {
        try {
-               var shift_key = event.shiftKey;
+               //var shift_key = event.shiftKey;
 
                hideAuxDlg();
 
@@ -1734,14 +1796,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;
@@ -1864,7 +1926,20 @@ function initHeadlinesMenu() {
                                hlOpenInNewTab(event, this.getParent().callerRowId);
                                }}));
 
-//             menu.addChild(new dijit.MenuSeparator());
+               menu.addChild(new dijit.MenuSeparator());
+
+               menu.addChild(new dijit.MenuItem({
+                       label: __("Mark above as read"),
+                       onClick: function(event) {
+                               catchupRelativeToArticle(0, this.getParent().callerRowId);
+                               }}));
+
+               menu.addChild(new dijit.MenuItem({
+                       label: __("Mark below as read"),
+                       onClick: function(event) {
+                               catchupRelativeToArticle(1, this.getParent().callerRowId);
+                               }}));
+
 
                var labels = dijit.byId("feedTree").model.getItemsInCategory(-2);
 
@@ -2029,13 +2104,12 @@ 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;
                } catch (e) {
-                       if (e == QUOTA_EXCEEDED_ERR)
-                               sessionStorage.clear();
+                       sessionStorage.clear();
                }
 }
 
@@ -2060,9 +2134,11 @@ function cache_headlines(feed, is_cat, toolbar_obj, content_obj) {
                        JSON.stringify({toolbar: toolbar_obj, content: content_obj}));
        } else {
                try {
-                       obj =   JSON.parse(cache_get("feed:" + feed + ":" + is_cat));
+                       obj =   cache_get("feed:" + feed + ":" + is_cat);
 
                        if (obj) {
+                               obj = JSON.parse(obj);
+
                                if (toolbar_obj) obj.toolbar = toolbar_obj;
                                if (content_obj) obj.content = content_obj;
 
@@ -2090,7 +2166,80 @@ function render_local_headlines(feed, is_cat, obj) {
                selectArticles('none');
                setActiveFeedId(feed, is_cat);
                initHeadlinesMenu();
+
+               precache_headlines();
+
        } catch (e) {
                exception_error("render_local_headlines", e);
        }
 }
+
+function precache_headlines_idle() {
+       try {
+               if (!feed_precache_timeout_id) {
+                       var feeds = dijit.byId("feedTree").getVisibleUnreadFeeds();
+                       var uncached = [];
+
+                       feeds.each(function(item) {
+                               if (parseInt(item[0]) > 0 && !cache_get("feed:" + item[0] + ":" + item[1]))
+                                       uncached.push(item);
+                       });
+
+                       if (uncached.length > 0) {
+                               var rf = uncached[Math.floor(Math.random()*uncached.length)];
+                               viewfeed(rf[0], '', rf[1], 0, true);
+                       }
+               }
+               precache_idle_timeout_id = setTimeout("precache_headlines_idle()", 1000*30);
+
+       } catch (e) {
+               exception_error("precache_headlines_idle", e);
+       }
+}
+
+function precache_headlines() {
+       try {
+
+               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 != nuf && 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);
+               }
+
+       } catch (e) {
+               exception_error("precache_headlines", e);
+       }
+}
+
+function shareArticle(id) {
+       try {
+               if (dijit.byId("shareArticleDlg"))
+                       dijit.byId("shareArticleDlg").destroyRecursive();
+
+               var query = "backend.php?op=dlg&id=shareArticle&param=" + param_escape(id);
+
+               dialog = new dijit.Dialog({
+                       id: "shareArticleDlg",
+                       title: __("Share article by URL"),
+                       style: "width: 600px",
+                       href: query});
+
+               dialog.show();
+
+       } catch (e) {
+               exception_error("emailArticle", e);
+       }
+}
+
+