]> git.wh0rd.org - tt-rss.git/blobdiff - viewfeed.js
misc fixes, rework hotkeys code placement
[tt-rss.git] / viewfeed.js
index a1c99930827db11d05114da407bcf227592234f6..e5e862d59481fa3fc87dbf17de97b7ae74443297 100644 (file)
@@ -45,11 +45,8 @@ function catchup_callback2(transport, callback) {
        }
 }
 
-function headlines_callback2(transport, active_feed_id, is_cat, feed_cur_page) {
+function clean_feed_selections() {
        try {
-
-               debug("headlines_callback2 [page=" + feed_cur_page + "]");
-
                var feeds = document.getElementById("feedList").getElementsByTagName("LI");
 
                for (var i = 0; i < feeds.length; i++) {
@@ -57,6 +54,17 @@ function headlines_callback2(transport, active_feed_id, is_cat, feed_cur_page) {
                                feeds[i].className = feeds[i].className.replace("Selected", "");
                        }                       
                }
+       } catch (e) {
+               exception_error("clean_feed_selections", e);
+       }
+}
+
+function headlines_callback2(transport, active_feed_id, is_cat, feed_cur_page) {
+       try {
+
+               debug("headlines_callback2 [page=" + feed_cur_page + "]");
+
+               clean_feed_selections();
 
                setActiveFeedId(active_feed_id);
                
@@ -82,11 +90,19 @@ function headlines_callback2(transport, active_feed_id, is_cat, feed_cur_page) {
                if (transport.responseXML) {
                        var headlines = transport.responseXML.getElementsByTagName("headlines")[0];
                        var headlines_count_obj = transport.responseXML.getElementsByTagName("headlines-count")[0];
-       
+                       var headlines_unread_obj = transport.responseXML.getElementsByTagName("headlines-unread")[0];
+                       var disable_cache_obj = transport.responseXML.getElementsByTagName("disable-cache")[0];
+
                        var headlines_count = headlines_count_obj.getAttribute("value");
-       
-                       if (headlines_count == 0) _infscroll_disable = 1;
-       
+                       var headlines_unread = headlines_unread_obj.getAttribute("value");
+                       var disable_cache = disable_cache_obj.getAttribute("value") != "0";
+
+                       if (headlines_count == 0) {
+                               _infscroll_disable = 1;
+                       } else {
+                               _infscroll_disable = 0;
+                       }
+
                        var counters = transport.responseXML.getElementsByTagName("counters")[0];
                        var articles = transport.responseXML.getElementsByTagName("article");
                        var runtime_info = transport.responseXML.getElementsByTagName("runtime-info");
@@ -94,6 +110,22 @@ function headlines_callback2(transport, active_feed_id, is_cat, feed_cur_page) {
                        if (feed_cur_page == 0) {
                                if (headlines) {
                                        f.innerHTML = headlines.firstChild.nodeValue;
+
+                                       var cache_prefix = "";
+
+                                       if (is_cat) {
+                                               cache_prefix = "C:";
+                                       } else {
+                                               cache_prefix = "F:";
+                                       }
+
+                                       cache_invalidate(cache_prefix + active_feed_id);
+
+                                       if (!disable_cache) {
+                                               cache_inject(cache_prefix + active_feed_id,
+                                                       headlines.firstChild.nodeValue, headlines_unread);
+                                       }
+
                                } else {
                                        debug("headlines_callback: returned no data");
                                f.innerHTML = "<div class='whiteBox'>" + __('Could not update headlines (missing XML data)') + "</div>";
@@ -109,8 +141,19 @@ function headlines_callback2(transport, active_feed_id, is_cat, feed_cur_page) {
                                                if (!c) {
                                                        c = document.getElementById("headlinesInnerContainer");
                                                }
+
+                                               var ids = getSelectedArticleIds2();
        
                                                c.innerHTML = c.innerHTML + headlines.firstChild.nodeValue;
+
+                                               debug("restore selected ids: " + ids);
+
+                                               for (var i = 0; i < ids.length; i++) {
+                                                       markHeadline(ids[i]);
+                                               }
+
+                                               subtoolbarSearch();
+
                                        } else {
                                                debug("no new headlines received");
                                        }
@@ -204,17 +247,55 @@ function showArticleInHeadlines(id) {
                cleanSelected("headlinesList");
        
                var crow = document.getElementById("RROW-" + id);
+
+               if (!crow) return;
+
                var article_is_unread = crow.className.match("Unread");
                        
                crow.className = crow.className.replace("Unread", "");
-               
+
+               selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', false);
+       
                var upd_img_pic = document.getElementById("FUPDPIC-" + id);
-               
-               if (upd_img_pic) {
+
+               var cache_prefix = "";
+                               
+               if (activeFeedIsCat()) {
+                       cache_prefix = "C:";
+               } else {
+                       cache_prefix = "F:";
+               }
+
+               var view_mode = false;
+
+               try {
+                       view_mode = document.forms['main_toolbar_form'].view_mode;      
+                       view_mode = view_mode[view_mode.selectedIndex].value;
+               } catch (e) {
+                       exception_error("showArticleInHeadlines/viewmode", e, true);
+               }
+
+               if (upd_img_pic && upd_img_pic.src.match("updated.png")) {
                        upd_img_pic.src = "images/blank_icon.gif";
+
+                       cache_invalidate(cache_prefix + getActiveFeedId());
+
+                       cache_inject(cache_prefix + getActiveFeedId(),
+                               document.getElementById("headlines-frame").innerHTML,
+                               get_feed_unread(getActiveFeedId()));
+
+               } else if (article_is_unread && view_mode == "all_articles") {
+
+                       cache_invalidate(cache_prefix + getActiveFeedId());
+
+                       cache_inject(cache_prefix + getActiveFeedId(),
+                               document.getElementById("headlines-frame").innerHTML,
+                               get_feed_unread(getActiveFeedId())-1);
+
+               } else if (article_is_unread) {
+                       cache_invalidate(cache_prefix + getActiveFeedId());
                }
-               
-               selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', false);
+
                markHeadline(id);
 
        } catch (e) {
@@ -592,62 +673,171 @@ function correctHeadlinesOffset(id) {
 
 function moveToPost(mode) {
 
+       try {
+
        // check for combined mode
-       if (!document.getElementById("headlinesList"))
-               return;
+               if (document.getElementById("headlinesList")) {
+       
+                       var rows = getVisibleHeadlineIds();
+               
+                       var prev_id = false;
+                       var next_id = false;
+               
+                       if (!document.getElementById('RROW-' + active_post_id)) {
+                               active_post_id = false;
+                       }
+               
+                       if (active_post_id == false) {
+                               next_id = getFirstVisibleHeadlineId();
+                               prev_id = getLastVisibleHeadlineId();
+                       } else {        
+                               for (var i = 0; i < rows.length; i++) {
+                                       if (rows[i] == active_post_id) {
+                                               prev_id = rows[i-1];
+                                               next_id = rows[i+1];                    
+                                       }
+                               }
+                       }
+               
+                       if (mode == "next") {
+                               if (next_id) {
+                                       correctHeadlinesOffset(next_id);
+                                       view(next_id, getActiveFeedId());
+                               }
+                       }
+               
+                       if (mode == "prev") {
+                               if (prev_id) {
+                                       correctHeadlinesOffset(prev_id);
+                                       view(prev_id, getActiveFeedId());
+                               }
+                       } 
+               } else {
+                       var rows = cdmGetUnreadArticles();
 
-       var rows = getVisibleHeadlineIds();
+                       if (mode == "next") {
 
-       var prev_id = false;
-       var next_id = false;
+                               for (var i = 0; i < rows.length; i++) {
 
-       if (!document.getElementById('RROW-' + active_post_id)) {
-               active_post_id = false;
-       }
+                                       if (cdmArticleIsActuallyVisible(rows[i]) ||
+                                                       cdmArticleIsBelowViewport(rows[i])) {
+
+                                               if (!cdmArticleIsActuallyVisible(rows[i])) {
+                                                       cdmScrollToArticleId(rows[i]);
+                                               }
+                                               //setTimeout("toggleUnread(" + rows[i] + ", undefined, true)", 500);
+                                               toggleUnread(rows[i], undefined, true);
+
+                                               return;
+                                       }
+                               }
+
+                               cdmScrollViewport('bottom');
+
+                       } else if (mode == "prev") {
+
+                               for (var i = 0; i < rows.length; i++) {
+
+                                       if (cdmArticleIsAboveViewport(rows[i]) &&
+                                                               !cdmArticleIsAboveViewport(rows[i+1])) {
+
+                                               cdmScrollToArticleId(rows[i]);
+                                               //setTimeout("toggleUnread(" + rows[i] + ", undefined, true)", 500);
+                                               toggleUnread(rows[i], undefined, true);
+
+                                               break;
+                                       } 
+                               }
 
-       if (active_post_id == false) {
-               next_id = getFirstVisibleHeadlineId();
-               prev_id = getLastVisibleHeadlineId();
-       } else {        
-               for (var i = 0; i < rows.length; i++) {
-                       if (rows[i] == active_post_id) {
-                               prev_id = rows[i-1];
-                               next_id = rows[i+1];                    
                        }
+       
                }
-       }
 
-       if (mode == "next") {
-               if (next_id) {
-                       correctHeadlinesOffset(next_id);
-                       view(next_id, getActiveFeedId());
-               }
+       } catch (e) {
+               exception_error(e, "moveToPost");
        }
+}
+
+function toggleSelected(id) {
+       try {
+       
+               var row = document.getElementById("RROW-" + id);
+               if (row) {
+                       var nc = row.className;
+                       
+                       if (!nc.match("Selected")) {
+                               nc = nc + "Selected";
+                       } else {
+                               nc = nc.replace("Selected", "");
+                       }
 
-       if (mode == "prev") {
-               if (prev_id) {
-                       correctHeadlinesOffset(prev_id);
-                       view(prev_id, getActiveFeedId());
+                       row.className = nc;
                }
-       } 
+       } catch (e) {
+               exception_error(e, "toggleSelected");
+       }
 }
 
-function toggleUnread(id, cmode) {
+function toggleUnread_afh(effect) {
+       try {
+
+               var elem = effect.element;
+               elem.style.backgroundColor = "";
+
+       } catch (e) {
+               exception_error(e, "toggleUnread_afh");
+       }
+} 
+
+function toggleUnread(id, cmode, effect) {
        try {
        
                var row = document.getElementById("RROW-" + id);
                if (row) {
                        var nc = row.className;
+                       var is_selected = row.className.match("Selected");
                        nc = nc.replace("Unread", "");
                        nc = nc.replace("Selected", "");
 
-                       if (row.className.match("Unread")) {
+                       // since we are removing selection from the object, uncheck
+                       // corresponding checkbox
+
+                       var cb = document.getElementById("RCHK-" + id);
+                       if (cb) {
+                               cb.checked = false;
+                       }
+
+                       // NOTE: I'm not sure that resetting selection here is a feature -fox
+
+                       if (cmode == undefined || cmode == 2) {
+                               if (row.className.match("Unread")) {
+                                       row.className = nc;
+
+                                       if (effect) {
+                                               new Effect.Highlight(row, {duration: 1, startcolor: "#fff7d5",
+                                                       afterFinish: toggleUnread_afh,
+                                                       queue: { position:'end', scope: 'TMRQ-' + id, limit: 1 } } );
+                                       } 
+
+                               } else {
+                                       row.className = nc + "Unread";
+                               }
+                       } else if (cmode == 0) {
                                row.className = nc;
-                       } else {
+
+                               if (effect) {
+                                       new Effect.Highlight(row, {duration: 1, startcolor: "#fff7d5",
+                                               afterFinish: toggleUnread_afh,
+                                               queue: { position:'end', scope: 'TMRQ-' + id, limit: 1 } } );
+                               } 
+                       } else if (cmode == 1) {
                                row.className = nc + "Unread";
                        }
 
-                       if (!cmode) cmode = 2;
+                       // Disable unmarking as selected for the time being (16.05.08) -fox
+                       if (is_selected) row.className = row.className + "Selected";
+
+                       if (cmode == undefined) cmode = 2;
 
                        var query = "backend.php?op=rpc&subop=catchupSelected&ids=" +
                                param_escape(id) + "&cmode=" + param_escape(cmode);
@@ -1083,6 +1273,104 @@ function editTagsInsert() {
        }
 }
 
+function cdmScrollViewport(where) {
+       debug("cdmScrollViewport: " + where);
+
+       var ctr = document.getElementById("headlinesInnerContainer");
+
+       if (!ctr) return;
+
+       if (where == "bottom") {
+               ctr.scrollTop = ctr.scrollHeight;
+       } else {
+               ctr.scrollTop = where;
+       }
+}
+
+function cdmArticleIsBelowViewport(id) {
+       try {
+               var ctr = document.getElementById("headlinesInnerContainer");
+               var e = document.getElementById("RROW-" + id);
+
+               if (!e || !ctr) return;
+
+               // article starts below viewport
+
+               if (ctr.scrollTop < e.offsetTop) {
+                       return true;
+               } else {        
+                       return false;
+               }
+
+       } catch (e) {
+               exception_error(e, "cdmArticleIsVisible");
+       }
+}
+
+function cdmArticleIsAboveViewport(id) {
+       try {
+               var ctr = document.getElementById("headlinesInnerContainer");
+               var e = document.getElementById("RROW-" + id);
+
+               if (!e || !ctr) return;
+
+               // article starts above viewport
+
+               if (ctr.scrollTop > e.offsetTop + e.offsetHeight) {
+                       return true;
+               } else {        
+                       return false;
+               }
+
+       } catch (e) {
+               exception_error(e, "cdmArticleIsVisible");
+       }
+}
+
+function cdmScrollToArticleId(id) {
+       try {
+               var ctr = document.getElementById("headlinesInnerContainer");
+               var e = document.getElementById("RROW-" + id);
+
+               if (!e || !ctr) return;
+
+               ctr.scrollTop = e.offsetTop;
+
+       } catch (e) {
+               exception_error(e, "cdmScrollToArticleId");
+       }
+}
+
+function cdmArticleIsActuallyVisible(id) {
+       try {
+               var ctr = document.getElementById("headlinesInnerContainer");
+               var e = document.getElementById("RROW-" + id);
+
+               if (!e || !ctr) return;
+
+               // article fits in viewport OR article is longer than viewport and
+               // its bottom is visible
+
+               if (ctr.scrollTop <= e.offsetTop && e.offsetTop + e.offsetHeight <=
+                               ctr.scrollTop + ctr.offsetHeight) {
+
+                       return true;
+               
+               } else if (e.offsetHeight > ctr.offsetHeight &&
+                               e.offsetTop + e.offsetHeight >= ctr.scrollTop &&
+                               e.offsetTop + e.offsetHeight <= ctr.scrollTop + ctr.offsetHeight) {
+
+                       return true;
+
+               }
+
+               return false;
+
+       } catch (e) {
+               exception_error(e, "cdmArticleIsVisible");
+       }
+}
+
 function cdmWatchdog() {
 
        try {
@@ -1163,19 +1451,20 @@ function cdmWatchdog() {
 }
 
 
-function cache_inject(id, article) {
-       if (!cache_check(id)) {
-               debug("cache_article: miss: " + id);
+function cache_inject(id, article, param) {
+       if (!cache_check_param(id, param)) {
+               debug("cache_article: miss: " + id + " [p=" + param + "]");
 
                var cache_obj = new Array();
 
                cache_obj["id"] = id;
                cache_obj["data"] = article;
+               cache_obj["param"] = param;
 
                article_cache.push(cache_obj);
 
        } else {
-               debug("cache_article: hit: " + id);
+               debug("cache_article: hit: " + id + " [p=" + param + "]");
        }
 }
 
@@ -1188,6 +1477,15 @@ function cache_find(id) {
        return false;
 }
 
+function cache_find_param(id, param) {
+       for (var i = 0; i < article_cache.length; i++) {
+               if (article_cache[i]["id"] == id && article_cache[i]["param"] == param) {
+                       return article_cache[i]["data"];
+               }
+       }
+       return false;
+}
+
 function cache_check(id) {
        for (var i = 0; i < article_cache.length; i++) {
                if (article_cache[i]["id"] == id) {
@@ -1197,12 +1495,29 @@ function cache_check(id) {
        return false;
 }
 
+function cache_check_param(id, param) {
+       for (var i = 0; i < article_cache.length; i++) {
+
+//             debug("cache_check_param " + article_cache[i]["id"] + ":" + 
+//                     article_cache[i]["param"] + " vs " + id + ":" + param);
+
+               if (article_cache[i]["id"] == id && article_cache[i]["param"] == param) {
+                       return true;
+               }
+       }
+       return false;
+}
+
 function cache_expire() {
        while (article_cache.length > 20) {
                article_cache.shift();
        }
 }
 
+function cache_empty() {
+       article_cache = new Array();
+}
+
 function cache_invalidate(id) {
        var i = 0
 
@@ -1254,7 +1569,11 @@ function headlines_scroll_handler() {
 
                var limit = toolbar_form.limit[toolbar_form.limit.selectedIndex];
                if (limit.value != 0) {
-                       if (e.scrollTop + e.offsetHeight > e.scrollHeight - 50) {
+               
+                       debug((e.scrollTop + e.offsetHeight) + " vs " + e.scrollHeight + " dis? " +
+                               _infscroll_disable);
+
+                       if (e.scrollTop + e.offsetHeight > e.scrollHeight - 100) {
                                if (!_infscroll_disable) {
                                        debug("more cowbell!");
                                        viewNextFeedPage();
@@ -1343,3 +1662,81 @@ function catchupRelativeToArticle(below) {
                exception_error("catchupRelativeToArticle", e);
        }
 }
+
+function cdmExpandArticle(a_id) {
+       try {
+               var id = 'CICD-' + a_id;
+
+               Effect.Appear(id, {duration : 0.5, 
+                       beforeStart: function(effect) { 
+                               var h_id = 'CICH-' + a_id;
+                               var h_elem = document.getElementById(h_id);
+                               if (h_elem) { h_elem.style.display = "none"; }
+
+                               toggleUnread(a_id, 0);
+                       }});
+
+
+       } catch (e) {
+               exception_error("appearBlockElementF", e);
+       }
+
+}
+
+function fixHeadlinesOrder(ids) {
+       try {
+               for (var i = 0; i < ids.length; i++) {
+                       var e = document.getElementById("RROW-" + ids[i]);
+
+                       if (e) {
+                               if (i % 2 == 0) {
+                                       e.className = e.className.replace("even", "odd");
+                               } else {
+                                       e.className = e.className.replace("odd", "even");
+                               }
+                       }
+               }
+       } catch (e) {
+               exception_error("fixHeadlinesOrder", e);
+       }
+}
+
+function subtoolbarSearch() {
+
+       try {
+
+               var q = document.getElementById("subtoolbar_search_box");
+               
+               if (!q) return;
+
+               q = q.value.toUpperCase();
+
+               var ids = false;
+               var vis_ids = new Array();
+
+               if (document.getElementById("headlinesList")) {
+                       ids = getVisibleHeadlineIds();
+               } else {
+                       ids = cdmGetVisibleArticles();
+               }
+
+               for (var i = 0; i < ids.length; i++) {
+                       var title = document.getElementById("RTITLE-" + ids[i]);
+
+                       if (title) {
+                               if (!title.innerHTML.toUpperCase().match(q)) {
+                                       Element.hide(document.getElementById("RROW-" + ids[i]));
+                               } else {
+                                       Element.show(document.getElementById("RROW-" + ids[i]));
+                                       vis_ids.push(ids[i]);
+                               }
+                       }
+               }
+
+               fixHeadlinesOrder(vis_ids);
+
+       } catch (e) {
+               exception_error("subtoolbarSearch", e);
+       }
+
+}