summaryrefslogtreecommitdiff
path: root/js/Headlines.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/Headlines.js')
-rwxr-xr-xjs/Headlines.js225
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) => {