]> git.wh0rd.org - tt-rss.git/blame - tt-rss.js
various category/feed id clash fixes
[tt-rss.git] / tt-rss.js
CommitLineData
1cd17194 1var xmlhttp = false;
76798ff3 2var total_unread = 0;
525116d4 3var first_run = true;
8143ae1f 4var display_tags = false;
806a3d14 5var global_unread = -1;
21703604 6var active_title_text = "";
21703604 7var current_subtitle = "";
c6784aea 8var daemon_enabled = false;
0d51e25d 9var daemon_refresh_only = false;
15da5cc1 10var _qfd_deleted_feed = 0;
2bf6e0a8 11var firsttime_update = true;
c441662f 12var last_refetch = 0;
76b4eae1 13var cookie_lifetime = 0;
33d13e72 14var active_feed_id = 0;
0a6c4846 15var active_feed_is_cat = false;
15da5cc1 16
a58069db 17var xmlhttp = Ajax.getTransport();
1cd17194 18
1035fcec 19var init_params = new Object();
3ac2b520 20
8143ae1f
AD
21function toggleTags() {
22 display_tags = !display_tags;
23
24 var p = document.getElementById("dispSwitchPrompt");
25
26 if (display_tags) {
27 p.innerHTML = "display feeds";
28 } else {
29 p.innerHTML = "display tags";
30 }
31
32 updateFeedList();
33}
34
6de5d056 35function dlg_frefresh_callback() {
1cd17194 36 if (xmlhttp.readyState == 4) {
a24f525c 37 notify(xmlhttp.responseText);
e2f8f7b4 38 updateFeedList(false, false);
15da5cc1
AD
39 if (_qfd_deleted_feed) {
40 var hframe = document.getElementById("headlines-frame");
41 if (hframe) {
42 hframe.src = "backend.php?op=error&msg=No%20feed%20selected.";
43 }
44 }
eff4997c 45 closeInfoBox();
c0e5a40e 46 }
1cd17194 47}
e2f8f7b4 48
8158c57a 49function refetch_callback() {
29fb8c70 50 if (xmlhttp.readyState == 4) {
7719618b 51 try {
310da49d 52
c441662f
AD
53 var date = new Date();
54
55 last_refetch = date.getTime() / 1000;
56
7719618b 57 if (!xmlhttp.responseXML) {
0530ddd8 58 notify("refetch_callback: backend did not return valid XML", true, true);
7719618b
AD
59 return;
60 }
61
62 var reply = xmlhttp.responseXML.firstChild;
262bd8ea 63
7719618b 64 if (!reply) {
0530ddd8 65 notify("refetch_callback: backend did not return expected XML object", true, true);
e2cb4c6d 66 updateTitle("");
7719618b
AD
67 return;
68 }
262bd8ea 69
7719618b
AD
70 var error_code = reply.getAttribute("error-code");
71
72 if (error_code && error_code != 0) {
af106b0e 73 return fatalError(error_code, reply.getAttribute("error-msg"));
7719618b 74 }
f54f515f
AD
75
76 var counters = reply.firstChild;
7719618b 77
f54f515f 78 parse_counters(counters, true);
c6784aea 79
71ad883b
AD
80 var runtime_info = counters.nextSibling;
81
82 parse_runtime_info(runtime_info);
83
0ee1d1a0
AD
84 debug("refetch_callback: done");
85
0d51e25d 86 if (!daemon_enabled && !daemon_refresh_only) {
c6784aea 87 notify("All feeds updated.");
5a180505 88 updateTitle("");
4c059b7b
AD
89 } else {
90 notify("");
c6784aea 91 }
7719618b
AD
92 } catch (e) {
93 exception_error("refetch_callback", e);
e2cb4c6d 94 updateTitle("");
7719618b 95 }
090e250b
AD
96 }
97}
1a66d16e 98
295f9b42
AD
99function backend_sanity_check_callback() {
100
101 if (xmlhttp.readyState == 4) {
295f9b42 102
7719618b
AD
103 try {
104
105 if (!xmlhttp.responseXML) {
462a192b 106 fatalError(3, "[D001, Received reply is not XML]: " + xmlhttp.responseText);
7719618b
AD
107 return;
108 }
295f9b42 109
3ac2b520 110 var reply = xmlhttp.responseXML.firstChild.firstChild;
7719618b
AD
111
112 if (!reply) {
af106b0e 113 fatalError(3, "[D002, Invalid RPC reply]: " + xmlhttp.responseText);
7719618b
AD
114 return;
115 }
116
117 var error_code = reply.getAttribute("error-code");
118
119 if (error_code && error_code != 0) {
af106b0e 120 return fatalError(error_code, reply.getAttribute("error-msg"));
7719618b
AD
121 }
122
0ee1d1a0
AD
123 debug("sanity check ok");
124
3ac2b520
AD
125 var params = reply.nextSibling;
126
127 if (params) {
128 debug('reading init-params...');
129 var param = params.firstChild;
130
131 while (param) {
132 var k = param.getAttribute("key");
133 var v = param.getAttribute("value");
134 debug(k + " => " + v);
135 init_params[k] = v;
136 param = param.nextSibling;
137 }
138 }
139
7719618b 140 init_second_stage();
295f9b42 141
7719618b
AD
142 } catch (e) {
143 exception_error("backend_sanity_check_callback", e);
144 }
295f9b42
AD
145 }
146}
147
cb246176 148function scheduleFeedUpdate(force) {
525116d4 149
0d51e25d 150 if (!daemon_enabled && !daemon_refresh_only) {
4d4200a8 151 notify("Updating feeds, please wait.", true);
c6784aea
AD
152 updateTitle("Updating");
153 }
55193822 154
cb246176
AD
155 var query_str = "backend.php?op=rpc&subop=";
156
157 if (force) {
c3b81db0 158 query_str = query_str + "forceUpdateAllFeeds";
cb246176 159 } else {
c3b81db0 160 query_str = query_str + "updateAllFeeds";
cb246176 161 }
525116d4 162
9826bd2e
AD
163 var omode;
164
b6104dee 165 if (firsttime_update && !navigator.userAgent.match("Opera")) {
2bf6e0a8
AD
166 firsttime_update = false;
167 omode = "T";
9826bd2e 168 } else {
2bf6e0a8
AD
169 if (display_tags) {
170 omode = "t";
171 } else {
172 omode = "flc";
173 }
9826bd2e 174 }
2bf6e0a8 175
9826bd2e 176 query_str = query_str + "&omode=" + omode;
78ea1de0 177 query_str = query_str + "&uctr=" + global_unread;
9826bd2e 178
0ee1d1a0 179 debug("in scheduleFeedUpdate");
2bf6e0a8 180
c441662f
AD
181 var date = new Date();
182
183 if (!xmlhttp_ready(xmlhttp) && last_refetch < date.getTime() / 1000 - 60) {
a7565293 184 debug("<b>xmlhttp seems to be stuck, aborting</b>");
c441662f
AD
185 xmlhttp.abort();
186 }
187
29fb8c70
AD
188 if (xmlhttp_ready(xmlhttp)) {
189 xmlhttp.open("GET", query_str, true);
190 xmlhttp.onreadystatechange=refetch_callback;
191 xmlhttp.send(null);
525116d4 192 } else {
c441662f 193 debug("xmlhttp busy");
bed0f18f 194 //printLockingError();
c0e5a40e 195 }
525116d4 196}
1cd17194 197
525116d4 198function updateFeedList(silent, fetch) {
c0e5a40e 199
1a66d16e
AD
200// if (silent != true) {
201// notify("Loading feed list...");
202// }
82baad4a 203
331900c6
AD
204 var query_str = "backend.php?op=feeds";
205
8143ae1f
AD
206 if (display_tags) {
207 query_str = query_str + "&tags=1";
208 }
209
86741347
AD
210 if (getActiveFeedId()) {
211 query_str = query_str + "&actid=" + getActiveFeedId();
175847de
AD
212 }
213
59b8192f
AD
214 if (navigator.userAgent.match("Opera")) {
215 var date = new Date();
216 var timestamp = Math.round(date.getTime() / 1000);
217 query_str = query_str + "&ts=" + timestamp
218 }
219
1a66d16e 220 if (fetch) query_str = query_str + "&fetch=yes";
e1123aee 221
1a66d16e 222 var feeds_frame = document.getElementById("feeds-frame");
e1123aee 223
1a66d16e
AD
224 feeds_frame.src = query_str;
225}
175847de 226
476cac42 227function catchupAllFeeds() {
076682aa 228
476cac42
AD
229 var query_str = "backend.php?op=feeds&subop=catchupAll";
230
231 notify("Marking all feeds as read...");
232
1a66d16e
AD
233 var feeds_frame = document.getElementById("feeds-frame");
234
235 feeds_frame.src = query_str;
476cac42 236
fc69e641 237 global_unread = 0;
21703604 238 updateTitle("");
fc69e641 239
476cac42 240}
1cd17194 241
767e2486 242function viewCurrentFeed(subop) {
1a66d16e 243
86741347 244 if (getActiveFeedId()) {
767e2486 245 viewfeed(getActiveFeedId(), subop);
033e47e0
AD
246 } else {
247 disableContainerChildren("headlinesToolbar", false, document);
767e2486 248 viewfeed(-1, subop); // FIXME
f0601b87 249 }
164f4738 250 return false; // block unneeded form submits
f0601b87
AD
251}
252
767e2486 253function viewfeed(feed, subop) {
db8d6f67 254 var f = window.frames["feeds-frame"];
767e2486 255 f.viewfeed(feed, subop);
9cfc649a
AD
256}
257
40d13c28 258function timeout() {
05732aa0 259 scheduleFeedUpdate(false);
f5de0d8d 260
3ac2b520 261 var refresh_time = getInitParam("feeds_frame_refresh");
f5de0d8d 262
3ac2b520 263 if (!refresh_time) refresh_time = 600;
f5de0d8d
AD
264
265 setTimeout("timeout()", refresh_time*1000);
ac53063a
AD
266}
267
c374a3fe 268function resetSearch() {
64c620ce
AD
269 var searchbox = document.getElementById("searchbox")
270
86741347 271 if (searchbox.value != "" && getActiveFeedId()) {
64c620ce 272 searchbox.value = "";
767e2486 273 viewfeed(getActiveFeedId(), "");
ac43eba1 274 }
c374a3fe 275}
ac53063a 276
86b682ce
AD
277function searchCancel() {
278 closeInfoBox(true);
279}
280
f0601b87 281function search() {
eff4997c 282 closeInfoBox();
4ce19859 283 viewCurrentFeed(0, "");
76798ff3 284}
1cd17194 285
13ad9102
AD
286function localPiggieFunction(enable) {
287 if (enable) {
288 var query_str = "backend.php?op=feeds&subop=piggie";
289
c0e5a40e 290 if (xmlhttp_ready(xmlhttp)) {
13ad9102
AD
291
292 xmlhttp.open("GET", query_str, true);
293 xmlhttp.onreadystatechange=feedlist_callback;
294 xmlhttp.send(null);
295 }
296 }
297}
298
806a3d14
AD
299// if argument is undefined, current subtitle is not updated
300// use blank string to clear subtitle
fc69e641
AD
301function updateTitle(s) {
302 var tmp = "Tiny Tiny RSS";
21703604 303
5a494a0b 304 if (s != undefined) {
21703604
AD
305 current_subtitle = s;
306 }
307
fc69e641
AD
308 if (global_unread > 0) {
309 tmp = tmp + " (" + global_unread + ")";
310 }
311
5a494a0b 312 if (current_subtitle) {
21703604 313 tmp = tmp + " - " + current_subtitle;
fc69e641 314 }
21703604
AD
315
316 if (active_title_text.length > 0) {
317 tmp = tmp + " > " + active_title_text;
318 }
319
fc69e641
AD
320 document.title = tmp;
321}
322
22a93ad8 323function genericSanityCheck() {
ac43eba1 324
295f9b42
AD
325 if (!xmlhttp) fatalError(1);
326
327 setCookie("ttrss_vf_test", "TEST");
328
329 if (getCookie("ttrss_vf_test") != "TEST") {
330 fatalError(2);
331 }
332
22a93ad8
AD
333 return true;
334}
335
336function init() {
337
7719618b 338 try {
fe2f1970 339
97dcd654
AD
340 // this whole shebang is based on http://www.birnamdesigns.com/misc/busted2.html
341
342 if (arguments.callee.done) return;
343 arguments.callee.done = true;
344
7719618b 345 disableContainerChildren("headlinesToolbar", true);
70830c87 346
86b682ce
AD
347 Form.disable("main_toolbar_form");
348
7719618b
AD
349 if (!genericSanityCheck())
350 return;
ac43eba1 351
0ee1d1a0
AD
352 if (getURLParam('debug')) {
353 document.getElementById('debug_output').style.display = 'block';
354 debug('debug mode activated');
355 }
356
7719618b
AD
357 xmlhttp.open("GET", "backend.php?op=rpc&subop=sanityCheck", true);
358 xmlhttp.onreadystatechange=backend_sanity_check_callback;
359 xmlhttp.send(null);
47179952 360
7719618b
AD
361 } catch (e) {
362 exception_error("init", e);
a8d28f48 363 }
7719618b 364}
86741347 365
1de2b92c
AD
366function resize_feeds_frame() {
367 var f = document.getElementById("feeds-frame");
368 var tf = document.getElementById("mainFooter");
369 var th = document.getElementById("mainHeader");
a6c3f28c
AD
370
371 var footer_height = 0;
372 var header_height = 0;
373
374 if (tf) {
375 footer_height = tf.scrollHeight;
376 }
377
378 if (th) {
379 header_height = th.scrollHeight;
380 }
381
382 f.style.height = document.body.scrollHeight - footer_height -
383 header_height - 50 + "px";
1de2b92c
AD
384}
385
7719618b 386function init_second_stage() {
295f9b42 387
7719618b 388 try {
2f587484 389
76b4eae1
AD
390 cookie_lifetime = getCookie("ttrss_cltime");
391
392 delCookie("ttrss_vf_test");
7719618b
AD
393
394 updateFeedList(false, false);
395 document.onkeydown = hotkey_handler;
1b0809ae 396
f31673f7
AD
397 var tb = parent.document.forms["main_toolbar_form"];
398
3ac2b520
AD
399 dropboxSelect(tb.view_mode, getInitParam("toolbar_view_mode"));
400 dropboxSelect(tb.limit, getInitParam("toolbar_limit"));
c6784aea 401
0d51e25d
AD
402 daemon_enabled = getInitParam("daemon_enabled") == 1;
403 daemon_refresh_only = getInitParam("daemon_refresh_only") == 1;
5f136c9a 404
1de2b92c
AD
405 // FIXME should be callled after window resize
406
caa53a7c
AD
407 var h = document.getElementById("headlines");
408 var c = document.getElementById("content");
409
5f136c9a 410 if (navigator.userAgent.match("Opera")) {
1de2b92c 411 resize_feeds_frame();
5f136c9a 412 }
0ee1d1a0
AD
413
414 debug("second stage ok");
7719618b 415
7719618b
AD
416 } catch (e) {
417 exception_error("init_second_stage", e);
2f587484 418 }
1cd17194 419}
ac43eba1 420
c09ec856 421function quickMenuChange() {
cbe45fa8 422 var chooser = document.getElementById("quickMenuChooser");
86b682ce 423 var opid = chooser[chooser.selectedIndex].value;
e2f8f7b4 424
c09ec856
AD
425 chooser.selectedIndex = 0;
426 quickMenuGo(opid);
427}
428
429function quickMenuGo(opid) {
bb3423cf 430 try {
c09ec856 431
bb3423cf
AD
432 if (opid == "qmcPrefs") {
433 gotoPreferences();
434 }
435
436 if (opid == "qmcSearch") {
0a6c4846 437 displayDlg("search", getActiveFeedId() + ":" + activeFeedIsCat());
6de5d056
AD
438 return;
439 }
bb3423cf
AD
440
441 if (opid == "qmcAddFeed") {
442 displayDlg("quickAddFeed");
443 return;
69668465 444 }
6de5d056 445
bb3423cf
AD
446 if (opid == "qmcRemoveFeed") {
447 var actid = getActiveFeedId();
448
449 if (!actid) {
0530ddd8 450 alert("Please select some feed first.");
bb3423cf
AD
451 return;
452 }
64a2875d
AD
453
454 var fn = getFeedName(actid);
bb3423cf 455
64a2875d 456 if (confirm("Unsubscribe from " + fn + "?")) {
bb3423cf
AD
457 qfdDelete(actid);
458 }
459
460 return;
461 }
462
463 if (opid == "qmcUpdateFeeds") {
464 scheduleFeedUpdate(true);
465 return;
466 }
467
468 if (opid == "qmcCatchupAll") {
469 catchupAllFeeds();
470 return;
471 }
472
473 if (opid == "qmcShowOnlyUnread") {
474 toggleDispRead();
475 return;
476 }
477
478 if (opid == "qmcAddFilter") {
479 displayDlg("quickAddFilter", getActiveFeedId());
480 }
481 } catch (e) {
482 exception_error("quickMenuGo", e);
a24f525c 483 }
e2f8f7b4
AD
484}
485
6de5d056
AD
486function qfdDelete(feed_id) {
487
488 notify("Removing feed...");
489
7f123cda
AD
490 if (!xmlhttp_ready(xmlhttp)) {
491 printLockingError();
492 return
493 }
494
15da5cc1
AD
495 _qfd_deleted_feed = feed_id;
496
69668465 497 xmlhttp.open("GET", "backend.php?op=pref-feeds&quiet=1&subop=remove&ids=" + feed_id);
6de5d056
AD
498 xmlhttp.onreadystatechange=dlg_frefresh_callback;
499 xmlhttp.send(null);
6de5d056 500}
033e47e0 501
3745788e 502
21703604
AD
503function updateFeedTitle(t) {
504 active_title_text = t;
505 updateTitle();
506}
507
3745788e 508function toggleDispRead() {
7f123cda 509 try {
3745788e 510
7f123cda
AD
511 if (!xmlhttp_ready(xmlhttp)) {
512 printLockingError();
513 return
514 }
3745788e 515
e8bd0da9 516 var hide_read_feeds = (getInitParam("hide_read_feeds") == "1");
3745788e 517
7f123cda 518 hide_read_feeds = !hide_read_feeds;
e8bd0da9
AD
519
520 debug("toggle_disp_read => " + hide_read_feeds);
521
522 hideOrShowFeeds(getFeedsContext().document, hide_read_feeds);
523
7f123cda
AD
524 var query = "backend.php?op=rpc&subop=setpref" +
525 "&key=HIDE_READ_FEEDS&value=" + param_escape(hide_read_feeds);
3745788e 526
e8bd0da9
AD
527 storeInitParam("hide_read_feeds", hide_read_feeds, true);
528
529 new Ajax.Request(query);
7f123cda
AD
530
531 } catch (e) {
532 exception_error("toggleDispRead", e);
3745788e 533 }
3745788e 534}
295f9b42 535
71ad883b
AD
536function parse_runtime_info(elem) {
537 var param = elem.firstChild;
538
1cb7492d
AD
539 debug("parse_runtime_info");
540
71ad883b
AD
541 while (param) {
542 var k = param.getAttribute("key");
543 var v = param.getAttribute("value");
3ac2b520 544
1cb7492d
AD
545 debug("RI: " + k + " => " + v);
546
71ad883b
AD
547 var w = document.getElementById("noDaemonWarning");
548
549 if (w) {
550 if (k == "daemon_is_running" && v != 1) {
551 w.style.display = "block";
552 } else {
553 w.style.display = "none";
554 }
555 }
556 param = param.nextSibling;
557 }
558}
fce24838
AD
559
560function catchupCurrentFeed() {
561
234e467c 562 var fn = getFeedName(getActiveFeedId(), active_feed_is_cat);
fce24838 563
234e467c
AD
564 var str = "Mark all articles in " + fn + " as read?";
565
566/* if (active_feed_is_cat) {
567 str = "Mark all articles in this category as read?";
568 } */
569
570 if (confirm(str)) {
fce24838
AD
571 return viewCurrentFeed(0, 'MarkAllRead')
572 }
573}
88040f57 574