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