catchup batching:

* behave better if invoked during an infinite scroll request
* flush catchup batch when article is selected manually
This commit is contained in:
Andrew Dolgov 2018-12-01 11:42:57 +03:00
parent 195180b64d
commit 710d06a288
1 changed files with 26 additions and 233 deletions

View File

@ -178,10 +178,11 @@ function headlines_callback2(transport, offset, background, infscroll_req) {
_infscroll_request_sent = 0; _infscroll_request_sent = 0;
_last_headlines_update = new Date().getTime(); _last_headlines_update = new Date().getTime();
unpackVisibleHeadlines(); // this is used to auto-catchup articles if needed after infscroll request has finished,
// unpack visible articles, etc
headlinesScrollHandler();
// if we have some more space in the buffer, why not try to fill it // if we have some more space in the buffer, why not try to fill it
if (!_infscroll_disable && $("headlines-spacer") && if (!_infscroll_disable && $("headlines-spacer") &&
$("headlines-spacer").offsetTop < $("headlines-frame").offsetHeight) { $("headlines-spacer").offsetTop < $("headlines-frame").offsetHeight) {
@ -215,50 +216,6 @@ function render_article(article) {
} catch (e) { } } catch (e) { }
} }
/*
function showArticleInHeadlines(id, noexpand) {
const row = $("RROW-" + id);
if (!row) return;
if (!noexpand)
row.removeClassName("Unread");
row.addClassName("active");
selectArticles('none');
markHeadline(id);
}
function article_callback2(transport, id) {
console.log("article_callback2 " + id);
const reply = handle_rpc_json(transport);
if (reply) {
reply.each(function(article) {
if (getActiveArticleId() == article['id']) {
render_article(article['content']);
}
cids_requested.remove(article['id']);
cache_set("article:" + article['id'], article['content']);
});
} else {
console.error("Invalid object received: " + transport.responseText);
render_article("<div class='whiteBox'>" +
__('Could not display article (invalid object received - see error console for details)') + "</div>");
}
const unread_in_buffer = $$("#headlines-frame > div[id*=RROW][class*=Unread]").length;
request_counters(unread_in_buffer == 0);
notify("");
}
*/
function view(id, noexpand) { function view(id, noexpand) {
setActiveArticleId(id); setActiveArticleId(id);
@ -316,83 +273,10 @@ function view(id, noexpand) {
} }
return false; return false;
/* const oldrow = $("RROW-" + getActiveArticleId());
if (oldrow) oldrow.removeClassName("active");
const crow = $("RROW-" + id);
if (!crow) return;
if (noexpand) {
setActiveArticleId(id);
showArticleInHeadlines(id, noexpand);
return;
}
console.log("loading article: " + id);
const cached_article = cache_get("article:" + id);
console.log("cache check result: " + (cached_article != false));
const query = {op: "article", method: "view", id: id};
const neighbor_ids = getRelativePostIds(id);
/* only request uncached articles */
/* const cids_to_request = [];
for (let i = 0; i < neighbor_ids.length; i++) {
if (cids_requested.indexOf(neighbor_ids[i]) == -1)
if (!cache_get("article:" + neighbor_ids[i])) {
cids_to_request.push(neighbor_ids[i]);
cids_requested.push(neighbor_ids[i]);
}
}
console.log("additional ids: " + cids_to_request.toString());
query.cids = cids_to_request.toString();
const article_is_unread = crow.hasClassName("Unread");
setActiveArticleId(id);
showArticleInHeadlines(id);
if (cached_article && article_is_unread) {
query.mode = "prefetch";
render_article(cached_article);
} else if (cached_article) {
query.mode = "prefetch_old";
render_article(cached_article);
// if we don't need to request any relative ids, we might as well skip
// the server roundtrip altogether
if (cids_to_request.length == 0) {
return;
}
}
last_requested_article = id;
console.log(query);
if (article_is_unread) {
decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
}
xhrPost("backend.php", query, (transport) => {
article_callback2(transport, id);
})
return false;
*/
} }
function toggleMark(id, client_only) { function toggleMark(id, client_only) {
const query = { op: "rpc", id: id, method: "mark" }; const query = { op: "rpc", id: id, method: "mark" };
const row = $("RROW-" + id); const row = $("RROW-" + id);
if (row) { if (row) {
@ -526,28 +410,8 @@ function moveToPost(mode, noscroll, noexpand) {
} }
} }
} }
} }
/* function toggleSelected(id, force_on) {
const row = $("RROW-" + id);
if (row) {
const cb = dijit.getEnclosingWidget(
row.getElementsByClassName("rchk")[0]);
if (row.hasClassName('Selected') && !force_on) {
row.removeClassName('Selected');
if (cb) cb.attr("checked", false);
} else {
row.addClassName('Selected');
if (cb) cb.attr("checked", true);
}
}
updateSelectedPrompt();
} */
function updateSelectedPrompt() { function updateSelectedPrompt() {
const count = getSelectedArticleIds2().length; const count = getSelectedArticleIds2().length;
const elem = $("selected_prompt"); const elem = $("selected_prompt");
@ -556,12 +420,8 @@ function updateSelectedPrompt() {
elem.innerHTML = ngettext("%d article selected", elem.innerHTML = ngettext("%d article selected",
"%d articles selected", count).replace("%d", count); "%d articles selected", count).replace("%d", count);
if (count > 0) count > 0 ? Element.show(elem) : Element.hide(elem);
Element.show(elem);
else
Element.hide(elem);
} }
} }
function toggleUnread(id, cmode) { function toggleUnread(id, cmode) {
@ -721,8 +581,7 @@ function getSelectedArticleIds2() {
rv.push(child.getAttribute("data-article-id")); rv.push(child.getAttribute("data-article-id"));
}); });
// i wonder if this is a good idea: consider active article a honorary member // consider active article a honorary member of selected articles
// of selected articles
if (getActiveArticleId()) if (getActiveArticleId())
rv.push(getActiveArticleId()); rv.push(getActiveArticleId());
@ -741,7 +600,6 @@ function getLoadedArticleIds() {
}); });
return rv; return rv;
} }
// mode = all,none,unread,invert,marked,published // mode = all,none,unread,invert,marked,published
@ -799,64 +657,7 @@ function selectArticles(mode) {
} }
} }
// mode = all,none,unread,invert,marked,published // noinspection JSUnusedGlobalSymbols
/* function selectArticles(mode, query) {
if (!query) query = "#headlines-frame > div[id*=RROW]";
const children = $$(query);
children.each(function(child) {
//const id = child.getAttribute("data-article-id");
const cb = dijit.getEnclosingWidget(
child.getElementsByClassName("rchk")[0]);
if (mode == "all") {
child.addClassName("Selected");
if (cb) cb.attr("checked", true);
} else if (mode == "unread") {
if (child.hasClassName("Unread")) {
child.addClassName("Selected");
if (cb) cb.attr("checked", true);
} else {
child.removeClassName("Selected");
if (cb) cb.attr("checked", false);
}
} else if (mode == "marked") {
if (child.hasClassName("marked")) {
child.addClassName("Selected");
if (cb) cb.attr("checked", true);
} else {
child.removeClassName("Selected");
if (cb) cb.attr("checked", false);
}
} else if (mode == "published") {
if (child.hasClassName("published")) {
child.addClassName("Selected");
if (cb) cb.attr("checked", true);
} else {
child.removeClassName("Selected");
if (cb) cb.attr("checked", false);
}
} else if (mode == "invert") {
if (child.hasClassName("Selected")) {
child.removeClassName("Selected");
if (cb) cb.attr("checked", false);
} else {
child.addClassName("Selected");
if (cb) cb.attr("checked", true);
}
} else {
child.removeClassName("Selected");
if (cb) cb.attr("checked", false);
}
});
updateSelectedPrompt();
} */
function deleteSelection() { function deleteSelection() {
const rows = getSelectedArticleIds2(); const rows = getSelectedArticleIds2();
@ -890,6 +691,7 @@ function deleteSelection() {
}); });
} }
// noinspection JSUnusedGlobalSymbols
function archiveSelection() { function archiveSelection() {
const rows = getSelectedArticleIds2(); const rows = getSelectedArticleIds2();
@ -908,7 +710,6 @@ function archiveSelection() {
op = "archive"; op = "archive";
} else { } else {
str = ngettext("Move %d archived article back?", "Move %d archived articles back?", rows.length); str = ngettext("Move %d archived article back?", "Move %d archived articles back?", rows.length);
str += " " + __("Please note that unstarred articles might get purged on next feed update."); str += " " + __("Please note that unstarred articles might get purged on next feed update.");
op = "unarchive"; op = "unarchive";
@ -968,8 +769,6 @@ function editArticleTags(id) {
style: "width: 600px", style: "width: 600px",
execute: function() { execute: function() {
if (this.validate()) { if (this.validate()) {
const query = dojo.objectToQuery(this.attr('value'));
notify_progress("Saving article tags...", true); notify_progress("Saving article tags...", true);
xhrPost("backend.php", this.attr('value'), (transport) => { xhrPost("backend.php", this.attr('value'), (transport) => {
@ -997,7 +796,7 @@ function editArticleTags(id) {
href: query href: query
}); });
var tmph = dojo.connect(dialog, 'onLoad', function() { const tmph = dojo.connect(dialog, 'onLoad', function() {
dojo.disconnect(tmph); dojo.disconnect(tmph);
new Ajax.Autocompleter('tags_str', 'tags_choices', new Ajax.Autocompleter('tags_str', 'tags_choices',
@ -1021,17 +820,10 @@ function cdmScrollToArticleId(id, force) {
// expanded cdm has a 4px margin now // expanded cdm has a 4px margin now
ctr.scrollTop = parseInt(e.offsetTop) - 4; ctr.scrollTop = parseInt(e.offsetTop) - 4;
/*setActiveArticleId(id);
// article is selected manually, set it read
toggleUnread(id, 0); */
Element.hide("floatingTitle"); Element.hide("floatingTitle");
} }
} }
// for the time being active article does not affect buffer selection (we still re/set the checkbox
// because of getSelectedArticleIds2() hack
function setActiveArticleId(id) { function setActiveArticleId(id) {
console.log("setActiveArticleId", id); console.log("setActiveArticleId", id);
@ -1042,7 +834,7 @@ function setActiveArticleId(id) {
const cb = dijit.getEnclosingWidget(e.select(".rchk")[0]); const cb = dijit.getEnclosingWidget(e.select(".rchk")[0]);
if (cb) cb.attr("checked", false); if (cb) cb.attr("checked", false);
} }
}) });
_active_article_id = id; _active_article_id = id;
@ -1059,10 +851,13 @@ function setActiveArticleId(id) {
} }
if (row.hasClassName("Unread")) { if (row.hasClassName("Unread")) {
toggleUnread(id, 0);
decrementFeedCounter(getActiveFeedId(), activeFeedIsCat()); catchupBatchedArticles(() => {
updateFloatingTitle(true); decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
toggleUnread(id, 0);
updateFloatingTitle(true);
});
} }
row.addClassName("active"); row.addClassName("active");
@ -1090,7 +885,7 @@ function postMouseOut(id) {
post_under_pointer = false; post_under_pointer = false;
} }
function unpackVisibleHeadlines() { function unpackVisibleArticles() {
if (!isCombinedMode() || !getInitParam("cdm_expanded")) return; if (!isCombinedMode() || !getInitParam("cdm_expanded")) return;
const rows = $$("#headlines-frame div[id*=RROW][data-content]"); const rows = $$("#headlines-frame div[id*=RROW][data-content]");
@ -1106,20 +901,15 @@ function unpackVisibleHeadlines() {
row.removeAttribute("data-content"); row.removeAttribute("data-content");
PluginHost.run(PluginHost.HOOK_ARTICLE_RENDERED_CDM, row); PluginHost.run(PluginHost.HOOK_ARTICLE_RENDERED_CDM, row);
// i wonder if this is a good idea?
//if (!getActiveArticleId() && !row.hasClassName("Unread"))
// setActiveArticleId(row.getAttribute("data-article-id"));
} else { } else {
break; break;
} }
} }
} }
function headlinesScrollHandler(event) { function headlinesScrollHandler(/* event */) {
try { try {
unpackVisibleHeadlines(); unpackVisibleArticles();
if (isCombinedMode()) { if (isCombinedMode()) {
updateFloatingTitle(); updateFloatingTitle();
@ -1158,7 +948,7 @@ function headlinesScrollHandler(event) {
} }
} }
if (getInitParam("cdm_auto_catchup") == 1) { if (getInitParam("cdm_auto_catchup") == 1 && !_infscroll_request_sent) {
let rows = $$("#headlines-frame > div[id*=RROW][class*=Unread]"); let rows = $$("#headlines-frame > div[id*=RROW][class*=Unread]");
@ -1166,7 +956,6 @@ function headlinesScrollHandler(event) {
const row = rows[i]; const row = rows[i];
if ($("headlines-frame").scrollTop > (row.offsetTop + row.offsetHeight/2)) { if ($("headlines-frame").scrollTop > (row.offsetTop + row.offsetHeight/2)) {
const id = row.getAttribute("data-article-id") const id = row.getAttribute("data-article-id")
if (catchup_id_batch.indexOf(id) == -1) if (catchup_id_batch.indexOf(id) == -1)
@ -1202,10 +991,10 @@ function openNextUnreadFeed() {
if (nuf) viewfeed({feed: nuf, is_cat: is_cat}); if (nuf) viewfeed({feed: nuf, is_cat: is_cat});
} }
function catchupBatchedArticles() { function catchupBatchedArticles(callback) {
if (catchup_id_batch.length > 0 && !_infscroll_request_sent && !_catchup_request_sent) { console.log("catchupBatchedArticles, size=", catchup_id_batch.length);
console.log("catchupBatchedArticles, size=", catchup_id_batch.length); if (catchup_id_batch.length > 0 /* && !_infscroll_request_sent */ && !_catchup_request_sent) {
// make a copy of the array // make a copy of the array
const batch = catchup_id_batch.slice(); const batch = catchup_id_batch.slice();
@ -1230,7 +1019,11 @@ function catchupBatchedArticles() {
} }
updateFloatingTitle(true); updateFloatingTitle(true);
if (callback) callback();
}); });
} else {
if (callback) callback();
} }
} }