]> git.wh0rd.org - tt-rss.git/blame_incremental - js/prefs.js
add pref_labels class
[tt-rss.git] / js / prefs.js
... / ...
CommitLineData
1var init_params = new Array();
2
3var hotkey_prefix = false;
4var hotkey_prefix_pressed = false;
5
6var seq = "";
7
8function instancelist_callback2(transport) {
9 try {
10 dijit.byId('instanceConfigTab').attr('content', transport.responseText);
11 selectTab("instanceConfig", true);
12 notify("");
13 } catch (e) {
14 exception_error("instancelist_callback2", e);
15 }
16}
17
18function filterlist_callback2(transport) {
19 dijit.byId('filterConfigTab').attr('content', transport.responseText);
20 notify("");
21}
22
23function userlist_callback2(transport) {
24 try {
25 dijit.byId('userConfigTab').attr('content', transport.responseText);
26
27 notify("");
28 } catch (e) {
29 exception_error("userlist_callback2", e);
30 }
31}
32
33function notify_callback2(transport) {
34 notify_info(transport.responseText);
35}
36
37function updateFeedList(sort_key) {
38
39 var user_search = $("feed_search");
40 var search = "";
41 if (user_search) { search = user_search.value; }
42
43 new Ajax.Request("backend.php", {
44 parameters: "?op=pref-feeds&search=" + param_escape(search),
45 onComplete: function(transport) {
46 dijit.byId('feedConfigTab').attr('content', transport.responseText);
47 selectTab("feedConfig", true);
48 notify("");
49 } });
50}
51
52function updateInstanceList(sort_key) {
53 new Ajax.Request("backend.php", {
54 parameters: "?op=pref-instances&sort=" + param_escape(sort_key),
55 onComplete: function(transport) {
56 instancelist_callback2(transport);
57 } });
58}
59
60function updateUsersList(sort_key) {
61
62 try {
63
64 var user_search = $("user_search");
65 var search = "";
66 if (user_search) { search = user_search.value; }
67
68 var query = "?op=pref-users&sort="
69 + param_escape(sort_key) +
70 "&search=" + param_escape(search);
71
72 new Ajax.Request("backend.php", {
73 parameters: query,
74 onComplete: function(transport) {
75 userlist_callback2(transport);
76 } });
77
78 } catch (e) {
79 exception_error("updateUsersList", e);
80 }
81}
82
83function addUser() {
84
85 try {
86
87 var login = prompt(__("Please enter login:"), "");
88
89 if (login == null) {
90 return false;
91 }
92
93 if (login == "") {
94 alert(__("Can't create user: no login specified."));
95 return false;
96 }
97
98 notify_progress("Adding user...");
99
100 var query = "?op=pref-users&method=add&login=" +
101 param_escape(login);
102
103 new Ajax.Request("backend.php", {
104 parameters: query,
105 onComplete: function(transport) {
106 userlist_callback2(transport);
107 } });
108
109 } catch (e) {
110 exception_error("addUser", e);
111 }
112}
113
114function editUser(id, event) {
115
116 try {
117 if (!event || !event.ctrlKey) {
118
119 notify_progress("Loading, please wait...");
120
121 selectTableRows('prefUserList', 'none');
122 selectTableRowById('UMRR-'+id, 'UMCHK-'+id, true);
123
124 var query = "?op=pref-users&method=edit&id=" +
125 param_escape(id);
126
127 new Ajax.Request("backend.php", {
128 parameters: query,
129 onComplete: function(transport) {
130 infobox_callback2(transport);
131 document.forms['user_edit_form'].login.focus();
132 } });
133
134 } else if (event.ctrlKey) {
135 var cb = $('UMCHK-' + id);
136 cb.checked = !cb.checked;
137 toggleSelectRow(cb);
138 }
139
140 } catch (e) {
141 exception_error("editUser", e);
142 }
143
144}
145
146function editFilter(id) {
147 try {
148
149 var query = "backend.php?op=pref-filters&method=edit&id=" + param_escape(id);
150
151 if (dijit.byId("filterEditDlg"))
152 dijit.byId("filterEditDlg").destroyRecursive();
153
154 dialog = new dijit.Dialog({
155 id: "filterEditDlg",
156 title: __("Edit Filter"),
157 style: "width: 600px",
158 removeFilter: function() {
159 var title = this.attr('value').reg_exp;
160 var msg = __("Remove filter %s?").replace("%s", title);
161
162 if (confirm(msg)) {
163 this.hide();
164
165 notify_progress("Removing filter...");
166
167 var id = this.attr('value').id;
168
169 var query = "?op=pref-filters&method=remove&ids="+
170 param_escape(id);
171
172 new Ajax.Request("backend.php", {
173 parameters: query,
174 onComplete: function(transport) {
175 updateFilterList();
176 } });
177 }
178 },
179 test: function() {
180 if (this.validate()) {
181
182 if (dijit.byId("filterTestDlg"))
183 dijit.byId("filterTestDlg").destroyRecursive();
184
185 tdialog = new dijit.Dialog({
186 id: "filterTestDlg",
187 title: __("Filter Test Results"),
188 style: "width: 600px",
189 href: "backend.php?savemode=test&" +
190 dojo.objectToQuery(dialog.attr('value')),
191 });
192
193 tdialog.show();
194
195 }
196 },
197 execute: function() {
198 if (this.validate()) {
199
200 var query = "?op=rpc&method=verifyRegexp&reg_exp=" +
201 param_escape(dialog.attr('value').reg_exp);
202
203 notify_progress("Verifying regular expression...");
204
205 new Ajax.Request("backend.php", {
206 parameters: query,
207 onComplete: function(transport) {
208 var reply = JSON.parse(transport.responseText);
209
210 if (reply) {
211 notify('');
212
213 if (!reply['status']) {
214 alert("Match regular expression seems to be invalid.");
215 return;
216 } else {
217 notify_progress("Saving data...", true);
218
219 console.log(dojo.objectToQuery(dialog.attr('value')));
220
221 new Ajax.Request("backend.php", {
222 parameters: dojo.objectToQuery(dialog.attr('value')),
223 onComplete: function(transport) {
224 dialog.hide();
225 updateFilterList();
226 }});
227 }
228 }
229 }});
230 }
231 },
232 href: query});
233
234 dialog.show();
235
236
237 } catch (e) {
238 exception_error("editFilter", e);
239 }
240}
241
242function getSelectedLabels() {
243 var tree = dijit.byId("labelTree");
244 var items = tree.model.getCheckedItems();
245 var rv = [];
246
247 items.each(function(item) {
248 rv.push(tree.model.store.getValue(item, 'bare_id'));
249 });
250
251 return rv;
252}
253
254function getSelectedUsers() {
255 return getSelectedTableRowIds("prefUserList");
256}
257
258function getSelectedFeeds() {
259 var tree = dijit.byId("feedTree");
260 var items = tree.model.getCheckedItems();
261 var rv = [];
262
263 items.each(function(item) {
264 if (item.id[0].match("FEED:"))
265 rv.push(tree.model.store.getValue(item, 'bare_id'));
266 });
267
268 return rv;
269}
270
271function getSelectedFilters() {
272 var tree = dijit.byId("filterTree");
273 var items = tree.model.getCheckedItems();
274 var rv = [];
275
276 items.each(function(item) {
277 rv.push(tree.model.store.getValue(item, 'bare_id'));
278 });
279
280 return rv;
281
282}
283
284/* function getSelectedFeedCats() {
285 return getSelectedTableRowIds("prefFeedCatList");
286} */
287
288function removeSelectedLabels() {
289
290 var sel_rows = getSelectedLabels();
291
292 if (sel_rows.length > 0) {
293
294 var ok = confirm(__("Remove selected labels?"));
295
296 if (ok) {
297 notify_progress("Removing selected labels...");
298
299 var query = "?op=pref-labels&method=remove&ids="+
300 param_escape(sel_rows.toString());
301
302 new Ajax.Request("backend.php", {
303 parameters: query,
304 onComplete: function(transport) {
305 updateLabelList();
306 } });
307
308 }
309 } else {
310 alert(__("No labels are selected."));
311 }
312
313 return false;
314}
315
316function removeSelectedUsers() {
317
318 try {
319
320 var sel_rows = getSelectedUsers();
321
322 if (sel_rows.length > 0) {
323
324 var ok = confirm(__("Remove selected users? Neither default admin nor your account will be removed."));
325
326 if (ok) {
327 notify_progress("Removing selected users...");
328
329 var query = "?op=pref-users&method=remove&ids="+
330 param_escape(sel_rows.toString());
331
332 new Ajax.Request("backend.php", {
333 parameters: query,
334 onComplete: function(transport) {
335 userlist_callback2(transport);
336 } });
337
338 }
339
340 } else {
341 alert(__("No users are selected."));
342 }
343
344 } catch (e) {
345 exception_error("removeSelectedUsers", e);
346 }
347
348 return false;
349}
350
351function removeSelectedFilters() {
352
353 try {
354
355 var sel_rows = getSelectedFilters();
356
357 if (sel_rows.length > 0) {
358
359 var ok = confirm(__("Remove selected filters?"));
360
361 if (ok) {
362 notify_progress("Removing selected filters...");
363
364 var query = "?op=pref-filters&method=remove&ids="+
365 param_escape(sel_rows.toString());
366
367 new Ajax.Request("backend.php", {
368 parameters: query,
369 onComplete: function(transport) {
370 updateFilterList();
371 } });
372 }
373 } else {
374 alert(__("No filters are selected."));
375 }
376
377 } catch (e) {
378 exception_error("removeSelectedFilters", e);
379 }
380
381 return false;
382}
383
384
385function removeSelectedFeeds() {
386
387 try {
388
389 var sel_rows = getSelectedFeeds();
390
391 if (sel_rows.length > 0) {
392
393 var ok = confirm(__("Unsubscribe from selected feeds?"));
394
395 if (ok) {
396
397 notify_progress("Unsubscribing from selected feeds...", true);
398
399 var query = "?op=pref-feeds&method=remove&ids="+
400 param_escape(sel_rows.toString());
401
402 console.log(query);
403
404 new Ajax.Request("backend.php", {
405 parameters: query,
406 onComplete: function(transport) {
407 updateFeedList();
408 } });
409 }
410
411 } else {
412 alert(__("No feeds are selected."));
413 }
414
415 } catch (e) {
416 exception_error("removeSelectedFeeds", e);
417 }
418
419 return false;
420}
421
422function clearSelectedFeeds() {
423
424 var sel_rows = getSelectedFeeds();
425
426 if (sel_rows.length > 1) {
427 alert(__("Please select only one feed."));
428 return;
429 }
430
431 if (sel_rows.length > 0) {
432
433 var ok = confirm(__("Erase all non-starred articles in selected feed?"));
434
435 if (ok) {
436 notify_progress("Clearing selected feed...");
437 clearFeedArticles(sel_rows[0]);
438 }
439
440 } else {
441
442 alert(__("No feeds are selected."));
443
444 }
445
446 return false;
447}
448
449function purgeSelectedFeeds() {
450
451 var sel_rows = getSelectedFeeds();
452
453 if (sel_rows.length > 0) {
454
455 var pr = prompt(__("How many days of articles to keep (0 - use default)?"), "0");
456
457 if (pr != undefined) {
458 notify_progress("Purging selected feed...");
459
460 var query = "?op=rpc&method=purge&ids="+
461 param_escape(sel_rows.toString()) + "&days=" + pr;
462
463 console.log(query);
464
465 new Ajax.Request("prefs.php", {
466 parameters: query,
467 onComplete: function(transport) {
468 notify('');
469 } });
470 }
471
472 } else {
473
474 alert(__("No feeds are selected."));
475
476 }
477
478 return false;
479}
480
481function userEditCancel() {
482 closeInfoBox();
483 return false;
484}
485
486function userEditSave() {
487
488 try {
489
490 var login = document.forms["user_edit_form"].login.value;
491
492 if (login.length == 0) {
493 alert(__("Login field cannot be blank."));
494 return;
495 }
496
497 notify_progress("Saving user...");
498
499 closeInfoBox();
500
501 var query = Form.serialize("user_edit_form");
502
503 new Ajax.Request("backend.php", {
504 parameters: query,
505 onComplete: function(transport) {
506 userlist_callback2(transport);
507 } });
508
509 } catch (e) {
510 exception_error("userEditSave", e);
511 }
512
513 return false;
514
515}
516
517
518function editSelectedUser() {
519 var rows = getSelectedUsers();
520
521 if (rows.length == 0) {
522 alert(__("No users are selected."));
523 return;
524 }
525
526 if (rows.length > 1) {
527 alert(__("Please select only one user."));
528 return;
529 }
530
531 notify("");
532
533 editUser(rows[0]);
534}
535
536function resetSelectedUserPass() {
537
538 try {
539
540 var rows = getSelectedUsers();
541
542 if (rows.length == 0) {
543 alert(__("No users are selected."));
544 return;
545 }
546
547 if (rows.length > 1) {
548 alert(__("Please select only one user."));
549 return;
550 }
551
552 var ok = confirm(__("Reset password of selected user?"));
553
554 if (ok) {
555 notify_progress("Resetting password for selected user...");
556
557 var id = rows[0];
558
559 var query = "?op=pref-users&method=resetPass&id=" +
560 param_escape(id);
561
562 new Ajax.Request("backend.php", {
563 parameters: query,
564 onComplete: function(transport) {
565 userlist_callback2(transport);
566 } });
567
568 }
569
570 } catch (e) {
571 exception_error("resetSelectedUserPass", e);
572 }
573}
574
575function selectedUserDetails() {
576
577 try {
578
579 var rows = getSelectedUsers();
580
581 if (rows.length == 0) {
582 alert(__("No users are selected."));
583 return;
584 }
585
586 if (rows.length > 1) {
587 alert(__("Please select only one user."));
588 return;
589 }
590
591 notify_progress("Loading, please wait...");
592
593 var id = rows[0];
594
595 var query = "?op=pref-users&method=user-details&id=" + id;
596
597 new Ajax.Request("backend.php", {
598 parameters: query,
599 onComplete: function(transport) {
600 infobox_callback2(transport);
601 } });
602 } catch (e) {
603 exception_error("selectedUserDetails", e);
604 }
605}
606
607
608function editSelectedFilter() {
609 var rows = getSelectedFilters();
610
611 if (rows.length == 0) {
612 alert(__("No filters are selected."));
613 return;
614 }
615
616 if (rows.length > 1) {
617 alert(__("Please select only one filter."));
618 return;
619 }
620
621 notify("");
622
623 editFilter(rows[0]);
624
625}
626
627
628function editSelectedFeed() {
629 var rows = getSelectedFeeds();
630
631 if (rows.length == 0) {
632 alert(__("No feeds are selected."));
633 return;
634 }
635
636 if (rows.length > 1) {
637 return editSelectedFeeds();
638 }
639
640 notify("");
641
642 editFeed(rows[0], {});
643
644}
645
646function editSelectedFeeds() {
647
648 try {
649 var rows = getSelectedFeeds();
650
651 if (rows.length == 0) {
652 alert(__("No feeds are selected."));
653 return;
654 }
655
656 notify_progress("Loading, please wait...");
657
658 var query = "backend.php?op=pref-feeds&method=editfeeds&ids=" +
659 param_escape(rows.toString());
660
661 console.log(query);
662
663 if (dijit.byId("feedEditDlg"))
664 dijit.byId("feedEditDlg").destroyRecursive();
665
666 new Ajax.Request("backend.php", {
667 parameters: query,
668 onComplete: function(transport) {
669
670 notify("");
671
672 var dialog = new dijit.Dialog({
673 id: "feedEditDlg",
674 title: __("Edit Multiple Feeds"),
675 style: "width: 600px",
676 getChildByName: function (name) {
677 var rv = null;
678 this.getChildren().each(
679 function(child) {
680 if (child.name == name) {
681 rv = child;
682 return;
683 }
684 });
685 return rv;
686 },
687 toggleField: function (checkbox, elem, label) {
688 this.getChildByName(elem).attr('disabled', !checkbox.checked);
689
690 if ($(label))
691 if (checkbox.checked)
692 $(label).removeClassName('insensitive');
693 else
694 $(label).addClassName('insensitive');
695
696 },
697 execute: function() {
698 if (this.validate() && confirm(__("Save changes to selected feeds?"))) {
699 var query = dojo.objectToQuery(this.attr('value'));
700
701 /* Form.serialize ignores unchecked checkboxes */
702
703 if (!query.match("&rtl_content=") &&
704 this.getChildByName('rtl_content').attr('disabled') == false) {
705 query = query + "&rtl_content=false";
706 }
707
708 if (!query.match("&private=") &&
709 this.getChildByName('private').attr('disabled') == false) {
710 query = query + "&private=false";
711 }
712
713 try {
714 if (!query.match("&cache_images=") &&
715 this.getChildByName('cache_images').attr('disabled') == false) {
716 query = query + "&cache_images=false";
717 }
718 } catch (e) { }
719
720 if (!query.match("&include_in_digest=") &&
721 this.getChildByName('include_in_digest').attr('disabled') == false) {
722 query = query + "&include_in_digest=false";
723 }
724
725 if (!query.match("&always_display_enclosures=") &&
726 this.getChildByName('always_display_enclosures').attr('disabled') == false) {
727 query = query + "&always_display_enclosures=false";
728 }
729
730 if (!query.match("&mark_unread_on_update=") &&
731 this.getChildByName('mark_unread_on_update').attr('disabled') == false) {
732 query = query + "&mark_unread_on_update=false";
733 }
734
735 if (!query.match("&update_on_checksum_change=") &&
736 this.getChildByName('update_on_checksum_change').attr('disabled') == false) {
737 query = query + "&update_on_checksum_change=false";
738 }
739
740 console.log(query);
741
742 notify_progress("Saving data...", true);
743
744 new Ajax.Request("backend.php", {
745 parameters: query,
746 onComplete: function(transport) {
747 dialog.hide();
748 updateFeedList();
749 }});
750 }
751 },
752 content: transport.responseText});
753
754 dialog.show();
755
756 } });
757
758 } catch (e) {
759 exception_error("editSelectedFeeds", e);
760 }
761}
762
763function piggie(enable) {
764 if (enable) {
765 console.log("I LOVEDED IT!");
766 var piggie = $("piggie");
767
768 Element.show(piggie);
769 Position.Center(piggie);
770 Effect.Puff(piggie);
771
772 }
773}
774
775function opmlImportComplete(iframe) {
776 try {
777 if (!iframe.contentDocument.body.innerHTML) return false;
778
779 notify('');
780
781 if (dijit.byId('opmlImportDlg'))
782 dijit.byId('opmlImportDlg').destroyRecursive();
783
784 var content = iframe.contentDocument.body.innerHTML;
785
786 dialog = new dijit.Dialog({
787 id: "opmlImportDlg",
788 title: __("OPML Import"),
789 style: "width: 600px",
790 onCancel: function() {
791 updateFeedList();
792 },
793 content: content});
794
795 dialog.show();
796
797 } catch (e) {
798 exception_error("opmlImportComplete", e);
799 }
800}
801
802function opmlImport() {
803
804 var opml_file = $("opml_file");
805
806 if (opml_file.value.length == 0) {
807 alert(__("Please choose an OPML file first."));
808 return false;
809 } else {
810 notify_progress("Importing, please wait...", true);
811 return true;
812 }
813}
814
815function updateFilterList() {
816 new Ajax.Request("backend.php", {
817 parameters: "?op=pref-filters",
818 onComplete: function(transport) {
819 filterlist_callback2(transport);
820 } });
821}
822
823function updateLabelList() {
824 new Ajax.Request("backend.php", {
825 parameters: "?op=pref-labels",
826 onComplete: function(transport) {
827 dijit.byId('labelConfigTab').attr('content', transport.responseText);
828 notify("");
829 } });
830}
831
832function updatePrefsList() {
833 new Ajax.Request("backend.php", {
834 parameters: "?op=pref-prefs",
835 onComplete: function(transport) {
836 dijit.byId('genConfigTab').attr('content', transport.responseText);
837 notify("");
838 } });
839}
840
841function selectTab(id, noupdate, method) {
842 try {
843 if (!noupdate) {
844 notify_progress("Loading, please wait...");
845
846 if (id == "feedConfig") {
847 updateFeedList();
848 } else if (id == "filterConfig") {
849 updateFilterList();
850 } else if (id == "labelConfig") {
851 updateLabelList();
852 } else if (id == "genConfig") {
853 updatePrefsList();
854 } else if (id == "userConfig") {
855 updateUsersList();
856 }
857
858 var tab = dijit.byId(id + "Tab");
859 dijit.byId("pref-tabs").selectChild(tab);
860
861 }
862
863 } catch (e) {
864 exception_error("selectTab", e);
865 }
866}
867
868function init_second_stage() {
869 try {
870
871 document.onkeydown = pref_hotkey_handler;
872 loading_set_progress(50);
873 notify("");
874
875 dojo.addOnLoad(function() {
876 var tab = getURLParam('tab');
877
878 if (tab) {
879 tab = dijit.byId(tab + "Tab");
880 if (tab) dijit.byId("pref-tabs").selectChild(tab);
881 }
882
883 var method = getURLParam('method');
884
885 if (method == 'editFeed') {
886 var param = getURLParam('methodparam');
887
888 window.setTimeout('editFeed(' + param + ')', 100);
889 }
890 });
891
892 setTimeout("hotkey_prefix_timeout()", 5*1000);
893
894 } catch (e) {
895 exception_error("init_second_stage", e);
896 }
897}
898
899function init() {
900
901 try {
902 dojo.registerModulePath("lib", "..");
903 dojo.registerModulePath("fox", "../../js/");
904
905 dojo.require("lib.CheckBoxTree");
906 dojo.require("fox.PrefFeedTree");
907 dojo.require("fox.PrefFilterTree");
908 dojo.require("fox.PrefLabelTree");
909
910 dojo.parser.parse();
911
912 dojo.addOnLoad(function() {
913 loading_set_progress(50);
914
915 new Ajax.Request("backend.php", {
916 parameters: {op: "rpc", method: "sanityCheck"},
917 onComplete: function(transport) {
918 backend_sanity_check_callback(transport);
919 } });
920 });
921
922 } catch (e) {
923 exception_error("init", e);
924 }
925}
926
927function validatePrefsReset() {
928 try {
929 var ok = confirm(__("Reset to defaults?"));
930
931 if (ok) {
932
933 query = "?op=pref-prefs&method=resetconfig";
934 console.log(query);
935
936 new Ajax.Request("backend.php", {
937 parameters: query,
938 onComplete: function(transport) {
939 var msg = transport.responseText;
940 if (msg.match("PREFS_THEME_CHANGED")) {
941 window.location.reload();
942 } else {
943 notify_info(msg);
944 selectTab();
945 }
946 } });
947
948 }
949
950 } catch (e) {
951 exception_error("validatePrefsReset", e);
952 }
953
954 return false;
955
956}
957
958
959function pref_hotkey_handler(e) {
960 try {
961 if (e.target.nodeName == "INPUT") return;
962
963 var keycode = false;
964 var shift_key = false;
965
966 var cmdline = $('cmdline');
967
968 try {
969 shift_key = e.shiftKey;
970 } catch (e) {
971
972 }
973
974 if (window.event) {
975 keycode = window.event.keyCode;
976 } else if (e) {
977 keycode = e.which;
978 }
979
980 var keychar = String.fromCharCode(keycode);
981
982 if (keycode == 27) { // escape
983 if (Element.visible("hotkey_help_overlay")) {
984 Element.hide("hotkey_help_overlay");
985 }
986 hotkey_prefix = false;
987 closeInfoBox();
988 }
989
990 if (keycode == 16) return; // ignore lone shift
991 if (keycode == 17) return; // ignore lone ctrl
992
993 if ((keycode == 67 || keycode == 71) && !hotkey_prefix) {
994 hotkey_prefix = keycode;
995
996 var date = new Date();
997 var ts = Math.round(date.getTime() / 1000);
998
999 hotkey_prefix_pressed = ts;
1000
1001 cmdline.innerHTML = keychar;
1002 Element.show(cmdline);
1003
1004 console.log("KP: PREFIX=" + keycode + " CHAR=" + keychar);
1005 return;
1006 }
1007
1008 if (Element.visible("hotkey_help_overlay")) {
1009 Element.hide("hotkey_help_overlay");
1010 }
1011
1012 if (keycode == 13 || keycode == 27) {
1013 seq = "";
1014 } else {
1015 seq = seq + "" + keycode;
1016 }
1017
1018 /* Global hotkeys */
1019
1020 Element.hide(cmdline);
1021
1022 if (!hotkey_prefix) {
1023
1024 if ((keycode == 191 || keychar == '?') && shift_key) { // ?
1025 if (!Element.visible("hotkey_help_overlay")) {
1026 //Element.show("hotkey_help_overlay");
1027 Effect.Appear("hotkey_help_overlay", {duration : 0.3, to: 0.9});
1028 } else {
1029 Element.hide("hotkey_help_overlay");
1030 }
1031 return false;
1032 }
1033
1034 if (keycode == 191 || keychar == '/') { // /
1035 var search_boxes = new Array("label_search",
1036 "feed_search", "filter_search", "user_search", "feed_browser_search");
1037
1038 for (var i = 0; i < search_boxes.length; i++) {
1039 var elem = $(search_boxes[i]);
1040 if (elem) {
1041 $(search_boxes[i]).focus();
1042 return false;
1043 }
1044 }
1045 }
1046 }
1047
1048 /* Prefix c */
1049
1050 if (hotkey_prefix == 67) { // c
1051 hotkey_prefix = false;
1052
1053 if (keycode == 70) { // f
1054 quickAddFilter();
1055 return false;
1056 }
1057
1058 if (keycode == 83) { // s
1059 quickAddFeed();
1060 return false;
1061 }
1062
1063 if (keycode == 85) { // u
1064 // no-op
1065 }
1066
1067 if (keycode == 67) { // c
1068 editFeedCats();
1069 return false;
1070 }
1071
1072 if (keycode == 84 && shift_key) { // T
1073 feedBrowser();
1074 return false;
1075 }
1076
1077 }
1078
1079 /* Prefix g */
1080
1081 if (hotkey_prefix == 71) { // g
1082
1083 hotkey_prefix = false;
1084
1085 if (keycode == 49 && $("genConfigTab")) { // 1
1086 selectTab("genConfig");
1087 return false;
1088 }
1089
1090 if (keycode == 50 && $("feedConfigTab")) { // 2
1091 selectTab("feedConfig");
1092 return false;
1093 }
1094
1095 if (keycode == 51 && $("filterConfigTab")) { // 4
1096 selectTab("filterConfig");
1097 return false;
1098 }
1099
1100 if (keycode == 52 && $("labelConfigTab")) { // 5
1101 selectTab("labelConfig");
1102 return false;
1103 }
1104
1105 if (keycode == 53 && $("userConfigTab")) { // 6
1106 selectTab("userConfig");
1107 return false;
1108 }
1109
1110 if (keycode == 88) { // x
1111 return gotoMain();
1112 }
1113
1114 }
1115
1116 if ($("piggie")) {
1117 if (seq.match("8073717369")) {
1118 seq = "";
1119 piggie(true);
1120 } else {
1121 piggie(false);
1122 }
1123 }
1124
1125 if (hotkey_prefix) {
1126 console.log("KP: PREFIX=" + hotkey_prefix + " CODE=" + keycode + " CHAR=" + keychar);
1127 } else {
1128 console.log("KP: CODE=" + keycode + " CHAR=" + keychar);
1129 }
1130
1131 } catch (e) {
1132 exception_error("pref_hotkey_handler", e);
1133 }
1134}
1135
1136function editFeedCats() {
1137 try {
1138 var query = "backend.php?op=pref-feeds&method=editCats";
1139
1140 if (dijit.byId("feedCatEditDlg"))
1141 dijit.byId("feedCatEditDlg").destroyRecursive();
1142
1143 dialog = new dijit.Dialog({
1144 id: "feedCatEditDlg",
1145 title: __("Feed Categories"),
1146 style: "width: 600px",
1147 getSelectedCategories: function() {
1148 return getSelectedTableRowIds("prefFeedCatList");
1149 },
1150 removeSelected: function() {
1151 var sel_rows = this.getSelectedCategories();
1152
1153 if (sel_rows.length > 0) {
1154 var ok = confirm(__("Remove selected categories?"));
1155
1156 if (ok) {
1157 notify_progress("Removing selected categories...", true);
1158
1159 var query = "?op=pref-feeds&method=editCats&action=remove&ids="+
1160 param_escape(sel_rows.toString());
1161
1162 new Ajax.Request("backend.php", {
1163 parameters: query,
1164 onComplete: function(transport) {
1165 notify('');
1166 dialog.attr('content', transport.responseText);
1167 updateFeedList();
1168 } });
1169
1170 }
1171
1172 } else {
1173 alert(__("No categories are selected."));
1174 }
1175 },
1176 addCategory: function() {
1177 if (this.validate()) {
1178 notify_progress("Creating category...");
1179
1180 var query = "?op=pref-feeds&method=editCats&action=add&cat=" +
1181 param_escape(this.attr('value').newcat);
1182
1183 new Ajax.Request("backend.php", {
1184 parameters: query,
1185 onComplete: function(transport) {
1186 notify('');
1187 dialog.attr('content', transport.responseText);
1188 updateFeedList();
1189 } });
1190 }
1191 },
1192 execute: function() {
1193 if (this.validate()) {
1194 }
1195 },
1196 href: query});
1197
1198 dialog.show();
1199
1200 } catch (e) {
1201 exception_error("editFeedCats", e);
1202 }
1203}
1204
1205function showInactiveFeeds() {
1206 try {
1207 var query = "backend.php?op=dlg&method=inactiveFeeds";
1208
1209 if (dijit.byId("inactiveFeedsDlg"))
1210 dijit.byId("inactiveFeedsDlg").destroyRecursive();
1211
1212 dialog = new dijit.Dialog({
1213 id: "inactiveFeedsDlg",
1214 title: __("Feeds without recent updates"),
1215 style: "width: 600px",
1216 getSelectedFeeds: function() {
1217 return getSelectedTableRowIds("prefInactiveFeedList");
1218 },
1219 removeSelected: function() {
1220 var sel_rows = this.getSelectedFeeds();
1221
1222 console.log(sel_rows);
1223
1224 if (sel_rows.length > 0) {
1225 var ok = confirm(__("Remove selected feeds?"));
1226
1227 if (ok) {
1228 notify_progress("Removing selected feeds...", true);
1229
1230 var query = "?op=pref-feeds&method=remove&ids="+
1231 param_escape(sel_rows.toString());
1232
1233 new Ajax.Request("backend.php", {
1234 parameters: query,
1235 onComplete: function(transport) {
1236 notify('');
1237 dialog.hide();
1238 updateFeedList();
1239 } });
1240 }
1241
1242 } else {
1243 alert(__("No feeds are selected."));
1244 }
1245 },
1246 execute: function() {
1247 if (this.validate()) {
1248 }
1249 },
1250 href: query});
1251
1252 dialog.show();
1253
1254 } catch (e) {
1255 exception_error("showInactiveFeeds", e);
1256 }
1257
1258}
1259
1260function opmlRegenKey() {
1261
1262 try {
1263 var ok = confirm(__("Replace current OPML publishing address with a new one?"));
1264
1265 if (ok) {
1266
1267 notify_progress("Trying to change address...", true);
1268
1269 var query = "?op=rpc&method=regenOPMLKey";
1270
1271 new Ajax.Request("backend.php", {
1272 parameters: query,
1273 onComplete: function(transport) {
1274 var reply = JSON.parse(transport.responseText);
1275
1276 var new_link = reply.link;
1277
1278 var e = $('pub_opml_url');
1279
1280 if (new_link) {
1281 e.href = new_link;
1282 e.innerHTML = new_link;
1283
1284 new Effect.Highlight(e);
1285
1286 notify('');
1287
1288 } else {
1289 notify_error("Could not change feed URL.");
1290 }
1291 } });
1292 }
1293 } catch (e) {
1294 exception_error("opmlRegenKey", e);
1295 }
1296 return false;
1297}
1298
1299function feedActionChange() {
1300 try {
1301 var chooser = $("feedActionChooser");
1302 var opid = chooser[chooser.selectedIndex].value;
1303
1304 chooser.selectedIndex = 0;
1305 feedActionGo(opid);
1306 } catch (e) {
1307 exception_error("feedActionChange", e);
1308 }
1309}
1310
1311function feedActionGo(op) {
1312 try {
1313 if (op == "facEdit") {
1314
1315 var rows = getSelectedFeeds();
1316
1317 if (rows.length > 1) {
1318 editSelectedFeeds();
1319 } else {
1320 editSelectedFeed();
1321 }
1322 }
1323
1324 if (op == "facClear") {
1325 clearSelectedFeeds();
1326 }
1327
1328 if (op == "facPurge") {
1329 purgeSelectedFeeds();
1330 }
1331
1332 if (op == "facEditCats") {
1333 editFeedCats();
1334 }
1335
1336 if (op == "facRescore") {
1337 rescoreSelectedFeeds();
1338 }
1339
1340 if (op == "facUnsubscribe") {
1341 removeSelectedFeeds();
1342 }
1343
1344 } catch (e) {
1345 exception_error("feedActionGo", e);
1346
1347 }
1348}
1349
1350function clearFeedArticles(feed_id) {
1351
1352 notify_progress("Clearing feed...");
1353
1354 var query = "?op=pref-feeds&quiet=1&method=clear&id=" + feed_id;
1355
1356 new Ajax.Request("backend.php", {
1357 parameters: query,
1358 onComplete: function(transport) {
1359 notify('');
1360 } });
1361
1362 return false;
1363}
1364
1365function rescoreSelectedFeeds() {
1366
1367 var sel_rows = getSelectedFeeds();
1368
1369 if (sel_rows.length > 0) {
1370
1371 //var ok = confirm(__("Rescore last 100 articles in selected feeds?"));
1372 var ok = confirm(__("Rescore articles in selected feeds?"));
1373
1374 if (ok) {
1375 notify_progress("Rescoring selected feeds...", true);
1376
1377 var query = "?op=pref-feeds&method=rescore&quiet=1&ids="+
1378 param_escape(sel_rows.toString());
1379
1380 new Ajax.Request("backend.php", {
1381 parameters: query,
1382 onComplete: function(transport) {
1383 notify_callback2(transport);
1384 } });
1385
1386 }
1387 } else {
1388 alert(__("No feeds are selected."));
1389 }
1390
1391 return false;
1392}
1393
1394function rescore_all_feeds() {
1395 var ok = confirm(__("Rescore all articles? This operation may take a lot of time."));
1396
1397 if (ok) {
1398 notify_progress("Rescoring feeds...", true);
1399
1400 var query = "?op=pref-feeds&method=rescoreAll&quiet=1";
1401
1402 new Ajax.Request("backend.php", {
1403 parameters: query,
1404 onComplete: function(transport) {
1405 notify_callback2(transport);
1406 } });
1407 }
1408}
1409
1410function labelColorReset() {
1411 try {
1412 var labels = getSelectedLabels();
1413
1414 if (labels.length > 0) {
1415 var ok = confirm(__("Reset selected labels to default colors?"));
1416
1417 if (ok) {
1418 var query = "?op=pref-labels&method=colorreset&ids="+
1419 param_escape(labels.toString());
1420
1421 new Ajax.Request("backend.php", {
1422 parameters: query,
1423 onComplete: function(transport) {
1424 updateLabelList();
1425 } });
1426 }
1427
1428 } else {
1429 alert(__("No labels are selected."));
1430 }
1431
1432 } catch (e) {
1433 exception_error("labelColorReset", e);
1434 }
1435}
1436
1437
1438function inPreferences() {
1439 return true;
1440}
1441
1442function editProfiles() {
1443 try {
1444
1445 if (dijit.byId("profileEditDlg"))
1446 dijit.byId("profileEditDlg").destroyRecursive();
1447
1448 var query = "backend.php?op=dlg&method=editPrefProfiles";
1449
1450 dialog = new dijit.Dialog({
1451 id: "profileEditDlg",
1452 title: __("Settings Profiles"),
1453 style: "width: 600px",
1454 getSelectedProfiles: function() {
1455 return getSelectedTableRowIds("prefFeedProfileList");
1456 },
1457 removeSelected: function() {
1458 var sel_rows = this.getSelectedProfiles();
1459
1460 if (sel_rows.length > 0) {
1461 var ok = confirm(__("Remove selected profiles? Active and default profiles will not be removed."));
1462
1463 if (ok) {
1464 notify_progress("Removing selected profiles...", true);
1465
1466 var query = "?op=rpc&method=remprofiles&ids="+
1467 param_escape(sel_rows.toString());
1468
1469 new Ajax.Request("backend.php", {
1470 parameters: query,
1471 onComplete: function(transport) {
1472 notify('');
1473 editProfiles();
1474 } });
1475
1476 }
1477
1478 } else {
1479 alert(__("No profiles are selected."));
1480 }
1481 },
1482 activateProfile: function() {
1483 var sel_rows = this.getSelectedProfiles();
1484
1485 if (sel_rows.length == 1) {
1486
1487 var ok = confirm(__("Activate selected profile?"));
1488
1489 if (ok) {
1490 notify_progress("Loading, please wait...");
1491
1492 var query = "?op=rpc&method=setprofile&id="+
1493 param_escape(sel_rows.toString());
1494
1495 new Ajax.Request("backend.php", {
1496 parameters: query,
1497 onComplete: function(transport) {
1498 window.location.reload();
1499 } });
1500 }
1501
1502 } else {
1503 alert(__("Please choose a profile to activate."));
1504 }
1505 },
1506 addProfile: function() {
1507 if (this.validate()) {
1508 notify_progress("Creating profile...", true);
1509
1510 var query = "?op=rpc&method=addprofile&title=" +
1511 param_escape(dialog.attr('value').newprofile);
1512
1513 new Ajax.Request("backend.php", {
1514 parameters: query,
1515 onComplete: function(transport) {
1516 notify('');
1517 editProfiles();
1518 } });
1519
1520 }
1521 },
1522 execute: function() {
1523 if (this.validate()) {
1524 }
1525 },
1526 href: query});
1527
1528 dialog.show();
1529 } catch (e) {
1530 exception_error("editProfiles", e);
1531 }
1532}
1533
1534function activatePrefProfile() {
1535
1536 var sel_rows = getSelectedFeedCats();
1537
1538 if (sel_rows.length == 1) {
1539
1540 var ok = confirm(__("Activate selected profile?"));
1541
1542 if (ok) {
1543 notify_progress("Loading, please wait...");
1544
1545 var query = "?op=rpc&method=setprofile&id="+
1546 param_escape(sel_rows.toString());
1547
1548 new Ajax.Request("backend.php", {
1549 parameters: query,
1550 onComplete: function(transport) {
1551 window.location.reload();
1552 } });
1553 }
1554
1555 } else {
1556 alert(__("Please choose a profile to activate."));
1557 }
1558
1559 return false;
1560}
1561
1562function clearFeedAccessKeys() {
1563
1564 var ok = confirm(__("This will invalidate all previously generated feed URLs. Continue?"));
1565
1566 if (ok) {
1567 notify_progress("Clearing URLs...");
1568
1569 var query = "?op=rpc&method=clearKeys";
1570
1571 new Ajax.Request("backend.php", {
1572 parameters: query,
1573 onComplete: function(transport) {
1574 notify_info("Generated URLs cleared.");
1575 } });
1576 }
1577
1578 return false;
1579}
1580
1581function clearArticleAccessKeys() {
1582
1583 var ok = confirm(__("This will invalidate all previously shared article URLs. Continue?"));
1584
1585 if (ok) {
1586 notify_progress("Clearing URLs...");
1587
1588 var query = "?op=rpc&method=clearArticleKeys";
1589
1590 new Ajax.Request("backend.php", {
1591 parameters: query,
1592 onComplete: function(transport) {
1593 notify_info("Shared URLs cleared.");
1594 } });
1595 }
1596
1597 return false;
1598}
1599function resetFeedOrder() {
1600 try {
1601 notify_progress("Loading, please wait...");
1602
1603 new Ajax.Request("backend.php", {
1604 parameters: "?op=pref-feeds&method=feedsortreset",
1605 onComplete: function(transport) {
1606 updateFeedList();
1607 } });
1608
1609
1610 } catch (e) {
1611 exception_error("resetFeedOrder");
1612 }
1613}
1614
1615function resetCatOrder() {
1616 try {
1617 notify_progress("Loading, please wait...");
1618
1619 new Ajax.Request("backend.php", {
1620 parameters: "?op=pref-feeds&method=catsortreset",
1621 onComplete: function(transport) {
1622 updateFeedList();
1623 } });
1624
1625
1626 } catch (e) {
1627 exception_error("resetCatOrder");
1628 }
1629}
1630
1631function editCat(id, item, event) {
1632 try {
1633 var new_name = prompt(__('Rename category to:'), item.name);
1634
1635 if (new_name && new_name != item.name) {
1636
1637 notify_progress("Loading, please wait...");
1638
1639 new Ajax.Request("backend.php", {
1640 parameters: {
1641 op: 'pref-feeds',
1642 method: 'renamecat',
1643 id: id,
1644 title: new_name,
1645 },
1646 onComplete: function(transport) {
1647 updateFeedList();
1648 } });
1649 }
1650
1651 } catch (e) {
1652 exception_error("editCat", e);
1653 }
1654}
1655
1656function editLabel(id, event) {
1657 try {
1658 var query = "backend.php?op=pref-labels&method=edit&id=" +
1659 param_escape(id);
1660
1661 if (dijit.byId("labelEditDlg"))
1662 dijit.byId("labelEditDlg").destroyRecursive();
1663
1664 dialog = new dijit.Dialog({
1665 id: "labelEditDlg",
1666 title: __("Label Editor"),
1667 style: "width: 600px",
1668 setLabelColor: function(id, fg, bg) {
1669
1670 var kind = '';
1671 var color = '';
1672
1673 if (fg && bg) {
1674 kind = 'both';
1675 } else if (fg) {
1676 kind = 'fg';
1677 color = fg;
1678 } else if (bg) {
1679 kind = 'bg';
1680 color = bg;
1681 }
1682
1683 var query = "?op=pref-labels&method=colorset&kind="+kind+
1684 "&ids=" + param_escape(id) + "&fg=" + param_escape(fg) +
1685 "&bg=" + param_escape(bg) + "&color=" + param_escape(color);
1686
1687 // console.log(query);
1688
1689 var e = $("LICID-" + id);
1690
1691 if (e) {
1692 if (fg) e.style.color = fg;
1693 if (bg) e.style.backgroundColor = bg;
1694 }
1695
1696 new Ajax.Request("backend.php", { parameters: query });
1697
1698 updateFilterList();
1699 },
1700 execute: function() {
1701 if (this.validate()) {
1702 var caption = this.attr('value').caption;
1703 var fg_color = this.attr('value').fg_color;
1704 var bg_color = this.attr('value').bg_color;
1705 var query = dojo.objectToQuery(this.attr('value'));
1706
1707 dijit.byId('labelTree').setNameById(id, caption);
1708 this.setLabelColor(id, fg_color, bg_color);
1709 this.hide();
1710
1711 new Ajax.Request("backend.php", {
1712 parameters: query,
1713 onComplete: function(transport) {
1714 updateFilterList();
1715 } });
1716 }
1717 },
1718 href: query});
1719
1720 dialog.show();
1721
1722 } catch (e) {
1723 exception_error("editLabel", e);
1724 }
1725}
1726
1727function clearTwitterCredentials() {
1728 try {
1729 var ok = confirm(__("This will clear your stored authentication information for Twitter. Continue?"));
1730
1731 if (ok) {
1732 notify_progress("Clearing credentials...");
1733
1734 var query = "?op=pref-feeds&method=remtwitterinfo";
1735
1736 new Ajax.Request("backend.php", {
1737 parameters: query,
1738 onComplete: function(transport) {
1739 notify_info("Twitter credentials have been cleared.");
1740 updateFeedList();
1741 } });
1742 }
1743
1744 } catch (e) {
1745 exception_error("clearTwitterCredentials", e);
1746 }
1747}
1748
1749function customizeCSS() {
1750 try {
1751 var query = "backend.php?op=dlg&method=customizeCSS";
1752
1753 if (dijit.byId("cssEditDlg"))
1754 dijit.byId("cssEditDlg").destroyRecursive();
1755
1756 dialog = new dijit.Dialog({
1757 id: "cssEditDlg",
1758 title: __("Customize stylesheet"),
1759 style: "width: 600px",
1760 execute: function() {
1761 notify_progress('Saving data...', true);
1762 new Ajax.Request("backend.php", {
1763 parameters: dojo.objectToQuery(this.attr('value')),
1764 onComplete: function(transport) {
1765 notify('');
1766 window.location.reload();
1767 } });
1768
1769 },
1770 href: query});
1771
1772 dialog.show();
1773
1774 } catch (e) {
1775 exception_error("customizeCSS", e);
1776 }
1777}
1778
1779function insertSSLserial(value) {
1780 try {
1781 dijit.byId("SSL_CERT_SERIAL").attr('value', value);
1782 } catch (e) {
1783 exception_error("insertSSLcerial", e);
1784 }
1785}
1786
1787function getSelectedInstances() {
1788 return getSelectedTableRowIds("prefInstanceList");
1789}
1790
1791function addInstance() {
1792 try {
1793 var query = "backend.php?op=dlg&method=addInstance";
1794
1795 if (dijit.byId("instanceAddDlg"))
1796 dijit.byId("instanceAddDlg").destroyRecursive();
1797
1798 dialog = new dijit.Dialog({
1799 id: "instanceAddDlg",
1800 title: __("Link Instance"),
1801 style: "width: 600px",
1802 regenKey: function() {
1803 new Ajax.Request("backend.php", {
1804 parameters: "?op=rpc&method=genHash",
1805 onComplete: function(transport) {
1806 var reply = JSON.parse(transport.responseText);
1807 if (reply)
1808 dijit.byId('instance_add_key').attr('value', reply.hash);
1809
1810 } });
1811 },
1812 execute: function() {
1813 if (this.validate()) {
1814 console.warn(dojo.objectToQuery(this.attr('value')));
1815
1816 notify_progress('Saving data...', true);
1817 new Ajax.Request("backend.php", {
1818 parameters: dojo.objectToQuery(this.attr('value')),
1819 onComplete: function(transport) {
1820 dialog.hide();
1821 notify('');
1822 updateInstanceList();
1823 } });
1824 }
1825 },
1826 href: query,
1827 });
1828
1829 dialog.show();
1830
1831 } catch (e) {
1832 exception_error("addInstance", e);
1833 }
1834}
1835
1836function editInstance(id, event) {
1837 try {
1838 if (!event || !event.ctrlKey) {
1839
1840 selectTableRows('prefInstanceList', 'none');
1841 selectTableRowById('LIRR-'+id, 'LICHK-'+id, true);
1842
1843 var query = "backend.php?op=pref-instances&method=edit&id=" +
1844 param_escape(id);
1845
1846 if (dijit.byId("instanceEditDlg"))
1847 dijit.byId("instanceEditDlg").destroyRecursive();
1848
1849 dialog = new dijit.Dialog({
1850 id: "instanceEditDlg",
1851 title: __("Edit Instance"),
1852 style: "width: 600px",
1853 regenKey: function() {
1854 new Ajax.Request("backend.php", {
1855 parameters: "?op=rpc&method=genHash",
1856 onComplete: function(transport) {
1857 var reply = JSON.parse(transport.responseText);
1858 if (reply)
1859 dijit.byId('instance_edit_key').attr('value', reply.hash);
1860
1861 } });
1862 },
1863 execute: function() {
1864 if (this.validate()) {
1865// console.warn(dojo.objectToQuery(this.attr('value')));
1866
1867 notify_progress('Saving data...', true);
1868 new Ajax.Request("backend.php", {
1869 parameters: dojo.objectToQuery(this.attr('value')),
1870 onComplete: function(transport) {
1871 dialog.hide();
1872 notify('');
1873 updateInstanceList();
1874 } });
1875 }
1876 },
1877 href: query,
1878 });
1879
1880 dialog.show();
1881
1882 } else if (event.ctrlKey) {
1883 var cb = $('LICHK-' + id);
1884 cb.checked = !cb.checked;
1885 toggleSelectRow(cb);
1886 }
1887
1888
1889 } catch (e) {
1890 exception_error("editInstance", e);
1891 }
1892}
1893
1894function removeSelectedInstances() {
1895 try {
1896 var sel_rows = getSelectedInstances();
1897
1898 if (sel_rows.length > 0) {
1899
1900 var ok = confirm(__("Remove selected instances?"));
1901
1902 if (ok) {
1903 notify_progress("Removing selected instances...");
1904
1905 var query = "?op=pref-instances&method=remove&ids="+
1906 param_escape(sel_rows.toString());
1907
1908 new Ajax.Request("backend.php", {
1909 parameters: query,
1910 onComplete: function(transport) {
1911 notify('');
1912 updateInstanceList();
1913 } });
1914 }
1915
1916 } else {
1917 alert(__("No instances are selected."));
1918 }
1919
1920 } catch (e) {
1921 exception_error("removeInstance", e);
1922 }
1923}
1924
1925function editSelectedInstance() {
1926 var rows = getSelectedInstances();
1927
1928 if (rows.length == 0) {
1929 alert(__("No instances are selected."));
1930 return;
1931 }
1932
1933 if (rows.length > 1) {
1934 alert(__("Please select only one instance."));
1935 return;
1936 }
1937
1938 notify("");
1939
1940 editInstance(rows[0]);
1941}
1942