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