diff options
author | Andrew Dolgov <[email protected]> | 2021-02-24 21:56:52 +0300 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2021-02-24 21:56:52 +0300 |
commit | 93940d2a9f80d9e1dac49b5eb7db23230d31c5f6 (patch) | |
tree | 71016661f6017918d0934eb462bd9552018d557a /js/PrefFeedTree.js | |
parent | 8b022c2bfb356d7dddaf334bc931d6dec77086fb (diff) | |
parent | 1adacd057230aea4ede29dab510385bf01cf99a3 (diff) |
Merge branch 'master' of git.fakecake.org:fox/tt-rss into weblate-integration
Diffstat (limited to 'js/PrefFeedTree.js')
-rw-r--r-- | js/PrefFeedTree.js | 310 |
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(); } }); }); |