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