diff options
Diffstat (limited to 'js/Headlines.js')
-rwxr-xr-x | js/Headlines.js | 225 |
1 files changed, 200 insertions, 25 deletions
diff --git a/js/Headlines.js b/js/Headlines.js index e0caddc2a..4524f0556 100755 --- a/js/Headlines.js +++ b/js/Headlines.js @@ -4,7 +4,7 @@ define(["dojo/_base/declare"], function (declare) { Headlines = { vgroup_last_feed: undefined, _headlines_scroll_timeout: 0, - loaded_article_ids: [], + headlines: [], current_first_id: 0, catchup_id_batch: [], click: function (event, id, in_body) { @@ -23,6 +23,8 @@ define(["dojo/_base/declare"], function (declare) { if (!App.getInitParam("cdm_expanded")) Article.cdmScrollToId(id); + } else if (in_body) { + Headlines.toggleUnread(id, 0); } return in_body; @@ -153,9 +155,10 @@ define(["dojo/_base/declare"], function (declare) { console.warn("scrollHandler", e); } }, - updateFloatingTitle: function (unread_only) { + updateFloatingTitle: function (status_only) { if (!App.isCombinedMode()/* || !App.getInitParam("cdm_expanded")*/) return; + const safety_offset = 120; /* px, needed for firefox */ const hf = $("headlines-frame"); const elems = $$("#headlines-frame > div[id*=RROW]"); const ft = $("floatingTitle"); @@ -163,18 +166,18 @@ define(["dojo/_base/declare"], function (declare) { for (let i = 0; i < elems.length; i++) { const row = elems[i]; - if (row && row.offsetTop + row.offsetHeight > hf.scrollTop) { + if (row && row.offsetTop + row.offsetHeight > hf.scrollTop + safety_offset) { const header = row.select(".header")[0]; const id = row.getAttribute("data-article-id"); - if (unread_only || id != ft.getAttribute("data-article-id")) { + if (status_only || id != ft.getAttribute("data-article-id")) { if (id != ft.getAttribute("data-article-id")) { ft.setAttribute("data-article-id", id); ft.innerHTML = header.innerHTML; - ft.select(".dijitCheckBox")[0].outerHTML = "<i class=\"material-icons anchor\" onclick=\"Article.cdmScrollToId(" + id + ", true)\">expand_more</i>"; + ft.select(".dijitCheckBox")[0].outerHTML = "<i class=\"material-icons icon-anchor\" onclick=\"Article.cdmScrollToId(" + id + ", true)\">expand_more</i>"; this.initFloatingMenu(); @@ -185,16 +188,31 @@ define(["dojo/_base/declare"], function (declare) { else ft.removeClassName("Unread"); + if (row.hasClassName("marked")) + ft.addClassName("marked"); + else + ft.removeClassName("marked"); + + if (row.hasClassName("published")) + ft.addClassName("published"); + else + ft.removeClassName("published"); + PluginHost.run(PluginHost.HOOK_FLOATING_TITLE, row); } - ft.style.marginRight = hf.offsetWidth - row.offsetWidth + "px"; + //ft.style.marginRight = hf.offsetWidth - row.offsetWidth + "px"; - if (header.offsetTop + header.offsetHeight < hf.scrollTop + ft.offsetHeight - 5 && + /* if (header.offsetTop + header.offsetHeight < hf.scrollTop + ft.offsetHeight - 5 && row.offsetTop + row.offsetHeight >= hf.scrollTop + ft.offsetHeight - 5) - new Effect.Appear(ft, {duration: 0.3}); + Element.show(ft); + else + Element.hide(ft); */ + + if (hf.scrollTop - row.offsetTop <= header.offsetHeight + safety_offset) + ft.fade({duration: 0.2}); else - Element.hide(ft); + ft.appear({duration: 0.2}); return; } @@ -221,6 +239,141 @@ define(["dojo/_base/declare"], function (declare) { } } }, + objectById: function (id){ + return this.headlines[id]; + }, + renderHeadline: function (headlines, hl) { + let row = null; + + let row_class = ""; + + if (hl.marked) row_class += " marked"; + if (hl.published) row_class += " published"; + if (hl.unread) row_class += " Unread"; + if (headlines.vfeed_group_enabled) row_class += " vgrlf"; + + if (headlines.vfeed_group_enabled && hl.feed_title && this.vgroup_last_feed != hl.feed_id) { + let vgrhdr = `<div data-feed-id='${hl.feed_id}' class='feed-title'> + <div style='float : right'>${hl.feed_icon}</div> + <a class="title" href="#" onclick="Feeds.open({feed:${hl.feed_id}})">${hl.feed_title} + <a class="catchup" title="${__('mark feed as read')}" onclick="Feeds.catchupFeedInGroup(${hl.feed_id})" href="#"><i class="icon-done material-icons">done_all</i></a> + </div>` + + const tmp = document.createElement("div"); + tmp.innerHTML = vgrhdr; + + $("headlines-frame").appendChild(tmp.firstChild); + + this.vgroup_last_feed = hl.feed_id; + } + + if (App.isCombinedMode()) { + row_class += App.getInitParam("cdm_expanded") ? " expanded" : " expandable"; + + const comments = Article.formatComments(hl); + const originally_from = Article.formatOriginallyFrom(hl); + + row = `<div class="cdm ${row_class} ${hl.score_class}" id="RROW-${hl.id}" data-article-id="${hl.id}" data-orig-feed-id="${hl.feed_id}" + data-content="${escapeHtml(hl.content)}" onmouseover="Article.mouseIn(${hl.id})" onmouseout="Article.mouseOut(${hl.id})"> + + <div class="header"> + <div class="left"> + <input dojoType="dijit.form.CheckBox" type="checkbox" onclick="Headlines.onRowChecked(this)" class='rchk'> + <i class="marked-pic marked-${hl.id} material-icons" onclick="Headlines.toggleMark(${hl.id})">star</i> + <i class="pub-pic pub-${hl.id} material-icons" onclick="Headlines.togglePub(${hl.id})">rss_feed</i> + </div> + + <span onclick="return Headlines.click(event, ${hl.id});" data-article-id="${hl.id}" class="titleWrap hlMenuAttach"> + <a class="title" title="${hl.title}" target="_blank" rel="noopener noreferrer" href="${hl.link}"> + ${hl.title}</a> + <span class="author">${hl.author}</span> + <span class="HLLCTR-${hl.id}">${hl.labels}</span> + ${hl.cdm_excerpt ? hl.cdm_excerpt : ""} + </span> + + <div class="feed"> + <a href="#" style="background-color: rgba(${hl.favicon_avg_color_rgba})" + onclick="Feeds.open({feed:${hl.feed_id}})">${hl.feed_title}</a> + </div> + + <span class="updated" title="${hl.imported}">${hl.updated}</span> + + <div class="right"> + <i class="material-icons icon-score" title="${hl.score}" data-score="${hl.score}" + onclick="Article.setScore(${hl.id}, this)">${hl.score_pic}</i> + + <span style="cursor : pointer" title="${hl.feed_title}" onclick="Feeds.open({feed:${hl.feed_id}})"> + ${hl.feed_icon}</span> + </div> + + </div> + + <div class="content" onclick="return Headlines.click(event, ${hl.id}, true);"> + <div id="POSTNOTE-${hl.id}">${hl.note}</div> + <div class="content-inner" lang="${hl.lang ? hl.lang : 'en'}"> + <img src="${App.getInitParam('icon_indicator_white')}"> + </div> + <div class="intermediate"> + ${hl.enclosures} + </div> + <div class="footer" onclick="event.stopPropagation()"> + + <div class="left"> + ${hl.buttons_left} + <i class="material-icons">label_outline</i> + <span id="ATSTR-${hl.id}">${hl.tags_str}</span> + <a title="${__("Edit tags for this article")}" href="#" + onclick="Article.editTags(${hl.id})">(+)</a> + ${comments} + </div> + + <div class="right"> + ${originally_from} + ${hl.buttons} + </div> + </div> + </div> + </div>`; + + + } else { + row = `<div class="hl ${row_class} ${hl.score_class}" data-orig-feed-id="${hl.feed_id}" data-article-id="${hl.id}" id="RROW-${hl.id}" + onmouseover="Article.mouseIn(${hl.id})" onmouseout="Article.mouseOut(${hl.id})"> + <div class="left"> + <input dojoType="dijit.form.CheckBox" type="checkbox" onclick="Headlines.onRowChecked(this)" class='rchk'> + <i class="marked-pic marked-${hl.id} material-icons" onclick="Headlines.toggleMark(${hl.id})">star</i> + <i class="pub-pic pub-${hl.id} material-icons" onclick="Headlines.togglePub(${hl.id})">rss_feed</i> + </div> + <div onclick="return Headlines.click(event, ${hl.id})" class="title"> + <span data-article-id="${hl.id}" class="hl-content hlMenuAttach"> + <a class="title" href="${hl.link}">${hl.title} <span class="preview">${hl.content_preview}</span></a> + <span class="author">${hl.author}</span> + <span class="HLLCTR-${hl.id}">${hl.labels}</span> + </span> + </div> + <span class="feed"> + <a style="background : rgba(${hl.favicon_avg_color_rgba})" href="#" onclick="Feeds.open({feed:${hl.feed_id}})">${hl.feed_title}</a> + </span> + <div title="${hl.imported}"> + <span class="updated">${hl.updated}</span> + </div> + <div class="right"> + <i class="material-icons icon-score" title="${hl.score}" data-score="${hl.score}" + onclick="Article.setScore(${hl.id}, this)">${hl.score_pic}</i> + <span onclick="Feeds.open({feed:${hl.feed_id})" style="cursor : pointer" title="${hl.feed_title}">${hl.feed_icon}</span> + </div> + </div> + `; + } + + const tmp = document.createElement("div"); + tmp.innerHTML = row; + dojo.parser.parse(tmp); + + PluginHost.run(PluginHost.HOOK_HEADLINE_RENDERED, tmp.firstChild); + + $("headlines-frame").appendChild(tmp.firstChild); + }, onLoaded: function (transport, offset) { const reply = App.handleRpcJson(transport); @@ -262,19 +415,31 @@ define(["dojo/_base/declare"], function (declare) { console.log('received', headlines_count, 'headlines, infscroll disabled=', Feeds.infscroll_disabled); - this.vgroup_last_feed = reply['headlines-info']['vgroup_last_feed']; + //this.vgroup_last_feed = reply['headlines-info']['vgroup_last_feed']; this.current_first_id = reply['headlines']['first_id']; if (offset == 0) { - this.loaded_article_ids = []; + //this.headlines = []; + this.vgroup_last_feed = undefined; dojo.html.set($("toolbar-headlines"), reply['headlines']['toolbar'], {parseContent: true}); - $("headlines-frame").innerHTML = ''; + if (typeof reply['headlines']['content'] == 'string') { + $("headlines-frame").innerHTML = reply['headlines']['content']; + } else { + $("headlines-frame").innerHTML = ''; + + for (let i = 0; i < reply['headlines']['content'].length; i++) { + const hl = reply['headlines']['content'][i]; + + this.renderHeadline(reply['headlines'], hl); + this.headlines[parseInt(hl.id)] = hl; + } + } - let tmp = document.createElement("div"); + /* let tmp = document.createElement("div"); tmp.innerHTML = reply['headlines']['content']; dojo.parser.parse(tmp); @@ -286,7 +451,7 @@ define(["dojo/_base/declare"], function (declare) { this.loaded_article_ids.push(row.id); } - } + } */ let hsp = $("headlines-spacer"); @@ -318,7 +483,7 @@ define(["dojo/_base/declare"], function (declare) { if (hsp) c.domNode.removeChild(hsp); - let tmp = document.createElement("div"); + /* let tmp = document.createElement("div"); tmp.innerHTML = reply['headlines']['content']; dojo.parser.parse(tmp); @@ -330,6 +495,17 @@ define(["dojo/_base/declare"], function (declare) { this.loaded_article_ids.push(row.id); } + } */ + + if (typeof reply['headlines']['content'] == 'string') { + $("headlines-frame").innerHTML = reply['headlines']['content']; + } else { + for (let i = 0; i < reply['headlines']['content'].length; i++) { + const hl = reply['headlines']['content'][i]; + + this.renderHeadline(reply['headlines'], hl); + this.headlines[parseInt(hl.id)] = hl; + } } if (!hsp) { @@ -392,10 +568,10 @@ define(["dojo/_base/declare"], function (declare) { let value = order_by.attr('value'); - if (value == "date_reverse") - value = "default"; - else + if (value != "date_reverse") value = "date_reverse"; + else + value = "default"; order_by.attr('value', value); @@ -438,11 +614,10 @@ define(["dojo/_base/declare"], function (declare) { cmode: cmode, ids: ids.toString() }; - Notify.progress("Loading, please wait..."); - xhrPost("backend.php", query, (transport) => { App.handleRpcJson(transport); if (callback) callback(transport); + Headlines.updateFloatingTitle(true); }); }, selectionToggleMarked: function (ids) { @@ -494,10 +669,11 @@ define(["dojo/_base/declare"], function (declare) { const row = $("RROW-" + id); if (row) { - row.toggleClassName("marked"); query.mark = row.hasClassName("marked") ? 1 : 0; + Headlines.updateFloatingTitle(true); + if (!client_only) xhrPost("backend.php", query, (transport) => { App.handleRpcJson(transport); @@ -513,6 +689,8 @@ define(["dojo/_base/declare"], function (declare) { row.toggleClassName("published"); query.pub = row.hasClassName("published") ? 1 : 0; + Headlines.updateFloatingTitle(true); + if (!client_only) xhrPost("backend.php", query, (transport) => { App.handleRpcJson(transport); @@ -637,6 +815,7 @@ define(["dojo/_base/declare"], function (declare) { xhrPost("backend.php", {op: "rpc", method: "catchupSelected", cmode: cmode, ids: id}, (transport) => { App.handleRpcJson(transport); + Headlines.updateFloatingTitle(true); }); } }, @@ -834,10 +1013,6 @@ define(["dojo/_base/declare"], function (declare) { return; } - for (let i = 0; i < rows.length; i++) { - ArticleCache.del(rows[i]); - } - const query = {op: "rpc", method: op, ids: rows.toString()}; xhrPost("backend.php", query, (transport) => { |