2018-12-02 15:38:27 +00:00
|
|
|
'use strict'
|
|
|
|
/* global __, ngettext */
|
2018-12-02 14:18:59 +00:00
|
|
|
define(["dojo/_base/declare"], function (declare) {
|
2018-12-03 06:33:44 +00:00
|
|
|
Feeds = {
|
2018-12-02 14:18:59 +00:00
|
|
|
counters_last_request: 0,
|
2019-05-07 16:10:11 +00:00
|
|
|
_active_feed_id: undefined,
|
2018-12-02 14:18:59 +00:00
|
|
|
_active_feed_is_cat: false,
|
|
|
|
infscroll_in_progress: 0,
|
|
|
|
infscroll_disabled: 0,
|
|
|
|
_infscroll_timeout: false,
|
|
|
|
_search_query: false,
|
|
|
|
last_search_query: [],
|
|
|
|
_viewfeed_wait_timeout: false,
|
|
|
|
_counters_prev: [],
|
|
|
|
// NOTE: this implementation is incomplete
|
|
|
|
// for general objects but good enough for counters
|
|
|
|
// http://adripofjavascript.com/blog/drips/object-equality-in-javascript.html
|
|
|
|
counterEquals: function(a, b) {
|
|
|
|
// Create arrays of property names
|
|
|
|
const aProps = Object.getOwnPropertyNames(a);
|
|
|
|
const bProps = Object.getOwnPropertyNames(b);
|
|
|
|
|
|
|
|
// If number of properties is different,
|
|
|
|
// objects are not equivalent
|
|
|
|
if (aProps.length != bProps.length) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (let i = 0; i < aProps.length; i++) {
|
|
|
|
const propName = aProps[i];
|
|
|
|
|
|
|
|
// If values of same property are not equal,
|
|
|
|
// objects are not equivalent
|
|
|
|
if (a[propName] !== b[propName]) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we made it this far, objects
|
|
|
|
// are considered equivalent
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
resetCounters: function () {
|
|
|
|
this._counters_prev = [];
|
|
|
|
},
|
|
|
|
parseCounters: function (elems) {
|
2019-05-06 06:49:04 +00:00
|
|
|
PluginHost.run(PluginHost.HOOK_COUNTERS_RECEIVED, elems);
|
|
|
|
|
2018-12-02 14:18:59 +00:00
|
|
|
for (let l = 0; l < elems.length; l++) {
|
|
|
|
|
|
|
|
if (Feeds._counters_prev[l] && this.counterEquals(elems[l], this._counters_prev[l])) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
const id = elems[l].id;
|
|
|
|
const kind = elems[l].kind;
|
|
|
|
const ctr = parseInt(elems[l].counter);
|
|
|
|
const error = elems[l].error;
|
|
|
|
const has_img = elems[l].has_img;
|
|
|
|
const updated = elems[l].updated;
|
|
|
|
|
|
|
|
if (id == "global-unread") {
|
|
|
|
App.global_unread = ctr;
|
|
|
|
App.updateTitle();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (id == "subscribed-feeds") {
|
|
|
|
/* feeds_found = ctr; */
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*if (this.getUnread(id, (kind == "cat")) != ctr ||
|
|
|
|
(kind == "cat")) {
|
|
|
|
}*/
|
|
|
|
|
|
|
|
this.setUnread(id, (kind == "cat"), ctr);
|
2020-01-24 11:35:10 +00:00
|
|
|
this.setValue(id, (kind == "cat"), 'auxcounter', parseInt(elems[l].auxcounter));
|
|
|
|
this.setValue(id, (kind == "cat"), 'markedcounter', parseInt(elems[l].markedcounter));
|
2018-12-02 14:18:59 +00:00
|
|
|
|
|
|
|
if (kind != "cat") {
|
|
|
|
this.setValue(id, false, 'error', error);
|
|
|
|
this.setValue(id, false, 'updated', updated);
|
|
|
|
|
|
|
|
if (id > 0) {
|
|
|
|
if (has_img) {
|
|
|
|
this.setIcon(id, false,
|
2018-12-02 18:52:50 +00:00
|
|
|
App.getInitParam("icons_url") + "/" + id + ".ico?" + has_img);
|
2018-12-02 14:18:59 +00:00
|
|
|
} else {
|
|
|
|
this.setIcon(id, false, 'images/blank_icon.gif');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-12 04:37:28 +00:00
|
|
|
Headlines.updateCurrentUnread();
|
|
|
|
|
2019-12-10 06:10:45 +00:00
|
|
|
this.hideOrShowFeeds(App.getInitParam("hide_read_feeds"));
|
2018-12-02 14:18:59 +00:00
|
|
|
this._counters_prev = elems;
|
2019-05-06 06:50:46 +00:00
|
|
|
|
|
|
|
PluginHost.run(PluginHost.HOOK_COUNTERS_PROCESSED);
|
2018-12-02 14:18:59 +00:00
|
|
|
},
|
|
|
|
reloadCurrent: function(method) {
|
|
|
|
if (this.getActive() != undefined) {
|
2019-05-07 16:10:11 +00:00
|
|
|
console.log("reloadCurrent: " + method);
|
|
|
|
|
2018-12-02 14:18:59 +00:00
|
|
|
this.open({feed: this.getActive(), is_cat: this.activeIsCat(), method: method});
|
|
|
|
}
|
|
|
|
return false; // block unneeded form submits
|
|
|
|
},
|
|
|
|
openNextUnread: function() {
|
|
|
|
const is_cat = this.activeIsCat();
|
|
|
|
const nuf = this.getNextUnread(this.getActive(), is_cat);
|
|
|
|
if (nuf) this.open({feed: nuf, is_cat: is_cat});
|
|
|
|
},
|
|
|
|
toggle: function() {
|
|
|
|
Element.toggle("feeds-holder");
|
|
|
|
|
|
|
|
const splitter = $("feeds-holder_splitter");
|
|
|
|
|
|
|
|
Element.visible("feeds-holder") ? splitter.show() : splitter.hide();
|
|
|
|
|
|
|
|
dijit.byId("main").resize();
|
2019-12-12 04:37:28 +00:00
|
|
|
|
|
|
|
Headlines.updateCurrentUnread();
|
2018-12-02 14:18:59 +00:00
|
|
|
},
|
|
|
|
cancelSearch: function() {
|
|
|
|
this._search_query = "";
|
|
|
|
this.reloadCurrent();
|
|
|
|
},
|
2018-12-12 17:06:44 +00:00
|
|
|
requestCounters: function() {
|
|
|
|
xhrPost("backend.php", {op: "rpc", method: "getAllCounters", seq: App.next_seq()}, (transport) => {
|
|
|
|
App.handleRpcJson(transport);
|
|
|
|
});
|
2018-12-02 14:18:59 +00:00
|
|
|
},
|
|
|
|
reload: function() {
|
|
|
|
try {
|
|
|
|
Element.show("feedlistLoading");
|
|
|
|
|
|
|
|
this.resetCounters();
|
|
|
|
|
|
|
|
if (dijit.byId("feedTree")) {
|
|
|
|
dijit.byId("feedTree").destroyRecursive();
|
|
|
|
}
|
|
|
|
|
|
|
|
const store = new dojo.data.ItemFileWriteStore({
|
|
|
|
url: "backend.php?op=pref_feeds&method=getfeedtree&mode=2"
|
|
|
|
});
|
|
|
|
|
|
|
|
// noinspection JSUnresolvedFunction
|
|
|
|
const treeModel = new fox.FeedStoreModel({
|
|
|
|
store: store,
|
|
|
|
query: {
|
2019-12-10 06:10:45 +00:00
|
|
|
"type": App.getInitParam('enable_feed_cats') ? "category" : "feed"
|
2018-12-02 14:18:59 +00:00
|
|
|
},
|
|
|
|
rootId: "root",
|
|
|
|
rootLabel: "Feeds",
|
|
|
|
childrenAttrs: ["items"]
|
|
|
|
});
|
|
|
|
|
|
|
|
// noinspection JSUnresolvedFunction
|
|
|
|
const tree = new fox.FeedTree({
|
|
|
|
model: treeModel,
|
|
|
|
onClick: function (item/*, node*/) {
|
|
|
|
const id = String(item.id);
|
|
|
|
const is_cat = id.match("^CAT:");
|
|
|
|
const feed = id.substr(id.indexOf(":") + 1);
|
|
|
|
Feeds.open({feed: feed, is_cat: is_cat});
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
openOnClick: false,
|
|
|
|
showRoot: false,
|
|
|
|
persist: true,
|
|
|
|
id: "feedTree",
|
|
|
|
}, "feedTree");
|
|
|
|
|
|
|
|
const tmph = dojo.connect(dijit.byId('feedMenu'), '_openMyself', function (event) {
|
|
|
|
console.log(dijit.getEnclosingWidget(event.target));
|
|
|
|
dojo.disconnect(tmph);
|
|
|
|
});
|
|
|
|
|
|
|
|
$("feeds-holder").appendChild(tree.domNode);
|
|
|
|
|
|
|
|
const tmph2 = dojo.connect(tree, 'onLoad', function () {
|
|
|
|
dojo.disconnect(tmph2);
|
|
|
|
Element.hide("feedlistLoading");
|
|
|
|
|
|
|
|
try {
|
|
|
|
Feeds.init();
|
2018-12-02 19:08:18 +00:00
|
|
|
App.setLoadingProgress(25);
|
2018-12-02 14:18:59 +00:00
|
|
|
} catch (e) {
|
2018-12-03 10:38:13 +00:00
|
|
|
App.Error.report(e);
|
2018-12-02 14:18:59 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
tree.startup();
|
|
|
|
} catch (e) {
|
2018-12-03 10:38:13 +00:00
|
|
|
App.Error.report(e);
|
2018-12-02 14:18:59 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
init: function() {
|
|
|
|
console.log("in feedlist init");
|
|
|
|
|
2018-12-02 19:08:18 +00:00
|
|
|
App.setLoadingProgress(50);
|
2018-12-02 14:18:59 +00:00
|
|
|
|
2018-12-05 06:11:12 +00:00
|
|
|
document.onkeydown = (event) => { return App.hotkeyHandler(event) };
|
Refactor hotkeys to use keypress instead of keydown
keydown returns the "raw" key in event.which. Depending on the keyboard
layout, this may not be what is wanted. For example, on a German
keyboard, Shift+7 has to be pressed to get a slash. However, event.which
will be 55, which corresponds to "7". In the keypress event, however,
event.which will be 47, which corresponds to "/".
Sadly, several important keys (such as escape and the arrow keys) do not
trigger a keypress event. Therefore, they have to be handled using a
keydown event.
This change refactors the hotkey support to make use of keypress events
whenever possible. This will make hotkeys work regardless of the user's
keyboard layout. Escape and arrow keys are still handled via keydown
events.
There should be only one change in behavior: I could not make Ctrl+/
work and therefore rebound the help dialog to "?".
2019-03-11 10:29:10 +00:00
|
|
|
document.onkeypress = (event) => { return App.hotkeyHandler(event) };
|
2018-12-06 10:24:36 +00:00
|
|
|
window.onresize = () => { Headlines.scrollHandler(); }
|
|
|
|
|
2019-05-06 18:57:58 +00:00
|
|
|
const hash_feed_id = hash_get('f');
|
|
|
|
const hash_feed_is_cat = hash_get('c') == "1";
|
|
|
|
|
|
|
|
if (hash_feed_id != undefined) {
|
|
|
|
this.open({feed: hash_feed_id, is_cat: hash_feed_is_cat});
|
2018-12-02 14:18:59 +00:00
|
|
|
} else {
|
2019-05-06 18:57:58 +00:00
|
|
|
this.open({feed: -3});
|
2018-12-02 14:18:59 +00:00
|
|
|
}
|
|
|
|
|
2019-12-10 06:10:45 +00:00
|
|
|
this.hideOrShowFeeds(App.getInitParam("hide_read_feeds"));
|
2018-12-02 14:18:59 +00:00
|
|
|
|
2018-12-02 18:52:50 +00:00
|
|
|
if (App.getInitParam("is_default_pw")) {
|
2018-12-02 14:18:59 +00:00
|
|
|
console.warn("user password is at default value");
|
|
|
|
|
|
|
|
const dialog = new dijit.Dialog({
|
|
|
|
title: __("Your password is at default value"),
|
|
|
|
href: "backend.php?op=dlg&method=defaultpasswordwarning",
|
2019-02-20 05:39:44 +00:00
|
|
|
id: 'defaultPasswordDlg',
|
2018-12-02 14:18:59 +00:00
|
|
|
style: "width: 600px",
|
|
|
|
onCancel: function () {
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
onExecute: function () {
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
onClose: function () {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
dialog.show();
|
|
|
|
}
|
|
|
|
|
|
|
|
// bw_limit disables timeout() so we request initial counters separately
|
2019-12-10 06:10:45 +00:00
|
|
|
if (App.getInitParam("bw_limit")) {
|
2018-12-02 14:18:59 +00:00
|
|
|
this.requestCounters(true);
|
|
|
|
} else {
|
|
|
|
setTimeout(() => {
|
|
|
|
this.requestCounters(true);
|
|
|
|
setInterval(() => { this.requestCounters(); }, 60 * 1000)
|
|
|
|
}, 250);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
activeIsCat: function() {
|
|
|
|
return !!this._active_feed_is_cat;
|
|
|
|
},
|
|
|
|
getActive: function() {
|
|
|
|
return this._active_feed_id;
|
|
|
|
},
|
|
|
|
setActive: function(id, is_cat) {
|
2019-05-06 18:57:58 +00:00
|
|
|
console.log('setActive', id, is_cat);
|
|
|
|
|
2018-12-02 14:18:59 +00:00
|
|
|
hash_set('f', id);
|
|
|
|
hash_set('c', is_cat ? 1 : 0);
|
|
|
|
|
|
|
|
this._active_feed_id = id;
|
|
|
|
this._active_feed_is_cat = is_cat;
|
|
|
|
|
|
|
|
$("headlines-frame").setAttribute("feed-id", id);
|
|
|
|
$("headlines-frame").setAttribute("is-cat", is_cat ? 1 : 0);
|
|
|
|
|
|
|
|
this.select(id, is_cat);
|
|
|
|
|
|
|
|
PluginHost.run(PluginHost.HOOK_FEED_SET_ACTIVE, [this._active_feed_id, this._active_feed_is_cat]);
|
|
|
|
},
|
|
|
|
select: function(feed, is_cat) {
|
|
|
|
const tree = dijit.byId("feedTree");
|
|
|
|
|
|
|
|
if (tree) return tree.selectFeed(feed, is_cat);
|
|
|
|
},
|
|
|
|
toggleUnread: function() {
|
2019-12-10 06:10:45 +00:00
|
|
|
const hide = !App.getInitParam("hide_read_feeds");
|
2018-12-02 14:18:59 +00:00
|
|
|
|
|
|
|
xhrPost("backend.php", {op: "rpc", method: "setpref", key: "HIDE_READ_FEEDS", value: hide}, () => {
|
|
|
|
this.hideOrShowFeeds(hide);
|
2018-12-02 18:52:50 +00:00
|
|
|
App.setInitParam("hide_read_feeds", hide);
|
2018-12-02 14:18:59 +00:00
|
|
|
});
|
|
|
|
},
|
|
|
|
hideOrShowFeeds: function(hide) {
|
|
|
|
const tree = dijit.byId("feedTree");
|
|
|
|
|
|
|
|
if (tree)
|
2018-12-02 18:52:50 +00:00
|
|
|
return tree.hideRead(hide, App.getInitParam("hide_read_shows_special"));
|
2018-12-02 14:18:59 +00:00
|
|
|
},
|
|
|
|
open: function(params) {
|
|
|
|
const feed = params.feed;
|
|
|
|
const is_cat = !!params.is_cat || false;
|
|
|
|
const offset = params.offset || 0;
|
|
|
|
const viewfeed_debug = params.viewfeed_debug;
|
2018-12-16 18:15:08 +00:00
|
|
|
const append = params.append || false;
|
2018-12-02 14:18:59 +00:00
|
|
|
const method = params.method;
|
|
|
|
// this is used to quickly switch between feeds, sets active but xhr is on a timeout
|
|
|
|
const delayed = params.delayed || false;
|
|
|
|
|
|
|
|
if (offset != 0) {
|
|
|
|
if (this.infscroll_in_progress)
|
|
|
|
return;
|
|
|
|
|
|
|
|
this.infscroll_in_progress = 1;
|
|
|
|
|
|
|
|
window.clearTimeout(this._infscroll_timeout);
|
|
|
|
this._infscroll_timeout = window.setTimeout(() => {
|
|
|
|
console.log('infscroll request timed out, aborting');
|
|
|
|
this.infscroll_in_progress = 0;
|
|
|
|
|
|
|
|
// call scroll handler to maybe repeat infscroll request
|
|
|
|
Headlines.scrollHandler();
|
|
|
|
}, 10 * 1000);
|
|
|
|
}
|
|
|
|
|
2018-12-05 07:03:58 +00:00
|
|
|
Form.enable("toolbar-main");
|
2018-12-02 14:18:59 +00:00
|
|
|
|
|
|
|
let query = Object.assign({op: "feeds", method: "view", feed: feed},
|
2018-12-05 07:03:58 +00:00
|
|
|
dojo.formToObject("toolbar-main"));
|
2018-12-02 14:18:59 +00:00
|
|
|
|
|
|
|
if (method) query.m = method;
|
|
|
|
|
|
|
|
if (offset > 0) {
|
|
|
|
if (Headlines.current_first_id) {
|
|
|
|
query.fid = Headlines.current_first_id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this._search_query) {
|
|
|
|
query = Object.assign(query, this._search_query);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (offset != 0) {
|
|
|
|
query.skip = offset;
|
|
|
|
} else if (!is_cat && feed == this.getActive() && !params.method) {
|
|
|
|
query.m = "ForceUpdate";
|
|
|
|
}
|
|
|
|
|
2018-12-05 07:03:58 +00:00
|
|
|
Form.enable("toolbar-main");
|
2018-12-02 14:18:59 +00:00
|
|
|
|
|
|
|
if (!delayed)
|
|
|
|
if (!this.setExpando(feed, is_cat,
|
|
|
|
(is_cat) ? 'images/indicator_tiny.gif' : 'images/indicator_white.gif'))
|
2018-12-02 17:56:30 +00:00
|
|
|
Notify.progress("Loading, please wait...", true);
|
2018-12-02 14:18:59 +00:00
|
|
|
|
|
|
|
query.cat = is_cat;
|
|
|
|
|
|
|
|
this.setActive(feed, is_cat);
|
|
|
|
|
|
|
|
if (viewfeed_debug) {
|
|
|
|
window.open("backend.php?" +
|
|
|
|
dojo.objectToQuery(
|
2018-12-07 18:22:51 +00:00
|
|
|
Object.assign({csrf_token: App.getInitParam("csrf_token")}, query)
|
2018-12-02 14:18:59 +00:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
window.clearTimeout(this._viewfeed_wait_timeout);
|
|
|
|
this._viewfeed_wait_timeout = window.setTimeout(() => {
|
2018-12-10 17:50:44 +00:00
|
|
|
xhrPost("backend.php", query, (transport) => {
|
|
|
|
try {
|
|
|
|
window.clearTimeout(this._infscroll_timeout);
|
|
|
|
this.setExpando(feed, is_cat, 'images/blank_icon.gif');
|
2018-12-16 18:15:08 +00:00
|
|
|
Headlines.onLoaded(transport, offset, append);
|
2018-12-10 17:50:44 +00:00
|
|
|
PluginHost.run(PluginHost.HOOK_FEED_LOADED, [feed, is_cat]);
|
|
|
|
} catch (e) {
|
|
|
|
App.Error.report(e);
|
|
|
|
}
|
2018-12-02 14:18:59 +00:00
|
|
|
});
|
|
|
|
}, delayed ? 250 : 0);
|
|
|
|
},
|
|
|
|
catchupAll: function() {
|
|
|
|
const str = __("Mark all articles as read?");
|
|
|
|
|
2018-12-02 18:52:50 +00:00
|
|
|
if (App.getInitParam("confirm_feed_catchup") != 1 || confirm(str)) {
|
2018-12-02 14:18:59 +00:00
|
|
|
|
2018-12-02 17:56:30 +00:00
|
|
|
Notify.progress("Marking all feeds as read...");
|
2018-12-02 14:18:59 +00:00
|
|
|
|
|
|
|
xhrPost("backend.php", {op: "feeds", method: "catchupAll"}, () => {
|
|
|
|
this.requestCounters(true);
|
|
|
|
this.reloadCurrent();
|
|
|
|
});
|
|
|
|
|
|
|
|
App.global_unread = 0;
|
|
|
|
App.updateTitle();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
catchupFeed: function(feed, is_cat, mode) {
|
2019-12-10 06:10:45 +00:00
|
|
|
is_cat = is_cat || false;
|
2018-12-02 14:18:59 +00:00
|
|
|
|
|
|
|
let str = false;
|
|
|
|
|
|
|
|
switch (mode) {
|
|
|
|
case "1day":
|
|
|
|
str = __("Mark %w in %s older than 1 day as read?");
|
|
|
|
break;
|
|
|
|
case "1week":
|
|
|
|
str = __("Mark %w in %s older than 1 week as read?");
|
|
|
|
break;
|
|
|
|
case "2week":
|
|
|
|
str = __("Mark %w in %s older than 2 weeks as read?");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
str = __("Mark %w in %s as read?");
|
|
|
|
}
|
|
|
|
|
|
|
|
const mark_what = this.last_search_query && this.last_search_query[0] ? __("search results") : __("all articles");
|
|
|
|
const fn = this.getName(feed, is_cat);
|
|
|
|
|
|
|
|
str = str.replace("%s", fn)
|
|
|
|
.replace("%w", mark_what);
|
|
|
|
|
2019-12-10 06:10:45 +00:00
|
|
|
if (App.getInitParam("confirm_feed_catchup") && !confirm(str)) {
|
2018-12-02 14:18:59 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const catchup_query = {
|
|
|
|
op: 'rpc', method: 'catchupFeed', feed_id: feed,
|
|
|
|
is_cat: is_cat, mode: mode, search_query: this.last_search_query[0],
|
|
|
|
search_lang: this.last_search_query[1]
|
|
|
|
};
|
|
|
|
|
2018-12-02 17:56:30 +00:00
|
|
|
Notify.progress("Loading, please wait...", true);
|
2018-12-02 14:18:59 +00:00
|
|
|
|
|
|
|
xhrPost("backend.php", catchup_query, (transport) => {
|
2018-12-02 19:08:18 +00:00
|
|
|
App.handleRpcJson(transport);
|
2018-12-02 14:18:59 +00:00
|
|
|
|
2019-12-10 06:10:45 +00:00
|
|
|
const show_next_feed = App.getInitParam("on_catchup_show_next_feed");
|
2018-12-02 14:18:59 +00:00
|
|
|
|
|
|
|
if (show_next_feed) {
|
|
|
|
const nuf = this.getNextUnread(feed, is_cat);
|
|
|
|
|
|
|
|
if (nuf) {
|
|
|
|
this.open({feed: nuf, is_cat: is_cat});
|
|
|
|
}
|
|
|
|
} else if (feed == this.getActive() && is_cat == this.activeIsCat()) {
|
|
|
|
this.reloadCurrent();
|
|
|
|
}
|
|
|
|
|
2018-12-02 17:56:30 +00:00
|
|
|
Notify.close();
|
2018-12-02 14:18:59 +00:00
|
|
|
});
|
|
|
|
},
|
|
|
|
catchupCurrent: function(mode) {
|
|
|
|
this.catchupFeed(this.getActive(), this.activeIsCat(), mode);
|
|
|
|
},
|
|
|
|
catchupFeedInGroup: function(id) {
|
|
|
|
const title = this.getName(id);
|
|
|
|
|
|
|
|
const str = __("Mark all articles in %s as read?").replace("%s", title);
|
|
|
|
|
2018-12-02 18:52:50 +00:00
|
|
|
if (App.getInitParam("confirm_feed_catchup") != 1 || confirm(str)) {
|
2018-12-02 14:18:59 +00:00
|
|
|
|
2018-12-09 10:52:21 +00:00
|
|
|
const rows = $$("#headlines-frame > div[id*=RROW][class*=Unread][data-orig-feed-id='" + id + "']");
|
2018-12-02 14:18:59 +00:00
|
|
|
|
2018-12-10 17:50:44 +00:00
|
|
|
rows.each((row) => {
|
|
|
|
row.removeClassName("Unread");
|
|
|
|
})
|
2018-12-02 14:18:59 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
getUnread: function(feed, is_cat) {
|
|
|
|
try {
|
|
|
|
const tree = dijit.byId("feedTree");
|
|
|
|
|
|
|
|
if (tree && tree.model)
|
|
|
|
return tree.model.getFeedUnread(feed, is_cat);
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
//
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
},
|
|
|
|
getCategory: function(feed) {
|
|
|
|
try {
|
|
|
|
const tree = dijit.byId("feedTree");
|
|
|
|
|
|
|
|
if (tree && tree.model)
|
|
|
|
return tree.getFeedCategory(feed);
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
//
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
getName: function(feed, is_cat) {
|
|
|
|
if (isNaN(feed)) return feed; // it's a tag
|
|
|
|
|
|
|
|
const tree = dijit.byId("feedTree");
|
|
|
|
|
|
|
|
if (tree && tree.model)
|
|
|
|
return tree.model.getFeedValue(feed, is_cat, 'name');
|
|
|
|
},
|
|
|
|
setUnread: function(feed, is_cat, unread) {
|
|
|
|
const tree = dijit.byId("feedTree");
|
|
|
|
|
|
|
|
if (tree && tree.model)
|
|
|
|
return tree.model.setFeedUnread(feed, is_cat, unread);
|
|
|
|
},
|
|
|
|
setValue: function(feed, is_cat, key, value) {
|
|
|
|
try {
|
|
|
|
const tree = dijit.byId("feedTree");
|
|
|
|
|
|
|
|
if (tree && tree.model)
|
|
|
|
return tree.model.setFeedValue(feed, is_cat, key, value);
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
//
|
|
|
|
}
|
|
|
|
},
|
|
|
|
getValue: function(feed, is_cat, key) {
|
|
|
|
try {
|
|
|
|
const tree = dijit.byId("feedTree");
|
|
|
|
|
|
|
|
if (tree && tree.model)
|
|
|
|
return tree.model.getFeedValue(feed, is_cat, key);
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
//
|
|
|
|
}
|
|
|
|
return '';
|
|
|
|
},
|
|
|
|
setIcon: function(feed, is_cat, src) {
|
|
|
|
const tree = dijit.byId("feedTree");
|
|
|
|
|
|
|
|
if (tree) return tree.setFeedIcon(feed, is_cat, src);
|
|
|
|
},
|
|
|
|
setExpando: function(feed, is_cat, src) {
|
|
|
|
const tree = dijit.byId("feedTree");
|
|
|
|
|
|
|
|
if (tree) return tree.setFeedExpandoIcon(feed, is_cat, src);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
getNextUnread: function(feed, is_cat) {
|
|
|
|
const tree = dijit.byId("feedTree");
|
|
|
|
const nuf = tree.model.getNextUnreadFeed(feed, is_cat);
|
|
|
|
|
|
|
|
if (nuf)
|
|
|
|
return tree.model.store.getValue(nuf, 'bare_id');
|
|
|
|
},
|
|
|
|
search: function() {
|
|
|
|
const query = "backend.php?op=feeds&method=search¶m=" +
|
2018-12-02 17:07:57 +00:00
|
|
|
encodeURIComponent(Feeds.getActive() + ":" + Feeds.activeIsCat());
|
2018-12-02 14:18:59 +00:00
|
|
|
|
|
|
|
if (dijit.byId("searchDlg"))
|
|
|
|
dijit.byId("searchDlg").destroyRecursive();
|
|
|
|
|
|
|
|
const dialog = new dijit.Dialog({
|
|
|
|
id: "searchDlg",
|
|
|
|
title: __("Search"),
|
|
|
|
style: "width: 600px",
|
|
|
|
execute: function () {
|
|
|
|
if (this.validate()) {
|
|
|
|
Feeds._search_query = this.attr('value');
|
2019-05-20 04:59:53 +00:00
|
|
|
|
|
|
|
// disallow empty queries
|
|
|
|
if (!Feeds._search_query.query)
|
|
|
|
Feeds._search_query = false;
|
|
|
|
|
2018-12-02 14:18:59 +00:00
|
|
|
this.hide();
|
|
|
|
Feeds.reloadCurrent();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
href: query
|
|
|
|
});
|
|
|
|
|
2019-05-20 04:59:53 +00:00
|
|
|
const tmph = dojo.connect(dialog, 'onLoad', function () {
|
|
|
|
dojo.disconnect(tmph);
|
|
|
|
|
|
|
|
if (Feeds._search_query) {
|
|
|
|
if (Feeds._search_query.query)
|
|
|
|
dijit.byId('search_query')
|
|
|
|
.attr('value', Feeds._search_query.query);
|
|
|
|
|
|
|
|
if (Feeds._search_query.search_language)
|
|
|
|
dijit.byId('search_language')
|
|
|
|
.attr('value', Feeds._search_query.search_language);
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
2018-12-02 14:18:59 +00:00
|
|
|
dialog.show();
|
|
|
|
},
|
|
|
|
updateRandom: function() {
|
|
|
|
console.log("in update_random_feed");
|
|
|
|
|
2018-12-06 09:19:05 +00:00
|
|
|
xhrPost("backend.php", {op: "rpc", method: "updaterandomfeed"}, (transport) => {
|
2018-12-02 19:08:18 +00:00
|
|
|
App.handleRpcJson(transport, true);
|
2018-12-02 14:18:59 +00:00
|
|
|
});
|
|
|
|
},
|
2018-12-03 06:33:44 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
return Feeds;
|
2018-12-02 17:21:37 +00:00
|
|
|
});
|