]> git.wh0rd.org - tt-rss.git/blame_incremental - tt-rss.js
various category/feed id clash fixes
[tt-rss.git] / tt-rss.js
... / ...
CommitLineData
1var xmlhttp = false;
2var total_unread = 0;
3var first_run = true;
4var display_tags = false;
5var global_unread = -1;
6var active_title_text = "";
7var current_subtitle = "";
8var daemon_enabled = false;
9var daemon_refresh_only = false;
10var _qfd_deleted_feed = 0;
11var firsttime_update = true;
12var last_refetch = 0;
13var cookie_lifetime = 0;
14var active_feed_id = 0;
15var active_feed_is_cat = false;
16
17var xmlhttp = Ajax.getTransport();
18
19var init_params = new Object();
20
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
35function dlg_frefresh_callback() {
36 if (xmlhttp.readyState == 4) {
37 notify(xmlhttp.responseText);
38 updateFeedList(false, false);
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 }
45 closeInfoBox();
46 }
47}
48
49function refetch_callback() {
50 if (xmlhttp.readyState == 4) {
51 try {
52
53 var date = new Date();
54
55 last_refetch = date.getTime() / 1000;
56
57 if (!xmlhttp.responseXML) {
58 notify("refetch_callback: backend did not return valid XML", true, true);
59 return;
60 }
61
62 var reply = xmlhttp.responseXML.firstChild;
63
64 if (!reply) {
65 notify("refetch_callback: backend did not return expected XML object", true, true);
66 updateTitle("");
67 return;
68 }
69
70 var error_code = reply.getAttribute("error-code");
71
72 if (error_code && error_code != 0) {
73 return fatalError(error_code, reply.getAttribute("error-msg"));
74 }
75
76 var counters = reply.firstChild;
77
78 parse_counters(counters, true);
79
80 var runtime_info = counters.nextSibling;
81
82 parse_runtime_info(runtime_info);
83
84 debug("refetch_callback: done");
85
86 if (!daemon_enabled && !daemon_refresh_only) {
87 notify("All feeds updated.");
88 updateTitle("");
89 } else {
90 notify("");
91 }
92 } catch (e) {
93 exception_error("refetch_callback", e);
94 updateTitle("");
95 }
96 }
97}
98
99function backend_sanity_check_callback() {
100
101 if (xmlhttp.readyState == 4) {
102
103 try {
104
105 if (!xmlhttp.responseXML) {
106 fatalError(3, "[D001, Received reply is not XML]: " + xmlhttp.responseText);
107 return;
108 }
109
110 var reply = xmlhttp.responseXML.firstChild.firstChild;
111
112 if (!reply) {
113 fatalError(3, "[D002, Invalid RPC reply]: " + xmlhttp.responseText);
114 return;
115 }
116
117 var error_code = reply.getAttribute("error-code");
118
119 if (error_code && error_code != 0) {
120 return fatalError(error_code, reply.getAttribute("error-msg"));
121 }
122
123 debug("sanity check ok");
124
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
140 init_second_stage();
141
142 } catch (e) {
143 exception_error("backend_sanity_check_callback", e);
144 }
145 }
146}
147
148function scheduleFeedUpdate(force) {
149
150 if (!daemon_enabled && !daemon_refresh_only) {
151 notify("Updating feeds, please wait.", true);
152 updateTitle("Updating");
153 }
154
155 var query_str = "backend.php?op=rpc&subop=";
156
157 if (force) {
158 query_str = query_str + "forceUpdateAllFeeds";
159 } else {
160 query_str = query_str + "updateAllFeeds";
161 }
162
163 var omode;
164
165 if (firsttime_update && !navigator.userAgent.match("Opera")) {
166 firsttime_update = false;
167 omode = "T";
168 } else {
169 if (display_tags) {
170 omode = "t";
171 } else {
172 omode = "flc";
173 }
174 }
175
176 query_str = query_str + "&omode=" + omode;
177 query_str = query_str + "&uctr=" + global_unread;
178
179 debug("in scheduleFeedUpdate");
180
181 var date = new Date();
182
183 if (!xmlhttp_ready(xmlhttp) && last_refetch < date.getTime() / 1000 - 60) {
184 debug("<b>xmlhttp seems to be stuck, aborting</b>");
185 xmlhttp.abort();
186 }
187
188 if (xmlhttp_ready(xmlhttp)) {
189 xmlhttp.open("GET", query_str, true);
190 xmlhttp.onreadystatechange=refetch_callback;
191 xmlhttp.send(null);
192 } else {
193 debug("xmlhttp busy");
194 //printLockingError();
195 }
196}
197
198function updateFeedList(silent, fetch) {
199
200// if (silent != true) {
201// notify("Loading feed list...");
202// }
203
204 var query_str = "backend.php?op=feeds";
205
206 if (display_tags) {
207 query_str = query_str + "&tags=1";
208 }
209
210 if (getActiveFeedId()) {
211 query_str = query_str + "&actid=" + getActiveFeedId();
212 }
213
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
220 if (fetch) query_str = query_str + "&fetch=yes";
221
222 var feeds_frame = document.getElementById("feeds-frame");
223
224 feeds_frame.src = query_str;
225}
226
227function catchupAllFeeds() {
228
229 var query_str = "backend.php?op=feeds&subop=catchupAll";
230
231 notify("Marking all feeds as read...");
232
233 var feeds_frame = document.getElementById("feeds-frame");
234
235 feeds_frame.src = query_str;
236
237 global_unread = 0;
238 updateTitle("");
239
240}
241
242function viewCurrentFeed(subop) {
243
244 if (getActiveFeedId()) {
245 viewfeed(getActiveFeedId(), subop);
246 } else {
247 disableContainerChildren("headlinesToolbar", false, document);
248 viewfeed(-1, subop); // FIXME
249 }
250 return false; // block unneeded form submits
251}
252
253function viewfeed(feed, subop) {
254 var f = window.frames["feeds-frame"];
255 f.viewfeed(feed, subop);
256}
257
258function timeout() {
259 scheduleFeedUpdate(false);
260
261 var refresh_time = getInitParam("feeds_frame_refresh");
262
263 if (!refresh_time) refresh_time = 600;
264
265 setTimeout("timeout()", refresh_time*1000);
266}
267
268function resetSearch() {
269 var searchbox = document.getElementById("searchbox")
270
271 if (searchbox.value != "" && getActiveFeedId()) {
272 searchbox.value = "";
273 viewfeed(getActiveFeedId(), "");
274 }
275}
276
277function searchCancel() {
278 closeInfoBox(true);
279}
280
281function search() {
282 closeInfoBox();
283 viewCurrentFeed(0, "");
284}
285
286function localPiggieFunction(enable) {
287 if (enable) {
288 var query_str = "backend.php?op=feeds&subop=piggie";
289
290 if (xmlhttp_ready(xmlhttp)) {
291
292 xmlhttp.open("GET", query_str, true);
293 xmlhttp.onreadystatechange=feedlist_callback;
294 xmlhttp.send(null);
295 }
296 }
297}
298
299// if argument is undefined, current subtitle is not updated
300// use blank string to clear subtitle
301function updateTitle(s) {
302 var tmp = "Tiny Tiny RSS";
303
304 if (s != undefined) {
305 current_subtitle = s;
306 }
307
308 if (global_unread > 0) {
309 tmp = tmp + " (" + global_unread + ")";
310 }
311
312 if (current_subtitle) {
313 tmp = tmp + " - " + current_subtitle;
314 }
315
316 if (active_title_text.length > 0) {
317 tmp = tmp + " > " + active_title_text;
318 }
319
320 document.title = tmp;
321}
322
323function genericSanityCheck() {
324
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
333 return true;
334}
335
336function init() {
337
338 try {
339
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
345 disableContainerChildren("headlinesToolbar", true);
346
347 Form.disable("main_toolbar_form");
348
349 if (!genericSanityCheck())
350 return;
351
352 if (getURLParam('debug')) {
353 document.getElementById('debug_output').style.display = 'block';
354 debug('debug mode activated');
355 }
356
357 xmlhttp.open("GET", "backend.php?op=rpc&subop=sanityCheck", true);
358 xmlhttp.onreadystatechange=backend_sanity_check_callback;
359 xmlhttp.send(null);
360
361 } catch (e) {
362 exception_error("init", e);
363 }
364}
365
366function resize_feeds_frame() {
367 var f = document.getElementById("feeds-frame");
368 var tf = document.getElementById("mainFooter");
369 var th = document.getElementById("mainHeader");
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";
384}
385
386function init_second_stage() {
387
388 try {
389
390 cookie_lifetime = getCookie("ttrss_cltime");
391
392 delCookie("ttrss_vf_test");
393
394 updateFeedList(false, false);
395 document.onkeydown = hotkey_handler;
396
397 var tb = parent.document.forms["main_toolbar_form"];
398
399 dropboxSelect(tb.view_mode, getInitParam("toolbar_view_mode"));
400 dropboxSelect(tb.limit, getInitParam("toolbar_limit"));
401
402 daemon_enabled = getInitParam("daemon_enabled") == 1;
403 daemon_refresh_only = getInitParam("daemon_refresh_only") == 1;
404
405 // FIXME should be callled after window resize
406
407 var h = document.getElementById("headlines");
408 var c = document.getElementById("content");
409
410 if (navigator.userAgent.match("Opera")) {
411 resize_feeds_frame();
412 }
413
414 debug("second stage ok");
415
416 } catch (e) {
417 exception_error("init_second_stage", e);
418 }
419}
420
421function quickMenuChange() {
422 var chooser = document.getElementById("quickMenuChooser");
423 var opid = chooser[chooser.selectedIndex].value;
424
425 chooser.selectedIndex = 0;
426 quickMenuGo(opid);
427}
428
429function quickMenuGo(opid) {
430 try {
431
432 if (opid == "qmcPrefs") {
433 gotoPreferences();
434 }
435
436 if (opid == "qmcSearch") {
437 displayDlg("search", getActiveFeedId() + ":" + activeFeedIsCat());
438 return;
439 }
440
441 if (opid == "qmcAddFeed") {
442 displayDlg("quickAddFeed");
443 return;
444 }
445
446 if (opid == "qmcRemoveFeed") {
447 var actid = getActiveFeedId();
448
449 if (!actid) {
450 alert("Please select some feed first.");
451 return;
452 }
453
454 var fn = getFeedName(actid);
455
456 if (confirm("Unsubscribe from " + fn + "?")) {
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);
483 }
484}
485
486function qfdDelete(feed_id) {
487
488 notify("Removing feed...");
489
490 if (!xmlhttp_ready(xmlhttp)) {
491 printLockingError();
492 return
493 }
494
495 _qfd_deleted_feed = feed_id;
496
497 xmlhttp.open("GET", "backend.php?op=pref-feeds&quiet=1&subop=remove&ids=" + feed_id);
498 xmlhttp.onreadystatechange=dlg_frefresh_callback;
499 xmlhttp.send(null);
500}
501
502
503function updateFeedTitle(t) {
504 active_title_text = t;
505 updateTitle();
506}
507
508function toggleDispRead() {
509 try {
510
511 if (!xmlhttp_ready(xmlhttp)) {
512 printLockingError();
513 return
514 }
515
516 var hide_read_feeds = (getInitParam("hide_read_feeds") == "1");
517
518 hide_read_feeds = !hide_read_feeds;
519
520 debug("toggle_disp_read => " + hide_read_feeds);
521
522 hideOrShowFeeds(getFeedsContext().document, hide_read_feeds);
523
524 var query = "backend.php?op=rpc&subop=setpref" +
525 "&key=HIDE_READ_FEEDS&value=" + param_escape(hide_read_feeds);
526
527 storeInitParam("hide_read_feeds", hide_read_feeds, true);
528
529 new Ajax.Request(query);
530
531 } catch (e) {
532 exception_error("toggleDispRead", e);
533 }
534}
535
536function parse_runtime_info(elem) {
537 var param = elem.firstChild;
538
539 debug("parse_runtime_info");
540
541 while (param) {
542 var k = param.getAttribute("key");
543 var v = param.getAttribute("value");
544
545 debug("RI: " + k + " => " + v);
546
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}
559
560function catchupCurrentFeed() {
561
562 var fn = getFeedName(getActiveFeedId(), active_feed_is_cat);
563
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)) {
571 return viewCurrentFeed(0, 'MarkAllRead')
572 }
573}
574