]> git.wh0rd.org - tt-rss.git/blame - js/prefs.js
remove ok = confirm() thing
[tt-rss.git] / js / prefs.js
CommitLineData
4508e310
AD
1/* global dijit, __ */
2
8572e010 3let seq = "";
a998dbef 4
66665fba
AD
5function notify_callback2(transport, sticky) {
6 notify_info(transport.responseText, sticky);
60715b53
AD
7}
8
05185108 9function updateFeedList() {
16270276 10
424e28db
AD
11 const user_search = $("feed_search");
12 let search = "";
16270276
AD
13 if (user_search) { search = user_search.value; }
14
ef129fed
AD
15 xhrPost("backend.php", { op: "pref-feeds", search: search }, (transport) => {
16 dijit.byId('feedConfigTab').attr('content', transport.responseText);
17 selectTab("feedConfig", true);
18 notify("");
19 });
007bda35
AD
20}
21
f9c1f8b0 22function checkInactiveFeeds() {
ef129fed
AD
23 xhrPost("backend.php", { op: "pref-feeds", method: "getinactivefeeds" }, (transport) => {
24 if (parseInt(transport.responseText) > 0) {
25 Element.show(dijit.byId("pref_feeds_inactive_btn").domNode);
1bfe1d7b
AD
26 }
27 });
f9c1f8b0 28}
373266eb 29
79ec0f2f 30function updateUsersList(sort_key) {
424e28db 31 const user_search = $("user_search");
ef129fed 32 const search = user_search ? user_search.value : "";
fb5662de 33
ef129fed 34 const query = { op: "pref-users", sort: sort_key, search: search };
e6cb77a0 35
ef129fed
AD
36 xhrPost("backend.php", query, (transport) => {
37 dijit.byId('userConfigTab').attr('content', transport.responseText);
38 selectTab("userConfig", true)
39 notify("");
1bfe1d7b 40 });
e6cb77a0
AD
41}
42
e6cb77a0 43function addUser() {
424e28db 44 const login = prompt(__("Please enter login:"), "");
e6cb77a0 45
1bfe1d7b
AD
46 if (login == null) {
47 return false;
48 }
fb5662de 49
1bfe1d7b
AD
50 if (login == "") {
51 alert(__("Can't create user: no login specified."));
52 return false;
53 }
fb5662de 54
1bfe1d7b 55 notify_progress("Adding user...");
fb5662de 56
ef129fed
AD
57 xhrPost("backend.php", { op: "pref-users", method: "add", login: login }, (transport) => {
58 notify_callback2(transport);
59 updateUsersList();
60 });
e6cb77a0 61
e6cb77a0
AD
62}
63
05185108 64function editUser(id) {
e6cb77a0 65
424e28db 66 const query = "backend.php?op=pref-users&method=edit&id=" +
1bfe1d7b 67 param_escape(id);
222a61c2 68
1bfe1d7b
AD
69 if (dijit.byId("userEditDlg"))
70 dijit.byId("userEditDlg").destroyRecursive();
222a61c2 71
9dc5524d 72 const dialog = new dijit.Dialog({
1bfe1d7b
AD
73 id: "userEditDlg",
74 title: __("User Editor"),
75 style: "width: 600px",
76 execute: function () {
77 if (this.validate()) {
78 notify_progress("Saving data...", true);
222a61c2 79
ef129fed
AD
80 xhrPost("backend.php", dojo.formToObject("user_edit_form"), (transport) => {
81 dialog.hide();
82 updateUsersList();
83 });
1bfe1d7b
AD
84 }
85 },
86 href: query
87 });
fb5662de 88
1bfe1d7b 89 dialog.show();
e6cb77a0
AD
90}
91
261226a3 92function editFilter(id) {
261226a3 93
424e28db 94 const query = "backend.php?op=pref-filters&method=edit&id=" + param_escape(id);
261226a3 95
1bfe1d7b
AD
96 if (dijit.byId("feedEditDlg"))
97 dijit.byId("feedEditDlg").destroyRecursive();
261226a3 98
1bfe1d7b
AD
99 if (dijit.byId("filterEditDlg"))
100 dijit.byId("filterEditDlg").destroyRecursive();
ec630524 101
9dc5524d 102 const dialog = new dijit.Dialog({
1bfe1d7b
AD
103 id: "filterEditDlg",
104 title: __("Edit Filter"),
105 style: "width: 600px",
ec630524 106
1bfe1d7b 107 test: function () {
424e28db 108 const query = "backend.php?" + dojo.formToQuery("filter_edit_form") + "&savemode=test";
fb5662de 109
1bfe1d7b
AD
110 editFilterTest(query);
111 },
112 selectRules: function (select) {
113 $$("#filterDlg_Matches input[type=checkbox]").each(function (e) {
114 e.checked = select;
115 if (select)
116 e.parentNode.addClassName("Selected");
117 else
118 e.parentNode.removeClassName("Selected");
119 });
120 },
121 selectActions: function (select) {
122 $$("#filterDlg_Actions input[type=checkbox]").each(function (e) {
123 e.checked = select;
90e4e726 124
1bfe1d7b
AD
125 if (select)
126 e.parentNode.addClassName("Selected");
127 else
128 e.parentNode.removeClassName("Selected");
fb5662de 129
1bfe1d7b
AD
130 });
131 },
132 editRule: function (e) {
424e28db
AD
133 const li = e.parentNode;
134 const rule = li.getElementsByTagName("INPUT")[1].value;
1bfe1d7b
AD
135 addFilterRule(li, rule);
136 },
137 editAction: function (e) {
424e28db
AD
138 const li = e.parentNode;
139 const action = li.getElementsByTagName("INPUT")[1].value;
1bfe1d7b
AD
140 addFilterAction(li, action);
141 },
142 removeFilter: function () {
424e28db 143 const msg = __("Remove filter?");
1bfe1d7b
AD
144
145 if (confirm(msg)) {
146 this.hide();
90e4e726 147
1bfe1d7b 148 notify_progress("Removing filter...");
90e4e726 149
ef129fed 150 const query = { op: "pref-filters", method: "remove", ids: this.attr('value').id };
141fb6e3 151
ef129fed
AD
152 xhrPost("backend.php", query, () => {
153 updateFilterList();
1bfe1d7b
AD
154 });
155 }
156 },
157 addAction: function () {
158 addFilterAction();
159 },
160 addRule: function () {
161 addFilterRule();
162 },
163 deleteAction: function () {
164 $$("#filterDlg_Actions li[class*=Selected]").each(function (e) {
165 e.parentNode.removeChild(e)
166 });
167 },
168 deleteRule: function () {
169 $$("#filterDlg_Matches li[class*=Selected]").each(function (e) {
170 e.parentNode.removeChild(e)
171 });
172 },
173 execute: function () {
174 if (this.validate()) {
141fb6e3 175
1bfe1d7b 176 notify_progress("Saving data...", true);
6aff7845 177
ef129fed
AD
178 xhrPost("backend.php", dojo.formToObject("filter_edit_form"), () => {
179 dialog.hide();
180 updateFilterList();
1bfe1d7b
AD
181 });
182 }
183 },
184 href: query
185 });
a0d53889 186
1bfe1d7b 187 dialog.show();
a0d53889
AD
188}
189
1bfe1d7b 190
91ff844a 191function getSelectedLabels() {
424e28db
AD
192 const tree = dijit.byId("labelTree");
193 const items = tree.model.getCheckedItems();
194 const rv = [];
fb8b2153
AD
195
196 items.each(function(item) {
197 rv.push(tree.model.store.getValue(item, 'bare_id'));
198 });
199
200 return rv;
91ff844a 201}
48f0adb0 202
91ff844a 203function getSelectedUsers() {
e69fb880 204 return getSelectedTableRowIds("prefUserList");
a0d53889
AD
205}
206
83fe4d6d 207function getSelectedFeeds() {
424e28db
AD
208 const tree = dijit.byId("feedTree");
209 const items = tree.model.getCheckedItems();
210 const rv = [];
1985a5e0
AD
211
212 items.each(function(item) {
7c227bb3
AD
213 if (item.id[0].match("FEED:"))
214 rv.push(tree.model.store.getValue(item, 'bare_id'));
1985a5e0
AD
215 });
216
217 return rv;
91ff844a 218}
331900c6 219
fd26d5bf 220function getSelectedCategories() {
424e28db
AD
221 const tree = dijit.byId("feedTree");
222 const items = tree.model.getCheckedItems();
223 const rv = [];
fd26d5bf
AD
224
225 items.each(function(item) {
226 if (item.id[0].match("CAT:"))
227 rv.push(tree.model.store.getValue(item, 'bare_id'));
228 });
229
230 return rv;
231}
232
91ff844a 233function getSelectedFilters() {
424e28db
AD
234 const tree = dijit.byId("filterTree");
235 const items = tree.model.getCheckedItems();
236 const rv = [];
a740f4b5
AD
237
238 items.each(function(item) {
239 rv.push(tree.model.store.getValue(item, 'bare_id'));
240 });
241
242 return rv;
243
91ff844a 244}
331900c6 245
48f0adb0
AD
246function removeSelectedLabels() {
247
424e28db 248 const sel_rows = getSelectedLabels();
48f0adb0
AD
249
250 if (sel_rows.length > 0) {
da1a3c2c 251 if (confirm(__("Remove selected labels?"))) {
42c32916 252 notify_progress("Removing selected labels...");
fb5662de 253
ef129fed
AD
254 const query = { op: "pref-labels", method: "remove",
255 ids: sel_rows.toString() };
a796bfc1 256
ef129fed
AD
257 xhrPost("backend.php", query, () => {
258 updateLabelList();
259 });
69668465 260 }
48f0adb0 261 } else {
89cb787e 262 alert(__("No labels are selected."));
48f0adb0 263 }
90ac84df
AD
264
265 return false;
48f0adb0
AD
266}
267
e6cb77a0
AD
268function removeSelectedUsers() {
269
424e28db 270 const sel_rows = getSelectedUsers();
fb5662de 271
1bfe1d7b 272 if (sel_rows.length > 0) {
fb5662de 273
da1a3c2c 274 if (confirm(__("Remove selected users? Neither default admin nor your account will be removed."))) {
1bfe1d7b 275 notify_progress("Removing selected users...");
fb5662de 276
ef129fed
AD
277 const query = { op: "pref-users", method: "remove",
278 ids: sel_rows.toString() };
fb5662de 279
ef129fed
AD
280 xhrPost("backend.php", query, () => {
281 updateUsersList();
1bfe1d7b 282 });
69668465 283 }
e6cb77a0 284
1bfe1d7b
AD
285 } else {
286 alert(__("No users are selected."));
e6cb77a0 287 }
90ac84df
AD
288
289 return false;
e6cb77a0
AD
290}
291
48f0adb0
AD
292function removeSelectedFilters() {
293
424e28db 294 const sel_rows = getSelectedFilters();
fb5662de 295
1bfe1d7b 296 if (sel_rows.length > 0) {
da1a3c2c 297 if (confirm(__("Remove selected filters?"))) {
1bfe1d7b 298 notify_progress("Removing selected filters...");
fb5662de 299
ef129fed
AD
300 const query = { op: "pref-filters", method: "remove",
301 ids: sel_rows.toString() };
fb5662de 302
ef129fed
AD
303 xhrPost("backend.php", query, () => {
304 updateFilterList();
1bfe1d7b 305 });
69668465 306 }
1bfe1d7b
AD
307 } else {
308 alert(__("No filters are selected."));
48f0adb0 309 }
90ac84df
AD
310
311 return false;
48f0adb0
AD
312}
313
83fe4d6d
AD
314function removeSelectedFeeds() {
315
424e28db 316 const sel_rows = getSelectedFeeds();
fb5662de 317
1bfe1d7b 318 if (sel_rows.length > 0) {
da1a3c2c 319 if (confirm(__("Unsubscribe from selected feeds?"))) {
fb5662de 320
1bfe1d7b 321 notify_progress("Unsubscribing from selected feeds...", true);
b6a6e262 322
ef129fed
AD
323 const query = { op: "pref-feeds", method: "remove",
324 ids: sel_rows.toString() };
fb5662de 325
ef129fed
AD
326 xhrPost("backend.php", query, () => {
327 updateFeedList();
1bfe1d7b 328 });
69668465 329 }
71ad3959 330
1bfe1d7b
AD
331 } else {
332 alert(__("No feeds are selected."));
71ad3959 333 }
fb5662de 334
90ac84df 335 return false;
71ad3959 336}
007bda35 337
e6cb77a0 338function editSelectedUser() {
424e28db 339 const rows = getSelectedUsers();
e6cb77a0
AD
340
341 if (rows.length == 0) {
f3977cf5 342 alert(__("No users are selected."));
e6cb77a0
AD
343 return;
344 }
345
346 if (rows.length > 1) {
f3977cf5 347 alert(__("Please select only one user."));
e6cb77a0
AD
348 return;
349 }
350
dbd9e2f1
AD
351 notify("");
352
e6cb77a0
AD
353 editUser(rows[0]);
354}
355
356function resetSelectedUserPass() {
e6cb77a0 357
424e28db 358 const rows = getSelectedUsers();
fb5662de 359
1bfe1d7b
AD
360 if (rows.length == 0) {
361 alert(__("No users are selected."));
362 return;
363 }
fb5662de 364
1bfe1d7b
AD
365 if (rows.length > 1) {
366 alert(__("Please select only one user."));
367 return;
368 }
fb5662de 369
da1a3c2c 370 if (confirm(__("Reset password of selected user?"))) {
1bfe1d7b 371 notify_progress("Resetting password for selected user...");
fb5662de 372
424e28db 373 const id = rows[0];
fb5662de 374
ef129fed
AD
375 xhrPost("backend.php", { op: "pref-users", method: "resetPass", id: id }, (transport) => {
376 notify_info(transport.responseText, true);
1bfe1d7b 377 });
fbf7d545 378
69668465 379 }
e6cb77a0
AD
380}
381
717f5e64 382function selectedUserDetails() {
e6cb77a0 383
424e28db 384 const rows = getSelectedUsers();
fb5662de 385
1bfe1d7b
AD
386 if (rows.length == 0) {
387 alert(__("No users are selected."));
388 return;
389 }
fb5662de 390
1bfe1d7b
AD
391 if (rows.length > 1) {
392 alert(__("Please select only one user."));
393 return;
394 }
fb5662de 395
ef129fed 396 const query = "backend.php?op=pref-users&method=userdetails&id=" + param_escape(rows[0]);
d9afd9b2 397
1bfe1d7b
AD
398 if (dijit.byId("userDetailsDlg"))
399 dijit.byId("userDetailsDlg").destroyRecursive();
d9afd9b2 400
9dc5524d 401 const dialog = new dijit.Dialog({
1bfe1d7b
AD
402 id: "userDetailsDlg",
403 title: __("User details"),
404 style: "width: 600px",
405 execute: function () {
406 dialog.hide();
407 },
408 href: query
409 });
717f5e64 410
1bfe1d7b 411 dialog.show();
c6c3a07f
AD
412}
413
a0d53889
AD
414
415function editSelectedFilter() {
424e28db 416 const rows = getSelectedFilters();
a0d53889
AD
417
418 if (rows.length == 0) {
f3977cf5 419 alert(__("No filters are selected."));
a0d53889
AD
420 return;
421 }
422
423 if (rows.length > 1) {
f3977cf5 424 alert(__("Please select only one filter."));
a0d53889
AD
425 return;
426 }
427
dbd9e2f1
AD
428 notify("");
429
a0d53889
AD
430 editFilter(rows[0]);
431
432}
433
6aff7845 434function joinSelectedFilters() {
424e28db 435 const rows = getSelectedFilters();
6aff7845
AD
436
437 if (rows.length == 0) {
438 alert(__("No filters are selected."));
439 return;
440 }
441
da1a3c2c 442 if (confirm(__("Combine selected filters?"))) {
6aff7845
AD
443 notify_progress("Joining filters...");
444
ef129fed
AD
445 xhrPost("backend.php", { op: "pref-filters", method: "join", ids: rows.toString() }, () => {
446 updateFilterList();
447 });
6aff7845
AD
448 }
449}
a0d53889 450
508a81e1 451function editSelectedFeed() {
424e28db 452 const rows = getSelectedFeeds();
508a81e1
AD
453
454 if (rows.length == 0) {
f3977cf5 455 alert(__("No feeds are selected."));
508a81e1
AD
456 return;
457 }
458
459 if (rows.length > 1) {
1e5548db 460 return editSelectedFeeds();
508a81e1
AD
461 }
462
dbd9e2f1
AD
463 notify("");
464
951906dc 465 editFeed(rows[0], {});
91ff844a
AD
466
467}
468
758e1c4a 469function editSelectedFeeds() {
424e28db 470 const rows = getSelectedFeeds();
758e1c4a 471
1bfe1d7b
AD
472 if (rows.length == 0) {
473 alert(__("No feeds are selected."));
474 return;
475 }
05acc0d6 476
1bfe1d7b 477 notify_progress("Loading, please wait...");
05acc0d6 478
1bfe1d7b
AD
479 if (dijit.byId("feedEditDlg"))
480 dijit.byId("feedEditDlg").destroyRecursive();
755c8f95 481
7e8be97b
AD
482 xhrPost("backend.php", { op: "pref-feeds", method: "editfeeds", ids: rows.toString() }, (transport) => {
483 notify("");
758e1c4a 484
7e8be97b
AD
485 const dialog = new dijit.Dialog({
486 id: "feedEditDlg",
487 title: __("Edit Multiple Feeds"),
488 style: "width: 600px",
489 getChildByName: function (name) {
490 let rv = null;
491 this.getChildren().each(
492 function (child) {
493 if (child.name == name) {
494 rv = child;
495 return;
496 }
497 });
498 return rv;
499 },
500 toggleField: function (checkbox, elem, label) {
501 this.getChildByName(elem).attr('disabled', !checkbox.checked);
502
503 if ($(label))
504 if (checkbox.checked)
505 $(label).removeClassName('insensitive');
506 else
507 $(label).addClassName('insensitive');
508
509 },
510 execute: function () {
511 if (this.validate() && confirm(__("Save changes to selected feeds?"))) {
512 const query = this.attr('value');
513
514 /* normalize unchecked checkboxes because [] is not serialized */
515
516 Object.keys(query).each((key) => {
517 let val = query[key];
518
519 if (typeof val == "object" && val.length == 0)
520 query[key] = ["off"];
521 });
522
523 notify_progress("Saving data...", true);
524
525 xhrPost("backend.php", query, () => {
526 dialog.hide();
527 updateFeedList();
528 });
529 }
530 },
531 content: transport.responseText
532 });
e1218480 533
7e8be97b 534 dialog.show();
1bfe1d7b
AD
535 });
536}
e1218480 537
1bfe1d7b
AD
538function opmlImportComplete(iframe) {
539 if (!iframe.contentDocument.body.innerHTML) return false;
540
541 Element.show(iframe);
542
543 notify('');
544
545 if (dijit.byId('opmlImportDlg'))
546 dijit.byId('opmlImportDlg').destroyRecursive();
547
424e28db 548 const content = iframe.contentDocument.body.innerHTML;
1bfe1d7b 549
424e28db 550 const dialog = new dijit.Dialog({
1bfe1d7b
AD
551 id: "opmlImportDlg",
552 title: __("OPML Import"),
553 style: "width: 600px",
554 onCancel: function () {
12b7b90c 555 window.location.reload();
1bfe1d7b
AD
556 },
557 execute: function () {
12b7b90c 558 window.location.reload();
1bfe1d7b
AD
559 },
560 content: content
561 });
e1218480 562
1bfe1d7b 563 dialog.show();
e1218480
AD
564}
565
b6a6e262 566function opmlImport() {
fb5662de 567
424e28db 568 const opml_file = $("opml_file");
9f311df6
AD
569
570 if (opml_file.value.length == 0) {
d2d75353 571 alert(__("Please choose an OPML file first."));
9f311df6
AD
572 return false;
573 } else {
4d7cd9ed 574 notify_progress("Importing, please wait...", true);
55f34b81
AD
575
576 Element.show("upload_iframe");
577
9f311df6
AD
578 return true;
579 }
580}
581
55f34b81 582
05acc0d6 583function updateFilterList() {
424e28db
AD
584 const user_search = $("filter_search");
585 let search = "";
310fa2dd
AD
586 if (user_search) { search = user_search.value; }
587
7e8be97b
AD
588 xhrPost("backend.php", { op: "pref-filters", search: search }, (transport) => {
589 dijit.byId('filterConfigTab').attr('content', transport.responseText);
590 notify("");
591 });
a0d53889
AD
592}
593
05acc0d6 594function updateLabelList() {
7e8be97b
AD
595 xhrPost("backend.php", { op: "pref-labels" }, (transport) => {
596 dijit.byId('labelConfigTab').attr('content', transport.responseText);
597 notify("");
598 });
48f0adb0
AD
599}
600
4255b24c 601function updatePrefsList() {
7e8be97b
AD
602 xhrPost("backend.php", { op: "pref-prefs" }, (transport) => {
603 dijit.byId('genConfigTab').attr('content', transport.responseText);
604 notify("");
605 });
4255b24c
AD
606}
607
2cbdc95b 608function updateSystemList() {
7e8be97b
AD
609 xhrPost("backend.php", { op: "pref-system" }, (transport) => {
610 dijit.byId('systemConfigTab').attr('content', transport.responseText);
611 notify("");
612 });
2cbdc95b
AD
613}
614
05185108 615function selectTab(id, noupdate) {
1bfe1d7b
AD
616 if (!noupdate) {
617 notify_progress("Loading, please wait...");
d62796de 618
7e8be97b
AD
619 switch (id) {
620 case "feedConfig":
621 updateFeedList();
622 break;
623 case "filterConfig":
624 updateFilterList();
625 break;
626 case "labelConfig":
627 updateLabelList();
628 break;
629 case "genConfig":
630 updatePrefsList();
631 break;
632 case "userConfig":
633 updateUsersList();
634 break;
635 case "systemConfig":
636 updateSystemList();
637 break;
638 default:
639 console.warn("unknown tab", id);
f5a50b25 640 }
fb5662de 641
424e28db 642 const tab = dijit.byId(id + "Tab");
1bfe1d7b
AD
643 dijit.byId("pref-tabs").selectChild(tab);
644
a7565293 645 }
a7565293
AD
646}
647
a7565293 648function init_second_stage() {
1bfe1d7b
AD
649 document.onkeydown = pref_hotkey_handler;
650 loading_set_progress(50);
651 notify("");
b01b1b38 652
424e28db 653 let tab = getURLParam('tab');
b01b1b38 654
1bfe1d7b
AD
655 if (tab) {
656 tab = dijit.byId(tab + "Tab");
657 if (tab) dijit.byId("pref-tabs").selectChild(tab);
658 }
b01b1b38 659
424e28db 660 const method = getURLParam('method');
556e5b46 661
1bfe1d7b 662 if (method == 'editFeed') {
424e28db 663 const param = getURLParam('methodparam');
78935092 664
1bfe1d7b 665 window.setTimeout(function() { editFeed(param) }, 100);
b2caf812 666 }
1bfe1d7b 667
7e8be97b 668 setInterval(hotkey_prefix_timeout, 5*1000);
a0d53889
AD
669}
670
007bda35 671function init() {
1bfe1d7b
AD
672 window.onerror = function (message, filename, lineno, colno, error) {
673 report_error(message, filename, lineno, colno, error);
674 };
675
676 require(["dojo/_base/kernel",
677 "dojo/ready",
678 "dojo/parser",
679 "dojo/_base/loader",
680 "dojo/_base/html",
681 "dijit/ColorPalette",
682 "dijit/Dialog",
683 "dijit/form/Button",
684 "dijit/form/CheckBox",
685 "dijit/form/DropDownButton",
686 "dijit/form/FilteringSelect",
12b7b90c 687 "dijit/form/MultiSelect",
1bfe1d7b
AD
688 "dijit/form/Form",
689 "dijit/form/RadioButton",
690 "dijit/form/ComboButton",
691 "dijit/form/Select",
692 "dijit/form/SimpleTextarea",
693 "dijit/form/TextBox",
694 "dijit/form/ValidationTextBox",
695 "dijit/InlineEditBox",
696 "dijit/layout/AccordionContainer",
697 "dijit/layout/AccordionPane",
698 "dijit/layout/BorderContainer",
699 "dijit/layout/ContentPane",
700 "dijit/layout/TabContainer",
701 "dijit/Menu",
702 "dijit/ProgressBar",
703 "dijit/Toolbar",
704 "dijit/Tree",
705 "dijit/tree/dndSource",
706 "dojo/data/ItemFileWriteStore",
a3e2f1a9
AD
707 "lib/CheckBoxStoreModel",
708 "lib/CheckBoxTree",
709 "fox/PrefFeedStore",
710 "fox/PrefFilterStore",
1bfe1d7b
AD
711 "fox/PrefFeedTree",
712 "fox/PrefFilterTree",
713 "fox/PrefLabelTree"], function (dojo, ready, parser) {
714
715 ready(function () {
716 try {
717 parser.parse();
718
719 loading_set_progress(50);
720
424e28db 721 const clientTzOffset = new Date().getTimezoneOffset() * 60;
fd752a79 722 const params = { op: "rpc", method: "sanityCheck", clientTzOffset: clientTzOffset };
e2ec66a8 723
fd752a79
AD
724 xhrPost("backend.php", params, (transport) => {
725 backend_sanity_check_callback(transport);
fd539f28 726 });
fd752a79 727
1bfe1d7b
AD
728 } catch (e) {
729 exception_error(e);
730 }
731 });
732 });
007bda35 733}
b1895692 734
b652c1b7 735
1bfe1d7b 736function validatePrefsReset() {
7e8be97b 737 if (confirm(__("Reset to defaults?"))) {
b652c1b7 738
424e28db 739 const query = "?op=pref-prefs&method=resetconfig";
b652c1b7 740
7e8be97b
AD
741 xhrPost("backend.php", { op: "pref-prefs", method: "resetconfig" }, (transport) => {
742 updatePrefsList();
743 notify_info(transport.responseText);
744 });
b652c1b7
AD
745 }
746
747 return false;
69668465 748}
f9cb39ac 749
d437c8cf 750function pref_hotkey_handler(e) {
7e8be97b
AD
751 if (e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA") return;
752
753 const action_name = keyevent_to_action(e);
754
755 if (action_name) {
756 switch (action_name) {
757 case "feed_subscribe":
758 quickAddFeed();
759 return false;
760 case "create_label":
761 addLabel();
762 return false;
763 case "create_filter":
764 quickAddFilter();
765 return false;
766 case "help_dialog":
767 helpDialog("main");
768 return false;
769 default:
770 console.log("unhandled action: " + action_name + "; keycode: " + e.which);
771 }
d437c8cf
AD
772 }
773}
774
5ef071e0 775function removeCategory(id, item) {
350468d0 776
fd752a79 777 if (confirm(__("Remove category %s? Any nested feeds would be placed into Uncategorized.").replace("%s", item.name))) {
1bfe1d7b 778 notify_progress("Removing category...");
fb5662de 779
fd752a79
AD
780 const query = { op: "pref-feeds", method: "removeCat",
781 ids: id };
782
783 xhrPost("backend.php", query, () => {
784 notify('');
785 updateFeedList();
786 });
5ef071e0
AD
787 }
788}
fb5662de 789
fd26d5bf 790function removeSelectedCategories() {
424e28db 791 const sel_rows = getSelectedCategories();
fd26d5bf
AD
792
793 if (sel_rows.length > 0) {
fd752a79 794 if (confirm(__("Remove selected categories?"))) {
fd26d5bf
AD
795 notify_progress("Removing selected categories...");
796
fd752a79
AD
797 const query = { op: "pref-feeds", method: "removeCat",
798 ids: sel_rows.toString() };
fd26d5bf 799
fd752a79
AD
800 xhrPost("backend.php", query, () => {
801 updateFeedList();
802 });
fd26d5bf
AD
803 }
804 } else {
805 alert(__("No categories are selected."));
806 }
807
808 return false;
809}
810
5ef071e0 811function createCategory() {
424e28db 812 const title = prompt(__("Category title:"));
fb5662de 813
1bfe1d7b 814 if (title) {
1bfe1d7b 815 notify_progress("Creating category...");
da1f74c9 816
fd752a79
AD
817 xhrPost("backend.php", { op: "pref-feeds", method: "addCat", cat: title }, () => {
818 notify('');
819 updateFeedList();
820 });
a349077c 821 }
9c483746 822}
a3656a41 823
8ffd2011 824function showInactiveFeeds() {
424e28db 825 const query = "backend.php?op=pref-feeds&method=inactiveFeeds";
8ffd2011 826
1bfe1d7b
AD
827 if (dijit.byId("inactiveFeedsDlg"))
828 dijit.byId("inactiveFeedsDlg").destroyRecursive();
8ffd2011 829
9dc5524d 830 const dialog = new dijit.Dialog({
1bfe1d7b
AD
831 id: "inactiveFeedsDlg",
832 title: __("Feeds without recent updates"),
833 style: "width: 600px",
834 getSelectedFeeds: function () {
835 return getSelectedTableRowIds("prefInactiveFeedList");
836 },
837 removeSelected: function () {
424e28db 838 const sel_rows = this.getSelectedFeeds();
8ffd2011 839
1bfe1d7b 840 if (sel_rows.length > 0) {
fd752a79 841 if (confirm(__("Remove selected feeds?"))) {
1bfe1d7b 842 notify_progress("Removing selected feeds...", true);
8ffd2011 843
fd752a79
AD
844 const query = { op: "pref-feeds", method: "remove",
845 ids: sel_rows.toString() };
8ffd2011 846
fd752a79
AD
847 xhrPost("backend.php", query, () => {
848 notify('');
849 dialog.hide();
850 updateFeedList();
851 });
8ffd2011 852 }
8ffd2011 853
1bfe1d7b
AD
854 } else {
855 alert(__("No feeds are selected."));
856 }
857 },
858 execute: function () {
859 if (this.validate()) {
860 }
861 },
862 href: query
863 });
8ffd2011 864
1bfe1d7b 865 dialog.show();
8ffd2011
AD
866}
867
ef7b7bbd 868function opmlRegenKey() {
fd752a79 869 if (confirm(__("Replace current OPML publishing address with a new one?"))) {
1bfe1d7b 870 notify_progress("Trying to change address...", true);
fb5662de 871
fd752a79
AD
872 xhrJson("backend.php", { op: "pref-feeds", method: "regenOPMLKey" }, (reply) => {
873 if (reply) {
874 const new_link = reply.link;
875 const e = $('pub_opml_url');
91d16ff1 876
fd752a79
AD
877 if (new_link) {
878 e.href = new_link;
879 e.innerHTML = new_link;
fb5662de 880
fd752a79 881 new Effect.Highlight(e);
fb5662de 882
fd752a79 883 notify('');
fb5662de 884
fd752a79
AD
885 } else {
886 notify_error("Could not change feed URL.");
887 }
888 }
889 });
ef7b7bbd
MK
890 }
891 return false;
892}
c4a36709 893
b8776a07 894function labelColorReset() {
424e28db 895 const labels = getSelectedLabels();
b8776a07 896
1bfe1d7b 897 if (labels.length > 0) {
fd752a79 898 if (confirm(__("Reset selected labels to default colors?"))) {
b8776a07 899
fd752a79
AD
900 const query = { op: "pref-labels", method: "colorreset",
901 ids: labels.toString() };
f695cdb2 902
fd752a79
AD
903 xhrPost("backend.php", query, () => {
904 updateLabelList();
905 });
b8776a07
AD
906 }
907
1bfe1d7b
AD
908 } else {
909 alert(__("No labels are selected."));
b8776a07
AD
910 }
911}
912
a5819bb3
AD
913function inPreferences() {
914 return true;
915}
d9084cf2
AD
916
917function editProfiles() {
22988692 918
1bfe1d7b
AD
919 if (dijit.byId("profileEditDlg"))
920 dijit.byId("profileEditDlg").destroyRecursive();
22988692 921
424e28db 922 const query = "backend.php?op=pref-prefs&method=editPrefProfiles";
22988692 923
9dc5524d 924 const dialog = new dijit.Dialog({
1bfe1d7b
AD
925 id: "profileEditDlg",
926 title: __("Settings Profiles"),
927 style: "width: 600px",
928 getSelectedProfiles: function () {
929 return getSelectedTableRowIds("prefFeedProfileList");
930 },
931 removeSelected: function () {
424e28db 932 const sel_rows = this.getSelectedProfiles();
fb5662de 933
1bfe1d7b 934 if (sel_rows.length > 0) {
da1a3c2c 935 if (confirm(__("Remove selected profiles? Active and default profiles will not be removed."))) {
1bfe1d7b 936 notify_progress("Removing selected profiles...", true);
fb5662de 937
ef129fed
AD
938 const query = { op: "rpc", method: "remprofiles",
939 ids: sel_rows.toString() };
fb5662de 940
ef129fed
AD
941 xhrPost("backend.php", query, () => {
942 notify('');
943 editProfiles();
1bfe1d7b 944 });
22988692 945 }
fb5662de 946
1bfe1d7b
AD
947 } else {
948 alert(__("No profiles are selected."));
949 }
950 },
951 activateProfile: function () {
424e28db 952 const sel_rows = this.getSelectedProfiles();
fb5662de 953
1bfe1d7b 954 if (sel_rows.length == 1) {
da1a3c2c 955 if (confirm(__("Activate selected profile?"))) {
1bfe1d7b 956 notify_progress("Loading, please wait...");
fb5662de 957
ef129fed
AD
958 xhrPost("backend.php", { op: "rpc", method: "setprofile", id: sel_rows.toString() }, () => {
959 window.location.reload();
960 });
fb5662de 961 }
22988692 962
1bfe1d7b
AD
963 } else {
964 alert(__("Please choose a profile to activate."));
965 }
966 },
967 addProfile: function () {
968 if (this.validate()) {
969 notify_progress("Creating profile...", true);
22988692 970
ef129fed 971 const query = { op: "rpc", method: "addprofile", title: dialog.attr('value').newprofile };
22988692 972
ef129fed
AD
973 xhrPost("backend.php", query, () => {
974 notify('');
975 editProfiles();
1bfe1d7b 976 });
22988692 977
1bfe1d7b
AD
978 }
979 },
980 execute: function () {
981 if (this.validate()) {
982 }
983 },
984 href: query
985 });
986
987 dialog.show();
d9084cf2
AD
988}
989
ef129fed 990/*
d9084cf2
AD
991function activatePrefProfile() {
992
424e28db 993 const sel_rows = getSelectedFeedCats();
d9084cf2
AD
994
995 if (sel_rows.length == 1) {
996
424e28db 997 const ok = confirm(__("Activate selected profile?"));
d9084cf2
AD
998
999 if (ok) {
1000 notify_progress("Loading, please wait...");
fb5662de 1001
ef129fed
AD
1002 xhrPost("backend.php", { op: "rpc", method: "setprofile", id: sel_rows.toString() }, () => {
1003 window.location.reload();
1004 });
d9084cf2
AD
1005 }
1006
1007 } else {
1008 alert(__("Please choose a profile to activate."));
1009 }
1010
1011 return false;
ef129fed 1012} */
d9084cf2 1013
8d86f15f
AD
1014function clearFeedAccessKeys() {
1015
da1a3c2c 1016 if (confirm(__("This will invalidate all previously generated feed URLs. Continue?"))) {
8d86f15f
AD
1017 notify_progress("Clearing URLs...");
1018
ef129fed
AD
1019 xhrPost("backend.php", { op: "pref-feeds", method: "clearKeys" }, () => {
1020 notify_info("Generated URLs cleared.");
1021 });
8d86f15f 1022 }
fb5662de 1023
8d86f15f
AD
1024 return false;
1025}
1026
a86ba0a6 1027function resetFilterOrder() {
1bfe1d7b 1028 notify_progress("Loading, please wait...");
a86ba0a6 1029
ef129fed
AD
1030 xhrPost("backend.php", { op: "pref-filters", method: "filtersortreset" }, () => {
1031 updateFilterList();
1032 });
a86ba0a6
AD
1033}
1034
1035
1bfe1d7b
AD
1036function resetFeedOrder() {
1037 notify_progress("Loading, please wait...");
7b8a143f 1038
ef129fed
AD
1039 xhrPost("backend.php", { op: "pref-feeds", method: "feedsortreset" }, () => {
1040 updateFeedList();
1041 });
7b8a143f
AD
1042}
1043
1044function resetCatOrder() {
1bfe1d7b 1045 notify_progress("Loading, please wait...");
7b8a143f 1046
ef129fed
AD
1047 xhrPost("backend.php", { op: "pref-feeds", method: "catsortreset" }, () => {
1048 updateFeedList();
1bfe1d7b 1049 });
7b8a143f
AD
1050}
1051
05185108 1052function editCat(id, item) {
424e28db 1053 const new_name = prompt(__('Rename category to:'), item.name);
7b8a143f 1054
1bfe1d7b 1055 if (new_name && new_name != item.name) {
7b8a143f 1056
1bfe1d7b 1057 notify_progress("Loading, please wait...");
7b8a143f 1058
ef129fed
AD
1059 xhrPost("backend.php", { op: 'pref-feeds', method: 'renamecat', id: id, title: new_name }, () => {
1060 updateFeedList();
1bfe1d7b 1061 });
7b8a143f
AD
1062 }
1063}
fb8b2153 1064
05185108 1065function editLabel(id) {
424e28db 1066 const query = "backend.php?op=pref-labels&method=edit&id=" +
1bfe1d7b
AD
1067 param_escape(id);
1068
1069 if (dijit.byId("labelEditDlg"))
1070 dijit.byId("labelEditDlg").destroyRecursive();
1071
424e28db 1072 const dialog = new dijit.Dialog({
1bfe1d7b
AD
1073 id: "labelEditDlg",
1074 title: __("Label Editor"),
1075 style: "width: 600px",
1076 setLabelColor: function (id, fg, bg) {
1077
424e28db
AD
1078 let kind = '';
1079 let color = '';
1bfe1d7b
AD
1080
1081 if (fg && bg) {
1082 kind = 'both';
1083 } else if (fg) {
1084 kind = 'fg';
1085 color = fg;
1086 } else if (bg) {
1087 kind = 'bg';
1088 color = bg;
1089 }
fb5662de 1090
424e28db 1091 const e = $("LICID-" + id);
fb5662de 1092
1bfe1d7b
AD
1093 if (e) {
1094 if (fg) e.style.color = fg;
1095 if (bg) e.style.backgroundColor = bg;
1096 }
05acc0d6 1097
ef129fed
AD
1098 const query = { op: "pref-labels", method: "colorset", kind: kind,
1099 ids: id, fg: fg, bg: bg, color: color };
1100
1101 xhrPost("backend.php", query, () => {
1102 updateFilterList(); // maybe there's labels in there
1103 });
48b05a29 1104
1bfe1d7b
AD
1105 },
1106 execute: function () {
1107 if (this.validate()) {
424e28db
AD
1108 const caption = this.attr('value').caption;
1109 const fg_color = this.attr('value').fg_color;
1110 const bg_color = this.attr('value').bg_color;
48b05a29 1111
1bfe1d7b
AD
1112 dijit.byId('labelTree').setNameById(id, caption);
1113 this.setLabelColor(id, fg_color, bg_color);
1114 this.hide();
fb8b2153 1115
ef129fed
AD
1116 xhrPost("backend.php", this.attr('value'), () => {
1117 updateFilterList(); // maybe there's labels in there
1bfe1d7b
AD
1118 });
1119 }
1120 },
1121 href: query
1122 });
fb8b2153 1123
1bfe1d7b 1124 dialog.show();
fb8b2153 1125}
018caf6f 1126
88e4e597
AD
1127
1128function customizeCSS() {
424e28db 1129 const query = "backend.php?op=pref-prefs&method=customizeCSS";
88e4e597 1130
1bfe1d7b
AD
1131 if (dijit.byId("cssEditDlg"))
1132 dijit.byId("cssEditDlg").destroyRecursive();
88e4e597 1133
424e28db 1134 const dialog = new dijit.Dialog({
1bfe1d7b
AD
1135 id: "cssEditDlg",
1136 title: __("Customize stylesheet"),
1137 style: "width: 600px",
1138 execute: function () {
1139 notify_progress('Saving data...', true);
ef129fed
AD
1140
1141 xhrPost("backend.php", this.attr('value'), () => {
1142 window.location.reload();
1bfe1d7b 1143 });
88e4e597 1144
1bfe1d7b
AD
1145 },
1146 href: query
1147 });
88e4e597 1148
1bfe1d7b 1149 dialog.show();
88e4e597 1150}
3d72afa1
AD
1151
1152function insertSSLserial(value) {
1bfe1d7b 1153 dijit.byId("SSL_CERT_SERIAL").attr('value', value);
3d72afa1 1154}
373266eb 1155
41f68571 1156function gotoExportOpml(filename, settings) {
424e28db 1157 const tmp = settings ? 1 : 0;
d75409bf 1158 document.location.href = "backend.php?op=opml&method=export&filename=" + filename + "&settings=" + tmp;
41f68571
AD
1159}
1160
1161
33f0fdd0 1162function batchSubscribe() {
424e28db 1163 const query = "backend.php?op=pref-feeds&method=batchSubscribe";
33f0fdd0 1164
1bfe1d7b
AD
1165 // overlapping widgets
1166 if (dijit.byId("batchSubDlg")) dijit.byId("batchSubDlg").destroyRecursive();
1167 if (dijit.byId("feedAddDlg")) dijit.byId("feedAddDlg").destroyRecursive();
33f0fdd0 1168
9dc5524d 1169 const dialog = new dijit.Dialog({
1bfe1d7b
AD
1170 id: "batchSubDlg",
1171 title: __("Batch subscribe"),
1172 style: "width: 600px",
1173 execute: function () {
1174 if (this.validate()) {
1bfe1d7b 1175 notify_progress(__("Subscribing to feeds..."), true);
33f0fdd0 1176
ef129fed
AD
1177 xhrPost("backend.php", this.attr('value'), () => {
1178 notify("");
1179 updateFeedList();
1180 dialog.hide();
1bfe1d7b
AD
1181 });
1182 }
1183 },
1184 href: query
1185 });
33f0fdd0 1186
1bfe1d7b 1187 dialog.show();
33f0fdd0 1188}
55f34b81 1189
1bfe1d7b
AD
1190function clearPluginData(name) {
1191 if (confirm(__("Clear stored data for this plugin?"))) {
f9ebb32c
AD
1192 notify_progress("Loading, please wait...");
1193
ef129fed
AD
1194 xhrPost("backend.php", { op: "pref-prefs", method: "clearplugindata", name: name }, () => {
1195 notify('');
1196 updatePrefsList();
1197 });
5d9abb1e
AD
1198 }
1199}
52e7b5a0
AD
1200
1201function clearSqlLog() {
1202
1203 if (confirm(__("Clear all messages in the error log?"))) {
1204
1205 notify_progress("Loading, please wait...");
52e7b5a0 1206
ef129fed
AD
1207 xhrPost("backend.php", { op: "pref-system", method: "clearLog" }, () => {
1208 updateSystemList();
1209 });
52e7b5a0
AD
1210
1211 }
1212}
1213
ab235fc5
AD
1214function updateSelectedPrompt() {
1215 // no-op shim for toggleSelectedRow()
1216}
e2e24799 1217