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