]>
git.wh0rd.org - tt-rss.git/blob - js/prefs.js
3 let hotkey_prefix
= false;
4 let hotkey_prefix_pressed
= false;
8 function notify_callback2(transport
, sticky
) {
9 notify_info(transport
.responseText
, sticky
);
12 function updateFeedList() {
14 const user_search
= $("feed_search");
16 if (user_search
) { search
= user_search
.value
; }
18 xhrPost("backend.php", { op
: "pref-feeds", search
: search
}, (transport
) => {
19 dijit
.byId('feedConfigTab').attr('content', transport
.responseText
);
20 selectTab("feedConfig", true);
25 function checkInactiveFeeds() {
26 xhrPost("backend.php", { op
: "pref-feeds", method
: "getinactivefeeds" }, (transport
) => {
27 if (parseInt(transport
.responseText
) > 0) {
28 Element
.show(dijit
.byId("pref_feeds_inactive_btn").domNode
);
33 function updateUsersList(sort_key
) {
34 const user_search
= $("user_search");
35 const search
= user_search
? user_search
.value
: "";
37 const query
= { op
: "pref-users", sort
: sort_key
, search
: search
};
39 xhrPost("backend.php", query
, (transport
) => {
40 dijit
.byId('userConfigTab').attr('content', transport
.responseText
);
41 selectTab("userConfig", true)
47 const login
= prompt(__("Please enter login:"), "");
54 alert(__("Can't create user: no login specified."));
58 notify_progress("Adding user...");
60 xhrPost("backend.php", { op
: "pref-users", method
: "add", login
: login
}, (transport
) => {
61 notify_callback2(transport
);
67 function editUser(id
) {
69 const query
= "backend.php?op=pref-users&method=edit&id=" +
72 if (dijit
.byId("userEditDlg"))
73 dijit
.byId("userEditDlg").destroyRecursive();
75 const dialog
= new dijit
.Dialog({
77 title
: __("User Editor"),
78 style
: "width: 600px",
79 execute: function () {
80 if (this.validate()) {
81 notify_progress("Saving data...", true);
83 xhrPost("backend.php", dojo
.formToObject("user_edit_form"), (transport
) => {
95 function editFilter(id
) {
97 const query
= "backend.php?op=pref-filters&method=edit&id=" + param_escape(id
);
99 if (dijit
.byId("feedEditDlg"))
100 dijit
.byId("feedEditDlg").destroyRecursive();
102 if (dijit
.byId("filterEditDlg"))
103 dijit
.byId("filterEditDlg").destroyRecursive();
105 const dialog
= new dijit
.Dialog({
107 title
: __("Edit Filter"),
108 style
: "width: 600px",
111 const query
= "backend.php?" + dojo
.formToQuery("filter_edit_form") + "&savemode=test";
113 editFilterTest(query
);
115 selectRules: function (select
) {
116 $$("#filterDlg_Matches input[type=checkbox]").each(function (e
) {
119 e
.parentNode
.addClassName("Selected");
121 e
.parentNode
.removeClassName("Selected");
124 selectActions: function (select
) {
125 $$("#filterDlg_Actions input[type=checkbox]").each(function (e
) {
129 e
.parentNode
.addClassName("Selected");
131 e
.parentNode
.removeClassName("Selected");
135 editRule: function (e
) {
136 const li
= e
.parentNode
;
137 const rule
= li
.getElementsByTagName("INPUT")[1].value
;
138 addFilterRule(li
, rule
);
140 editAction: function (e
) {
141 const li
= e
.parentNode
;
142 const action
= li
.getElementsByTagName("INPUT")[1].value
;
143 addFilterAction(li
, action
);
145 removeFilter: function () {
146 const msg
= __("Remove filter?");
151 notify_progress("Removing filter...");
153 const query
= { op
: "pref-filters", method
: "remove", ids
: this.attr('value').id
};
155 xhrPost("backend.php", query
, () => {
160 addAction: function () {
163 addRule: function () {
166 deleteAction: function () {
167 $$("#filterDlg_Actions li[class*=Selected]").each(function (e
) {
168 e
.parentNode
.removeChild(e
)
171 deleteRule: function () {
172 $$("#filterDlg_Matches li[class*=Selected]").each(function (e
) {
173 e
.parentNode
.removeChild(e
)
176 execute: function () {
177 if (this.validate()) {
179 notify_progress("Saving data...", true);
181 xhrPost("backend.php", dojo
.formToObject("filter_edit_form"), () => {
194 function getSelectedLabels() {
195 const tree
= dijit
.byId("labelTree");
196 const items
= tree
.model
.getCheckedItems();
199 items
.each(function(item
) {
200 rv
.push(tree
.model
.store
.getValue(item
, 'bare_id'));
206 function getSelectedUsers() {
207 return getSelectedTableRowIds("prefUserList");
210 function getSelectedFeeds() {
211 const tree
= dijit
.byId("feedTree");
212 const items
= tree
.model
.getCheckedItems();
215 items
.each(function(item
) {
216 if (item
.id
[0].match("FEED:"))
217 rv
.push(tree
.model
.store
.getValue(item
, 'bare_id'));
223 function getSelectedCategories() {
224 const tree
= dijit
.byId("feedTree");
225 const items
= tree
.model
.getCheckedItems();
228 items
.each(function(item
) {
229 if (item
.id
[0].match("CAT:"))
230 rv
.push(tree
.model
.store
.getValue(item
, 'bare_id'));
236 function getSelectedFilters() {
237 const tree
= dijit
.byId("filterTree");
238 const items
= tree
.model
.getCheckedItems();
241 items
.each(function(item
) {
242 rv
.push(tree
.model
.store
.getValue(item
, 'bare_id'));
249 function removeSelectedLabels() {
251 const sel_rows
= getSelectedLabels();
253 if (sel_rows
.length
> 0) {
255 const ok
= confirm(__("Remove selected labels?"));
258 notify_progress("Removing selected labels...");
260 const query
= { op
: "pref-labels", method
: "remove",
261 ids
: sel_rows
.toString() };
263 xhrPost("backend.php", query
, () => {
268 alert(__("No labels are selected."));
274 function removeSelectedUsers() {
276 const sel_rows
= getSelectedUsers();
278 if (sel_rows
.length
> 0) {
280 const ok
= confirm(__("Remove selected users? Neither default admin nor your account will be removed."));
283 notify_progress("Removing selected users...");
285 const query
= { op
: "pref-users", method
: "remove",
286 ids
: sel_rows
.toString() };
288 xhrPost("backend.php", query
, () => {
294 alert(__("No users are selected."));
300 function removeSelectedFilters() {
302 const sel_rows
= getSelectedFilters();
304 if (sel_rows
.length
> 0) {
306 const ok
= confirm(__("Remove selected filters?"));
309 notify_progress("Removing selected filters...");
311 const query
= { op
: "pref-filters", method
: "remove",
312 ids
: sel_rows
.toString() };
314 xhrPost("backend.php", query
, () => {
319 alert(__("No filters are selected."));
325 function removeSelectedFeeds() {
327 const sel_rows
= getSelectedFeeds();
329 if (sel_rows
.length
> 0) {
331 const ok
= confirm(__("Unsubscribe from selected feeds?"));
335 notify_progress("Unsubscribing from selected feeds...", true);
337 const query
= { op
: "pref-feeds", method
: "remove",
338 ids
: sel_rows
.toString() };
340 xhrPost("backend.php", query
, () => {
346 alert(__("No feeds are selected."));
352 function editSelectedUser() {
353 const rows
= getSelectedUsers();
355 if (rows
.length
== 0) {
356 alert(__("No users are selected."));
360 if (rows
.length
> 1) {
361 alert(__("Please select only one user."));
370 function resetSelectedUserPass() {
372 const rows
= getSelectedUsers();
374 if (rows
.length
== 0) {
375 alert(__("No users are selected."));
379 if (rows
.length
> 1) {
380 alert(__("Please select only one user."));
384 const ok
= confirm(__("Reset password of selected user?"));
387 notify_progress("Resetting password for selected user...");
391 xhrPost("backend.php", { op
: "pref-users", method
: "resetPass", id
: id
}, (transport
) => {
392 notify_info(transport
.responseText
, true);
398 function selectedUserDetails() {
400 const rows
= getSelectedUsers();
402 if (rows
.length
== 0) {
403 alert(__("No users are selected."));
407 if (rows
.length
> 1) {
408 alert(__("Please select only one user."));
412 const query
= "backend.php?op=pref-users&method=userdetails&id=" + param_escape(rows
[0]);
414 if (dijit
.byId("userDetailsDlg"))
415 dijit
.byId("userDetailsDlg").destroyRecursive();
417 const dialog
= new dijit
.Dialog({
418 id
: "userDetailsDlg",
419 title
: __("User details"),
420 style
: "width: 600px",
421 execute: function () {
431 function editSelectedFilter() {
432 const rows
= getSelectedFilters();
434 if (rows
.length
== 0) {
435 alert(__("No filters are selected."));
439 if (rows
.length
> 1) {
440 alert(__("Please select only one filter."));
450 function joinSelectedFilters() {
451 const rows
= getSelectedFilters();
453 if (rows
.length
== 0) {
454 alert(__("No filters are selected."));
458 const ok
= confirm(__("Combine selected filters?"));
461 notify_progress("Joining filters...");
463 xhrPost("backend.php", { op
: "pref-filters", method
: "join", ids
: rows
.toString() }, () => {
469 function editSelectedFeed() {
470 const rows
= getSelectedFeeds();
472 if (rows
.length
== 0) {
473 alert(__("No feeds are selected."));
477 if (rows
.length
> 1) {
478 return editSelectedFeeds();
483 editFeed(rows
[0], {});
487 function editSelectedFeeds() {
488 const rows
= getSelectedFeeds();
490 if (rows
.length
== 0) {
491 alert(__("No feeds are selected."));
495 notify_progress("Loading, please wait...");
497 const query
= "backend.php?op=pref-feeds&method=editfeeds&ids=" +
498 param_escape(rows
.toString());
502 if (dijit
.byId("feedEditDlg"))
503 dijit
.byId("feedEditDlg").destroyRecursive();
505 new Ajax
.Request("backend.php", {
507 onComplete: function (transport
) {
511 const dialog
= new dijit
.Dialog({
513 title
: __("Edit Multiple Feeds"),
514 style
: "width: 600px",
515 getChildByName: function (name
) {
517 this.getChildren().each(
519 if (child
.name
== name
) {
526 toggleField: function (checkbox
, elem
, label
) {
527 this.getChildByName(elem
).attr('disabled', !checkbox
.checked
);
530 if (checkbox
.checked
)
531 $(label
).removeClassName('insensitive');
533 $(label
).addClassName('insensitive');
536 execute: function () {
537 if (this.validate() && confirm(__("Save changes to selected feeds?"))) {
538 const query
= this.attr('value');
540 //console.log(query); return;
542 /* Form.serialize ignores unchecked checkboxes */
544 /*if (!query.match("&private=") &&
545 this.getChildByName('private').attr('disabled') == false) {
546 query.private = "false";
550 if (!query.match("&cache_images=") &&
551 this.getChildByName('cache_images').attr('disabled') == false) {
552 query.cache_images = "false";
558 if (!query.match("&hide_images=") &&
559 this.getChildByName('hide_images').attr('disabled') == false) {
560 query.hide_images = "false";
565 if (!query.match("&include_in_digest=") &&
566 this.getChildByName('include_in_digest').attr('disabled') == false) {
567 query.include_in_digest = "false";
570 if (!query.match("&always_display_enclosures=") &&
571 this.getChildByName('always_display_enclosures').attr('disabled') == false) {
572 query.always_display_enclosures = "false";
575 if (!query.match("&mark_unread_on_update=") &&
576 this.getChildByName('mark_unread_on_update').attr('disabled') == false) {
577 query.mark_unread_on_update = "false";
580 notify_progress("Saving data...", true);
582 xhrPost("backend.php", query
, () => {
588 content
: transport
.responseText
597 function opmlImportComplete(iframe
) {
598 if (!iframe
.contentDocument
.body
.innerHTML
) return false;
600 Element
.show(iframe
);
604 if (dijit
.byId('opmlImportDlg'))
605 dijit
.byId('opmlImportDlg').destroyRecursive();
607 const content
= iframe
.contentDocument
.body
.innerHTML
;
609 const dialog
= new dijit
.Dialog({
611 title
: __("OPML Import"),
612 style
: "width: 600px",
613 onCancel: function () {
614 window
.location
.reload();
616 execute: function () {
617 window
.location
.reload();
625 function opmlImport() {
627 const opml_file
= $("opml_file");
629 if (opml_file
.value
.length
== 0) {
630 alert(__("Please choose an OPML file first."));
633 notify_progress("Importing, please wait...", true);
635 Element
.show("upload_iframe");
642 function updateFilterList() {
643 const user_search
= $("filter_search");
645 if (user_search
) { search
= user_search
.value
; }
647 new Ajax
.Request("backend.php", {
648 parameters
: "?op=pref-filters&search=" + param_escape(search
),
649 onComplete: function(transport
) {
650 dijit
.byId('filterConfigTab').attr('content', transport
.responseText
);
655 function updateLabelList() {
656 new Ajax
.Request("backend.php", {
657 parameters
: "?op=pref-labels",
658 onComplete: function(transport
) {
659 dijit
.byId('labelConfigTab').attr('content', transport
.responseText
);
664 function updatePrefsList() {
665 new Ajax
.Request("backend.php", {
666 parameters
: "?op=pref-prefs",
667 onComplete: function(transport
) {
668 dijit
.byId('genConfigTab').attr('content', transport
.responseText
);
673 function updateSystemList() {
674 new Ajax
.Request("backend.php", {
675 parameters
: "?op=pref-system",
676 onComplete: function(transport
) {
677 dijit
.byId('systemConfigTab').attr('content', transport
.responseText
);
682 function selectTab(id
, noupdate
) {
684 notify_progress("Loading, please wait...");
686 if (id
== "feedConfig") {
688 } else if (id
== "filterConfig") {
690 } else if (id
== "labelConfig") {
692 } else if (id
== "genConfig") {
694 } else if (id
== "userConfig") {
696 } else if (id
== "systemConfig") {
700 const tab
= dijit
.byId(id
+ "Tab");
701 dijit
.byId("pref-tabs").selectChild(tab
);
706 function init_second_stage() {
707 document
.onkeydown
= pref_hotkey_handler
;
708 loading_set_progress(50);
711 let tab
= getURLParam('tab');
714 tab
= dijit
.byId(tab
+ "Tab");
715 if (tab
) dijit
.byId("pref-tabs").selectChild(tab
);
718 const method
= getURLParam('method');
720 if (method
== 'editFeed') {
721 const param
= getURLParam('methodparam');
723 window
.setTimeout(function() { editFeed(param
) }, 100);
726 setTimeout(hotkey_prefix_timeout
, 5*1000);
730 window
.onerror = function (message
, filename
, lineno
, colno
, error
) {
731 report_error(message
, filename
, lineno
, colno
, error
);
734 require(["dojo/_base/kernel",
739 "dijit/ColorPalette",
742 "dijit/form/CheckBox",
743 "dijit/form/DropDownButton",
744 "dijit/form/FilteringSelect",
745 "dijit/form/MultiSelect",
747 "dijit/form/RadioButton",
748 "dijit/form/ComboButton",
750 "dijit/form/SimpleTextarea",
751 "dijit/form/TextBox",
752 "dijit/form/ValidationTextBox",
753 "dijit/InlineEditBox",
754 "dijit/layout/AccordionContainer",
755 "dijit/layout/AccordionPane",
756 "dijit/layout/BorderContainer",
757 "dijit/layout/ContentPane",
758 "dijit/layout/TabContainer",
763 "dijit/tree/dndSource",
764 "dojo/data/ItemFileWriteStore",
765 "lib/CheckBoxStoreModel",
768 "fox/PrefFilterStore",
770 "fox/PrefFilterTree",
771 "fox/PrefLabelTree"], function (dojo
, ready
, parser
) {
777 loading_set_progress(50);
779 const clientTzOffset
= new Date().getTimezoneOffset() * 60;
781 new Ajax
.Request("backend.php", {
783 op
: "rpc", method
: "sanityCheck",
784 clientTzOffset
: clientTzOffset
786 onComplete: function (transport
) {
787 backend_sanity_check_callback(transport
);
798 function validatePrefsReset() {
799 const ok
= confirm(__("Reset to defaults?"));
803 const query
= "?op=pref-prefs&method=resetconfig";
806 new Ajax
.Request("backend.php", {
808 onComplete: function(transport
) {
810 notify_info(transport
.responseText
);
819 function pref_hotkey_handler(e
) {
821 if (e
.target
.nodeName
== "INPUT" || e
.target
.nodeName
== "TEXTAREA") return;
824 let shift_key
= false;
826 const cmdline
= $('cmdline');
829 shift_key
= e
.shiftKey
;
835 keycode
= window
.event
.keyCode
;
840 let keychar
= String
.fromCharCode(keycode
);
842 if (keycode
== 27) { // escape
843 hotkey_prefix
= false;
846 if (keycode
== 16) return; // ignore lone shift
847 if (keycode
== 17) return; // ignore lone ctrl
849 if (!shift_key
) keychar
= keychar
.toLowerCase();
851 var hotkeys
= getInitParam("hotkeys");
853 if (!hotkey_prefix
&& hotkeys
[0].indexOf(keychar
) != -1) {
855 const date
= new Date();
856 const ts
= Math
.round(date
.getTime() / 1000);
858 hotkey_prefix
= keychar
;
859 hotkey_prefix_pressed
= ts
;
861 cmdline
.innerHTML
= keychar
;
862 Element
.show(cmdline
);
867 Element
.hide(cmdline
);
869 let hotkey
= keychar
.search(/[a-zA-Z0-9]/) != -1 ? keychar
: "(" + keycode
+ ")";
870 hotkey
= hotkey_prefix
? hotkey_prefix
+ " " + hotkey
: hotkey
;
871 hotkey_prefix
= false;
873 let hotkey_action
= false;
874 var hotkeys
= getInitParam("hotkeys");
876 for (const sequence
in hotkeys
[1]) {
877 if (sequence
== hotkey
) {
878 hotkey_action
= hotkeys
[1][sequence
];
883 switch (hotkey_action
) {
884 case "feed_subscribe":
890 case "create_filter":
894 //helpDialog("prefs");
897 console
.log("unhandled action: " + hotkey_action
+ "; hotkey: " + hotkey
);
901 function removeCategory(id
, item
) {
903 const ok
= confirm(__("Remove category %s? Any nested feeds would be placed into Uncategorized.").replace("%s", item
.name
));
906 const query
= "?op=pref-feeds&method=removeCat&ids=" +
909 notify_progress("Removing category...");
911 new Ajax
.Request("backend.php", {
913 onComplete: function (transport
) {
921 function removeSelectedCategories() {
923 const sel_rows
= getSelectedCategories();
925 if (sel_rows
.length
> 0) {
927 const ok
= confirm(__("Remove selected categories?"));
930 notify_progress("Removing selected categories...");
932 const query
= "?op=pref-feeds&method=removeCat&ids="+
933 param_escape(sel_rows
.toString());
935 new Ajax
.Request("backend.php", {
937 onComplete: function(transport
) {
943 alert(__("No categories are selected."));
949 function createCategory() {
950 const title
= prompt(__("Category title:"));
954 notify_progress("Creating category...");
956 const query
= "?op=pref-feeds&method=addCat&cat=" +
959 new Ajax
.Request("backend.php", {
961 onComplete: function (transport
) {
969 function showInactiveFeeds() {
970 const query
= "backend.php?op=pref-feeds&method=inactiveFeeds";
972 if (dijit
.byId("inactiveFeedsDlg"))
973 dijit
.byId("inactiveFeedsDlg").destroyRecursive();
975 const dialog
= new dijit
.Dialog({
976 id
: "inactiveFeedsDlg",
977 title
: __("Feeds without recent updates"),
978 style
: "width: 600px",
979 getSelectedFeeds: function () {
980 return getSelectedTableRowIds("prefInactiveFeedList");
982 removeSelected: function () {
983 const sel_rows
= this.getSelectedFeeds();
985 console
.log(sel_rows
);
987 if (sel_rows
.length
> 0) {
988 const ok
= confirm(__("Remove selected feeds?"));
991 notify_progress("Removing selected feeds...", true);
993 const query
= "?op=pref-feeds&method=remove&ids=" +
994 param_escape(sel_rows
.toString());
996 new Ajax
.Request("backend.php", {
998 onComplete: function (transport
) {
1007 alert(__("No feeds are selected."));
1010 execute: function () {
1011 if (this.validate()) {
1020 function opmlRegenKey() {
1021 const ok
= confirm(__("Replace current OPML publishing address with a new one?"));
1025 notify_progress("Trying to change address...", true);
1027 const query
= "?op=pref-feeds&method=regenOPMLKey";
1029 new Ajax
.Request("backend.php", {
1031 onComplete: function (transport
) {
1032 const reply
= JSON
.parse(transport
.responseText
);
1034 const new_link
= reply
.link
;
1036 const e
= $('pub_opml_url');
1040 e
.innerHTML
= new_link
;
1042 new Effect
.Highlight(e
);
1047 notify_error("Could not change feed URL.");
1055 function labelColorReset() {
1056 const labels
= getSelectedLabels();
1058 if (labels
.length
> 0) {
1059 const ok
= confirm(__("Reset selected labels to default colors?"));
1062 const query
= "?op=pref-labels&method=colorreset&ids=" +
1063 param_escape(labels
.toString());
1065 new Ajax
.Request("backend.php", {
1067 onComplete: function (transport
) {
1074 alert(__("No labels are selected."));
1078 function inPreferences() {
1082 function editProfiles() {
1084 if (dijit
.byId("profileEditDlg"))
1085 dijit
.byId("profileEditDlg").destroyRecursive();
1087 const query
= "backend.php?op=pref-prefs&method=editPrefProfiles";
1089 const dialog
= new dijit
.Dialog({
1090 id
: "profileEditDlg",
1091 title
: __("Settings Profiles"),
1092 style
: "width: 600px",
1093 getSelectedProfiles: function () {
1094 return getSelectedTableRowIds("prefFeedProfileList");
1096 removeSelected: function () {
1097 const sel_rows
= this.getSelectedProfiles();
1099 if (sel_rows
.length
> 0) {
1100 const ok
= confirm(__("Remove selected profiles? Active and default profiles will not be removed."));
1103 notify_progress("Removing selected profiles...", true);
1105 const query
= { op
: "rpc", method
: "remprofiles",
1106 ids
: sel_rows
.toString() };
1108 xhrPost("backend.php", query
, () => {
1115 alert(__("No profiles are selected."));
1118 activateProfile: function () {
1119 const sel_rows
= this.getSelectedProfiles();
1121 if (sel_rows
.length
== 1) {
1123 const ok
= confirm(__("Activate selected profile?"));
1126 notify_progress("Loading, please wait...");
1128 xhrPost("backend.php", { op
: "rpc", method
: "setprofile", id
: sel_rows
.toString() }, () => {
1129 window
.location
.reload();
1134 alert(__("Please choose a profile to activate."));
1137 addProfile: function () {
1138 if (this.validate()) {
1139 notify_progress("Creating profile...", true);
1141 const query
= { op
: "rpc", method
: "addprofile", title
: dialog
.attr('value').newprofile
};
1143 xhrPost("backend.php", query
, () => {
1150 execute: function () {
1151 if (this.validate()) {
1161 function activatePrefProfile() {
1163 const sel_rows = getSelectedFeedCats();
1165 if (sel_rows.length == 1) {
1167 const ok = confirm(__("Activate selected profile?"));
1170 notify_progress("Loading, please wait...");
1172 xhrPost("backend.php", { op: "rpc", method: "setprofile", id: sel_rows.toString() }, () => {
1173 window.location.reload();
1178 alert(__("Please choose a profile to activate."));
1184 function clearFeedAccessKeys() {
1186 const ok
= confirm(__("This will invalidate all previously generated feed URLs. Continue?"));
1189 notify_progress("Clearing URLs...");
1191 xhrPost("backend.php", { op
: "pref-feeds", method
: "clearKeys" }, () => {
1192 notify_info("Generated URLs cleared.");
1199 function resetFilterOrder() {
1200 notify_progress("Loading, please wait...");
1202 xhrPost("backend.php", { op
: "pref-filters", method
: "filtersortreset" }, () => {
1208 function resetFeedOrder() {
1209 notify_progress("Loading, please wait...");
1211 xhrPost("backend.php", { op
: "pref-feeds", method
: "feedsortreset" }, () => {
1216 function resetCatOrder() {
1217 notify_progress("Loading, please wait...");
1219 xhrPost("backend.php", { op
: "pref-feeds", method
: "catsortreset" }, () => {
1224 function editCat(id
, item
) {
1225 const new_name
= prompt(__('Rename category to:'), item
.name
);
1227 if (new_name
&& new_name
!= item
.name
) {
1229 notify_progress("Loading, please wait...");
1231 xhrPost("backend.php", { op
: 'pref-feeds', method
: 'renamecat', id
: id
, title
: new_name
}, () => {
1237 function editLabel(id
) {
1238 const query
= "backend.php?op=pref-labels&method=edit&id=" +
1241 if (dijit
.byId("labelEditDlg"))
1242 dijit
.byId("labelEditDlg").destroyRecursive();
1244 const dialog
= new dijit
.Dialog({
1246 title
: __("Label Editor"),
1247 style
: "width: 600px",
1248 setLabelColor: function (id
, fg
, bg
) {
1263 const e
= $("LICID-" + id
);
1266 if (fg
) e
.style
.color
= fg
;
1267 if (bg
) e
.style
.backgroundColor
= bg
;
1270 const query
= { op
: "pref-labels", method
: "colorset", kind
: kind
,
1271 ids
: id
, fg
: fg
, bg
: bg
, color
: color
};
1273 xhrPost("backend.php", query
, () => {
1274 updateFilterList(); // maybe there's labels in there
1278 execute: function () {
1279 if (this.validate()) {
1280 const caption
= this.attr('value').caption
;
1281 const fg_color
= this.attr('value').fg_color
;
1282 const bg_color
= this.attr('value').bg_color
;
1284 dijit
.byId('labelTree').setNameById(id
, caption
);
1285 this.setLabelColor(id
, fg_color
, bg_color
);
1288 xhrPost("backend.php", this.attr('value'), () => {
1289 updateFilterList(); // maybe there's labels in there
1300 function customizeCSS() {
1301 const query
= "backend.php?op=pref-prefs&method=customizeCSS";
1303 if (dijit
.byId("cssEditDlg"))
1304 dijit
.byId("cssEditDlg").destroyRecursive();
1306 const dialog
= new dijit
.Dialog({
1308 title
: __("Customize stylesheet"),
1309 style
: "width: 600px",
1310 execute: function () {
1311 notify_progress('Saving data...', true);
1313 xhrPost("backend.php", this.attr('value'), () => {
1314 window
.location
.reload();
1324 function insertSSLserial(value
) {
1325 dijit
.byId("SSL_CERT_SERIAL").attr('value', value
);
1328 function gotoExportOpml(filename
, settings
) {
1329 const tmp
= settings
? 1 : 0;
1330 document
.location
.href
= "backend.php?op=opml&method=export&filename=" + filename
+ "&settings=" + tmp
;
1334 function batchSubscribe() {
1335 const query
= "backend.php?op=pref-feeds&method=batchSubscribe";
1337 // overlapping widgets
1338 if (dijit
.byId("batchSubDlg")) dijit
.byId("batchSubDlg").destroyRecursive();
1339 if (dijit
.byId("feedAddDlg")) dijit
.byId("feedAddDlg").destroyRecursive();
1341 const dialog
= new dijit
.Dialog({
1343 title
: __("Batch subscribe"),
1344 style
: "width: 600px",
1345 execute: function () {
1346 if (this.validate()) {
1347 notify_progress(__("Subscribing to feeds..."), true);
1349 xhrPost("backend.php", this.attr('value'), () => {
1362 function clearPluginData(name
) {
1363 if (confirm(__("Clear stored data for this plugin?"))) {
1364 notify_progress("Loading, please wait...");
1366 xhrPost("backend.php", { op
: "pref-prefs", method
: "clearplugindata", name
: name
}, () => {
1373 function clearSqlLog() {
1375 if (confirm(__("Clear all messages in the error log?"))) {
1377 notify_progress("Loading, please wait...");
1379 xhrPost("backend.php", { op
: "pref-system", method
: "clearLog" }, () => {
1386 function updateSelectedPrompt() {
1387 // no-op shim for toggleSelectedRow()