X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=viewfeed.js;h=acce5310d8f714965e4deb26328229fc2dfb7d15;hb=91743a49ff54862ac5b14e6d026849705c8651df;hp=c2a07c487dae858362ded3554664450fb11b83f5;hpb=4c009c783caeee59f26de5b458ab87bf4c3c64b1;p=tt-rss.git diff --git a/viewfeed.js b/viewfeed.js index c2a07c48..acce5310 100644 --- a/viewfeed.js +++ b/viewfeed.js @@ -2,13 +2,6 @@ var active_post_id = false; var last_article_view = false; var active_real_feed_id = false; -var _tag_active_post_id = false; -var _tag_active_feed_id = false; -var _tag_active_cdm = false; - -// FIXME: kludge, to restore scrollTop after tag editor terminates -var _tag_cdm_scroll = false; - // FIXME: kludges, needs proper implementation var _reload_feedlist_after_view = false; @@ -17,20 +10,10 @@ var _cdm_wd_vishist = new Array(); var article_cache = new Array(); -function catchup_callback() { - if (xmlhttp_rpc.readyState == 4) { - try { - debug("catchup_callback"); - notify(""); - all_counters_callback2(xmlhttp_rpc); - if (_catchup_callback_func) { - setTimeout(_catchup_callback_func, 10); - } - } catch (e) { - exception_error("catchup_callback", e); - } - } -} +var vgroup_last_feed = false; +var post_under_pointer = false; + +var last_requested_article = false; function catchup_callback2(transport, callback) { try { @@ -41,7 +24,7 @@ function catchup_callback2(transport, callback) { setTimeout(callback, 10); } } catch (e) { - exception_error("catchup_callback2", e); + exception_error("catchup_callback2", e, transport); } } @@ -53,27 +36,45 @@ function clean_feed_selections() { if (feeds[i].id && feeds[i].id.match("FEEDR-")) { feeds[i].className = feeds[i].className.replace("Selected", ""); } + if (feeds[i].id && feeds[i].id.match("FCAT-")) { + 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) { +function headlines_callback2(transport, feed_cur_page) { try { + loading_set_progress(100); + debug("headlines_callback2 [page=" + feed_cur_page + "]"); + if (!transport_error_check(transport)) return; + clean_feed_selections(); + + var is_cat = false; + var feed_id = false; - setActiveFeedId(active_feed_id); - - if (is_cat != undefined) { - active_feed_is_cat = is_cat; + if (transport.responseXML) { + var headlines = transport.responseXML.getElementsByTagName("headlines")[0]; + if (headlines) { + is_cat = headlines.getAttribute("is_cat"); + feed_id = headlines.getAttribute("id"); + setActiveFeedId(feed_id, is_cat); + } } - + if (!is_cat) { - var feedr = document.getElementById("FEEDR-" + active_feed_id); + var feedr = document.getElementById("FEEDR-" + feed_id); + if (feedr && !feedr.className.match("Selected")) { + feedr.className = feedr.className + "Selected"; + } + } else { + var feedr = document.getElementById("FCAT-" + feed_id); if (feedr && !feedr.className.match("Selected")) { feedr.className = feedr.className + "Selected"; } @@ -93,12 +94,20 @@ function headlines_callback2(transport, active_feed_id, is_cat, feed_cur_page) { var headlines_unread_obj = transport.responseXML.getElementsByTagName("headlines-unread")[0]; var disable_cache_obj = transport.responseXML.getElementsByTagName("disable-cache")[0]; + var vgroup_last_feed_obj = transport.responseXML.getElementsByTagName("vgroup-last-feed")[0]; + var headlines_count = headlines_count_obj.getAttribute("value"); var headlines_unread = headlines_unread_obj.getAttribute("value"); var disable_cache = disable_cache_obj.getAttribute("value") != "0"; - if (headlines_count == 0) _infscroll_disable = 1; - + vgroup_last_feed = vgroup_last_feed_obj.getAttribute("value"); + + 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"); @@ -115,10 +124,10 @@ function headlines_callback2(transport, active_feed_id, is_cat, feed_cur_page) { cache_prefix = "F:"; } - cache_invalidate(cache_prefix + active_feed_id); + cache_invalidate(cache_prefix + feed_id); if (!disable_cache) { - cache_inject(cache_prefix + active_feed_id, + cache_inject(cache_prefix + feed_id, headlines.firstChild.nodeValue, headlines_unread); } @@ -155,7 +164,7 @@ function headlines_callback2(transport, active_feed_id, is_cat, feed_cur_page) { debug("headlines_callback: returned no data"); notify_error("Error while trying to load more headlines"); } - + } if (articles) { @@ -172,7 +181,8 @@ function headlines_callback2(transport, active_feed_id, is_cat, feed_cur_page) { debug("parsing piggybacked counters: " + counters); parse_counters(counters, false); } else { - debug("counters container not found in reply"); + debug("counters container not found in reply, requesting..."); + request_counters(); } if (runtime_info) { @@ -194,6 +204,7 @@ function headlines_callback2(transport, active_feed_id, is_cat, feed_cur_page) { if (_cdm_wd_timeout) window.clearTimeout(_cdm_wd_timeout); if (!document.getElementById("headlinesList") && + getActiveFeedId() != -3 && getInitParam("cdm_auto_catchup") == 1) { debug("starting CDM watchdog"); _cdm_wd_timeout = window.setTimeout("cdmWatchdog()", 5000); @@ -202,21 +213,15 @@ function headlines_callback2(transport, active_feed_id, is_cat, feed_cur_page) { debug("not in CDM mode or watchdog disabled"); } - if (_tag_cdm_scroll) { - try { - document.getElementById("headlinesInnerContainer").scrollTop = _tag_cdm_scroll; - _tag_cdm_scroll = false; - debug("resetting headlinesInner scrollTop"); - - } catch (e) { } - } - _feed_cur_page = feed_cur_page; _infscroll_request_sent = 0; notify(""); + + remove_splash(); + } catch (e) { - exception_error("headlines_callback2", e); + exception_error("headlines_callback2", e, transport); } } @@ -227,7 +232,13 @@ function render_article(article) { f.scrollTop = 0; } catch (e) { }; - f.innerHTML = article; + var fi = document.getElementById("content-insert"); + + try { + fi.scrollTop = 0; + } catch (e) { }; + + fi.innerHTML = article; } catch (e) { exception_error("render_article", e); @@ -259,7 +270,16 @@ function showArticleInHeadlines(id) { } 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) { + // + } + if (upd_img_pic && upd_img_pic.src.match("updated.png")) { upd_img_pic.src = "images/blank_icon.gif"; @@ -269,7 +289,7 @@ function showArticleInHeadlines(id) { document.getElementById("headlines-frame").innerHTML, get_feed_unread(getActiveFeedId())); - } else if (article_is_unread) { + } else if (article_is_unread && view_mode == "all_articles") { cache_invalidate(cache_prefix + getActiveFeedId()); @@ -277,6 +297,8 @@ function showArticleInHeadlines(id) { document.getElementById("headlines-frame").innerHTML, get_feed_unread(getActiveFeedId())-1); + } else if (article_is_unread) { + cache_invalidate(cache_prefix + getActiveFeedId()); } markHeadline(id); @@ -292,12 +314,9 @@ function article_callback2(transport, id, feed_id) { if (transport.responseXML) { - active_real_feed_id = feed_id; - active_post_id = id; - - showArticleInHeadlines(id); + if (!transport_error_check(transport)) return; - var reply = transport.responseXML.firstChild.firstChild; + debug("looking for articles to cache..."); var articles = transport.responseXML.getElementsByTagName("article"); @@ -313,11 +332,27 @@ function article_callback2(transport, id, feed_id) { cache_inject(a_id, articles[i].firstChild.nodeValue); } + + if (id != last_requested_article) { + debug("requested article id is out of sequence, aborting"); + return; + } + + active_real_feed_id = feed_id; + active_post_id = id; + + showArticleInHeadlines(id); + + if (db) { + db.execute("UPDATE articles SET unread = 0 WHERE id = ?", [id]); + } + + var reply = transport.responseXML.firstChild.firstChild; } else { debug("article_callback: returned no XML object"); - var f = document.getElementById("content-frame"); - f.innerHTML = "
" + __('Could not display article (missing XML object)') + "
"; + //var f = document.getElementById("content-frame"); + //f.innerHTML = "
" + __('Could not display article (missing XML object)') + "
"; } var date = new Date(); @@ -331,19 +366,22 @@ function article_callback2(transport, id, feed_id) { setTimeout('updateFeedList(false, false)', 50); _reload_feedlist_after_view = false; } else { - var counters = transport.responseXML.getElementsByTagName("counters")[0]; + if (transport.responseXML) { + var counters = transport.responseXML.getElementsByTagName("counters")[0]; - if (counters) { - debug("parsing piggybacked counters: " + counters); - parse_counters(counters, false); - } else { - debug("counters container not found in reply"); + if (counters) { + debug("parsing piggybacked counters: " + counters); + parse_counters(counters, false); + } else { + debug("counters container not found in reply, requesting..."); + request_counters(); + } } } notify(""); } catch (e) { - exception_error("article_callback2", e); + exception_error("article_callback2", e, transport); } } @@ -351,7 +389,9 @@ function view(id, feed_id, skip_history) { try { debug("loading article: " + id + "/" + feed_id); - + + if (offline_mode) return view_offline(id, feed_id); + var cached_article = cache_find(id); debug("cache check result: " + (cached_article != false)); @@ -396,11 +436,15 @@ function view(id, feed_id, skip_history) { var crow = document.getElementById("RROW-" + id); var article_is_unread = crow.className.match("Unread"); + if (!async_counters_work) { + query = query + "&csync=true"; + } + showArticleInHeadlines(id); if (!cached_article) { - notify_progress("Loading, please wait..."); + notify_progress("Loading, please wait...", true); } else if (cached_article && article_is_unread) { @@ -412,15 +456,20 @@ function view(id, feed_id, skip_history) { query = query + "&mode=prefetch_old"; render_article(cached_article); + } cache_expire(); + last_requested_article = id; + new Ajax.Request(query, { onComplete: function(transport) { article_callback2(transport, id, feed_id); } }); + return false; + } catch (e) { exception_error("view", e); } @@ -483,6 +532,9 @@ function toggleMark(id, client_only, no_effects) { } var mark_img = document.getElementById("FMPIC-" + id); + + if (!mark_img) return; + var vfeedu = document.getElementById("FEEDU--1"); var crow = document.getElementById("RROW-" + id); @@ -490,46 +542,30 @@ function toggleMark(id, client_only, no_effects) { mark_img.src = mark_img.src.replace("mark_unset", "mark_set"); mark_img.alt = __("Unstar article"); query = query + "&mark=1"; - -/* if (vfeedu && crow.className.match("Unread")) { - vfeedu.innerHTML = (+vfeedu.innerHTML) + 1; - } */ - + + if (db) { + db.execute("UPDATE articles SET marked = 1 WHERE id = ?", [id]); + } + } else { //mark_img.src = "images/mark_unset.png"; mark_img.alt = __("Please wait..."); query = query + "&mark=0"; -/* if (vfeedu && crow.className.match("Unread")) { - vfeedu.innerHTML = (+vfeedu.innerHTML) - 1; - } */ - if (document.getElementById("headlinesList") && !no_effects) { Effect.Puff(mark_img, {duration : 0.25, afterFinish: tMark_afh_off}); } else { mark_img.src = mark_img.src.replace("mark_set", "mark_unset"); mark_img.alt = __("Star article"); } - } - -/* var vfeedctr = document.getElementById("FEEDCTR--1"); - var vfeedr = document.getElementById("FEEDR--1"); - - if (vfeedu && vfeedctr) { - if ((+vfeedu.innerHTML) > 0) { - if (crow.className.match("Unread") && !vfeedr.className.match("Unread")) { - vfeedr.className = vfeedr.className + "Unread"; - vfeedctr.className = "odd"; - } - } else { - vfeedctr.className = "invisible"; - vfeedr.className = vfeedr.className.replace("Unread", ""); + + if (db) { + db.execute("UPDATE articles SET marked = 0 WHERE id = ?", [id]); } + } - - debug("toggle starred for aid " + id); - - //new Ajax.Request(query); */ + + update_local_feedlist_counters(); if (!client_only) { debug(query); @@ -561,6 +597,9 @@ function togglePub(id, client_only, no_effects) { } var mark_img = document.getElementById("FPPIC-" + id); + + if (!mark_img) return; + var vfeedu = document.getElementById("FEEDU--2"); var crow = document.getElementById("RROW-" + id); @@ -569,19 +608,12 @@ function togglePub(id, client_only, no_effects) { mark_img.alt = __("Unpublish article"); query = query + "&pub=1"; -/* if (vfeedu && crow.className.match("Unread")) { - vfeedu.innerHTML = (+vfeedu.innerHTML) + 1; - } */ - + } else { //mark_img.src = "images/pub_unset.png"; mark_img.alt = __("Please wait..."); query = query + "&pub=0"; -/* if (vfeedu && crow.className.match("Unread")) { - vfeedu.innerHTML = (+vfeedu.innerHTML) - 1; - } */ - if (document.getElementById("headlinesList") && !no_effects) { Effect.Puff(mark_img, {duration : 0.25, afterFinish: tPub_afh_off}); } else { @@ -589,25 +621,6 @@ function togglePub(id, client_only, no_effects) { mark_img.alt = __("Publish article"); } } - -/* var vfeedctr = document.getElementById("FEEDCTR--2"); - var vfeedr = document.getElementById("FEEDR--2"); - - if (vfeedu && vfeedctr) { - if ((+vfeedu.innerHTML) > 0) { - if (crow.className.match("Unread") && !vfeedr.className.match("Unread")) { - vfeedr.className = vfeedr.className + "Unread"; - vfeedctr.className = "odd"; - } - } else { - vfeedctr.className = "invisible"; - vfeedr.className = vfeedr.className.replace("Unread", ""); - } - } - - debug("toggle published for aid " + id); - - new Ajax.Request(query); */ if (!client_only) { new Ajax.Request(query, { @@ -656,67 +669,183 @@ function correctHeadlinesOffset(id) { function moveToPost(mode) { - // check for combined mode - if (!document.getElementById("headlinesList")) - return; - - var rows = getVisibleHeadlineIds(); - - var prev_id = false; - var next_id = false; + try { - if (!document.getElementById('RROW-' + active_post_id)) { - active_post_id = false; - } + var rows; - 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 (isCdmMode()) { + rows = cdmGetVisibleArticles(); + } else { + 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) { + if (isCdmMode()) { + + if (!cdmArticleIsActuallyVisible(next_id)) { + cdmScrollToArticleId(next_id); + } + cdmSelectArticles("none"); + toggleUnread(next_id, 0, true); + toggleSelected(next_id); - if (mode == "next") { - if (next_id) { - correctHeadlinesOffset(next_id); - view(next_id, getActiveFeedId()); + } else { + correctHeadlinesOffset(next_id); + view(next_id, getActiveFeedId()); + } + } } + + if (mode == "prev") { + if (prev_id) { + if (isCdmMode()) { + cdmScrollToArticleId(prev_id); + cdmSelectArticles("none"); + toggleUnread(prev_id, 0, true); + toggleSelected(prev_id); + } else { + correctHeadlinesOffset(prev_id); + view(prev_id, getActiveFeedId()); + } + } + } + + } catch (e) { + exception_error("moveToPost", e); } +} + +function toggleSelected(id) { + try { + + var cb = document.getElementById("RCHK-" + id); + + var row = document.getElementById("RROW-" + id); + if (row) { + var nc = row.className; + + if (!nc.match("Selected")) { + nc = nc + "Selected"; + if (cb) { + cb.checked = true; + } + + // In CDM basically last selected article == active article + if (isCdmMode()) active_post_id = id; + } else { + nc = nc.replace("Selected", ""); + if (cb) { + cb.checked = false; + } + + } - if (mode == "prev") { - if (prev_id) { - correctHeadlinesOffset(prev_id); - view(prev_id, getActiveFeedId()); + row.className = nc; } - } + } catch (e) { + exception_error("toggleSelected", e); + } } -function toggleUnread(id, cmode) { +function toggleUnread_afh(effect) { + try { + + var elem = effect.element; + elem.style.backgroundColor = ""; + + } catch (e) { + exception_error("toggleUnread_afh", e); + } +} + +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", ""); + // 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"; } + + if (db) { + db.execute("UPDATE articles SET unread = not unread "+ + "WHERE id = ?", [id]); + } + } else if (cmode == 0) { row.className = nc; + + if (effect) { + new Effect.Highlight(row, {duration: 1, startcolor: "#fff7d5", + afterFinish: toggleUnread_afh, + queue: { position:'end', scope: 'TMRQ-' + id, limit: 1 } } ); + } + + if (db) { + db.execute("UPDATE articles SET unread = 0 "+ + "WHERE id = ?", [id]); + } + } else if (cmode == 1) { row.className = nc + "Unread"; + + if (db) { + db.execute("UPDATE articles SET unread = 1 "+ + "WHERE id = ?", [id]); + } + } + update_local_feedlist_counters(); + + // 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=" + @@ -731,12 +860,81 @@ function toggleUnread(id, cmode) { } - } catch (e) { exception_error("toggleUnread", e); } } +function selectionRemoveLabel(id) { + try { + + var ids = getSelectedArticleIds2(); + + if (ids.length == 0) { + alert(__("No articles are selected.")); + return; + } + +// var ok = confirm(__("Remove selected articles from label?")); + +// if (ok) { + + var query = "backend.php?op=rpc&subop=removeFromLabel&ids=" + + param_escape(ids.toString()) + "&lid=" + param_escape(id); + +// notify_progress("Loading, please wait..."); + + cache_invalidate("F:" + (-11 - id)); + + new Ajax.Request(query, { + onComplete: function(transport) { + show_labels_in_headlines(transport); + all_counters_callback2(transport); + } }); + +// } + + } catch (e) { + exception_error("selectionAssignLabel", e); + + } +} + +function selectionAssignLabel(id) { + try { + + var ids = getSelectedArticleIds2(); + + if (ids.length == 0) { + alert(__("No articles are selected.")); + return; + } + +// var ok = confirm(__("Assign selected articles to label?")); + +// if (ok) { + + cache_invalidate("F:" + (-11 - id)); + + var query = "backend.php?op=rpc&subop=assignToLabel&ids=" + + param_escape(ids.toString()) + "&lid=" + param_escape(id); + +// notify_progress("Loading, please wait..."); + + new Ajax.Request(query, { + onComplete: function(transport) { + show_labels_in_headlines(transport); + all_counters_callback2(transport); + } }); + +// } + + } catch (e) { + exception_error("selectionAssignLabel", e); + + } +} + function selectionToggleUnread(cdm_mode, set_state, callback_func, no_error) { try { var rows; @@ -907,7 +1105,7 @@ function cdmGetSelectedArticles() { for (i = 0; i < container.childNodes.length; i++) { var child = container.childNodes[i]; - if (child.id.match("RROW-") && child.className.match("Selected")) { + if (child.id && child.id.match("RROW-") && child.className.match("Selected")) { var c_id = child.id.replace("RROW-", ""); sel_articles.push(c_id); } @@ -920,10 +1118,12 @@ function cdmGetVisibleArticles() { var sel_articles = new Array(); var container = document.getElementById("headlinesInnerContainer"); + if (!container) return sel_articles; + for (i = 0; i < container.childNodes.length; i++) { var child = container.childNodes[i]; - if (child.id.match("RROW-")) { + if (child.id && child.id.match("RROW-")) { var c_id = child.id.replace("RROW-", ""); sel_articles.push(c_id); } @@ -939,7 +1139,7 @@ function cdmGetUnreadArticles() { for (i = 0; i < container.childNodes.length; i++) { var child = container.childNodes[i]; - if (child.id.match("RROW-") && child.className.match("Unread")) { + if (child.id && child.id.match("RROW-") && child.className.match("Unread")) { var c_id = child.id.replace("RROW-", ""); sel_articles.push(c_id); } @@ -956,7 +1156,7 @@ function cdmSelectArticles(mode) { for (i = 0; i < container.childNodes.length; i++) { var child = container.childNodes[i]; - if (child.id.match("RROW-")) { + if (child.id && child.id.match("RROW-")) { var aid = child.id.replace("RROW-", ""); var cb = document.getElementById("RCHK-" + aid); @@ -981,7 +1181,7 @@ function cdmSelectArticles(mode) { function catchupPage() { - var fn = getFeedName(getActiveFeedId(), active_feed_is_cat); + var fn = getFeedName(getActiveFeedId(), activeFeedIsCat()); var str = __("Mark all visible articles in %s as read?"); @@ -1020,7 +1220,7 @@ function catchupSelection() { } - var fn = getFeedName(getActiveFeedId(), active_feed_is_cat); + var fn = getFeedName(getActiveFeedId(), activeFeedIsCat()); var str = __("Mark %d selected articles in %s as read?"); @@ -1044,68 +1244,40 @@ function catchupSelection() { } } +function editArticleTags(id, feed_id, cdm_enabled) { + displayDlg('editArticleTags', id); +} -function labelFromSearch(search, search_mode, match_on, feed_id, is_cat) { - - if (!xmlhttp_ready(xmlhttp_rpc)) { - printLockingError(); - } - var title = prompt(__("Please enter label title:"), ""); +function tag_saved_callback(transport) { + try { + debug("in tag_saved_callback"); - if (title) { + closeInfoBox(); + notify(""); - var query = "backend.php?op=labelFromSearch&search=" + param_escape(search) + - "&smode=" + param_escape(search_mode) + "&match=" + param_escape(match_on) + - "&feed=" + param_escape(feed_id) + "&is_cat=" + param_escape(is_cat) + - "&title=" + param_escape(title); + if (tagsAreDisplayed()) { + _reload_feedlist_after_view = true; + } - debug("LFS: " + query); - new Ajax.Request(query, { - onComplete: function(transport) { - dlg_frefresh_callback(transport); - } }); - } -} - -function editArticleTags(id, feed_id, cdm_enabled) { - _tag_active_post_id = id; - _tag_active_feed_id = feed_id; - _tag_active_cdm = cdm_enabled; - - cache_invalidate(id); - - try { - _tag_cdm_scroll = document.getElementById("headlinesInnerContainer").scrollTop; - } catch (e) { } - displayDlg('editArticleTags', id); -} - - -function tag_saved_callback(transport) { - try { - debug("in tag_saved_callback"); - - closeInfoBox(); - notify(""); - - if (tagsAreDisplayed()) { - _reload_feedlist_after_view = true; - } + if (transport.responseXML) { + var tags_str = transport.responseXML.getElementsByTagName("tags-str")[0]; + + if (tags_str) { + var id = tags_str.getAttribute("id"); - if (!_tag_active_cdm) { - if (active_post_id == _tag_active_post_id) { - debug("reloading current article"); - view(_tag_active_post_id, _tag_active_feed_id); + if (id) { + var tags = document.getElementById("ATSTR-" + id); + if (tags) { + tags.innerHTML = tags_str.firstChild.nodeValue; + } + } } - } else { - debug("reloading current feed"); - viewCurrentFeed(); } } catch (e) { - exception_error("catchup_callback", e); + exception_error("tag_saved_callback", e); } } @@ -1149,7 +1321,105 @@ function editTagsInsert() { found_tags.selectedIndex = 0; } catch (e) { - exception_error(e, "editTagsInsert"); + exception_error("editTagsInsert", e); + } +} + +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("cdmArticleIsVisible", e); + } +} + +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("cdmArticleIsVisible", e); + } +} + +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("cdmScrollToArticleId", e); + } +} + +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("cdmArticleIsVisible", e); } } @@ -1227,88 +1497,184 @@ function cdmWatchdog() { _cdm_wd_timeout = window.setTimeout("cdmWatchdog()", 4000); } catch (e) { - exception_error(e, "cdmWatchdog"); + exception_error("cdmWatchdog", e); } } 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; + try { + if (!cache_check_param(id, param)) { + debug("cache_article: miss: " + id + " [p=" + param + "]"); + + + if (db) { - article_cache.push(cache_obj); + var date = new Date(); + var ts = Math.round(date.getTime() / 1000); - } else { - debug("cache_article: hit: " + id + " [p=" + param + "]"); + db.execute("INSERT INTO cache (id, article, param, added) VALUES (?, ?, ?, ?)", + [id, article, param, ts]); + } else { + + 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 + " [p=" + param + "]"); + } + } catch (e) { + exception_error("cache_inject", e); } } function cache_find(id) { - for (var i = 0; i < article_cache.length; i++) { - if (article_cache[i]["id"] == id) { - return article_cache[i]["data"]; + + if (db) { + var rs = db.execute("SELECT article FROM cache WHERE id = ?", [id]); + var a = false; + + if (rs.isValidRow()) { + var a = rs.field(0); + } + + rs.close(); + + return a; + + } else { + for (var i = 0; i < article_cache.length; i++) { + if (article_cache[i]["id"] == id) { + return article_cache[i]["data"]; + } } } 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"]; + + if (db) { + var rs = db.execute("SELECT article FROM cache WHERE id = ? AND param = ?", + [id, param]); + var a = false; + + if (rs.isValidRow()) { + a = rs.field(0); + } + + rs.close(); + + return a; + + } else { + 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) { - return true; + + if (db) { + var rs = db.execute("SELECT COUNT(*) AS c FROM cache WHERE id = ?", + [id]); + var a = false; + + if (rs.isValidRow()) { + a = rs.field(0) != "0"; + } + + rs.close(); + + return a; + + } else { + for (var i = 0; i < article_cache.length; i++) { + if (article_cache[i]["id"] == id) { + return true; + } } } 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 (db) { + var rs = db.execute("SELECT COUNT(*) AS c FROM cache WHERE id = ? AND param = ?", + [id, param]); + var a = false; - if (article_cache[i]["id"] == id && article_cache[i]["param"] == param) { - return true; + if (rs.isValidRow()) { + a = rs.field(0) != "0"; + } + + rs.close(); + + return a; + + } else { + for (var i = 0; i < article_cache.length; i++) { + 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(); + if (db) { + var date = new Date(); + var ts = Math.round(date.getTime() / 1000); + + db.execute("DELETE FROM cache WHERE added < ? - 1800 AND id LIKE 'FEEDLIST'", [ts]); + db.execute("DELETE FROM cache WHERE added < ? - 600 AND (id LIKE 'F:%' OR id LIKE 'C:%')", [ts]); + db.execute("DELETE FROM cache WHERE added < ? - 86400", [ts]); + + + } else { + while (article_cache.length > 25) { + article_cache.shift(); + } } } -function cache_invalidate(id) { - var i = 0 +function cache_empty() { + article_cache = new Array(); +} +function cache_invalidate(id) { try { - while (i < article_cache.length) { - if (article_cache[i]["id"] == id) { - debug("cache_invalidate: removed id " + id); - article_cache.splice(i, 1); - return true; + if (db) { + rs = db.execute("DELETE FROM cache WHERE id = ?", [id]); + return rs.rowsAffected != 0; + } else { + + var i = 0 + + while (i < article_cache.length) { + if (article_cache[i]["id"] == id) { + debug("cache_invalidate: removed id " + id); + article_cache.splice(i, 1); + return true; + } + i++; } - i++; } + debug("cache_invalidate: id not found: " + id); return false; } catch (e) { @@ -1320,20 +1686,97 @@ function getActiveArticleId() { return active_post_id; } -function cdmMouseIn(elem) { +function cdmClicked(id) { try { - if (elem.id && elem.id.match("RROW-")) { + var elem = document.getElementById("RROW-" + id); + + if (elem) { var id = elem.id.replace("RROW-", ""); active_post_id = id; + +// cdmSelectArticles("none"); + toggleUnread(id, 0, true); +// toggleSelected(id); + } } catch (e) { - exception_error("cdmMouseIn", e); + exception_error("cdmClicked", e); + } +} + +function preload_article_callback(transport) { + try { + if (transport.responseXML) { + var articles = transport.responseXML.getElementsByTagName("article"); + + for (var i = 0; i < articles.length; i++) { + var id = articles[i].getAttribute("id"); + if (!cache_check(id)) { + cache_inject(id, articles[i].firstChild.nodeValue); + debug("preloaded article: " + id); + } + } + } + } catch (e) { + exception_error("preload_article_callback", e); } +} + +function preloadArticleUnderPointer(id) { + try { + if (getInitParam("bw_limit") == "1") return; + + if (post_under_pointer == id && !cache_check(id)) { + + debug("trying to preload article " + id); + var neighbor_ids = getRelativePostIds(id, 1); + + /* only request uncached articles */ + + var cids_to_request = Array(); + + for (var i = 0; i < neighbor_ids.length; i++) { + if (!cache_check(neighbor_ids[i])) { + cids_to_request.push(neighbor_ids[i]); + } + } + debug("additional ids: " + cids_to_request.toString()); + + cids_to_request.push(id); + + var query = "backend.php?op=rpc&subop=getArticles&ids=" + + cids_to_request.toString(); + new Ajax.Request(query, { + onComplete: function(transport) { + preload_article_callback(transport); + } }); + } + } catch (e) { + exception_error("preloadArticleUnderPointer", e); + } +} + +function postMouseIn(id) { + try { + if (post_under_pointer != id) { + post_under_pointer = id; + if (!isCdmMode()) { + window.setTimeout("preloadArticleUnderPointer(" + id + ")", 250); + } + } + + } catch (e) { + exception_error("postMouseIn", e); + } } -function cdmMouseOut(elem) { - active_post_id = false; +function postMouseOut(id) { + try { + post_under_pointer = false; + } catch (e) { + exception_error("postMouseOut", e); + } } function headlines_scroll_handler() { @@ -1347,7 +1790,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(); @@ -1364,10 +1811,7 @@ function catchupRelativeToArticle(below) { try { - if (!xmlhttp_ready(xmlhttp_rpc)) { - printLockingError(); - } - + if (!getActiveArticleId()) { alert(__("No article is selected.")); return; @@ -1441,6 +1885,10 @@ function cdmExpandArticle(a_id) { try { var id = 'CICD-' + a_id; + try { + Element.hide("CEXC-" + a_id); + } catch (e) { } + Effect.Appear(id, {duration : 0.5, beforeStart: function(effect) { var h_id = 'CICH-' + a_id; @@ -1457,4 +1905,219 @@ function cdmExpandArticle(a_id) { } +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 hideReadHeadlines() { + try { + + var ids = false; + var vis_ids = new Array(); + + if (document.getElementById("headlinesList")) { + ids = getVisibleHeadlineIds(); + } else { + ids = cdmGetVisibleArticles(); + } + + var read_headlines_visible = true; + + for (var i = 0; i < ids.length; i++) { + var row = document.getElementById("RROW-" + ids[i]); + + if (row && row.className) { + if (read_headlines_visible) { + if (row.className.match("Unread") || row.className.match("Selected")) { + Element.show(row); + vis_ids.push(ids[i]); + } else { + //Effect.Fade(row, {duration : 0.3}); + Element.hide(row); + } + } else { + Element.show(row); + vis_ids.push(ids[i]); + } + } + } + + fixHeadlinesOrder(vis_ids); + + read_headlines_visible = !read_headlines_visible; + + } catch (e) { + exception_error("hideReadHeadlines", e); + } +} + +function invertHeadlineSelection() { + try { + var rows = new Array(); + var r = false; + + if (!isCdmMode()) { + r = document.getElementsByTagName("TR"); + } else { + r = document.getElementsByTagName("DIV"); + } + + for (var i = 0; i < r.length; i++) { + if (r[i].id && r[i].id.match("RROW-")) { + rows.push(r[i]); + } + } + + for (var i = 0; i < rows.length; i++) { + var nc = rows[i].className; + var id = rows[i].id.replace("RROW-", ""); + var cb = document.getElementById("RCHK-" + id); + + if (!rows[i].className.match("Selected")) { + nc = nc + "Selected"; + cb.checked = true; + } else { + nc = nc.replace("Selected", ""); + cb.checked = false; + } + + rows[i].className = nc; + + } + + } catch (e) { + exception_error("invertHeadlineSelection", e); + } +} + +function getArticleUnderPointer() { + return post_under_pointer; +} + +function zoomToArticle(id) { + try { + var w = window.open("backend.php?op=view&mode=zoom&id=" + param_escape(id), + "ttrss_zoom_" + id, + "status=0,toolbar=0,location=0,width=450,height=300,scrollbars=1,menubar=0"); + + } catch (e) { + exception_error("zoomToArticle", e); + } +} + +function showOriginalArticleInline(id) { + try { + + var query = "backend.php?op=rpc&subop=getArticleLink&id=" + id; + + notify_progress("Loading, please wait...", true); + + new Ajax.Request(query, { + onComplete: function(transport) { + + if (transport.responseXML) { + + var link = transport.responseXML.getElementsByTagName("link")[0]; + var id = transport.responseXML.getElementsByTagName("id")[0]; + + notify(""); + + if (link && id) { + link = link.firstChild.nodeValue; + + var ci = document.getElementById("content-insert"); + + var tmp = ""; + + render_article(tmp); + + } + } + } }); + + } catch (e) { + exception_error("showOriginalArticleInline", e); + } +} + + +function scrollArticle(offset) { + try { + if (!isCdmMode()) { + var ci = document.getElementById("content-insert"); + if (ci) { + ci.scrollTop += offset; + } + } else { + var hi = document.getElementById("headlinesInnerContainer"); + if (hi) { + hi.scrollTop += offset; + } + + } + } catch (e) { + exception_error("scrollArticle", e); + } +} + +function show_labels_in_headlines(transport) { + try { + if (transport.responseXML) { + var info = transport.responseXML.getElementsByTagName("info-for-headlines")[0]; + + var elems = info.getElementsByTagName("entry"); + + for (var l = 0; l < elems.length; l++) { + var e_id = elems[l].getAttribute("id"); + + if (e_id) { + + var ctr = document.getElementById("HLLCTR-" + e_id); + + if (ctr) { + ctr.innerHTML = elems[l].firstChild.nodeValue; + } + } + + } + + } + } catch (e) { + exception_error("show_labels_in_headlines", e); + + } +} + +function toggleHeadlineActions() { + try { + var e = document.getElementById("headlineActionsBody"); + var p = document.getElementById("headlineActionsDrop"); + + if (!Element.visible(e)) { + Element.show(e); + } else { + Element.hide(e); + } + + e.scrollTop = 0; + e.style.left = (p.offsetLeft + 1) + "px"; +// e.style.top = (p.offsetTop + p.offsetHeight - 1) + "px"; + + } catch (e) { + exception_error("toggleHeadlineActions", e); + } +}