]> git.wh0rd.org - tt-rss.git/blobdiff - tt-rss.js
release 1.0
[tt-rss.git] / tt-rss.js
index aeaac22cce562ab5a1bf27279359f8178ac7ac8c..e6eca217234eaa96be4d23f99120435fa5ef5934 100644 (file)
--- a/tt-rss.js
+++ b/tt-rss.js
@@ -4,6 +4,22 @@
 */
 
 var xmlhttp = false;
+var xmlhttp_rpc = false;
+var xmlhttp_view = false;
+
+var total_unread = 0;
+var first_run = true;
+
+var active_post_id = false;
+var active_feed_id = false;
+var active_offset = false;
+
+var total_feed_entries = false;
+
+var _viewfeed_autoselect_first = false;
+var _viewfeed_autoselect_last = false;
+
+var search_query = "";
 
 /*@cc_on @*/
 /*@if (@_jscript_version >= 5)
@@ -14,43 +30,34 @@ try {
 } catch (e) {
        try {
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
+               xmlhttp_rpc = new ActiveXObject("Microsoft.XMLHTTP");
+               xmlhttp_view = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (E) {
                xmlhttp = false;
+               xmlhttp_rpc = false;
+               xmlhttp_view = false;
        }
 }
 @end @*/
 
 if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
        xmlhttp = new XMLHttpRequest();
