diff --git a/feedlist.js b/feedlist.js index 1411f08b1..b7565c2ca 100644 --- a/feedlist.js +++ b/feedlist.js @@ -379,7 +379,7 @@ function feedlist_dragsorted(ctr) { var query = "?op=feeds&subop=catsort&corder=" + param_escape(ordered_cats.toString()); - console.log(query); + //console.log(query); new Ajax.Request("backend.php", { parameters: query }); } @@ -393,7 +393,7 @@ function feedlist_init() { try { loading_set_progress(90); - console.log("in feedlist init"); + //console.log("in feedlist init"); hideOrShowFeeds(getInitParam("hide_read_feeds") == 1); document.onkeydown = hotkey_handler; @@ -470,7 +470,7 @@ function hide_footer() { function init_collapsable_feedlist() { try { - console.log("init_collapsable_feedlist"); + //console.log("init_collapsable_feedlist"); var theme = getInitParam("theme"); var options = getInitParam("theme_options"); @@ -593,7 +593,7 @@ function request_counters_real() { parameters: query, onComplete: function(transport) { try { - all_counters_callback2(transport); + handle_rpc_reply(transport); } catch (e) { exception_error("viewfeed/getcounters", e); } diff --git a/functions.js b/functions.js index 46716a407..d757a38d7 100644 --- a/functions.js +++ b/functions.js @@ -520,7 +520,7 @@ function parse_counters(reply, scheduled_call) { var feeds_stored = number_of_feeds; - console.log("Feed counters, C: " + feeds_found + ", S:" + feeds_stored); + //console.log("Feed counters, C: " + feeds_found + ", S:" + feeds_stored); if (feeds_stored != feeds_found) { number_of_feeds = feeds_found; @@ -542,7 +542,7 @@ function parse_counters(reply, scheduled_call) { } } -function parse_counters_reply(transport, scheduled_call) { +/*function parse_counters_reply(transport, scheduled_call) { if (!transport.responseXML) { notify_error("Backend did not return valid XML", true); @@ -575,17 +575,56 @@ function parse_counters_reply(transport, scheduled_call) { hideOrShowFeeds(getInitParam("hide_read_feeds") == 1); -} +} */ -function all_counters_callback2(transport) { +function handle_rpc_reply(transport, scheduled_call) { try { - if (offline_mode) return; + if (offline_mode) return false; - parse_counters_reply(transport); + if (!transport.responseText && db) { + offlineConfirmModeChange(); + return false; + } + + if (transport.responseXML) { + + if (!transport_error_check(transport)) return false; + + var message = transport.responseXML.getElementsByTagName("message")[0]; + + if (message) { + message = message.firstChild.nodeValue; + + if (message == "UPDATE_COUNTERS") { + setInitParam("last_article_id", -1); + _force_scheduled_update = true; + } + } + + var counters = transport.responseXML.getElementsByTagName("counters")[0]; + + if (counters) + parse_counters(counters, scheduled_call); + + var runtime_info = transport.responseXML.getElementsByTagName("runtime-info")[0]; + + if (runtime_info) + parse_runtime_info(runtime_info); + + if (feedsSortByUnread()) + resort_feedlist(); + + hideOrShowFeeds(getInitParam("hide_read_feeds") == 1); + + } else { + notify_error("Error communicating with server."); + } } catch (e) { - exception_error("all_counters_callback2", e, transport); + exception_error("handle_rpc_reply", e, transport); } + + return true; } function get_feed_unread(id) { @@ -724,7 +763,7 @@ function hideOrShowFeeds(hide) { try { - console.log("hideOrShowFeeds: " + hide); + //console.log("hideOrShowFeeds: " + hide); if ($("FCATLIST--1")) { @@ -766,7 +805,7 @@ function hideOrShowFeedsCategory(id, hide) { var cat_unread = 0; if (!node) { - console.log("hideOrShowFeeds: passed node is null, aborting"); + console.warn("hideOrShowFeeds: passed node is null, aborting"); return; } @@ -1593,7 +1632,7 @@ function getRelativePostIds(id, limit) { if (!limit) limit = 3; - console.log("getRelativePostIds: " + id + " limit=" + limit); + //console.log("getRelativePostIds: " + id + " limit=" + limit); var ids = new Array(); var container = $("headlinesList"); diff --git a/functions.php b/functions.php index e44d0ea3f..43c2afa25 100644 --- a/functions.php +++ b/functions.php @@ -3178,6 +3178,8 @@ $data['num_feeds'] = (int) $num_feeds; + $data['last_article_id'] = getLastArticleId($link); + if (ENABLE_UPDATE_DAEMON) { $data['daemon_is_running'] = (int) file_is_locked("update_daemon.lock"); @@ -7006,4 +7008,14 @@ } } + function getLastArticleId($link) { + $result = db_query($link, "SELECT MAX(ref_id) AS id FROM ttrss_user_entries + WHERE owner_uid = " . $_SESSION["uid"]); + + if (db_num_rows($result) == 1) { + return db_fetch_result($result, 0, "id"); + } else { + return -1; + } + } ?> diff --git a/modules/backend-rpc.php b/modules/backend-rpc.php index e6e263cd1..8eacb199e 100644 --- a/modules/backend-rpc.php +++ b/modules/backend-rpc.php @@ -179,9 +179,9 @@ $result = db_query($link, "UPDATE ttrss_user_entries SET marked = $mark WHERE ref_id = '$id' AND owner_uid = " . $_SESSION["uid"]); - print ""; + print ""; + print "UPDATE_COUNTERS"; + print ""; return; } @@ -192,9 +192,9 @@ $result = db_query($link, "DELETE FROM ttrss_user_entries WHERE ref_id IN ($ids) AND owner_uid = " . $_SESSION["uid"]); - print ""; + print ""; + print "UPDATE_COUNTERS"; + print ""; return; } @@ -206,9 +206,9 @@ SET feed_id = orig_feed_id, orig_feed_id = NULL WHERE ref_id IN ($ids) AND owner_uid = " . $_SESSION["uid"]); - print ""; + print ""; + print "UPDATE_COUNTERS"; + print ""; return; } @@ -220,9 +220,9 @@ archive_article($link, $id, $_SESSION["uid"]); } - print ""; + print ""; + print "UPDATE_COUNTERS"; + print ""; return; } @@ -253,10 +253,6 @@ print ""; - print ""; - if ($note != 'undefined') { $note_size = strlen($note); print ""; @@ -264,6 +260,8 @@ print ""; } + print "UPDATE_COUNTERS"; + print ""; return; @@ -274,26 +272,28 @@ update_rss_feed($link, $feed_id); - print ""; - print ""; + print ""; + print "UPDATE_COUNTERS"; print ""; - + return; } if ($subop == "updateAllFeeds" || $subop == "getAllCounters") { - - $global_unread_caller = sprintf("%d", $_REQUEST["uctr"]); - $global_unread = getGlobalUnread($link); + + $last_article_id = (int) $_REQUEST["last_article_id"]; print ""; - if ($global_unread_caller != $global_unread) { + if ($last_article_id != getLastArticleId($link)) { print ""; } @@ -313,11 +313,7 @@ catchupArticlesById($link, $ids, $cmode); print ""; - print ""; - - print_runtime_info($link); + print "UPDATE_COUNTERS"; print ""; return; @@ -331,10 +327,7 @@ markArticlesById($link, $ids, $cmode); print ""; - print ""; - print_runtime_info($link); + print "UPDATE_COUNTERS"; print ""; return; @@ -348,10 +341,7 @@ publishArticlesById($link, $ids, $cmode); print ""; - print ""; - print_runtime_info($link); + print "UPDATE_COUNTERS"; print ""; return; @@ -608,9 +598,8 @@ print ""; - print ""; + print ""; + print "UPDATE_COUNTERS"; print ""; return; @@ -645,9 +634,8 @@ print ""; - print ""; + print ""; + print "UPDATE_COUNTERS"; print ""; return; @@ -1061,7 +1049,7 @@ print "ErrorInfo . "]]>"; } else { save_email_address($link, db_escape_string($destination)); - print "OK"; + print "UPDATE_COUNTERS"; } } else { @@ -1133,7 +1121,9 @@ db_query($link, "DELETE FROM ttrss_access_keys WHERE owner_uid = " . $_SESSION["uid"]); - print "OK"; + print ""; + print "UPDATE_COUNTERS"; + print ""; return; } diff --git a/tt-rss.js b/tt-rss.js index a3b184496..44c0b608e 100644 --- a/tt-rss.js +++ b/tt-rss.js @@ -1,23 +1,19 @@ - var total_unread = 0; -var first_run = true; var display_tags = false; var global_unread = -1; -var current_subtitle = ""; -var daemon_enabled = false; -//var _qfd_deleted_feed = 0; var firsttime_update = true; var _active_feed_id = 0; var _active_feed_is_cat = false; var number_of_feeds = 0; -var _hfd_scrolltop = 0; var hotkey_prefix = false; var hotkey_prefix_pressed = false; -var init_params = new Object(); +var init_params = {}; var ver_offset = 0; var hor_offset = 0; var feeds_sort_by_unread = false; var feedlist_sortable_enabled = false; +var _force_scheduled_update = false; +var last_scheduled_update = false; function activeFeedIsCat() { return _active_feed_is_cat; @@ -92,40 +88,9 @@ function dlg_frefresh_callback(transport, deleted_feed) { closeInfoBox(); } -function scheduleFeedUpdate() { - - window.clearTimeout(counter_timeout_id); - - var query_str = "backend.php?op=rpc&subop=getAllCounters"; - - var omode; - - if (firsttime_update && !navigator.userAgent.match("Opera")) { - firsttime_update = false; - omode = "T"; - } else { - if (display_tags) { - omode = "tl"; - } else { - omode = "flc"; - } - } - - query_str = query_str + "&omode=" + omode; - query_str = query_str + "&uctr=" + global_unread; - - console.log("[scheduleFeedUpdate] " + query_str); - - new Ajax.Request("backend.php", { - parameters: query_str, - onComplete: function(transport) { - parse_counters_reply(transport, true); - } }); -} - function updateFeedList() { try { - console.log("updateFeedList"); + //console.log("updateFeedList"); if (offline_mode) return render_offline_feedlist(); @@ -160,7 +125,7 @@ function catchupAllFeeds() { notify_progress("Marking all feeds as read..."); - console.log("catchupAllFeeds Q=" + query_str); + //console.log("catchupAllFeeds Q=" + query_str); new Ajax.Request("backend.php", { parameters: query_str, @@ -184,17 +149,56 @@ function viewCurrentFeed(subop) { return false; // block unneeded form submits } -function viewfeed(feed, subop) { +/*function viewfeed(feed, subop) { var f = window.frames["feeds-frame"]; f.viewfeed(feed, subop); -} +} */ function timeout() { if (getInitParam("bw_limit") == "1") return; - scheduleFeedUpdate(false); + try { + var date = new Date(); + var ts = Math.round(date.getTime() / 1000); - setTimeout("timeout()", 10*1000); + if (ts - last_scheduled_update > 10 || _force_scheduled_update) { + + window.clearTimeout(counter_timeout_id); + + var query_str = "?op=rpc&subop=getAllCounters"; + + var omode; + + if (firsttime_update && !navigator.userAgent.match("Opera")) { + firsttime_update = false; + omode = "T"; + } else { + if (display_tags) { + omode = "tl"; + } else { + omode = "flc"; + } + } + + query_str = query_str + "&omode=" + omode; + query_str = query_str + "&last_article_id=" + getInitParam("last_article_id"); + + //console.log("[timeout]" + query_str); + + new Ajax.Request("backend.php", { + parameters: query_str, + onComplete: function(transport) { + handle_rpc_reply(transport, true); + } }); + + last_scheduled_update = ts; + } + + } catch (e) { + exception_error("timeout", e); + } + + setTimeout("timeout()", 3000); } function resetSearch() { @@ -211,23 +215,13 @@ function search() { viewCurrentFeed(0, ""); } -// if argument is undefined, current subtitle is not updated -// use blank string to clear subtitle -function updateTitle(s) { +function updateTitle() { var tmp = "Tiny Tiny RSS"; - if (s != undefined) { - current_subtitle = s; - } - if (global_unread > 0) { tmp = tmp + " (" + global_unread + ")"; } - if (current_subtitle) { - tmp = tmp + " - " + current_subtitle; - } - if (window.fluid) { if (global_unread > 0) { window.fluid.dockBadge = global_unread; @@ -365,7 +359,6 @@ function init_second_stage() { dropboxSelect(toolbar.view_mode, getInitParam("default_view_mode")); dropboxSelect(toolbar.order_by, getInitParam("default_view_order_by")); - daemon_enabled = getInitParam("daemon_enabled") == 1; feeds_sort_by_unread = getInitParam("feeds_sort_by_unread") == 1; setTimeout('updateFeedList(false, false)', 50); @@ -454,11 +447,6 @@ function quickMenuGo(opid) { return; } - if (opid == "qmcUpdateFeeds") { - scheduleFeedUpdate(true); - return; - } - if (opid == "qmcCatchupAll") { catchupAllFeeds(); return; @@ -550,19 +538,20 @@ function toggleDispRead() { function parse_runtime_info(elem) { if (!elem || !elem.firstChild) { + console.warn("parse_runtime_info: invalid node passed"); return; } var data = JSON.parse(elem.firstChild.nodeValue); - console.log("parsing runtime info..."); + //console.log("parsing runtime info..."); for (k in data) { var v = data[k]; - console.log("RI: " + k + " => " + v); + // console.log("RI: " + k + " => " + v); - if (k == "num_feeds") { + if (k == "num_feeds" || k == "last_article_id") { init_params[k] = v; } @@ -697,7 +686,7 @@ function feedEditSave() { function collapse_feedlist() { try { - console.log("collapse_feedlist"); + //console.log("collapse_feedlist"); var theme = getInitParam("theme"); if (theme != "" && @@ -906,10 +895,10 @@ function hotkey_handler(e) { return false; } - if (keycode == 82 && shift_key) { // R +/* if (keycode == 82 && shift_key) { // R scheduleFeedUpdate(true); return; - } + } */ if (keycode == 74) { // j var feed = getActiveFeedId(); @@ -1076,10 +1065,10 @@ function hotkey_handler(e) { return false; } - if (keycode == 85 && shift_key) { // U +/* if (keycode == 85 && shift_key) { // U scheduleFeedUpdate(true); return false; - } + } */ if (keycode == 85) { // u if (getActiveFeedId()) { diff --git a/viewfeed.js b/viewfeed.js index dbb5d77db..92564da6c 100644 --- a/viewfeed.js +++ b/viewfeed.js @@ -24,7 +24,7 @@ function catchup_callback2(transport, callback) { try { console.log("catchup_callback2 " + transport + ", " + callback); notify(""); - all_counters_callback2(transport); + handle_rpc_reply(transport); if (callback) { setTimeout(callback, 10); } @@ -53,10 +53,7 @@ function clean_feed_selections() { function headlines_callback2(transport, feed_cur_page) { try { - if (!transport.responseText && db) { - offlineConfirmModeChange(); - return; - } + if (!handle_rpc_reply(transport)) return; loading_set_progress(100); @@ -106,7 +103,7 @@ function headlines_callback2(transport, feed_cur_page) { var f = $("headlines-frame"); try { if (feed_cur_page == 0) { - console.log("resetting headlines scrollTop"); + //console.log("resetting headlines scrollTop"); f.scrollTop = 0; } } catch (e) { }; @@ -119,8 +116,10 @@ function headlines_callback2(transport, feed_cur_page) { if (headlines_info) headlines_info = JSON.parse(headlines_info.firstChild.nodeValue); - else - console.log("didn't find headlines-info object in response"); + else { + console.error("didn't find headlines-info object in response"); + return; + } var headlines_count = headlines_info.count; var headlines_unread = headlines_info.unread; @@ -158,14 +157,14 @@ function headlines_callback2(transport, feed_cur_page) { } } else { - console.log("headlines_callback: returned no data"); + console.warn("headlines_callback: returned no data"); f.innerHTML = "
" + __('Could not update headlines (missing XML data)') + "
"; } } else { if (headlines) { if (headlines_count > 0) { - console.log("adding some more headlines..."); + console.warn("adding some more headlines..."); var c = $("headlinesList"); @@ -187,7 +186,7 @@ function headlines_callback2(transport, feed_cur_page) { console.log("no new headlines received"); } } else { - console.log("headlines_callback: returned no data"); + console.warn("headlines_callback: returned no data"); notify_error("Error while trying to load more headlines"); } @@ -196,30 +195,21 @@ function headlines_callback2(transport, feed_cur_page) { if (articles) { for (var i = 0; i < articles.length; i++) { var a_id = articles[i].getAttribute("id"); - console.log("found id: " + a_id); + //console.log("found id: " + a_id); cache_inject(a_id, articles[i].firstChild.nodeValue); } } else { console.log("no cached articles received"); } - if (counters) { - console.log("parsing piggybacked counters: " + counters); - parse_counters(counters, false); - } else { - console.log("counters container not found in reply, requesting..."); - request_counters(); - } - + request_counters(); + if (runtime_info) { - console.log("parsing runtime info: " + runtime_info[0]); parse_runtime_info(runtime_info[0]); - } else { - console.log("runtime info container not found in reply"); - } + } } else { - console.log("headlines_callback: returned no XML object"); + console.warn("headlines_callback: returned no XML object"); f.innerHTML = "
" + __('Could not update headlines (missing XML object)') + "
"; } @@ -339,10 +329,7 @@ function article_callback2(transport, id) { try { console.log("article_callback2 " + id); - if (!transport.responseText && db) { - offlineConfirmModeChange(); - return; - } + if (!handle_rpc_reply(transport)) return; if (transport.responseXML) { @@ -366,17 +353,17 @@ function article_callback2(transport, id) { active_post_id = id; - console.log("looking for articles to cache..."); + //console.log("looking for articles to cache..."); var articles = transport.responseXML.getElementsByTagName("article"); for (var i = 0; i < articles.length; i++) { var a_id = articles[i].getAttribute("id"); - console.log("found id: " + a_id); + //console.log("found id: " + a_id); if (a_id == active_post_id) { - console.log("active article, rendering..."); + //console.log("active article, rendering..."); render_article(articles[i].firstChild.nodeValue); } @@ -393,7 +380,7 @@ function article_callback2(transport, id) { var reply = transport.responseXML.firstChild.firstChild; } else { - console.log("article_callback: returned no XML object"); + console.warn("article_callback: returned no XML object"); //var f = $("content-frame"); //f.innerHTML = "
" + __('Could not display article (missing XML object)') + "
"; } @@ -405,17 +392,7 @@ function article_callback2(transport, id) { setTimeout('updateFeedList(false, false)', 50); _reload_feedlist_after_view = false; } else { - if (transport.responseXML) { - var counters = transport.responseXML.getElementsByTagName("counters")[0]; - - if (counters) { - console.log("parsing piggybacked counters: " + counters); - parse_counters(counters, false); - } else { - console.log("counters container not found in reply, requesting..."); - request_counters(); - } - } + request_counters(); } notify(""); @@ -518,7 +495,7 @@ function tMark_afh_off(effect) { try { var elem = effect.effects[0].element; - console.log("tMark_afh_off : " + elem.id); + //console.log("tMark_afh_off : " + elem.id); if (elem) { elem.src = elem.src.replace("mark_set", "mark_unset"); @@ -535,7 +512,7 @@ function tPub_afh_off(effect) { try { var elem = effect.effects[0].element; - console.log("tPub_afh_off : " + elem.id); + //console.log("tPub_afh_off : " + elem.id); if (elem) { elem.src = elem.src.replace("pub_set", "pub_unset"); @@ -598,12 +575,12 @@ function toggleMark(id, client_only, no_effects) { if (!no_effects) update_local_feedlist_counters(); if (!client_only) { - console.log(query); + //console.log(query); new Ajax.Request("backend.php", { parameters: query, onComplete: function(transport) { - all_counters_callback2(transport); + handle_rpc_reply(transport); } }); } @@ -661,7 +638,7 @@ function togglePub(id, client_only, no_effects, note) { new Ajax.Request("backend.php", { parameters: query, onComplete: function(transport) { - all_counters_callback2(transport); + handle_rpc_reply(transport); var note = transport.responseXML.getElementsByTagName("note")[0]; @@ -907,7 +884,7 @@ function toggleUnread(id, cmode, effect) { new Ajax.Request("backend.php", { parameters: query, onComplete: function(transport) { - all_counters_callback2(transport); + handle_rpc_reply(transport); } }); } @@ -944,7 +921,7 @@ function selectionRemoveLabel(id) { parameters: query, onComplete: function(transport) { show_labels_in_headlines(transport); - all_counters_callback2(transport); + handle_rpc_reply(transport); } }); // } @@ -982,7 +959,7 @@ function selectionAssignLabel(id) { parameters: query, onComplete: function(transport) { show_labels_in_headlines(transport); - all_counters_callback2(transport); + handle_rpc_reply(transport); } }); // } @@ -1099,7 +1076,7 @@ function selectionToggleMarked() { new Ajax.Request("backend.php", { parameters: query, onComplete: function(transport) { - all_counters_callback2(transport); + handle_rpc_reply(transport); } }); } @@ -1135,7 +1112,7 @@ function selectionTogglePublished() { new Ajax.Request("backend.php", { parameters: query, onComplete: function(transport) { - all_counters_callback2(transport); + handle_rpc_reply(transport); } }); } @@ -1395,13 +1372,13 @@ function editTagsSave() { query = "?op=rpc&subop=setArticleTags&" + query; - console.log(query); + //console.log(query); new Ajax.Request("backend.php", { parameters: query, onComplete: function(transport) { try { - console.log("tags saved..."); + //console.log("tags saved..."); closeInfoBox(); notify(""); @@ -1623,7 +1600,7 @@ function cdmWatchdog() { new Ajax.Request("backend.php", { parameters: query, onComplete: function(transport) { - all_counters_callback2(transport); + handle_rpc_reply(transport); } }); } @@ -1641,7 +1618,7 @@ function cache_inject(id, article, param) { try { if (!cache_check_param(id, param)) { - console.log("cache_article: miss: " + id + " [p=" + param + "]"); + //console.log("cache_article: miss: " + id + " [p=" + param + "]"); var date = new Date(); var ts = Math.round(date.getTime() / 1000); @@ -1669,7 +1646,7 @@ function cache_inject(id, article, param) { } } else { - console.log("cache_article: hit: " + id + " [p=" + param + "]"); + //console.log("cache_article: hit: " + id + " [p=" + param + "]"); } } catch (e) { exception_error("cache_inject", e); @@ -1893,7 +1870,7 @@ function cache_invalidate(id) { while (i < article_cache.length) { if (article_cache[i]["id"] == id) { - console.log("cache_invalidate: removed id " + id); + //console.log("cache_invalidate: removed id " + id); article_cache.splice(i, 1); return true; } @@ -1902,7 +1879,7 @@ function cache_invalidate(id) { } } - console.log("cache_invalidate: id not found: " + id); + //console.log("cache_invalidate: id not found: " + id); return false; } catch (e) { exception_error("cache_invalidate", e); @@ -1964,7 +1941,7 @@ function preloadArticleUnderPointer(id) { if (preload_id_batch.indexOf(id) == -1) preload_id_batch.push(id); - console.log("preload ids batch: " + preload_id_batch.toString()); + //console.log("preload ids batch: " + preload_id_batch.toString()); window.clearTimeout(preload_timeout_id); preload_batch_timeout_id = window.setTimeout('preloadBatchedArticles()', 1000); @@ -2009,7 +1986,6 @@ function headlines_scroll_handler() { if (e.scrollTop + e.offsetHeight > e.scrollHeight - 100) { if (!_infscroll_disable) { - console.log("more cowbell!"); viewNextFeedPage(); } }