]> git.wh0rd.org - tt-rss.git/blame - tt-rss.js
use Modalbox library for popup dialogs
[tt-rss.git] / tt-rss.js
CommitLineData
76798ff3 1var total_unread = 0;
8143ae1f 2var display_tags = false;
806a3d14 3var global_unread = -1;
2bf6e0a8 4var firsttime_update = true;
3d72bbdb
AD
5var _active_feed_id = 0;
6var _active_feed_is_cat = false;
9e397d0f 7var number_of_feeds = 0;
93f66472 8var hotkey_prefix = false;
164469f9 9var hotkey_prefix_pressed = false;
f8fb4498 10var init_params = {};
cfd58e50
AD
11var ver_offset = 0;
12var hor_offset = 0;
f8fb4498
AD
13var _force_scheduled_update = false;
14var last_scheduled_update = false;
a5550322 15
6237ea05
AD
16var _rpc_seq = 0;
17
18function next_seq() {
19 _rpc_seq += 1;
20 return _rpc_seq;
21}
22
23function get_seq() {
24 return _rpc_seq;
25}
26
3d72bbdb
AD
27function activeFeedIsCat() {
28 return _active_feed_is_cat;
29}
30
31function getActiveFeedId() {
3d72bbdb 32 try {
50eefedb 33 //console.log("gAFID: " + _active_feed_id);
3d72bbdb
AD
34 return _active_feed_id;
35 } catch (e) {
36 exception_error("getActiveFeedId", e);
37 }
38}
39
40function setActiveFeedId(id, is_cat) {
3d72bbdb 41 try {
50eefedb 42 //console.log("sAFID(" + id + ", " + is_cat + ")");
3d72bbdb
AD
43 _active_feed_id = id;
44
45 if (is_cat != undefined) {
46 _active_feed_is_cat = is_cat;
47 }
48
49 } catch (e) {
50 exception_error("setActiveFeedId", e);
51 }
52}
53
54
a5550322
AD
55function isFeedlistSortable() {
56 return feedlist_sortable_enabled;
57}
3ac2b520 58
0b126ac2
AD
59function tagsAreDisplayed() {
60 return display_tags;
61}
62
0979b696 63function toggleTags(show_all) {
8143ae1f 64
17a756d1
AD
65 try {
66
84c7b824 67 console.log("toggleTags: " + show_all + "; " + display_tags);
17a756d1 68
acac8448 69 var p = $("dispSwitchPrompt");
8143ae1f 70
0979b696
AD
71 if (!show_all && !display_tags) {
72 displayDlg("printTagCloud");
73 } else if (show_all) {
74 closeInfoBox();
75 display_tags = true;
709e7dc2 76 p.innerHTML = __("display feeds");
35a03bdd 77 notify_progress("Loading, please wait...", true);
0979b696
AD
78 updateFeedList();
79 } else if (display_tags) {
80 display_tags = false;
81 p.innerHTML = __("tag cloud");
35a03bdd 82 notify_progress("Loading, please wait...", true);
0979b696 83 updateFeedList();
8143ae1f 84 }
17a756d1
AD
85
86 } catch (e) {
87 exception_error("toggleTags", e);
88 }
8143ae1f
AD
89}
90
f3c6bf6e
AD
91function dlg_frefresh_callback(transport, deleted_feed) {
92 if (getActiveFeedId() == deleted_feed) {
fe1087fb 93 setTimeout("viewfeed(-5)", 100);
f3c6bf6e 94 }
abbe0154 95
f3c6bf6e
AD
96 setTimeout('updateFeedList(false, false)', 50);
97 closeInfoBox();
1cd17194 98}
e2f8f7b4 99
50eefedb
AD
100function updateFeedList() {
101 try {
f8fb4498 102 //console.log("updateFeedList");
59b8192f 103
50eefedb
AD
104 var query_str = "backend.php?op=feeds";
105
106 if (display_tags) {
107 query_str = query_str + "&tags=1";
108 }
109
110 if (getActiveFeedId() && !activeFeedIsCat()) {
111 query_str = query_str + "&actid=" + getActiveFeedId();
112 }
113
114 new Ajax.Request("backend.php", {
115 parameters: query_str,
116 onComplete: function(transport) {
117 render_feedlist(transport.responseText);
118 } });
e1123aee 119
50eefedb
AD
120 } catch (e) {
121 exception_error("updateFeedList", e);
122 }
1a66d16e 123}
175847de 124
476cac42 125function catchupAllFeeds() {
076682aa 126
f8232151 127 var str = __("Mark all articles as read?");
476cac42 128
f8232151 129 if (getInitParam("confirm_feed_catchup") != 1 || confirm(str)) {
476cac42 130
f8232151 131 var query_str = "backend.php?op=feeds&subop=catchupAll";
1a66d16e 132
f8232151 133 notify_progress("Marking all feeds as read...");
476cac42 134
f8fb4498 135 //console.log("catchupAllFeeds Q=" + query_str);
fc69e641 136
b4e75b2a
AD
137 new Ajax.Request("backend.php", {
138 parameters: query_str,
f8232151
AD
139 onComplete: function(transport) {
140 feedlist_callback2(transport);
141 } });
142
143 global_unread = 0;
144 updateTitle("");
145 }
476cac42 146}
1cd17194 147
767e2486 148function viewCurrentFeed(subop) {
1a66d16e 149
ec6e2fd3 150 if (getActiveFeedId() != undefined) {
3d72bbdb 151 viewfeed(getActiveFeedId(), subop, activeFeedIsCat());
f0601b87 152 }
164f4738 153 return false; // block unneeded form submits
f0601b87
AD
154}
155
40d13c28 156function timeout() {
a598370d
AD
157 if (getInitParam("bw_limit") == "1") return;
158
f8fb4498
AD
159 try {
160 var date = new Date();
161 var ts = Math.round(date.getTime() / 1000);
162
163 if (ts - last_scheduled_update > 10 || _force_scheduled_update) {
f5de0d8d 164
ac49453b
AD
165 //console.log("timeout()");
166
f8fb4498
AD
167 window.clearTimeout(counter_timeout_id);
168
6237ea05 169 var query_str = "?op=rpc&subop=getAllCounters&seq=" + next_seq();
f8fb4498
AD
170
171 var omode;
172
173 if (firsttime_update && !navigator.userAgent.match("Opera")) {
174 firsttime_update = false;
175 omode = "T";
176 } else {
177 if (display_tags) {
178 omode = "tl";
179 } else {
180 omode = "flc";
181 }
182 }
183
184 query_str = query_str + "&omode=" + omode;
ac49453b
AD
185
186 if (!_force_scheduled_update)
187 query_str = query_str + "&last_article_id=" + getInitParam("last_article_id");
f8fb4498
AD
188
189 //console.log("[timeout]" + query_str);
190
191 new Ajax.Request("backend.php", {
192 parameters: query_str,
193 onComplete: function(transport) {
47fb32b0
AD
194 handle_rpc_reply(transport, !_force_scheduled_update);
195 _force_scheduled_update = false;
f8fb4498
AD
196 } });
197
198 last_scheduled_update = ts;
199 }
200
201 } catch (e) {
202 exception_error("timeout", e);
203 }
204
205 setTimeout("timeout()", 3000);
ac53063a
AD
206}
207
f0601b87 208function search() {
eff4997c 209 closeInfoBox();
4169bb67 210 viewCurrentFeed();
76798ff3 211}
1cd17194 212
f8fb4498 213function updateTitle() {
fc69e641 214 var tmp = "Tiny Tiny RSS";
21703604 215
fc69e641
AD
216 if (global_unread > 0) {
217 tmp = tmp + " (" + global_unread + ")";
218 }
219
fdf47b9d
AD
220 if (window.fluid) {
221 if (global_unread > 0) {
222 window.fluid.dockBadge = global_unread;
223 } else {
224 window.fluid.dockBadge = "";
225 }
226 }
227
fc69e641
AD
228 document.title = tmp;
229}
230
22a93ad8 231function genericSanityCheck() {
57937c42 232 setCookie("ttrss_test", "TEST");
295f9b42 233
57937c42 234 if (getCookie("ttrss_test") != "TEST") {
295f9b42
AD
235 fatalError(2);
236 }
237
22a93ad8
AD
238 return true;
239}
240
241function init() {
7719618b 242 try {
86b682ce
AD
243 Form.disable("main_toolbar_form");
244
7719618b
AD
245 if (!genericSanityCheck())
246 return;
ac43eba1 247
4220d6b0
AD
248 var params = "&ua=" + param_escape(navigator.userAgent);
249
fca95d5f
AD
250 loading_set_progress(30);
251
b4e75b2a
AD
252 new Ajax.Request("backend.php", {
253 parameters: "backend.php?op=rpc&subop=sanityCheck" + params,
9ca945a6
AD
254 onComplete: function(transport) {
255 backend_sanity_check_callback(transport);
256 } });
47179952 257
7719618b
AD
258 } catch (e) {
259 exception_error("init", e);
a8d28f48 260 }
7719618b 261}
86741347 262
f3169d7e
AD
263function resize_headlines(delta_x, delta_y) {
264
e8f7d726 265 try {
cfd58e50 266
84c7b824 267 console.log("resize_headlines: " + delta_x + ":" + delta_y);
e8f7d726 268
acac8448
AD
269 var h_frame = $("headlines-frame");
270 var c_frame = $("content-frame");
271 var f_frame = $("footer");
272 var feeds_frame = $("feeds-holder");
273 var resize_grab = $("resize-grabber");
274 var resize_handle = $("resize-handle");
17042fc0 275
e8f7d726
AD
276 if (!c_frame || !h_frame) return;
277
e71f2610 278 if (feeds_frame && getInitParam("theme") == "old-skool") {
e8f7d726 279 feeds_frame.style.bottom = f_frame.offsetHeight + "px";
cfd58e50 280 }
e8f7d726 281
e71f2610 282 if (getInitParam("theme_options").match("horiz_resize")) {
e8f7d726
AD
283
284 if (delta_x != undefined) {
285 if (c_frame.offsetLeft - delta_x > feeds_frame.offsetWidth + feeds_frame.offsetLeft + 100 && c_frame.offsetWidth + delta_x > 100) {
286 hor_offset = hor_offset + delta_x;
287 }
e86dbf9d 288 }
e8f7d726 289
84c7b824 290 console.log("resize_headlines: HOR-mode: " + hor_offset);
e8f7d726
AD
291
292 c_frame.style.width = (400 + hor_offset) + "px";
293 h_frame.style.right = c_frame.offsetWidth - 1 + "px";
294
295 resize_grab.style.top = (h_frame.offsetTop + h_frame.offsetHeight - 60) + "px";
296 resize_grab.style.left = (h_frame.offsetLeft + h_frame.offsetWidth -
297 4) + "px";
298 resize_grab.style.display = "block";
17042fc0 299
4336531d 300 //resize_handle.src = "themes/"+getInitParam('theme')+"/images/resize_handle_vert.png";
17042fc0 301 resize_handle.style.paddingTop = (resize_grab.offsetHeight / 2 - 7) + "px";
e8f7d726
AD
302
303 } else {
304
305 if (delta_y != undefined) {
306 if (c_frame.offsetHeight + delta_y > 100 && h_frame.offsetHeight - delta_y > 100) {
307 ver_offset = ver_offset + delta_y;
308 }
309 }
310
84c7b824 311 console.log("resize_headlines: VER-mode: " + ver_offset);
e8f7d726
AD
312
313 h_frame.style.height = (300 - ver_offset) + "px";
314
f115fb2c 315 c_frame.style.top = (h_frame.offsetTop + h_frame.offsetHeight + 0) + "px";
e8f7d726 316 h_frame.style.height = h_frame.offsetHeight + "px";
17042fc0 317
6240dabe
AD
318 // Workaround for Opera: force the content page to be re-rendered,
319 // so it is not truncated:
320 var content_pane = $("content-insert");
321 content_pane.innerHTML = content_pane.innerHTML;
e8f7d726
AD
322 }
323
324 if (getInitParam("cookie_lifetime") != 0) {
325 setCookie("ttrss_offset_ver", ver_offset,
326 getInitParam("cookie_lifetime"));
327 setCookie("ttrss_offset_hor", hor_offset,
328 getInitParam("cookie_lifetime"));
329 } else {
330 setCookie("ttrss_offset_ver", ver_offset);
331 setCookie("ttrss_offset_hor", hor_offset);
d16a5159 332 }
cfd58e50 333
e8f7d726
AD
334 } catch (e) {
335 exception_error("resize_headlines", e);
cfd58e50
AD
336 }
337
a9d42cf7
AD
338}
339
7719618b 340function init_second_stage() {
295f9b42 341
7719618b 342 try {
2f587484 343
57937c42 344 delCookie("ttrss_test");
770bbb02 345
44258fa9 346 window.onresize=resize_headlines;
1b0809ae 347
40496720 348 var toolbar = document.forms["main_toolbar_form"];
f31673f7 349
40496720 350 dropboxSelect(toolbar.view_mode, getInitParam("default_view_mode"));
7b4d02a8 351 dropboxSelect(toolbar.order_by, getInitParam("default_view_order_by"));
c6784aea 352
61a20560 353 feeds_sort_by_unread = getInitParam("feeds_sort_by_unread") == 1;
5f136c9a 354
10a127db 355 setTimeout('updateFeedList(false, false)', 50);
0ee1d1a0 356
84c7b824 357 console.log("second stage ok");
fca95d5f 358
730dbf19
AD
359 loading_set_progress(60);
360
0fb6ae04
AD
361 ver_offset = parseInt(getCookie("ttrss_offset_ver"));
362 hor_offset = parseInt(getCookie("ttrss_offset_hor"));
363
84c7b824 364 console.log("got offsets from cookies: ver " + ver_offset + " hor " + hor_offset);
fc0b87e0 365
f74cfded
AD
366 /* fuck IE */
367
368 if (isNaN(hor_offset)) hor_offset = 0;
369 if (isNaN(ver_offset)) ver_offset = 0;
370
84c7b824 371 console.log("offsets from cookies [x:y]: " + hor_offset + ":" + ver_offset);
43dbb07f 372
0fb6ae04 373 resize_headlines();
43dbb07f 374
ff0010c1
AD
375 if (has_local_storage())
376 localStorage.clear();
377
7719618b
AD
378 } catch (e) {
379 exception_error("init_second_stage", e);
2f587484 380 }
1cd17194 381}
ac43eba1 382
c09ec856 383function quickMenuChange() {
acac8448 384 var chooser = $("quickMenuChooser");
86b682ce 385 var opid = chooser[chooser.selectedIndex].value;
e2f8f7b4 386
c09ec856
AD
387 chooser.selectedIndex = 0;
388 quickMenuGo(opid);
389}
390
391function quickMenuGo(opid) {
bb3423cf 392 try {
c09ec856 393
bb3423cf
AD
394 if (opid == "qmcPrefs") {
395 gotoPreferences();
396 }
397
398 if (opid == "qmcSearch") {
a44049f6
AD
399 displayDlg("search", getActiveFeedId() + ":" + activeFeedIsCat(),
400 function() {
401 document.forms['search_form'].query.focus();
402 });
6de5d056
AD
403 return;
404 }
bb3423cf
AD
405
406 if (opid == "qmcAddFeed") {
3393238d 407 quickAddFeed();
bb3423cf 408 return;
69668465 409 }
7086277c
AD
410
411 if (opid == "qmcEditFeed") {
412 editFeedDlg(getActiveFeedId());
413 }
6de5d056 414
bb3423cf
AD
415 if (opid == "qmcRemoveFeed") {
416 var actid = getActiveFeedId();
442d77f1
AD
417
418 if (activeFeedIsCat()) {
89cb787e 419 alert(__("You can't unsubscribe from the category."));
442d77f1
AD
420 return;
421 }
422
423 if (!actid) {
89cb787e 424 alert(__("Please select some feed first."));
bb3423cf
AD
425 return;
426 }
64a2875d
AD
427
428 var fn = getFeedName(actid);
89cb787e
AD
429
430 var pr = __("Unsubscribe from %s?").replace("%s", fn);
431
432 if (confirm(pr)) {
e978f78d 433 unsubscribeFeed(actid);
bb3423cf
AD
434 }
435
436 return;
437 }
d1f0c584 438
bb3423cf
AD
439 if (opid == "qmcCatchupAll") {
440 catchupAllFeeds();
441 return;
442 }
443
444 if (opid == "qmcShowOnlyUnread") {
445 toggleDispRead();
446 return;
447 }
448
449 if (opid == "qmcAddFilter") {
a6d0014d
AD
450 displayDlg('quickAddFilter', '',
451 function () {document.forms['filter_add_form'].reg_exp.focus();});
bb3423cf 452 }
0979b696 453
1380f8ee
AD
454 if (opid == "qmcAddLabel") {
455 addLabel();
456 }
457
9a85081a
AD
458 if (opid == "qmcRescoreFeed") {
459 rescoreCurrentFeed();
460 }
461
238eff01 462 if (opid == "qmcHKhelp") {
86deaa0e
AD
463 //Element.show("hotkey_help_overlay");
464 Effect.Appear("hotkey_help_overlay", {duration : 0.3});
238eff01
AD
465 }
466
d16a5159
AD
467 if (opid == "qmcResetUI") {
468 hor_offset = 0;
469 ver_offset = 0;
470 resize_headlines();
471 }
472
791c8396
AD
473 if (opid == "qmcToggleReorder") {
474 feedlist_sortable_enabled = !feedlist_sortable_enabled;
475
476 if (feedlist_sortable_enabled) {
477 notify_info("Category reordering enabled");
478 toggle_sortable_feedlist(true);
479 } else {
480 notify_info("Category reordering disabled");
481 toggle_sortable_feedlist(false);
482 }
483 }
484
9d393c84
AD
485 if (opid == "qmcResetCats") {
486
487 if (confirm(__("Reset category order?"))) {
488
b4e75b2a 489 var query = "?op=feeds&subop=catsortreset";
9d393c84
AD
490
491 notify_progress("Loading, please wait...", true);
492
b4e75b2a
AD
493 new Ajax.Request("backend.php", {
494 parameters: query,
9d393c84
AD
495 onComplete: function(transport) {
496 window.setTimeout('updateFeedList(false, false)', 50);
497 } });
498 }
499 }
500
bb3423cf
AD
501 } catch (e) {
502 exception_error("quickMenuGo", e);
a24f525c 503 }
e2f8f7b4
AD
504}
505
3745788e 506function toggleDispRead() {
7f123cda 507 try {
3745788e 508
dbfc9522 509 var hide = !(getInitParam("hide_read_feeds") == "1");
3745788e 510
dbfc9522 511 hideOrShowFeeds(hide);
e8bd0da9 512
dbfc9522
AD
513 var query = "?op=rpc&subop=setpref&key=HIDE_READ_FEEDS&value=" +
514 param_escape(hide);
e8bd0da9 515
dbfc9522
AD
516 new Ajax.Request("backend.php", {
517 parameters: query,
518 onComplete: function(transport) {
519 setInitParam("hide_read_feeds", hide);
520 } });
5158ced9 521
7f123cda
AD
522 } catch (e) {
523 exception_error("toggleDispRead", e);
3745788e 524 }
3745788e 525}
295f9b42 526
71ad883b 527function parse_runtime_info(elem) {
c4f7ba80
AD
528
529 if (!elem || !elem.firstChild) {
f8fb4498 530 console.warn("parse_runtime_info: invalid node passed");
4724a093
AD
531 return;
532 }
533
c4f7ba80 534 var data = JSON.parse(elem.firstChild.nodeValue);
71ad883b 535
f8fb4498 536 //console.log("parsing runtime info...");
1cb7492d 537
c4f7ba80
AD
538 for (k in data) {
539 var v = data[k];
3ac2b520 540
f8fb4498 541 // console.log("RI: " + k + " => " + v);
1cb7492d 542
d9fa39f1 543 if (k == "new_version_available") {
acac8448 544 var icon = $("newVersionIcon");
d9fa39f1
AD
545 if (icon) {
546 if (v == "1") {
547 icon.style.display = "inline";
548 } else {
549 icon.style.display = "none";
550 }
551 }
5ae8f858 552 return;
d9fa39f1
AD
553 }
554
8e00ae9b
AD
555 var error_flag;
556
ef16ae37 557 if (k == "daemon_is_running" && v != 1) {
8e00ae9b 558 notify_error("<span onclick=\"javascript:explainError(1)\">Update daemon is not running.</span>", true);
5ae8f858 559 return;
8e00ae9b
AD
560 }
561
562 if (k == "daemon_stamp_ok" && v != 1) {
563 notify_error("<span onclick=\"javascript:explainError(3)\">Update daemon is not updating feeds.</span>", true);
5ae8f858 564 return;
8e00ae9b
AD
565 }
566
5ae8f858
AD
567 init_params[k] = v;
568 notify('');
71ad883b
AD
569 }
570}
fce24838
AD
571
572function catchupCurrentFeed() {
573
3d72bbdb 574 var fn = getFeedName(getActiveFeedId(), activeFeedIsCat());
fce24838 575
2d936cd1 576 var str = __("Mark all articles in %s as read?").replace("%s", fn);
234e467c 577
f6d6e22f 578 if (getInitParam("confirm_feed_catchup") != 1 || confirm(str)) {
28de3732 579 return viewCurrentFeed('MarkAllRead')
fce24838
AD
580 }
581}
88040f57 582
338ce36c 583function catchupFeedInGroup(id) {
a9bcfb8f 584
338ce36c 585 try {
a9bcfb8f 586
338ce36c
AD
587 var title = getFeedName(id);
588
589 var str = __("Mark all articles in %s as read?").replace("%s", title);
590
591 if (getInitParam("confirm_feed_catchup") != 1 || confirm(str)) {
592 return viewCurrentFeed('MarkAllReadGR:' + id)
593 }
594
595 } catch (e) {
596 exception_error("catchupFeedInGroup", e);
a9bcfb8f
AD
597 }
598}
599
7086277c 600function editFeedDlg(feed) {
2a8504cd 601 try {
7086277c 602
2a8504cd
AD
603 if (!feed) {
604 alert(__("Please select some feed first."));
605 return;
606 }
607
f11b8a34 608 if ((feed <= 0) || activeFeedIsCat() || tagsAreDisplayed()) {
2a8504cd
AD
609 alert(__("You can't edit this kind of feed."));
610 return;
611 }
612
613 var query = "";
614
6f151277 615 if (feed > 0) {
b4e75b2a 616 query = "?op=pref-feeds&subop=editfeed&id=" + param_escape(feed);
6f151277 617 } else {
b4e75b2a 618 query = "?op=pref-labels&subop=edit&id=" + param_escape(-feed-11);
6f151277 619 }
c67d2990
AD
620
621 disableHotkeys();
622
219f57fd
AD
623 notify_progress("Loading, please wait...", true);
624
b4e75b2a
AD
625 new Ajax.Request("backend.php", {
626 parameters: query,
2a8504cd
AD
627 onComplete: function(transport) {
628 infobox_callback2(transport);
3393238d 629 document.forms["edit_feed_form"].title.focus();
2a8504cd
AD
630 } });
631
632 } catch (e) {
633 exception_error("editFeedDlg", e);
7086277c
AD
634 }
635}
636
637/* this functions duplicate those of prefs.js feed editor, with
638 some differences because there is no feedlist */
639
640function feedEditCancel() {
641 closeInfoBox();
642 return false;
643}
644
645function feedEditSave() {
646
647 try {
648
7086277c
AD
649 // FIXME: add parameter validation
650
651 var query = Form.serialize("edit_feed_form");
652
42c32916 653 notify_progress("Saving feed...");
7086277c 654
f3c6bf6e
AD
655 new Ajax.Request("backend.php", {
656 parameters: query,
657 onComplete: function(transport) {
658 dlg_frefresh_callback(transport);
659 } });
660
641444d3 661 cache_flush();
7086277c
AD
662 closeInfoBox();
663
664 return false;
665
666 } catch (e) {
667 exception_error("feedEditSave (main)", e);
668 }
669}
1dc8dba0 670
8389b150
AD
671function collapse_feedlist() {
672 try {
f8fb4498 673 //console.log("collapse_feedlist");
58daed52
AD
674
675 var theme = getInitParam("theme");
b3af99a0
AD
676 if (theme != "" &&
677 !getInitParam("theme_options").match("collapse_feedlist")) return;
8389b150 678
acac8448
AD
679 var fl = $("feeds-holder");
680 var fh = $("headlines-frame");
681 var fc = $("content-frame");
682 var ft = $("toolbar");
683 var ff = $("footer");
684 var fhdr = $("header");
685 var fbtn = $("collapse_feeds_btn");
8389b150
AD
686
687 if (!Element.visible(fl)) {
688 Element.show(fl);
74834573 689 fbtn.innerHTML = "&lt;&lt;";
8389b150 690
f0e8468b 691 if (theme != "graycube") {
8389b150 692
f0e8468b
AD
693 fh.style.left = fl.offsetWidth + "px";
694 ft.style.left = fl.offsetWidth + "px";
695 if (fc) fc.style.left = fl.offsetWidth + "px";
03177e82 696 if (ff && theme != "compat") ff.style.left = (fl.offsetWidth-1) + "px";
f0e8468b
AD
697
698 if (theme == "compact") fhdr.style.left = (fl.offsetWidth + 10) + "px";
699 } else {
700 fh.style.left = fl.offsetWidth + 40 + "px";
701 ft.style.left = fl.offsetWidth + 40 +"px";
702 if (fc) fc.style.left = fl.offsetWidth + 40 + "px";
703 }
58daed52 704
b4e75b2a 705 query = "?op=rpc&subop=setpref&key=_COLLAPSED_FEEDLIST&value=false";
57937c42 706
b4e75b2a 707 new Ajax.Request("backend.php", { parameters: query });
22936abb 708
8389b150
AD
709 } else {
710 Element.hide(fl);
74834573 711 fbtn.innerHTML = "&gt;&gt;";
8389b150 712
f0e8468b
AD
713 if (theme != "graycube") {
714
715 fh.style.left = "0px";
716 ft.style.left = "0px";
717 if (fc) fc.style.left = "0px";
718 if (ff) ff.style.left = "0px";
22936abb 719
f0e8468b
AD
720 if (theme == "compact") fhdr.style.left = "10px";
721
722 } else {
723 fh.style.left = "20px";
724 ft.style.left = "20px";
725 if (fc) fc.style.left = "20px";
726
727 }
58daed52 728
b4e75b2a 729 query = "?op=rpc&subop=setpref&key=_COLLAPSED_FEEDLIST&value=true";
57937c42 730
b4e75b2a 731 new Ajax.Request("backend.php", { parameters: query });
57937c42 732
8389b150
AD
733 }
734 } catch (e) {
f88c7814 735 exception_error("collapse_feedlist", e);
8389b150 736 }
3c2d7945 737}
8389b150 738
3c2d7945 739function viewModeChanged() {
641444d3 740 cache_flush();
35322147 741 return viewCurrentFeed('')
3c2d7945 742}
8389b150 743
3c2d7945 744function viewLimitChanged() {
641444d3 745 cache_flush();
35322147 746 return viewCurrentFeed('')
8389b150 747}
546499a9 748
9bf3f101 749/* function adjustArticleScore(id, score) {
546499a9
AD
750 try {
751
752 var pr = prompt(__("Assign score to article:"), score);
753
754 if (pr != undefined) {
b4e75b2a 755 var query = "?op=rpc&subop=setScore&id=" + id + "&score=" + pr;
546499a9 756
b4e75b2a
AD
757 new Ajax.Request("backend.php", {
758 parameters: query,
546499a9
AD
759 onComplete: function(transport) {
760 viewCurrentFeed();
761 } });
762
763 }
764 } catch (e) {
438f2ce9 765 exception_error("adjustArticleScore", e);
546499a9 766 }
9bf3f101 767} */
9a85081a
AD
768
769function rescoreCurrentFeed() {
770
771 var actid = getActiveFeedId();
772
773 if (activeFeedIsCat() || actid < 0 || tagsAreDisplayed()) {
774 alert(__("You can't rescore this kind of feed."));
775 return;
776 }
777
778 if (!actid) {
779 alert(__("Please select some feed first."));
780 return;
781 }
782
783 var fn = getFeedName(actid);
69811a7d 784 var pr = __("Rescore articles in %s?").replace("%s", fn);
9a85081a
AD
785
786 if (confirm(pr)) {
787 notify_progress("Rescoring articles...");
788
b4e75b2a 789 var query = "?op=pref-feeds&subop=rescore&quiet=1&ids=" + actid;
9a85081a 790
b4e75b2a
AD
791 new Ajax.Request("backend.php", {
792 parameters: query,
793 onComplete: function(transport) {
794 viewCurrentFeed();
795 } });
9a85081a
AD
796 }
797}
798
93f66472
AD
799function hotkey_handler(e) {
800
801 try {
802
803 var keycode;
804 var shift_key = false;
805
78935092 806 var cmdline = $('cmdline');
93f66472
AD
807
808 try {
809 shift_key = e.shiftKey;
810 } catch (e) {
811
812 }
813
814 if (window.event) {
815 keycode = window.event.keyCode;
816 } else if (e) {
817 keycode = e.which;
818 }
819
eec498c3 820 var keychar = String.fromCharCode(keycode);
c177f2e6 821
93f66472
AD
822 if (keycode == 27) { // escape
823 if (Element.visible("hotkey_help_overlay")) {
824 Element.hide("hotkey_help_overlay");
825 }
826 hotkey_prefix = false;
827 closeInfoBox();
828 }
829
830 if (!hotkeys_enabled) {
84c7b824 831 console.log("hotkeys disabled");
93f66472
AD
832 return;
833 }
834
835 if (keycode == 16) return; // ignore lone shift
ac743c83 836 if (keycode == 17) return; // ignore lone ctrl
93f66472 837
fe3320d2
AD
838 if ((keycode == 70 || keycode == 67 || keycode == 71)
839 && !hotkey_prefix) {
344702be 840
164469f9
AD
841 var date = new Date();
842 var ts = Math.round(date.getTime() / 1000);
843
93f66472 844 hotkey_prefix = keycode;
164469f9 845 hotkey_prefix_pressed = ts;
78935092
AD
846
847 cmdline.innerHTML = keychar;
848 Element.show(cmdline);
849
84c7b824 850 console.log("KP: PREFIX=" + keycode + " CHAR=" + keychar + " TS=" + ts);
344702be 851 return true;
93f66472
AD
852 }
853
854 if (Element.visible("hotkey_help_overlay")) {
855 Element.hide("hotkey_help_overlay");
856 }
857
858 /* Global hotkeys */
859
78935092
AD
860 Element.hide(cmdline);
861
93f66472
AD
862 if (!hotkey_prefix) {
863
eec498c3 864 if ((keycode == 191 || keychar == '?') && shift_key) { // ?
93f66472 865 if (!Element.visible("hotkey_help_overlay")) {
86deaa0e
AD
866 //Element.show("hotkey_help_overlay");
867 Effect.Appear("hotkey_help_overlay", {duration : 0.3});
93f66472
AD
868 } else {
869 Element.hide("hotkey_help_overlay");
870 }
eec498c3 871 return false;
93f66472 872 }
60ea2377 873
eec498c3 874 if (keycode == 191 || keychar == '/') { // /
a44049f6
AD
875 displayDlg("search", getActiveFeedId() + ":" + activeFeedIsCat(),
876 function() {
877 document.forms['search_form'].query.focus();
878 });
eec498c3 879 return false;
93f66472
AD
880 }
881
f8fb4498 882/* if (keycode == 82 && shift_key) { // R
eec498c3 883 scheduleFeedUpdate(true);
19d7bfcd 884 return;
f8fb4498 885 } */
bd7ad16c 886
93f66472
AD
887 if (keycode == 74) { // j
888 var feed = getActiveFeedId();
ec37f4f1
AD
889 var new_feed = getRelativeFeedId2(feed, activeFeedIsCat(), 'prev');
890// alert(feed + " IC: " + activeFeedIsCat() + " => " + new_feed);
891 if (new_feed) {
892 var is_cat = new_feed.match("CAT:");
893 if (is_cat) {
894 new_feed = new_feed.replace("CAT:", "");
895 viewCategory(new_feed);
896 } else {
897 viewfeed(new_feed, '', false);
898 }
899 }
19d7bfcd 900 return;
93f66472
AD
901 }
902
903 if (keycode == 75) { // k
904 var feed = getActiveFeedId();
ec37f4f1
AD
905 var new_feed = getRelativeFeedId2(feed, activeFeedIsCat(), 'next');
906// alert(feed + " IC: " + activeFeedIsCat() + " => " + new_feed);
907 if (new_feed) {
908 var is_cat = new_feed.match("CAT:");
909 if (is_cat == "CAT:") {
910 new_feed = new_feed.replace("CAT:", "");
911 viewCategory(new_feed);
912 } else {
913 viewfeed(new_feed, '', false);
914 }
915 }
19d7bfcd 916 return;
93f66472
AD
917 }
918
a411875b 919 if (shift_key && keycode == 40) { // shift-down
62f2d58f 920 catchupRelativeToArticle(1);
19d7bfcd 921 return;
62f2d58f
AD
922 }
923
a411875b 924 if (shift_key && keycode == 38) { // shift-up
62f2d58f 925 catchupRelativeToArticle(0);
19d7bfcd 926 return;
62f2d58f
AD
927 }
928
a411875b
AD
929 if (shift_key && keycode == 78) { // N
930 scrollArticle(50);
931 return;
932 }
933
934 if (shift_key && keycode == 80) { // P
935 scrollArticle(-50);
936 return;
937 }
938
0129090b 939 if (keycode == 68 && shift_key) { // shift-D
1ede5814
AD
940 dismissSelectedArticles();
941 }
942
943 if (keycode == 88 && shift_key) { // shift-X
944 dismissReadArticles();
0129090b 945 }
a411875b 946
93f66472
AD
947 if (keycode == 78 || keycode == 40) { // n, down
948 if (typeof moveToPost != 'undefined') {
314fcd2b 949 moveToPost('next');
dad14b51 950 return false;
93f66472
AD
951 }
952 }
953
954 if (keycode == 80 || keycode == 38) { // p, up
955 if (typeof moveToPost != 'undefined') {
314fcd2b 956 moveToPost('prev');
dad14b51 957 return false;
93f66472
AD
958 }
959 }
960
961 if (keycode == 83 && shift_key) { // S
ac743c83 962 selectionTogglePublished(undefined, false, true);
19d7bfcd 963 return;
93f66472
AD
964 }
965
966 if (keycode == 83) { // s
ac743c83 967 selectionToggleMarked(undefined, false, true);
19d7bfcd 968 return;
93f66472
AD
969 }
970
971
972 if (keycode == 85) { // u
ac743c83 973 selectionToggleUnread(undefined, false, true)
19d7bfcd 974 return;
93f66472
AD
975 }
976
314fcd2b 977 if (keycode == 84 && shift_key) { // T
93f66472
AD
978 var id = getActiveArticleId();
979 if (id) {
980 editArticleTags(id, getActiveFeedId(), isCdmMode());
19d7bfcd 981 return;
93f66472
AD
982 }
983 }
984
314fcd2b
AD
985 if (keycode == 9) { // tab
986 var id = getArticleUnderPointer();
93f66472 987 if (id) {
acac8448 988 var cb = $("RCHK-" + id);
93f66472
AD
989
990 if (cb) {
991 cb.checked = !cb.checked;
992 toggleSelectRowById(cb, "RROW-" + id);
eec498c3 993 return false;
93f66472
AD
994 }
995 }
314fcd2b 996 }
93f66472
AD
997
998 if (keycode == 79) { // o
999 if (getActiveArticleId()) {
1000 openArticleInNewWindow(getActiveArticleId());
19d7bfcd 1001 return;
93f66472
AD
1002 }
1003 }
1004
c1780289
AD
1005 if (keycode == 81 && shift_key) { // Q
1006 if (typeof catchupAllFeeds != 'undefined') {
1007 catchupAllFeeds();
36cebe0f 1008 return;
c1780289
AD
1009 }
1010 }
1011
9bbbc82c
AD
1012 if (keycode == 88) { // x
1013 if (activeFeedIsCat()) {
1014 toggleCollapseCat(getActiveFeedId());
1015 }
1016 }
93f66472
AD
1017 }
1018
1019 /* Prefix f */
1020
1021 if (hotkey_prefix == 70) { // f
1022
1023 hotkey_prefix = false;
1024
617698d7
AD
1025 if (keycode == 81) { // q
1026 if (getActiveFeedId()) {
1027 catchupCurrentFeed();
1028 return;
1029 }
1030 }
1031
1032 if (keycode == 82) { // r
1033 if (getActiveFeedId()) {
1034 viewfeed(getActiveFeedId(), "ForceUpdate", activeFeedIsCat());
1035 return;
1036 }
1037 }
1038
93f66472 1039 if (keycode == 65) { // a
eec498c3
AD
1040 toggleDispRead();
1041 return false;
93f66472
AD
1042 }
1043
f8fb4498 1044/* if (keycode == 85 && shift_key) { // U
eec498c3
AD
1045 scheduleFeedUpdate(true);
1046 return false;
f8fb4498 1047 } */
93f66472
AD
1048
1049 if (keycode == 85) { // u
1050 if (getActiveFeedId()) {
eec498c3
AD
1051 viewfeed(getActiveFeedId(), "ForceUpdate");
1052 return false;
93f66472
AD
1053 }
1054 }
1055
1056 if (keycode == 69) { // e
eec498c3
AD
1057 editFeedDlg(getActiveFeedId());
1058 return false;
93f66472
AD
1059 }
1060
1061 if (keycode == 83) { // s
3393238d 1062 quickAddFeed();
eec498c3 1063 return false;
93f66472
AD
1064 }
1065
1066 if (keycode == 67 && shift_key) { // C
1067 if (typeof catchupAllFeeds != 'undefined') {
eec498c3
AD
1068 catchupAllFeeds();
1069 return false;
93f66472
AD
1070 }
1071 }
1072
1073 if (keycode == 67) { // c
1074 if (getActiveFeedId()) {
eec498c3
AD
1075 catchupCurrentFeed();
1076 return false;
93f66472
AD
1077 }
1078 }
1079
60ea2377 1080 if (keycode == 87) { // w
61a20560 1081 feeds_sort_by_unread = !feeds_sort_by_unread;
60ea2377
AD
1082 return resort_feedlist();
1083 }
1084
8a3e0b1a
AD
1085 if (keycode == 88) { // x
1086 reverseHeadlineOrder();
1087 return;
1088 }
93f66472
AD
1089 }
1090
1091 /* Prefix c */
1092
1093 if (hotkey_prefix == 67) { // c
1094 hotkey_prefix = false;
1095
1096 if (keycode == 70) { // f
a6d0014d
AD
1097 displayDlg('quickAddFilter', '',
1098 function () {document.forms['filter_add_form'].reg_exp.focus();});
eec498c3 1099 return false;
93f66472
AD
1100 }
1101
fc2732f4
AD
1102 if (keycode == 76) { // l
1103 addLabel();
1104 return false;
1105 }
1106
93f66472
AD
1107 if (keycode == 83) { // s
1108 if (typeof collapse_feedlist != 'undefined') {
eec498c3
AD
1109 collapse_feedlist();
1110 return false;
93f66472
AD
1111 }
1112 }
1113
a5550322
AD
1114 if (keycode == 77) { // m
1115 feedlist_sortable_enabled = !feedlist_sortable_enabled;
1116 if (feedlist_sortable_enabled) {
1117 notify_info("Category reordering enabled");
1118 toggle_sortable_feedlist(true);
1119 } else {
1120 notify_info("Category reordering disabled");
1121 toggle_sortable_feedlist(false);
1122 }
1123 }
1124
a411875b
AD
1125 if (keycode == 78) { // n
1126 catchupRelativeToArticle(1);
1127 return;
1128 }
1129
1130 if (keycode == 80) { // p
1131 catchupRelativeToArticle(0);
1132 return;
1133 }
1134
1135
93f66472
AD
1136 }
1137
1138 /* Prefix g */
1139
1140 if (hotkey_prefix == 71) { // g
1141
1142 hotkey_prefix = false;
1143
49f4a7e9
AD
1144
1145 if (keycode == 65) { // a
1146 viewfeed(-4);
1147 return false;
1148 }
1149
93f66472 1150 if (keycode == 83) { // s
eec498c3
AD
1151 viewfeed(-1);
1152 return false;
93f66472
AD
1153 }
1154
1155 if (keycode == 80 && shift_key) { // P
eec498c3
AD
1156 gotoPreferences();
1157 return false;
93f66472
AD
1158 }
1159
1160 if (keycode == 80) { // p
eec498c3
AD
1161 viewfeed(-2);
1162 return false;
93f66472
AD
1163 }
1164
1165 if (keycode == 70) { // f
eec498c3
AD
1166 viewfeed(-3);
1167 return false;
93f66472
AD
1168 }
1169
5cf0cc5d 1170 if (keycode == 84 && shift_key) { // T
3a391f67 1171 toggleTags();
eec498c3 1172 return false;
3a391f67 1173 }
43319e5e
AD
1174 }
1175
1176 /* Cmd */
93f66472 1177
43319e5e
AD
1178 if (hotkey_prefix == 224 || hotkey_prefix == 91) { // f
1179 hotkey_prefix = false;
1180 return;
93f66472
AD
1181 }
1182
93f66472 1183 if (hotkey_prefix) {
84c7b824 1184 console.log("KP: PREFIX=" + hotkey_prefix + " CODE=" + keycode + " CHAR=" + keychar);
93f66472 1185 } else {
84c7b824 1186 console.log("KP: CODE=" + keycode + " CHAR=" + keychar);
93f66472
AD
1187 }
1188
1189
1190 } catch (e) {
1191 exception_error("hotkey_handler", e);
1192 }
1193}
61a20560 1194
a5819bb3
AD
1195function inPreferences() {
1196 return false;
1197}
8a3e0b1a
AD
1198
1199function reverseHeadlineOrder() {
1200 try {
1201
1202 var query_str = "?op=rpc&subop=togglepref&key=REVERSE_HEADLINES";
1203
1204 new Ajax.Request("backend.php", {
1205 parameters: query_str,
1206 onComplete: function(transport) {
1207 viewCurrentFeed();
1208 } });
1209
1210 } catch (e) {
1211 exception_error("reverseHeadlineOrder", e);
1212 }
1213}
fe1087fb
AD
1214
1215function showFeedsWithErrors() {
1216 displayDlg('feedUpdateErrors');
1217}
1218
f705f206
AD
1219function handle_rpc_reply(transport, scheduled_call) {
1220 try {
f705f206
AD
1221 if (transport.responseXML) {
1222
1223 if (!transport_error_check(transport)) return false;
1224
6237ea05
AD
1225 var seq = transport.responseXML.getElementsByTagName("seq")[0];
1226
1227 if (seq) {
1228 seq = seq.firstChild.nodeValue;
1229
1230 if (get_seq() != seq) {
1231 //console.log("[handle_rpc_reply] sequence mismatch: " + seq);
1232 return true;
1233 }
1234 }
1235
f705f206
AD
1236 var message = transport.responseXML.getElementsByTagName("message")[0];
1237
1238 if (message) {
1239 message = message.firstChild.nodeValue;
1240
1241 if (message == "UPDATE_COUNTERS") {
47fb32b0 1242 console.log("need to refresh counters...");
f705f206
AD
1243 setInitParam("last_article_id", -1);
1244 _force_scheduled_update = true;
1245 }
1246 }
1247
1248 var counters = transport.responseXML.getElementsByTagName("counters")[0];
1249
1250 if (counters)
1251 parse_counters(counters, scheduled_call);
1252
1253 var runtime_info = transport.responseXML.getElementsByTagName("runtime-info")[0];
1254
1255 if (runtime_info)
1256 parse_runtime_info(runtime_info);
1257
1258 if (feedsSortByUnread())
1259 resort_feedlist();
1260
1261 hideOrShowFeeds(getInitParam("hide_read_feeds") == 1);
1262
1263 } else {
1264 notify_error("Error communicating with server.");
1265 }
1266
1267 } catch (e) {
1268 exception_error("handle_rpc_reply", e, transport);
1269 }
1270
1271 return true;
1272}
1273
428b704d
AD
1274function scheduleFeedUpdate() {
1275 try {
1276
1277 if (!getActiveFeedId()) {
1278 alert(__("Please select some feed first."));
1279 return;
1280 }
1281
1282 var query = "?op=rpc&subop=scheduleFeedUpdate&id=" +
1283 param_escape(getActiveFeedId()) +
1284 "&is_cat=" + param_escape(activeFeedIsCat());
1285
1286 console.log(query);
1287
1288 new Ajax.Request("backend.php", {
1289 parameters: query,
1290 onComplete: function(transport) {
1291
1292 if (transport.responseXML) {
1293 var message = transport.responseXML.getElementsByTagName("message")[0];
1294
1295 if (message) {
1296 notify_info(message.firstChild.nodeValue);
1297 return;
1298 }
1299 }
1300
1301 notify_error("Error communicating with server.");
1302
1303 } });
1304
1305
1306 } catch (e) {
1307 exception_error("scheduleFeedUpdate", e);
1308 }
1309}