-}
-
-function param_escape(arg) {
-       if (typeof encodeURIComponent != 'undefined')
-               return encodeURIComponent(arg); 
-       else
-               return escape(arg);
-}
-
-function param_unescape(arg) {
-       if (typeof decodeURIComponent != 'undefined')
-               return decodeURIComponent(arg); 
-       else
-               return unescape(arg);
-}
-
-function notify(msg) {
-
-       var n = document.getElementById("notify");
-
-       n.innerHTML = msg;
-
+       xmlhttp_rpc = new XMLHttpRequest();
+       xmlhttp_view = new XMLHttpRequest();
 }
 
 function feedlist_callback() {
        var container = document.getElementById('feeds');
        if (xmlhttp.readyState == 4) {
                container.innerHTML=xmlhttp.responseText;
-       }
+
+               if (first_run) {
+                       scheduleFeedUpdate(false);
+                       first_run = false;
+               } else {
+                       notify("");
+               } 
+       } 
 }
 
 function viewfeed_callback() {
@@ -62,6 +69,16 @@ function viewfeed_callback() {
                var funread = document.getElementById("FUNREAD");
                var ftotal = document.getElementById("FTOTAL");
 
+               if (_viewfeed_autoselect_first == true) {
+                       _viewfeed_autoselect_first = false;
+                       view(getFirstVisibleHeadlineId(), active_feed_id);
+               }
+
+               if (_viewfeed_autoselect_last == true) {
+                       _viewfeed_autoselect_last = false;
+                       view(getLastVisibleHeadlineId(), active_feed_id);
+               }
+
                if (ftotal && factive && funread) {
                        var feed_id = factive.innerHTML;
 
@@ -72,53 +89,234 @@ function viewfeed_callback() {
                        feedt.innerHTML = ftotal.innerHTML;
                        feedu.innerHTML = funread.innerHTML;
 
+                       total_feed_entries = ftotal.innerHTML;  
+
                        if (feedu.innerHTML > 0 && !feedr.className.match("Unread")) {
                                        feedr.className = feedr.className + "Unread";
                        } else if (feedu.innerHTML <= 0) {      
                                        feedr.className = feedr.className.replace("Unread", "");
                        }
 
+                       cleanSelected("feedsList");
+
+                       feedr.className = feedr.className + "Selected";
                }
-       }
+
+               var searchbox = document.getElementById("searchbox");
+               searchbox.value = search_query;
+
+               markHeadline(active_post_id);
+
+               notify("");
+
+       }       
 }
 
 function view_callback() {
        var container = document.getElementById('content');
-       if (xmlhttp.readyState == 4) {
-               container.innerHTML=xmlhttp.responseText;               
+       if (xmlhttp_view.readyState == 4) {
+               container.innerHTML=xmlhttp_view.responseText;          
+               markHeadline(active_post_id);
+       }
+}
+
+function refetch_callback() {
+
+       if (xmlhttp_rpc.readyState == 4) {
+               notify("All feeds updated");
+               var container = document.getElementById('feeds');
+               container.innerHTML = xmlhttp_rpc.responseText;
+               document.title = "Tiny Tiny RSS";
+       } 
+}
+
+function scheduleFeedUpdate(force) {
+
+       notify("Updating feeds in background...");
+
+       document.title = "Tiny Tiny RSS - Updating...";
+
+       var query_str = "backend.php?op=rpc&subop=";
+
+       if (force) {
+               query_str = query_str + "forceUpdateAllFeeds";
+       } else {
+               query_str = query_str + "updateAllFeeds";
+       }
+
+       if (xmlhttp_ready(xmlhttp_rpc)) {
+               xmlhttp_rpc.open("GET", query_str, true);
+               xmlhttp_rpc.onreadystatechange=refetch_callback;
+               xmlhttp_rpc.send(null);
+       } else {
+               printLockingError();
+       }   
+}
+
+function updateFeedList(silent, fetch) {
+
+       if (silent != true) {
+               notify("Loading feed list...");
+       }
+
+       var query_str = "backend.php?op=feeds";
+
+       if (fetch) query_str = query_str + "&fetch=yes";
+
+       if (xmlhttp_ready(xmlhttp)) {
+               xmlhttp.open("GET", query_str, true);
+               xmlhttp.onreadystatechange=feedlist_callback;
+               xmlhttp.send(null);
+       } else {
+               printLockingError();
        }
 }
 
+function catchupPage(feed) {
+
+       if (!xmlhttp_ready(xmlhttp)) {
+               printLockingError();
+               return
+       }
+
+       var content = document.getElementById("headlinesList");
+
+       var rows = new Array();
+
+       for (i = 0; i < content.rows.length; i++) {
+               var row_id = content.rows[i].id.replace("RROW-", "");
+               if (row_id.length > 0) {
+                       if (content.rows[i].className.match("Unread")) {
+                               rows.push(row_id);      
+                               content.rows[i].className = content.rows[i].className.replace("Unread", "");
+                       }
+               }
+       }
+
+       if (rows.length > 0) {
+
+               var feedr = document.getElementById("FEEDR-" + feed);
+               var feedu = document.getElementById("FEEDU-" + feed);
+       
+               feedu.innerHTML = feedu.innerHTML - rows.length;
+       
+               if (feedu.innerHTML > 0 && !feedr.className.match("Unread")) {
+                               feedr.className = feedr.className + "Unread";
+               } else if (feedu.innerHTML <= 0) {      
+                               feedr.className = feedr.className.replace("Unread", "");
+               } 
 
-function update_feed_list(called_from_timer) {
+               var query_str = "backend.php?op=rpc&subop=catchupPage&ids=" + 
+                       param_escape(rows.toString());
+       
+               notify("Marking this page as read...");
 
-       if (called_from_timer != true) {
-               document.getElementById("feeds").innerHTML = "Updating feeds, please wait...";
+               var button = document.getElementById("btnCatchupPage");
+
+               button.className = "disabledButton";
+               button.href = "";
+       
+               xmlhttp.open("GET", query_str, true);
+               xmlhttp.onreadystatechange=notify_callback;
+               xmlhttp.send(null);
+
+       } else {
+               notify("No unread items on this page.");
+
+       }
+}
+
+function catchupAllFeeds() {
+
+       if (!xmlhttp_ready(xmlhttp)) {
+               printLockingError();
+               return
        }
+       var query_str = "backend.php?op=feeds&subop=catchupAll";
+
+       notify("Marking all feeds as read...");
 
-       xmlhttp.open("GET", "backend.php?op=feeds", true);
+       xmlhttp.open("GET", query_str, true);
        xmlhttp.onreadystatechange=feedlist_callback;
        xmlhttp.send(null);
 
-
 }
 
-function viewfeed(feed, skip, ext) {
+function viewfeed(feed, skip, subop) {
+
+       enableHotkeys();
+
+       var searchbox = document.getElementById("searchbox");
+
+       if (searchbox) {
+               search_query = searchbox.value;
+       } else {
+               search_query = "";
+       } 
+
+/*     if (active_feed_id == feed && subop != "ForceUpdate") {
+               notify("This feed is currently selected.");
+               return;
+       } */
+
+       if (skip < 0 || skip > total_feed_entries) {
+               return;
+       }
+
+       if (!xmlhttp_ready(xmlhttp)) {
+               printLockingError();
+               return
+       }
+
+       if (active_feed_id != feed || skip != active_offset) {
+               active_post_id = false;
+       }
 
-       notify("view-feed: " + feed);
+       active_feed_id = feed;
+       active_offset = skip;
 
-       document.getElementById('headlines').innerHTML='Loading headlines, please wait...';             
-       document.getElementById('content').innerHTML='&nbsp;';          
+       var query = "backend.php?op=viewfeed&feed=" + param_escape(feed) +
+               "&skip=" + param_escape(skip) + "&subop=" + param_escape(subop);
 
-       xmlhttp.open("GET", "backend.php?op=viewfeed&feed=" + param_escape(feed) +
-               "&skip=" + param_escape(skip) + "&ext=" + param_escape(ext) , true);
+       if (search_query != "") {
+               query = query + "&search=" + param_escape(search_query);
+       }
+       
+       xmlhttp.open("GET", query, true);
        xmlhttp.onreadystatechange=viewfeed_callback;
        xmlhttp.send(null);
 
+       notify("Loading headlines...");
+
+}
+
+function markHeadline(id) {
+       var row = document.getElementById("RROW-" + id);
+       if (row) {
+               row.className = row.className + "Selected";
+       }
+}
+
+function cleanSelected(element) {
+       var content = document.getElementById(element);
+
+       var rows = new Array();
+
+       for (i = 0; i < content.rows.length; i++) {
+               content.rows[i].className = content.rows[i].className.replace("Selected", "");
+       }
+
 }
 
 function view(id,feed_id) {
 
+       enableHotkeys();
+
+       if (!xmlhttp_ready(xmlhttp_view)) {
+               printLockingError();
+               return
+       }
+
        var crow = document.getElementById("RROW-" + id);
 
        if (crow.className.match("Unread")) {
@@ -130,44 +328,169 @@ function view(id,feed_id) {
                        var feedr = document.getElementById("FEEDR-" + feed_id);
                        feedr.className = feedr.className.replace("Unread", "");
                }
-       }
 
-       document.getElementById('content').innerHTML='Loading, please wait...';         
+               total_unread--;
+       }       
+
+       cleanSelected("headlinesList");
+//     crow.className = crow.className + "Selected";
+
+       var upd_img_pic = document.getElementById("FUPDPIC-" + id);
+
+       if (upd_img_pic) {
+               upd_img_pic.innerHTML = "";
+       } 
+
+//     document.getElementById('content').innerHTML='Loading, please wait...';         
+
+       active_post_id = id;
+
+       xmlhttp_view.open("GET", "backend.php?op=view&id=" + param_escape(id), true);
+       xmlhttp_view.onreadystatechange=view_callback;
+       xmlhttp_view.send(null);
 
-       xmlhttp.open("GET", "backend.php?op=view&id=" + param_escape(id), true);
-       xmlhttp.onreadystatechange=view_callback;
-       xmlhttp.send(null);
 
 }
 
 function timeout() {
+       scheduleFeedUpdate(true);
+       setTimeout("timeout()", 1800*1000);
+}
 
-       update_feed_list(true);
+function resetSearch() {
+       document.getElementById("searchbox").value = "";
+       viewfeed(active_feed_id, 0, "");
+}
 
-       setTimeout("timeout()", 1800*1000);
+function search(feed) {
+       viewfeed(feed, 0, "");
+}
+
+function localPiggieFunction(enable) {
+       if (enable) {
+               var query_str = "backend.php?op=feeds&subop=piggie";
+
+               if (xmlhttp_ready(xmlhttp)) {
 
+                       xmlhttp.open("GET", query_str, true);
+                       xmlhttp.onreadystatechange=feedlist_callback;
+                       xmlhttp.send(null);
+               }
+       }
 }
 
-function search(feed, sender) {
+function relativeid_callback() {
 
-       notify("Search: " + feed + ", " + sender.value)
+       if (xmlhttp_rpc.readyState == 4) {
+               notify(xmlhttp_rpc.responseText);
+       }
 
-       document.getElementById('headlines').innerHTML='Loading headlines, please wait...';             
-       document.getElementById('content').innerHTML='&nbsp;';          
+}
 
-       xmlhttp.open("GET", "backend.php?op=viewfeed&feed=" + param_escape(feed) +
-               "&search=" + param_escape(sender.value) + "&ext=SEARCH", true);
-       xmlhttp.onreadystatechange=viewfeed_callback;
-       xmlhttp.send(null);
+function getVisibleHeadlineIds() {
+
+       var content = document.getElementById("headlinesList");
 
+       var rows = new Array();
+
+       for (i = 0; i < content.rows.length; i++) {
+               var row_id = content.rows[i].id.replace("RROW-", "");
+               if (row_id.length > 0) {
+                               rows.push(row_id);      
+               }
+       }
+       return rows;
+}
+
+function getFirstVisibleHeadlineId() {
+       var rows = getVisibleHeadlineIds();
+       return rows[0];
+}
+
+function getLastVisibleHeadlineId() {
+       var rows = getVisibleHeadlineIds();
+       return rows[rows.length-1];
 }
 
+function moveToPost(mode) {
+
+       var rows = getVisibleHeadlineIds();
+
+       var prev_id;
+       var next_id;
+
+       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 != undefined) {
+                       view(next_id, active_feed_id);
+               } else {
+                       _viewfeed_autoselect_first = true;
+                       viewfeed(active_feed_id, active_offset+15);
+               }
+       }
+
+       if (mode == "prev") {
+               if ( prev_id != undefined) {
+                       view(prev_id, active_feed_id);
+               } else {
+                       _viewfeed_autoselect_last = true;
+                       viewfeed(active_feed_id, active_offset-15);
+               }
+       }
+
+}
+
+function localHotkeyHandler(keycode) {
+
+       if (keycode == 78) {
+               return moveToPost('next');
+       }
+
+       if (keycode == 80) {
+               return moveToPost('prev');
+       }
+
+       if (keycode == 82) {
+               return scheduleFeedUpdate(true);
+       }
+
+       if (keycode == 85) {
+               return viewfeed(active_feed_id, active_offset, "ForceUpdate");
+       }
+
+//     notify("KC: " + keycode);
+
+}
+
+
 function init() {
 
-       notify("init");
+       // IE kludge
 
-       update_feed_list();
+       if (xmlhttp && !xmlhttp_rpc) {
+               xmlhttp_rpc = xmlhttp;
+               xmlhttp_view = xmlhttp;
+       }
 
-       setTimeout("timeout()", 1800*1000);
+       if (!xmlhttp || !xmlhttp_rpc || !xmlhttp_view) {
+               document.getElementById("headlines").innerHTML = 
+                       "<b>Fatal error:</b> This program needs XmlHttpRequest " + 
+                       "to function properly. Your browser doesn't seem to support it.";
+               return;
+       }
 
+       updateFeedList(false, false);
+       document.onkeydown = hotkey_handler;
+       setTimeout("timeout()", 1800*1000);
 }