]> git.wh0rd.org - tt-rss.git/blame - js/prefs.js
remove duplicated code from hotkey actions handler
[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) {
251
424e28db 252 const ok = confirm(__("Remove selected labels?"));
48f0adb0 253
69668465 254 if (ok) {
42c32916 255 notify_progress("Removing selected labels...");
fb5662de 256
ef129fed
AD
257 const query = { op: "pref-labels", method: "remove",
258 ids: sel_rows.toString() };
a796bfc1 259
ef129fed
AD
260 xhrPost("backend.php", query, () => {
261 updateLabelList();
262 });
69668465 263 }
48f0adb0 264 } else {
89cb787e 265 alert(__("No labels are selected."));
48f0adb0 266 }
90ac84df
AD
267
268 return false;
48f0adb0
AD
269}
270
e6cb77a0
AD
271function removeSelectedUsers() {
272
424e28db 273 const sel_rows = getSelectedUsers();
fb5662de 274
1bfe1d7b 275 if (sel_rows.length > 0) {
fb5662de 276
424e28db 277 const ok = confirm(__("Remove selected users? Neither default admin nor your account will be removed."));
fb5662de 278
1bfe1d7b
AD
279 if (ok) {
280 notify_progress("Removing selected users...");
fb5662de 281
ef129fed
AD
282 const query = { op: "pref-users", method: "remove",
283 ids: sel_rows.toString() };
fb5662de 284
ef129fed
AD
285 xhrPost("backend.php", query, () => {
286 updateUsersList();
1bfe1d7b 287 });
69668465 288 }
e6cb77a0 289
1bfe1d7b
AD
290 } else {
291 alert(__("No users are selected."));
e6cb77a0 292 }
90ac84df
AD
293
294 return false;
e6cb77a0
AD
295}
296
48f0adb0
AD
297function removeSelectedFilters() {
298
424e28db 299 const sel_rows = getSelectedFilters();
fb5662de 300
1bfe1d7b 301 if (sel_rows.length > 0) {
fb5662de 302
424e28db 303 const ok = confirm(__("Remove selected filters?"));
fb5662de 304
1bfe1d7b
AD
305 if (ok) {
306 notify_progress("Removing selected filters...");
fb5662de 307
ef129fed
AD
308 const query = { op: "pref-filters", method: "remove",
309 ids: sel_rows.toString() };
fb5662de 310
ef129fed
AD
311 xhrPost("backend.php", query, () => {
312 updateFilterList();
1bfe1d7b 313 });
69668465 314 }
1bfe1d7b
AD
315 } else {
316 alert(__("No filters are selected."));
48f0adb0 317 }
90ac84df
AD
318
319 return false;
48f0adb0
AD
320}
321
83fe4d6d
AD
322function removeSelectedFeeds() {
323
424e28db 324 const sel_rows = getSelectedFeeds();
fb5662de 325
1bfe1d7b 326 if (sel_rows.length > 0) {
fb5662de 327
424e28db 328 const ok = confirm(__("Unsubscribe from selected feeds?"));
fb5662de 329
1bfe1d7b 330 if (ok) {
fb5662de 331
1bfe1d7b 332 notify_progress("Unsubscribing from selected feeds...", true);
b6a6e262 333
ef129fed
AD
334 const query = { op: "pref-feeds", method: "remove",
335 ids: sel_rows.toString() };
fb5662de 336
ef129fed
AD
337 xhrPost("backend.php", query, () => {
338 updateFeedList();
1bfe1d7b 339 });
69668465 340 }
71ad3959 341
1bfe1d7b
AD
342 } else {
343 alert(__("No feeds are selected."));
71ad3959 344 }
fb5662de 345
90ac84df 346 return false;
71ad3959 347}
007bda35 348
e6cb77a0 349function editSelectedUser() {
424e28db 350 const rows = getSelectedUsers();
e6cb77a0
AD
351
352 if (rows.length == 0) {
f3977cf5 353 alert(__("No users are selected."));
e6cb77a0
AD
354 return;
355 }
356
357 if (rows.length > 1) {
f3977cf5 358 alert(__("Please select only one user."));
e6cb77a0
AD
359 return;
360 }
361
dbd9e2f1
AD
362 notify("");
363
e6cb77a0
AD
364 editUser(rows[0]);
365}
366
367function resetSelectedUserPass() {
e6cb77a0 368
424e28db 369 const rows = getSelectedUsers();
fb5662de 370
1bfe1d7b
AD
371 if (rows.length == 0) {
372 alert(__("No users are selected."));
373 return;
374 }
fb5662de 375
1bfe1d7b
AD
376 if (rows.length > 1) {
377 alert(__("Please select only one user."));
378 return;
379 }
fb5662de 380
424e28db 381 const ok = confirm(__("Reset password of selected user?"));
fb5662de 382
1bfe1d7b
AD
383 if (ok) {
384 notify_progress("Resetting password for selected user...");
fb5662de 385
424e28db 386 const id = rows[0];
fb5662de 387
ef129fed
AD
388 xhrPost("backend.php", { op: "pref-users", method: "resetPass", id: id }, (transport) => {
389 notify_info(transport.responseText, true);
1bfe1d7b 390 });
fbf7d545 391
69668465 392 }
e6cb77a0
AD
393}
394
717f5e64 395function selectedUserDetails() {
e6cb77a0 396
424e28db 397 const rows = getSelectedUsers();
fb5662de 398
1bfe1d7b
AD
399 if (rows.length == 0) {
400 alert(__("No users are selected."));
401 return;
402 }
fb5662de 403
1bfe1d7b
AD
404 if (rows.length > 1) {
405 alert(__("Please select only one user."));
406 return;
407 }
fb5662de 408
ef129fed 409 const query = "backend.php?op=pref-users&method=userdetails&id=" + param_escape(rows[0]);
d9afd9b2 410
1bfe1d7b
AD
411 if (dijit.byId("userDetailsDlg"))
412 dijit.byId("userDetailsDlg").destroyRecursive();
d9afd9b2 413
9dc5524d 414 const dialog = new dijit.Dialog({
1bfe1d7b
AD
415 id: "userDetailsDlg",
416 title: __("User details"),
417 style: "width: 600px",
418 execute: function () {
419 dialog.hide();
420 },
421 href: query
422 });
717f5e64 423
1bfe1d7b 424 dialog.show();
c6c3a07f
AD
425}
426
a0d53889
AD
427
428function editSelectedFilter() {
424e28db 429 const rows = getSelectedFilters();
a0d53889
AD
430
431 if (rows.length == 0) {
f3977cf5 432 alert(__("No filters are selected."));
a0d53889
AD
433 return;
434 }
435
436 if (rows.length > 1) {
f3977cf5 437 alert(__("Please select only one filter."));
a0d53889
AD
438 return;
439 }
440
dbd9e2f1
AD
441 notify("");
442
a0d53889
AD
443 editFilter(rows[0]);
444
445}
446
6aff7845 447function joinSelectedFilters() {
424e28db 448 const rows = getSelectedFilters();
6aff7845
AD
449
450 if (rows.length == 0) {
451 alert(__("No filters are selected."));
452 return;
453 }
454
424e28db 455 const ok = confirm(__("Combine selected filters?"));
6aff7845
AD
456
457 if (ok) {
458 notify_progress("Joining filters...");
459
ef129fed
AD
460 xhrPost("backend.php", { op: "pref-filters", method: "join", ids: rows.toString() }, () => {
461 updateFilterList();
462 });
6aff7845
AD
463 }
464}
a0d53889 465
508a81e1 466function editSelectedFeed() {
424e28db 467 const rows = getSelectedFeeds();
508a81e1
AD
468
469 if (rows.length == 0) {
f3977cf5 470 alert(__("No feeds are selected."));
508a81e1
AD
471 return;
472 }
473
474 if (rows.length > 1) {
1e5548db 475 return editSelectedFeeds();
508a81e1
AD
476 }
477
dbd9e2f1
AD
478 notify("");
479
951906dc 480 editFeed(rows[0], {});
91ff844a
AD
481
482}
483
758e1c4a 484function editSelectedFeeds() {
424e28db 485 const rows = getSelectedFeeds();
758e1c4a 486
1bfe1d7b
AD
487 if (rows.length == 0) {
488 alert(__("No feeds are selected."));
489 return;
490 }
05acc0d6 491
1bfe1d7b 492 notify_progress("Loading, please wait...");
05acc0d6 493
1bfe1d7b
AD
494 if (dijit.byId("feedEditDlg"))
495 dijit.byId("feedEditDlg").destroyRecursive();
755c8f95 496
7e8be97b
AD
497 xhrPost("backend.php", { op: "pref-feeds", method: "editfeeds", ids: rows.toString() }, (transport) => {
498 notify("");
758e1c4a 499
7e8be97b
AD
500 const dialog = new dijit.Dialog({
501 id: "feedEditDlg",
502 title: __("Edit Multiple Feeds"),
503 style: "width: 600px",
504 getChildByName: function (name) {
505 let rv = null;
506 this.getChildren().each(
507 function (child) {
508 if (child.name == name) {
509 rv = child;
510 return;
511 }
512 });
513 return rv;
514 },
515 toggleField: function (checkbox, elem, label) {
516 this.getChildByName(elem).attr('disabled', !checkbox.checked);
517
518 if ($(label))
519 if (checkbox.checked)
520 $(label).removeClassName('insensitive');
521 else
522 $(label).addClassName('insensitive');
523
524 },
525 execute: function () {
526 if (this.validate() && confirm(__("Save changes to selected feeds?"))) {
527 const query = this.attr('value');
528
529 /* normalize unchecked checkboxes because [] is not serialized */
530
531 Object.keys(query).each((key) => {
532 let val = query[key];
533
534 if (typeof val == "object" && val.length == 0)
535 query[key] = ["off"];
536 });
537
538 notify_progress("Saving data...", true);
539
540 xhrPost("backend.php", query, () => {
541 dialog.hide();
542 updateFeedList();
543 });
544 }
545 },
546 content: transport.responseText
547 });
e1218480 548
7e8be97b 549 dialog.show();
1bfe1d7b
AD
550 });
551}
e1218480 552
1bfe1d7b
AD
553function opmlImportComplete(iframe) {
554 if (!iframe.contentDocument.body.innerHTML) return false;
555
556 Element.show(iframe);
557
558 notify('');
559
560 if (dijit.byId('opmlImportDlg'))
561 dijit.byId('opmlImportDlg').destroyRecursive();
562
424e28db 563 const content = iframe.contentDocument.body.innerHTML;
1bfe1d7b 564
424e28db 565 const dialog = new dijit.Dialog({
1bfe1d7b
AD
566 id: "opmlImportDlg",
567 title: __("OPML Import"),
568 style: "width: 600px",
569 onCancel: function () {
12b7b90c 570 window.location.reload();
1bfe1d7b
AD
571 },
572 execute: function () {
12b7b90c 573 window.location.reload();
1bfe1d7b
AD
574 },
575 content: content
576 });
e1218480 577
1bfe1d7b 578 dialog.show();
e1218480
AD
579}
580
b6a6e262 581function opmlImport() {
fb5662de 582
424e28db 583 const opml_file = $("opml_file");
9f311df6
AD
584
585 if (opml_file.value.length == 0) {
d2d75353 586 alert(__("Please choose an OPML file first."));
9f311df6
AD
587 return false;
588 } else {
4d7cd9ed 589 notify_progress("Importing, please wait...", true);
55f34b81
AD
590
591 Element.show("upload_iframe");
592
9f311df6
AD
593 return true;
594 }
595}
596
55f34b81 597
05acc0d6 598function updateFilterList() {
424e28db
AD
599 const user_search = $("filter_search");
600 let search = "";
310fa2dd
AD
601 if (user_search) { search = user_search.value; }
602
7e8be97b
AD
603 xhrPost("backend.php", { op: "pref-filters", search: search }, (transport) => {
604 dijit.byId('filterConfigTab').attr('content', transport.responseText);
605 notify("");
606 });
a0d53889
AD
607}
608
05acc0d6 609function updateLabelList() {
7e8be97b
AD
610 xhrPost("backend.php", { op: "pref-labels" }, (transport) => {
611 dijit.byId('labelConfigTab').attr('content', transport.responseText);
612 notify("");
613 });
48f0adb0
AD
614}
615
4255b24c 616function updatePrefsList() {
7e8be97b
AD
617 xhrPost("backend.php", { op: "pref-prefs" }, (transport) => {
618 dijit.byId('genConfigTab').attr('content', transport.responseText);
619 notify("");
620 });
4255b24c
AD
621}
622
2cbdc95b 623function updateSystemList() {
7e8be97b
AD
624 xhrPost("backend.php", { op: "pref-system" }, (transport) => {
625 dijit.byId('systemConfigTab').attr('content', transport.responseText);
626 notify("");
627 });
2cbdc95b
AD
628}
629
05185108 630function selectTab(id, noupdate) {
1bfe1d7b
AD
631 if (!noupdate) {
632 notify_progress("Loading, please wait...");
d62796de 633
7e8be97b
AD
634 switch (id) {
635 case "feedConfig":
636 updateFeedList();
637 break;
638 case "filterConfig":
639 updateFilterList();
640 break;
641 case "labelConfig":
642 updateLabelList();
643 break;
644 case "genConfig":
645 updatePrefsList();
646 break;
647 case "userConfig":
648 updateUsersList();
649 break;
650 case "systemConfig":
651 updateSystemList();
652 break;
653 default:
654 console.warn("unknown tab", id);
f5a50b25 655 }
fb5662de 656
424e28db 657 const tab = dijit.byId(id + "Tab");
1bfe1d7b
AD
658 dijit.byId("pref-tabs").selectChild(tab);
659
a7565293 660 }
a7565293
AD
661}
662
a7565293 663function init_second_stage() {
1bfe1d7b
AD
664 document.onkeydown = pref_hotkey_handler;
665 loading_set_progress(50);
666 notify("");
b01b1b38 667
424e28db 668 let tab = getURLParam('tab');
b01b1b38 669
1bfe1d7b
AD
670 if (tab) {
671 tab = dijit.byId(tab + "Tab");
672 if (tab) dijit.byId("pref-tabs").selectChild(tab);
673 }
b01b1b38 674
424e28db 675 const method = getURLParam('method');
556e5b46 676
1bfe1d7b 677 if (method == 'editFeed') {
424e28db 678 const param = getURLParam('methodparam');
78935092 679
1bfe1d7b 680 window.setTimeout(function() { editFeed(param) }, 100);
b2caf812 681 }
1bfe1d7b 682
7e8be97b 683 setInterval(hotkey_prefix_timeout, 5*1000);
a0d53889
AD
684}
685
007bda35 686function init() {
1bfe1d7b
AD
687 window.onerror = function (message, filename, lineno, colno, error) {
688 report_error(message, filename, lineno, colno, error);
689 };
690
691 require(["dojo/_base/kernel",
692 "dojo/ready",
693 "dojo/parser",
694 "dojo/_base/loader",
695 "dojo/_base/html",
696 "dijit/ColorPalette",
697 "dijit/Dialog",
698 "dijit/form/Button",
699 "dijit/form/CheckBox",
700 "dijit/form/DropDownButton",
701 "dijit/form/FilteringSelect",
12b7b90c 702 "dijit/form/MultiSelect",
1bfe1d7b
AD
703 "dijit/form/Form",
704 "dijit/form/RadioButton",
705 "dijit/form/ComboButton",
706 "dijit/form/Select",
707 "dijit/form/SimpleTextarea",
708 "dijit/form/TextBox",
709 "dijit/form/ValidationTextBox",
710 "dijit/InlineEditBox",
711 "dijit/layout/AccordionContainer",
712 "dijit/layout/AccordionPane",
713 "dijit/layout/BorderContainer",
714 "dijit/layout/ContentPane",
715 "dijit/layout/TabContainer",
716 "dijit/Menu",
717 "dijit/ProgressBar",
718 "dijit/Toolbar",
719 "dijit/Tree",
720 "dijit/tree/dndSource",
721 "dojo/data/ItemFileWriteStore",
a3e2f1a9
AD
722 "lib/CheckBoxStoreModel",
723 "lib/CheckBoxTree",
724 "fox/PrefFeedStore",
725 "fox/PrefFilterStore",
1bfe1d7b
AD
726 "fox/PrefFeedTree",
727 "fox/PrefFilterTree",
728 "fox/PrefLabelTree"], function (dojo, ready, parser) {
729
730 ready(function () {
731 try {
732 parser.parse();
733
734 loading_set_progress(50);
735
424e28db 736 const clientTzOffset = new Date().getTimezoneOffset() * 60;
e2ec66a8 737
1bfe1d7b
AD
738 new Ajax.Request("backend.php", {
739 parameters: {
740 op: "rpc", method: "sanityCheck",
741 clientTzOffset: clientTzOffset
742 },
743 onComplete: function (transport) {
744 backend_sanity_check_callback(transport);
745 }
fd539f28 746 });
1bfe1d7b
AD
747 } catch (e) {
748 exception_error(e);
749 }
750 });
751 });
007bda35 752}
b1895692 753
b652c1b7 754
1bfe1d7b 755function validatePrefsReset() {
7e8be97b 756 if (confirm(__("Reset to defaults?"))) {
b652c1b7 757
424e28db 758 const query = "?op=pref-prefs&method=resetconfig";
b652c1b7 759
7e8be97b
AD
760 xhrPost("backend.php", { op: "pref-prefs", method: "resetconfig" }, (transport) => {
761 updatePrefsList();
762 notify_info(transport.responseText);
763 });
b652c1b7
AD
764 }
765
766 return false;
69668465 767}
f9cb39ac 768
d437c8cf 769function pref_hotkey_handler(e) {
7e8be97b
AD
770 if (e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA") return;
771
772 const action_name = keyevent_to_action(e);
773
774 if (action_name) {
775 switch (action_name) {
776 case "feed_subscribe":
777 quickAddFeed();
778 return false;
779 case "create_label":
780 addLabel();
781 return false;
782 case "create_filter":
783 quickAddFilter();
784 return false;
785 case "help_dialog":
786 helpDialog("main");
787 return false;
788 default:
789 console.log("unhandled action: " + action_name + "; keycode: " + e.which);
790 }
d437c8cf
AD
791 }
792}
793
5ef071e0 794function removeCategory(id, item) {
350468d0 795
424e28db 796 const ok = confirm(__("Remove category %s? Any nested feeds would be placed into Uncategorized.").replace("%s", item.name));
da1f74c9 797
1bfe1d7b 798 if (ok) {
424e28db 799 const query = "?op=pref-feeds&method=removeCat&ids=" +
1bfe1d7b 800 param_escape(id);
fb5662de 801
1bfe1d7b 802 notify_progress("Removing category...");
fb5662de 803
1bfe1d7b
AD
804 new Ajax.Request("backend.php", {
805 parameters: query,
806 onComplete: function (transport) {
807 notify('');
808 updateFeedList();
5ef071e0 809 }
1bfe1d7b 810 });
5ef071e0
AD
811 }
812}
fb5662de 813
fd26d5bf
AD
814function removeSelectedCategories() {
815
424e28db 816 const sel_rows = getSelectedCategories();
fd26d5bf
AD
817
818 if (sel_rows.length > 0) {
819
424e28db 820 const ok = confirm(__("Remove selected categories?"));
fd26d5bf
AD
821
822 if (ok) {
823 notify_progress("Removing selected categories...");
824
424e28db 825 const query = "?op=pref-feeds&method=removeCat&ids="+
fd26d5bf
AD
826 param_escape(sel_rows.toString());
827
828 new Ajax.Request("backend.php", {
829 parameters: query,
830 onComplete: function(transport) {
831 updateFeedList();
832 } });
833
834 }
835 } else {
836 alert(__("No categories are selected."));
837 }
838
839 return false;
840}
841
5ef071e0 842function createCategory() {
424e28db 843 const title = prompt(__("Category title:"));
fb5662de 844
1bfe1d7b 845 if (title) {
da1f74c9 846
1bfe1d7b 847 notify_progress("Creating category...");
da1f74c9 848
424e28db 849 const query = "?op=pref-feeds&method=addCat&cat=" +
1bfe1d7b 850 param_escape(title);
da1f74c9 851
1bfe1d7b
AD
852 new Ajax.Request("backend.php", {
853 parameters: query,
854 onComplete: function (transport) {
855 notify('');
856 updateFeedList();
857 }
858 });
a349077c 859 }
9c483746 860}
a3656a41 861
8ffd2011 862function showInactiveFeeds() {
424e28db 863 const query = "backend.php?op=pref-feeds&method=inactiveFeeds";
8ffd2011 864
1bfe1d7b
AD
865 if (dijit.byId("inactiveFeedsDlg"))
866 dijit.byId("inactiveFeedsDlg").destroyRecursive();
8ffd2011 867
9dc5524d 868 const dialog = new dijit.Dialog({
1bfe1d7b
AD
869 id: "inactiveFeedsDlg",
870 title: __("Feeds without recent updates"),
871 style: "width: 600px",
872 getSelectedFeeds: function () {
873 return getSelectedTableRowIds("prefInactiveFeedList");
874 },
875 removeSelected: function () {
424e28db 876 const sel_rows = this.getSelectedFeeds();
8ffd2011 877
1bfe1d7b 878 console.log(sel_rows);
8ffd2011 879
1bfe1d7b 880 if (sel_rows.length > 0) {
424e28db 881 const ok = confirm(__("Remove selected feeds?"));
8ffd2011 882
1bfe1d7b
AD
883 if (ok) {
884 notify_progress("Removing selected feeds...", true);
8ffd2011 885
424e28db 886 const query = "?op=pref-feeds&method=remove&ids=" +
1bfe1d7b 887 param_escape(sel_rows.toString());
8ffd2011 888
1bfe1d7b
AD
889 new Ajax.Request("backend.php", {
890 parameters: query,
891 onComplete: function (transport) {
892 notify('');
893 dialog.hide();
894 updateFeedList();
895 }
896 });
8ffd2011 897 }
8ffd2011 898
1bfe1d7b
AD
899 } else {
900 alert(__("No feeds are selected."));
901 }
902 },
903 execute: function () {
904 if (this.validate()) {
905 }
906 },
907 href: query
908 });
8ffd2011 909
1bfe1d7b 910 dialog.show();
8ffd2011
AD
911}
912
ef7b7bbd 913function opmlRegenKey() {
424e28db 914 const ok = confirm(__("Replace current OPML publishing address with a new one?"));
ef7b7bbd 915
1bfe1d7b 916 if (ok) {
fb5662de 917
1bfe1d7b 918 notify_progress("Trying to change address...", true);
fb5662de 919
424e28db 920 const query = "?op=pref-feeds&method=regenOPMLKey";
fb5662de 921
1bfe1d7b
AD
922 new Ajax.Request("backend.php", {
923 parameters: query,
924 onComplete: function (transport) {
424e28db 925 const reply = JSON.parse(transport.responseText);
91d16ff1 926
424e28db 927 const new_link = reply.link;
fb5662de 928
424e28db 929 const e = $('pub_opml_url');
fb5662de 930
1bfe1d7b
AD
931 if (new_link) {
932 e.href = new_link;
933 e.innerHTML = new_link;
fb5662de 934
1bfe1d7b 935 new Effect.Highlight(e);
ef7b7bbd 936
1bfe1d7b 937 notify('');
fb5662de 938
1bfe1d7b
AD
939 } else {
940 notify_error("Could not change feed URL.");
941 }
942 }
943 });
ef7b7bbd
MK
944 }
945 return false;
946}
c4a36709 947
b8776a07 948function labelColorReset() {
424e28db 949 const labels = getSelectedLabels();
b8776a07 950
1bfe1d7b 951 if (labels.length > 0) {
424e28db 952 const ok = confirm(__("Reset selected labels to default colors?"));
b8776a07 953
1bfe1d7b 954 if (ok) {
424e28db 955 const query = "?op=pref-labels&method=colorreset&ids=" +
1bfe1d7b 956 param_escape(labels.toString());
f695cdb2 957
1bfe1d7b
AD
958 new Ajax.Request("backend.php", {
959 parameters: query,
960 onComplete: function (transport) {
961 updateLabelList();
962 }
963 });
b8776a07
AD
964 }
965
1bfe1d7b
AD
966 } else {
967 alert(__("No labels are selected."));
b8776a07
AD
968 }
969}
970
a5819bb3
AD
971function inPreferences() {
972 return true;
973}
d9084cf2
AD
974
975function editProfiles() {
22988692 976
1bfe1d7b
AD
977 if (dijit.byId("profileEditDlg"))
978 dijit.byId("profileEditDlg").destroyRecursive();
22988692 979
424e28db 980 const query = "backend.php?op=pref-prefs&method=editPrefProfiles";
22988692 981
9dc5524d 982 const dialog = new dijit.Dialog({
1bfe1d7b
AD
983 id: "profileEditDlg",
984 title: __("Settings Profiles"),
985 style: "width: 600px",
986 getSelectedProfiles: function () {
987 return getSelectedTableRowIds("prefFeedProfileList");
988 },
989 removeSelected: function () {
424e28db 990 const sel_rows = this.getSelectedProfiles();
fb5662de 991
1bfe1d7b 992 if (sel_rows.length > 0) {
424e28db 993 const ok = confirm(__("Remove selected profiles? Active and default profiles will not be removed."));
fb5662de 994
1bfe1d7b
AD
995 if (ok) {
996 notify_progress("Removing selected profiles...", true);
fb5662de 997
ef129fed
AD
998 const query = { op: "rpc", method: "remprofiles",
999 ids: sel_rows.toString() };
fb5662de 1000
ef129fed
AD
1001 xhrPost("backend.php", query, () => {
1002 notify('');
1003 editProfiles();
1bfe1d7b 1004 });
22988692 1005 }
fb5662de 1006
1bfe1d7b
AD
1007 } else {
1008 alert(__("No profiles are selected."));
1009 }
1010 },
1011 activateProfile: function () {
424e28db 1012 const sel_rows = this.getSelectedProfiles();
fb5662de 1013
1bfe1d7b 1014 if (sel_rows.length == 1) {
fb5662de 1015
424e28db 1016 const ok = confirm(__("Activate selected profile?"));
fb5662de 1017
1bfe1d7b
AD
1018 if (ok) {
1019 notify_progress("Loading, please wait...");
fb5662de 1020
ef129fed
AD
1021 xhrPost("backend.php", { op: "rpc", method: "setprofile", id: sel_rows.toString() }, () => {
1022 window.location.reload();
1023 });
fb5662de 1024 }
22988692 1025
1bfe1d7b
AD
1026 } else {
1027 alert(__("Please choose a profile to activate."));
1028 }
1029 },
1030 addProfile: function () {
1031 if (this.validate()) {
1032 notify_progress("Creating profile...", true);
22988692 1033
ef129fed 1034 const query = { op: "rpc", method: "addprofile", title: dialog.attr('value').newprofile };
22988692 1035
ef129fed
AD
1036 xhrPost("backend.php", query, () => {
1037 notify('');
1038 editProfiles();
1bfe1d7b 1039 });
22988692 1040
1bfe1d7b
AD
1041 }
1042 },
1043 execute: function () {
1044 if (this.validate()) {
1045 }
1046 },
1047 href: query
1048 });
1049
1050 dialog.show();
d9084cf2
AD
1051}
1052
ef129fed 1053/*
d9084cf2
AD
1054function activatePrefProfile() {
1055
424e28db 1056 const sel_rows = getSelectedFeedCats();
d9084cf2
AD
1057
1058 if (sel_rows.length == 1) {
1059
424e28db 1060 const ok = confirm(__("Activate selected profile?"));
d9084cf2
AD
1061
1062 if (ok) {
1063 notify_progress("Loading, please wait...");
fb5662de 1064
ef129fed
AD
1065 xhrPost("backend.php", { op: "rpc", method: "setprofile", id: sel_rows.toString() }, () => {
1066 window.location.reload();
1067 });
d9084cf2
AD
1068 }
1069
1070 } else {
1071 alert(__("Please choose a profile to activate."));
1072 }
1073
1074 return false;
ef129fed 1075} */
d9084cf2 1076
8d86f15f
AD
1077function clearFeedAccessKeys() {
1078
424e28db 1079 const ok = confirm(__("This will invalidate all previously generated feed URLs. Continue?"));
8d86f15f
AD
1080
1081 if (ok) {
1082 notify_progress("Clearing URLs...");
1083
ef129fed
AD
1084 xhrPost("backend.php", { op: "pref-feeds", method: "clearKeys" }, () => {
1085 notify_info("Generated URLs cleared.");
1086 });
8d86f15f 1087 }
fb5662de 1088
8d86f15f
AD
1089 return false;
1090}
1091
a86ba0a6 1092function resetFilterOrder() {
1bfe1d7b 1093 notify_progress("Loading, please wait...");
a86ba0a6 1094
ef129fed
AD
1095 xhrPost("backend.php", { op: "pref-filters", method: "filtersortreset" }, () => {
1096 updateFilterList();
1097 });
a86ba0a6
AD
1098}
1099
1100
1bfe1d7b
AD
1101function resetFeedOrder() {
1102 notify_progress("Loading, please wait...");
7b8a143f 1103
ef129fed
AD
1104 xhrPost("backend.php", { op: "pref-feeds", method: "feedsortreset" }, () => {
1105 updateFeedList();
1106 });
7b8a143f
AD
1107}
1108
1109function resetCatOrder() {
1bfe1d7b 1110 notify_progress("Loading, please wait...");
7b8a143f 1111
ef129fed
AD
1112 xhrPost("backend.php", { op: "pref-feeds", method: "catsortreset" }, () => {
1113 updateFeedList();
1bfe1d7b 1114 });
7b8a143f
AD
1115}
1116
05185108 1117function editCat(id, item) {
424e28db 1118 const new_name = prompt(__('Rename category to:'), item.name);
7b8a143f 1119
1bfe1d7b 1120 if (new_name && new_name != item.name) {
7b8a143f 1121
1bfe1d7b 1122 notify_progress("Loading, please wait...");
7b8a143f 1123
ef129fed
AD
1124 xhrPost("backend.php", { op: 'pref-feeds', method: 'renamecat', id: id, title: new_name }, () => {
1125 updateFeedList();
1bfe1d7b 1126 });
7b8a143f
AD
1127 }
1128}
fb8b2153 1129
05185108 1130function editLabel(id) {
424e28db 1131 const query = "backend.php?op=pref-labels&method=edit&id=" +
1bfe1d7b
AD
1132 param_escape(id);
1133
1134 if (dijit.byId("labelEditDlg"))
1135 dijit.byId("labelEditDlg").destroyRecursive();
1136
424e28db 1137 const dialog = new dijit.Dialog({
1bfe1d7b
AD
1138 id: "labelEditDlg",
1139 title: __("Label Editor"),
1140 style: "width: 600px",
1141 setLabelColor: function (id, fg, bg) {
1142
424e28db
AD
1143 let kind = '';
1144 let color = '';
1bfe1d7b
AD
1145
1146 if (fg && bg) {
1147 kind = 'both';
1148 } else if (fg) {
1149 kind = 'fg';
1150 color = fg;
1151 } else if (bg) {
1152 kind = 'bg';
1153 color = bg;
1154 }
fb5662de 1155
424e28db 1156 const e = $("LICID-" + id);
fb5662de 1157
1bfe1d7b
AD
1158 if (e) {
1159 if (fg) e.style.color = fg;
1160 if (bg) e.style.backgroundColor = bg;
1161 }
05acc0d6 1162
ef129fed
AD
1163 const query = { op: "pref-labels", method: "colorset", kind: kind,
1164 ids: id, fg: fg, bg: bg, color: color };
1165
1166 xhrPost("backend.php", query, () => {
1167 updateFilterList(); // maybe there's labels in there
1168 });
48b05a29 1169
1bfe1d7b
AD
1170 },
1171 execute: function () {
1172 if (this.validate()) {
424e28db
AD
1173 const caption = this.attr('value').caption;
1174 const fg_color = this.attr('value').fg_color;
1175 const bg_color = this.attr('value').bg_color;
48b05a29 1176
1bfe1d7b
AD
1177 dijit.byId('labelTree').setNameById(id, caption);
1178 this.setLabelColor(id, fg_color, bg_color);
1179 this.hide();
fb8b2153 1180
ef129fed
AD
1181 xhrPost("backend.php", this.attr('value'), () => {
1182 updateFilterList(); // maybe there's labels in there
1bfe1d7b
AD
1183 });
1184 }
1185 },
1186 href: query
1187 });
fb8b2153 1188
1bfe1d7b 1189 dialog.show();
fb8b2153 1190}
018caf6f 1191
88e4e597
AD
1192
1193function customizeCSS() {
424e28db 1194 const query = "backend.php?op=pref-prefs&method=customizeCSS";
88e4e597 1195
1bfe1d7b
AD
1196 if (dijit.byId("cssEditDlg"))
1197 dijit.byId("cssEditDlg").destroyRecursive();
88e4e597 1198
424e28db 1199 const dialog = new dijit.Dialog({
1bfe1d7b
AD
1200 id: "cssEditDlg",
1201 title: __("Customize stylesheet"),
1202 style: "width: 600px",
1203 execute: function () {
1204 notify_progress('Saving data...', true);
ef129fed
AD
1205
1206 xhrPost("backend.php", this.attr('value'), () => {
1207 window.location.reload();
1bfe1d7b 1208 });
88e4e597 1209
1bfe1d7b
AD
1210 },
1211 href: query
1212 });
88e4e597 1213
1bfe1d7b 1214 dialog.show();
88e4e597 1215}
3d72afa1
AD
1216
1217function insertSSLserial(value) {
1bfe1d7b 1218 dijit.byId("SSL_CERT_SERIAL").attr('value', value);
3d72afa1 1219}
373266eb 1220
41f68571 1221function gotoExportOpml(filename, settings) {
424e28db 1222 const tmp = settings ? 1 : 0;
d75409bf 1223 document.location.href = "backend.php?op=opml&method=export&filename=" + filename + "&settings=" + tmp;
41f68571
AD
1224}
1225
1226
33f0fdd0 1227function batchSubscribe() {
424e28db 1228 const query = "backend.php?op=pref-feeds&method=batchSubscribe";
33f0fdd0 1229
1bfe1d7b
AD
1230 // overlapping widgets
1231 if (dijit.byId("batchSubDlg")) dijit.byId("batchSubDlg").destroyRecursive();
1232 if (dijit.byId("feedAddDlg")) dijit.byId("feedAddDlg").destroyRecursive();
33f0fdd0 1233
9dc5524d 1234 const dialog = new dijit.Dialog({
1bfe1d7b
AD
1235 id: "batchSubDlg",
1236 title: __("Batch subscribe"),
1237 style: "width: 600px",
1238 execute: function () {
1239 if (this.validate()) {
1bfe1d7b 1240 notify_progress(__("Subscribing to feeds..."), true);
33f0fdd0 1241
ef129fed
AD
1242 xhrPost("backend.php", this.attr('value'), () => {
1243 notify("");
1244 updateFeedList();
1245 dialog.hide();
1bfe1d7b
AD
1246 });
1247 }
1248 },
1249 href: query
1250 });
33f0fdd0 1251
1bfe1d7b 1252 dialog.show();
33f0fdd0 1253}
55f34b81 1254
1bfe1d7b
AD
1255function clearPluginData(name) {
1256 if (confirm(__("Clear stored data for this plugin?"))) {
f9ebb32c
AD
1257 notify_progress("Loading, please wait...");
1258
ef129fed
AD
1259 xhrPost("backend.php", { op: "pref-prefs", method: "clearplugindata", name: name }, () => {
1260 notify('');
1261 updatePrefsList();
1262 });
5d9abb1e
AD
1263 }
1264}
52e7b5a0
AD
1265
1266function clearSqlLog() {
1267
1268 if (confirm(__("Clear all messages in the error log?"))) {
1269
1270 notify_progress("Loading, please wait...");
52e7b5a0 1271
ef129fed
AD
1272 xhrPost("backend.php", { op: "pref-system", method: "clearLog" }, () => {
1273 updateSystemList();
1274 });
52e7b5a0
AD
1275
1276 }
1277}
1278
ab235fc5
AD
1279function updateSelectedPrompt() {
1280 // no-op shim for toggleSelectedRow()
1281}
e2e24799 1282