]>
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 /* normalize unchecked checkboxes because [] is not serialized */
542 Object
.keys(query
).each((key
) => {
543 let val
= query
[key
];
545 if (typeof val
== "object" && val
.length
== 0)
546 query
[key
] = ["off"];
549 notify_progress("Saving data...", true);
551 xhrPost("backend.php", query
, () => {
557 content
: transport
.responseText
566 function opmlImportComplete(iframe
) {
567 if (!iframe
.contentDocument
.body
.innerHTML
) return false;
569 Element
.show(iframe
);
573 if (dijit
.byId('opmlImportDlg'))
574 dijit
.byId('opmlImportDlg').destroyRecursive();
576 const content
= iframe
.contentDocument
.body
.innerHTML
;
578 const dialog
= new dijit
.Dialog({
580 title
: __("OPML Import"),
581 style
: "width: 600px",
582 onCancel: function () {
583 window
.location
.reload();
585 execute: function () {
586 window
.location
.reload();
594 function opmlImport() {
596 const opml_file
= $("opml_file");
598 if (opml_file
.value
.length
== 0) {
599 alert(__("Please choose an OPML file first."));
602 notify_progress("Importing, please wait...", true);
604 Element
.show("upload_iframe");
611 function updateFilterList() {
612 const user_search
= $("filter_search");
614 if (user_search
) { search
= user_search
.value
; }
616 new Ajax
.Request("backend.php", {
617 parameters
: "?op=pref-filters&search=" + param_escape(search
),
618 onComplete: function(transport
) {
619 dijit
.byId('filterConfigTab').attr('content', transport
.responseText
);
624 function updateLabelList() {
625 new Ajax
.Request("backend.php", {
626 parameters
: "?op=pref-labels",
627 onComplete: function(transport
) {
628 dijit
.byId('labelConfigTab').attr('content', transport
.responseText
);
633 function updatePrefsList() {
634 new Ajax
.Request("backend.php", {
635 parameters
: "?op=pref-prefs",
636 onComplete: function(transport
) {
637 dijit
.byId('genConfigTab').attr('content', transport
.responseText
);
642 function updateSystemList() {
643 new Ajax
.Request("backend.php", {
644 parameters
: "?op=pref-system",
645 onComplete: function(transport
) {
646 dijit
.byId('systemConfigTab').attr('content', transport
.responseText
);
651 function selectTab(id
, noupdate
) {
653 notify_progress("Loading, please wait...");
655 if (id
== "feedConfig") {
657 } else if (id
== "filterConfig") {
659 } else if (id
== "labelConfig") {
661 } else if (id
== "genConfig") {
663 } else if (id
== "userConfig") {
665 } else if (id
== "systemConfig") {
669 const tab
= dijit
.byId(id
+ "Tab");
670 dijit
.byId("pref-tabs").selectChild(tab
);
675 function init_second_stage() {
676 document
.onkeydown
= pref_hotkey_handler
;
677 loading_set_progress(50);
680 let tab
= getURLParam('tab');
683 tab
= dijit
.byId(tab
+ "Tab");
684 if (tab
) dijit
.byId("pref-tabs").selectChild(tab
);
687 const method
= getURLParam('method');
689 if (method
== 'editFeed') {
690 const param
= getURLParam('methodparam');
692 window
.setTimeout(function() { editFeed(param
) }, 100);
695 setTimeout(hotkey_prefix_timeout
, 5*1000);
699 window
.onerror = function (message
, filename
, lineno
, colno
, error
) {
700 report_error(message
, filename
, lineno
, colno
, error
);
703 require(["dojo/_base/kernel",
708 "dijit/ColorPalette",
711 "dijit/form/CheckBox",
712 "dijit/form/DropDownButton",
713 "dijit/form/FilteringSelect",
714 "dijit/form/MultiSelect",
716 "dijit/form/RadioButton",
717 "dijit/form/ComboButton",
719 "dijit/form/SimpleTextarea",
720 "dijit/form/TextBox",
721 "dijit/form/ValidationTextBox",
722 "dijit/InlineEditBox",
723 "dijit/layout/AccordionContainer",
724 "dijit/layout/AccordionPane",
725 "dijit/layout/BorderContainer",
726 "dijit/layout/ContentPane",
727 "dijit/layout/TabContainer",
732 "dijit/tree/dndSource",
733 "dojo/data/ItemFileWriteStore",
734 "lib/CheckBoxStoreModel",
737 "fox/PrefFilterStore",
739 "fox/PrefFilterTree",
740 "fox/PrefLabelTree"], function (dojo
, ready
, parser
) {
746 loading_set_progress(50);
748 const clientTzOffset
= new Date().getTimezoneOffset() * 60;
750 new Ajax
.Request("backend.php", {
752 op
: "rpc", method
: "sanityCheck",
753 clientTzOffset
: clientTzOffset
755 onComplete: function (transport
) {
756 backend_sanity_check_callback(transport
);
767 function validatePrefsReset() {
768 const ok
= confirm(__("Reset to defaults?"));
772 const query
= "?op=pref-prefs&method=resetconfig";
775 new Ajax
.Request("backend.php", {
777 onComplete: function(transport
) {
779 notify_info(transport
.responseText
);
788 function pref_hotkey_handler(e
) {
790 if (e
.target
.nodeName
== "INPUT" || e
.target
.nodeName
== "TEXTAREA") return;
793 let shift_key
= false;
795 const cmdline
= $('cmdline');
798 shift_key
= e
.shiftKey
;
804 keycode
= window
.event
.keyCode
;
809 let keychar
= String
.fromCharCode(keycode
);
811 if (keycode
== 27) { // escape
812 hotkey_prefix
= false;
815 if (keycode
== 16) return; // ignore lone shift
816 if (keycode
== 17) return; // ignore lone ctrl
818 if (!shift_key
) keychar
= keychar
.toLowerCase();
820 var hotkeys
= getInitParam("hotkeys");
822 if (!hotkey_prefix
&& hotkeys
[0].indexOf(keychar
) != -1) {
824 const date
= new Date();
825 const ts
= Math
.round(date
.getTime() / 1000);
827 hotkey_prefix
= keychar
;
828 hotkey_prefix_pressed
= ts
;
830 cmdline
.innerHTML
= keychar
;
831 Element
.show(cmdline
);
836 Element
.hide(cmdline
);
838 let hotkey
= keychar
.search(/[a-zA-Z0-9]/) != -1 ? keychar
: "(" + keycode
+ ")";
839 hotkey
= hotkey_prefix
? hotkey_prefix
+ " " + hotkey
: hotkey
;
840 hotkey_prefix
= false;
842 let hotkey_action
= false;
843 var hotkeys
= getInitParam("hotkeys");
845 for (const sequence
in hotkeys
[1]) {
846 if (sequence
== hotkey
) {
847 hotkey_action
= hotkeys
[1][sequence
];
852 switch (hotkey_action
) {
853 case "feed_subscribe":
859 case "create_filter":
863 //helpDialog("prefs");
866 console
.log("unhandled action: " + hotkey_action
+ "; hotkey: " + hotkey
);
870 function removeCategory(id
, item
) {
872 const ok
= confirm(__("Remove category %s? Any nested feeds would be placed into Uncategorized.").replace("%s", item
.name
));
875 const query
= "?op=pref-feeds&method=removeCat&ids=" +
878 notify_progress("Removing category...");
880 new Ajax
.Request("backend.php", {
882 onComplete: function (transport
) {
890 function removeSelectedCategories() {
892 const sel_rows
= getSelectedCategories();
894 if (sel_rows
.length
> 0) {
896 const ok
= confirm(__("Remove selected categories?"));
899 notify_progress("Removing selected categories...");
901 const query
= "?op=pref-feeds&method=removeCat&ids="+
902 param_escape(sel_rows
.toString());
904 new Ajax
.Request("backend.php", {
906 onComplete: function(transport
) {
912 alert(__("No categories are selected."));
918 function createCategory() {
919 const title
= prompt(__("Category title:"));
923 notify_progress("Creating category...");
925 const query
= "?op=pref-feeds&method=addCat&cat=" +
928 new Ajax
.Request("backend.php", {
930 onComplete: function (transport
) {
938 function showInactiveFeeds() {
939 const query
= "backend.php?op=pref-feeds&method=inactiveFeeds";
941 if (dijit
.byId("inactiveFeedsDlg"))
942 dijit
.byId("inactiveFeedsDlg").destroyRecursive();
944 const dialog
= new dijit
.Dialog({
945 id
: "inactiveFeedsDlg",
946 title
: __("Feeds without recent updates"),
947 style
: "width: 600px",
948 getSelectedFeeds: function () {
949 return getSelectedTableRowIds("prefInactiveFeedList");
951 removeSelected: function () {
952 const sel_rows
= this.getSelectedFeeds();
954 console
.log(sel_rows
);
956 if (sel_rows
.length
> 0) {
957 const ok
= confirm(__("Remove selected feeds?"));
960 notify_progress("Removing selected feeds...", true);
962 const query
= "?op=pref-feeds&method=remove&ids=" +
963 param_escape(sel_rows
.toString());
965 new Ajax
.Request("backend.php", {
967 onComplete: function (transport
) {
976 alert(__("No feeds are selected."));
979 execute: function () {
980 if (this.validate()) {
989 function opmlRegenKey() {
990 const ok
= confirm(__("Replace current OPML publishing address with a new one?"));
994 notify_progress("Trying to change address...", true);
996 const query
= "?op=pref-feeds&method=regenOPMLKey";
998 new Ajax
.Request("backend.php", {
1000 onComplete: function (transport
) {
1001 const reply
= JSON
.parse(transport
.responseText
);
1003 const new_link
= reply
.link
;
1005 const e
= $('pub_opml_url');
1009 e
.innerHTML
= new_link
;
1011 new Effect
.Highlight(e
);
1016 notify_error("Could not change feed URL.");
1024 function labelColorReset() {
1025 const labels
= getSelectedLabels();
1027 if (labels
.length
> 0) {
1028 const ok
= confirm(__("Reset selected labels to default colors?"));
1031 const query
= "?op=pref-labels&method=colorreset&ids=" +
1032 param_escape(labels
.toString());
1034 new Ajax
.Request("backend.php", {
1036 onComplete: function (transport
) {
1043 alert(__("No labels are selected."));
1047 function inPreferences() {
1051 function editProfiles() {
1053 if (dijit
.byId("profileEditDlg"))
1054 dijit
.byId("profileEditDlg").destroyRecursive();
1056 const query
= "backend.php?op=pref-prefs&method=editPrefProfiles";
1058 const dialog
= new dijit
.Dialog({
1059 id
: "profileEditDlg",
1060 title
: __("Settings Profiles"),
1061 style
: "width: 600px",
1062 getSelectedProfiles: function () {
1063 return getSelectedTableRowIds("prefFeedProfileList");
1065 removeSelected: function () {
1066 const sel_rows
= this.getSelectedProfiles();
1068 if (sel_rows
.length
> 0) {
1069 const ok
= confirm(__("Remove selected profiles? Active and default profiles will not be removed."));
1072 notify_progress("Removing selected profiles...", true);
1074 const query
= { op
: "rpc", method
: "remprofiles",
1075 ids
: sel_rows
.toString() };
1077 xhrPost("backend.php", query
, () => {
1084 alert(__("No profiles are selected."));
1087 activateProfile: function () {
1088 const sel_rows
= this.getSelectedProfiles();
1090 if (sel_rows
.length
== 1) {
1092 const ok
= confirm(__("Activate selected profile?"));
1095 notify_progress("Loading, please wait...");
1097 xhrPost("backend.php", { op
: "rpc", method
: "setprofile", id
: sel_rows
.toString() }, () => {
1098 window
.location
.reload();
1103 alert(__("Please choose a profile to activate."));
1106 addProfile: function () {
1107 if (this.validate()) {
1108 notify_progress("Creating profile...", true);
1110 const query
= { op
: "rpc", method
: "addprofile", title
: dialog
.attr('value').newprofile
};
1112 xhrPost("backend.php", query
, () => {
1119 execute: function () {
1120 if (this.validate()) {
1130 function activatePrefProfile() {
1132 const sel_rows = getSelectedFeedCats();
1134 if (sel_rows.length == 1) {
1136 const ok = confirm(__("Activate selected profile?"));
1139 notify_progress("Loading, please wait...");
1141 xhrPost("backend.php", { op: "rpc", method: "setprofile", id: sel_rows.toString() }, () => {
1142 window.location.reload();
1147 alert(__("Please choose a profile to activate."));
1153 function clearFeedAccessKeys() {
1155 const ok
= confirm(__("This will invalidate all previously generated feed URLs. Continue?"));
1158 notify_progress("Clearing URLs...");
1160 xhrPost("backend.php", { op
: "pref-feeds", method
: "clearKeys" }, () => {
1161 notify_info("Generated URLs cleared.");
1168 function resetFilterOrder() {
1169 notify_progress("Loading, please wait...");
1171 xhrPost("backend.php", { op
: "pref-filters", method
: "filtersortreset" }, () => {
1177 function resetFeedOrder() {
1178 notify_progress("Loading, please wait...");
1180 xhrPost("backend.php", { op
: "pref-feeds", method
: "feedsortreset" }, () => {
1185 function resetCatOrder() {
1186 notify_progress("Loading, please wait...");
1188 xhrPost("backend.php", { op
: "pref-feeds", method
: "catsortreset" }, () => {
1193 function editCat(id
, item
) {
1194 const new_name
= prompt(__('Rename category to:'), item
.name
);
1196 if (new_name
&& new_name
!= item
.name
) {
1198 notify_progress("Loading, please wait...");
1200 xhrPost("backend.php", { op
: 'pref-feeds', method
: 'renamecat', id
: id
, title
: new_name
}, () => {
1206 function editLabel(id
) {
1207 const query
= "backend.php?op=pref-labels&method=edit&id=" +
1210 if (dijit
.byId("labelEditDlg"))
1211 dijit
.byId("labelEditDlg").destroyRecursive();
1213 const dialog
= new dijit
.Dialog({
1215 title
: __("Label Editor"),
1216 style
: "width: 600px",
1217 setLabelColor: function (id
, fg
, bg
) {
1232 const e
= $("LICID-" + id
);
1235 if (fg
) e
.style
.color
= fg
;
1236 if (bg
) e
.style
.backgroundColor
= bg
;
1239 const query
= { op
: "pref-labels", method
: "colorset", kind
: kind
,
1240 ids
: id
, fg
: fg
, bg
: bg
, color
: color
};
1242 xhrPost("backend.php", query
, () => {
1243 updateFilterList(); // maybe there's labels in there
1247 execute: function () {
1248 if (this.validate()) {
1249 const caption
= this.attr('value').caption
;
1250 const fg_color
= this.attr('value').fg_color
;
1251 const bg_color
= this.attr('value').bg_color
;
1253 dijit
.byId('labelTree').setNameById(id
, caption
);
1254 this.setLabelColor(id
, fg_color
, bg_color
);
1257 xhrPost("backend.php", this.attr('value'), () => {
1258 updateFilterList(); // maybe there's labels in there
1269 function customizeCSS() {
1270 const query
= "backend.php?op=pref-prefs&method=customizeCSS";
1272 if (dijit
.byId("cssEditDlg"))
1273 dijit
.byId("cssEditDlg").destroyRecursive();
1275 const dialog
= new dijit
.Dialog({
1277 title
: __("Customize stylesheet"),
1278 style
: "width: 600px",
1279 execute: function () {
1280 notify_progress('Saving data...', true);
1282 xhrPost("backend.php", this.attr('value'), () => {
1283 window
.location
.reload();
1293 function insertSSLserial(value
) {
1294 dijit
.byId("SSL_CERT_SERIAL").attr('value', value
);
1297 function gotoExportOpml(filename
, settings
) {
1298 const tmp
= settings
? 1 : 0;
1299 document
.location
.href
= "backend.php?op=opml&method=export&filename=" + filename
+ "&settings=" + tmp
;
1303 function batchSubscribe() {
1304 const query
= "backend.php?op=pref-feeds&method=batchSubscribe";
1306 // overlapping widgets
1307 if (dijit
.byId("batchSubDlg")) dijit
.byId("batchSubDlg").destroyRecursive();
1308 if (dijit
.byId("feedAddDlg")) dijit
.byId("feedAddDlg").destroyRecursive();
1310 const dialog
= new dijit
.Dialog({
1312 title
: __("Batch subscribe"),
1313 style
: "width: 600px",
1314 execute: function () {
1315 if (this.validate()) {
1316 notify_progress(__("Subscribing to feeds..."), true);
1318 xhrPost("backend.php", this.attr('value'), () => {
1331 function clearPluginData(name
) {
1332 if (confirm(__("Clear stored data for this plugin?"))) {
1333 notify_progress("Loading, please wait...");
1335 xhrPost("backend.php", { op
: "pref-prefs", method
: "clearplugindata", name
: name
}, () => {
1342 function clearSqlLog() {
1344 if (confirm(__("Clear all messages in the error log?"))) {
1346 notify_progress("Loading, please wait...");
1348 xhrPost("backend.php", { op
: "pref-system", method
: "clearLog" }, () => {
1355 function updateSelectedPrompt() {
1356 // no-op shim for toggleSelectedRow()