summaryrefslogtreecommitdiff
path: root/js/PrefFeedTree.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/PrefFeedTree.js')
-rw-r--r--js/PrefFeedTree.js310
1 files changed, 218 insertions, 92 deletions
diff --git a/js/PrefFeedTree.js b/js/PrefFeedTree.js
index 89195e616..bb5d25e67 100644
--- a/js/PrefFeedTree.js
+++ b/js/PrefFeedTree.js
@@ -1,9 +1,44 @@
/* eslint-disable prefer-rest-params */
-/* global __, lib, dijit, define, dojo, CommonDialogs, Notify, Tables, xhrPost, fox, App */
+/* global __, lib, dijit, define, dojo, CommonDialogs, Notify, Tables, xhrPost, xhr, fox, App */
-define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], function (declare, domConstruct) {
+define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree", "dojo/_base/array", "dojo/cookie"],
+ function (declare, domConstruct, checkBoxTree, array, cookie) {
return declare("fox.PrefFeedTree", lib.CheckBoxTree, {
+ // save state in localStorage instead of cookies
+ // reference: https://stackoverflow.com/a/27968996
+ _saveExpandedNodes: function(){
+ if (this.persist && this.cookieName){
+ const ary = [];
+ for (const id in this._openedNodes){
+ ary.push(id);
+ }
+ // Was:
+ // cookie(this.cookieName, ary.join(","), {expires: 365});
+ localStorage.setItem(this.cookieName, ary.join(","));
+ }
+ },
+ _initState: function(){
+ this.cookieName = 'prefs:' + this.cookieName;
+ // summary:
+ // Load in which nodes should be opened automatically
+ this._openedNodes = {};
+ if (this.persist && this.cookieName){
+ // Was:
+ // var oreo = cookie(this.cookieName);
+ let oreo = localStorage.getItem(this.cookieName);
+ // migrate old data if nothing in localStorage
+ if (oreo == null || oreo === '') {
+ oreo = cookie(this.cookieName);
+ cookie(this.cookieName, null, { expires: -1 });
+ }
+ if (oreo){
+ array.forEach(oreo.split(','), function(item){
+ this._openedNodes[item] = true;
+ }, this);
+ }
+ }
+ },
_createTreeNode: function(args) {
const tnode = this.inherited(arguments);
@@ -91,11 +126,11 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
return (!item || this.model.store.getValue(item, 'type') == 'category') ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "feed-icon";
},
reload: function() {
- const searchElem = $("feed_search");
+ const searchElem = App.byId("feed_search");
const search = (searchElem) ? searchElem.value : "";
- xhrPost("backend.php", { op: "pref-feeds", search: search }, (transport) => {
- dijit.byId('feedsTab').attr('content', transport.responseText);
+ xhr.post("backend.php", { op: "pref-feeds", search: search }, (reply) => {
+ dijit.byId('feedsTab').attr('content', reply);
Notify.close();
});
},
@@ -129,14 +164,14 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
resetFeedOrder: function() {
Notify.progress("Loading, please wait...");
- xhrPost("backend.php", {op: "pref-feeds", method: "feedsortreset"}, () => {
+ xhr.post("backend.php", {op: "pref-feeds", method: "feedsortreset"}, () => {
this.reload();
});
},
resetCatOrder: function() {
Notify.progress("Loading, please wait...");
- xhrPost("backend.php", {op: "pref-feeds", method: "catsortreset"}, () => {
+ xhr.post("backend.php", {op: "pref-feeds", method: "catsortreset"}, () => {
this.reload();
});
},
@@ -144,7 +179,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
if (confirm(__("Remove category %s? Any nested feeds would be placed into Uncategorized.").replace("%s", item.name))) {
Notify.progress("Removing category...");
- xhrPost("backend.php", {op: "pref-feeds", method: "removeCat", ids: id}, () => {
+ xhr.post("backend.php", {op: "pref-feeds", method: "removeCat", ids: id}, () => {
Notify.close();
this.reload();
});
@@ -163,7 +198,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
ids: sel_rows.toString()
};
- xhrPost("backend.php", query, () => {
+ xhr.post("backend.php", query, () => {
this.reload();
});
}
@@ -174,9 +209,16 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
return false;
},
+ checkErrorFeeds: function() {
+ xhr.json("backend.php", {op: "pref-feeds", method: "feedsWithErrors"}, (reply) => {
+ if (reply.length > 0) {
+ Element.show(dijit.byId("pref_feeds_errors_btn").domNode);
+ }
+ });
+ },
checkInactiveFeeds: function() {
- xhrPost("backend.php", {op: "pref-feeds", method: "getinactivefeeds"}, (transport) => {
- if (parseInt(transport.responseText) > 0) {
+ xhr.json("backend.php", {op: "pref-feeds", method: "inactivefeeds"}, (reply) => {
+ if (reply.length > 0) {
Element.show(dijit.byId("pref_feeds_inactive_btn").domNode);
}
});
@@ -186,7 +228,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
const items = tree.model.getCheckedItems();
const rv = [];
- items.each(function (item) {
+ items.forEach(function (item) {
if (item.id[0].match("CAT:"))
rv.push(tree.model.store.getValue(item, 'bare_id'));
});
@@ -205,7 +247,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
ids: sel_rows.toString()
};
- xhrPost("backend.php", query, () => {
+ xhr.post("backend.php", query, () => {
this.reload();
});
}
@@ -220,7 +262,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
const items = tree.model.getCheckedItems();
const rv = [];
- items.each(function (item) {
+ items.forEach(function (item) {
if (item.id[0].match("FEED:"))
rv.push(tree.model.store.getValue(item, 'bare_id'));
});
@@ -253,16 +295,15 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
Notify.progress("Loading, please wait...");
- xhrPost("backend.php", {op: "pref-feeds", method: "editfeeds", ids: rows.toString()}, (transport) => {
+ xhr.post("backend.php", {op: "pref-feeds", method: "editfeeds", ids: rows.toString()}, (reply) => {
Notify.close();
try {
const dialog = new fox.SingleUseDialog({
- id: "feedEditDlg",
title: __("Edit Multiple Feeds"),
- getChildByName: function (name) {
+ /*getChildByName: function (name) {
let rv = null;
- this.getChildren().each(
+ this.getChildren().forEach(
function (child) {
if (child.name == name) {
rv = child;
@@ -270,16 +311,22 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
}
});
return rv;
- },
- toggleField: function (checkbox, elem, label) {
- this.getChildByName(elem).attr('disabled', !checkbox.checked);
+ },*/
+ toggleField: function (checkbox) {
+ const name = checkbox.attr("data-control-for");
+ const target = dijit.getEnclosingWidget(dialog.domNode.querySelector(`input[name="${name}"]`));
- if ($(label))
- if (checkbox.checked)
- $(label).removeClassName('text-muted');
- else
- $(label).addClassName('text-muted');
+ target.attr('disabled', !checkbox.attr('checked'));
+ console.log(target, target.attr('type'));
+
+ if (target.attr('type') == "checkbox") {
+ const label = checkbox.domNode.closest("label");
+ if (checkbox.attr('checked'))
+ label.removeClassName('text-muted');
+ else
+ label.addClassName('text-muted');
+ }
},
execute: function () {
if (this.validate() && confirm(__("Save changes to selected feeds?"))) {
@@ -287,7 +334,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
/* normalize unchecked checkboxes because [] is not serialized */
- Object.keys(query).each((key) => {
+ Object.keys(query).forEach((key) => {
const val = query[key];
if (typeof val == "object" && val.length == 0)
@@ -296,7 +343,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
Notify.progress("Saving data...", true);
- xhrPost("backend.php", query, () => {
+ xhr.post("backend.php", query, () => {
dialog.hide();
const tree = dijit.byId("feedTree");
@@ -305,7 +352,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
});
}
},
- content: transport.responseText
+ content: reply
});
dialog.show();
@@ -325,7 +372,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
Notify.progress("Loading, please wait...");
- xhrPost("backend.php", { op: 'pref-feeds', method: 'renamecat', id: id, title: new_name }, () => {
+ xhr.post("backend.php", { op: 'pref-feeds', method: 'renamecat', id: id, title: new_name }, () => {
this.reload();
});
}
@@ -336,63 +383,22 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
if (title) {
Notify.progress("Creating category...");
- xhrPost("backend.php", {op: "pref-feeds", method: "addCat", cat: title}, () => {
+ xhr.post("backend.php", {op: "pref-feeds", method: "addCat", cat: title}, () => {
Notify.close();
this.reload();
});
}
},
batchSubscribe: function() {
- const dialog = new fox.SingleUseDialog({
- id: "batchSubDlg",
- title: __("Batch subscribe"),
- execute: function () {
- if (this.validate()) {
- Notify.progress(__("Subscribing to feeds..."), true);
-
- xhrPost("backend.php", this.attr('value'), () => {
- Notify.close();
-
- const tree = dijit.byId("feedTree");
- if (tree) tree.reload();
-
- dialog.hide();
- });
- }
- },
- content: __("Loading, please wait...")
- });
-
- const tmph = dojo.connect(dialog, 'onShow', function () {
- dojo.disconnect(tmph);
-
- xhrPost("backend.php", {op: 'pref-feeds', method: 'batchSubscribe'}, (transport) => {
- dialog.attr('content', transport.responseText);
- })
- });
-
- dialog.show();
- },
- showInactiveFeeds: function() {
- const dialog = new fox.SingleUseDialog({
- id: "inactiveFeedsDlg",
- title: __("Feeds without recent updates"),
- getSelectedFeeds: function () {
- return Tables.getSelected("inactive-feeds-list");
- },
- removeSelected: function () {
- const sel_rows = this.getSelectedFeeds();
-
- if (sel_rows.length > 0) {
- if (confirm(__("Remove selected feeds?"))) {
- Notify.progress("Removing selected feeds...", true);
-
- const query = {
- op: "pref-feeds", method: "remove",
- ids: sel_rows.toString()
- };
-
- xhrPost("backend.php", query, () => {
+ xhr.json("backend.php", {op: 'pref-feeds', method: 'batchSubscribe'}, (reply) => {
+ const dialog = new fox.SingleUseDialog({
+ id: "batchSubDlg",
+ title: __("Batch subscribe"),
+ execute: function () {
+ if (this.validate()) {
+ Notify.progress(__("Subscribing to feeds..."), true);
+
+ xhr.post("backend.php", this.attr('value'), () => {
Notify.close();
const tree = dijit.byId("feedTree");
@@ -401,23 +407,143 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
dialog.hide();
});
}
+ },
+ content: `
+ <form onsubmit='return false'>
+ ${App.FormFields.hidden_tag("op", "pref-feeds")}
+ ${App.FormFields.hidden_tag("method", "batchaddfeeds")}
+
+ <header class='horizontal'>
+ ${__("One valid feed per line (no detection is done)")}
+ </header>
+
+ <section>
+ <textarea style='font-size : 12px; width : 98%; height: 200px;'
+ dojoType='fox.form.ValidationTextArea' required='1' name='feeds'></textarea>
+
+ ${reply.enable_cats ?
+ `<fieldset>
+ <label>${__('Place in category:')}</label>
+ ${reply.cat_select}
+ </fieldset>
+ ` : ''
+ }
+ </section>
+
+ <div id='feedDlg_loginContainer' style='display : none'>
+ <header>${__("Authentication")}</header>
+ <section>
+ <input dojoType='dijit.form.TextBox' name='login' placeHolder="${__("Login")}">
+ <input placeHolder="${__("Password")}" dojoType="dijit.form.TextBox" type='password'
+ autocomplete='new-password' name='pass'></div>
+ </section>
+ </div>
+
+ <fieldset class='narrow'>
+ <label class='checkbox'><input type='checkbox' name='need_auth' dojoType='dijit.form.CheckBox'
+ onclick='App.displayIfChecked(this, "feedDlg_loginContainer")'>
+ ${__('Feeds require authentication.')}
+ </label>
+ </fieldset>
+
+ <footer>
+ <button dojoType='dijit.form.Button' onclick='App.dialogOf(this).execute()' type='submit' class='alt-primary'>
+ ${__('Subscribe')}
+ </button>
+ <button dojoType='dijit.form.Button' onclick='App.dialogOf(this).hide()'>
+ ${__('Cancel')}
+ </button>
+ </footer>
+ </form>
+ `
+ });
+
+ dialog.show();
- } else {
- alert(__("No feeds selected."));
- }
- },
- content: __("Loading, please wait...")
});
+ },
+ showInactiveFeeds: function() {
+ xhr.json("backend.php", {op: 'pref-feeds', method: 'inactivefeeds'}, function (reply) {
+
+ const dialog = new fox.SingleUseDialog({
+ id: "inactiveFeedsDlg",
+ title: __("Feeds without recent updates"),
+ getSelectedFeeds: function () {
+ return Tables.getSelected("inactive-feeds-list");
+ },
+ removeSelected: function () {
+ const sel_rows = this.getSelectedFeeds();
+
+ if (sel_rows.length > 0) {
+ if (confirm(__("Remove selected feeds?"))) {
+ Notify.progress("Removing selected feeds...", true);
+
+ const query = {
+ op: "pref-feeds", method: "remove",
+ ids: sel_rows.toString()
+ };
+
+ xhr.post("backend.php", query, () => {
+ Notify.close();
+
+ const tree = dijit.byId("feedTree");
+ if (tree) tree.reload();
+
+ dialog.hide();
+ });
+ }
+
+ } else {
+ alert(__("No feeds selected."));
+ }
+ },
+ content: `
+ <div dojoType='fox.Toolbar'>
+ <div dojoType='fox.form.DropDownButton'>
+ <span>${__('Select')}</span>
+ <div dojoType='dijit.Menu' style='display: none'>
+ <div onclick="Tables.select('inactive-feeds-list', true)"
+ dojoType='dijit.MenuItem'>${__('All')}</div>
+ <div onclick="Tables.select('inactive-feeds-list', false)"
+ dojoType='dijit.MenuItem'>${__('None')}</div>
+ </div>
+ </div>
+ </div>
+
+ <div class='panel panel-scrollable'>
+ <table width='100%' id='inactive-feeds-list'>
+ ${reply.map((row) => `<tr data-row-id='${row.id}'>
+ <td width='5%' align='center'>
+ <input onclick='Tables.onRowChecked(this)' dojoType='dijit.form.CheckBox' type='checkbox'>
+ </td>
+ <td>
+ <a href='#' "title="${__("Click to edit feed")}" onclick="CommonDialogs.editFeed(${row.id})">
+ ${App.escapeHtml(row.title)}
+ </a>
+ </td>
+ <td class='text-muted' align='right'>
+ ${row.last_article}
+ </td>
+ </tr>
+ `).join("")}
+ </table>
+ </div>
+
+ <footer>
+ <button style='float : left' class='alt-danger' dojoType='dijit.form.Button' onclick='App.dialogOf(this).removeSelected()'>
+ ${__('Unsubscribe from selected feeds')}
+ </button>
+ <button dojoType='dijit.form.Button' class='alt-primary' type='submit'>
+ ${__('Close this window')}
+ </button>
+ </footer>
+ `
+ });
- const tmph = dojo.connect(dialog, 'onShow', function () {
- dojo.disconnect(tmph);
+ dialog.show();
- xhrPost("backend.php", {op: "pref-feeds", method: "inactivefeeds"}, (transport) => {
- dialog.attr('content', transport.responseText);
- })
});
- dialog.show();
}
});
});