]> git.wh0rd.org - tt-rss.git/blob - digest.js
a3cbb4879a92b20c3ba5eb9748369a904b4e1d32
[tt-rss.git] / digest.js
1 var last_feeds = [];
2
3 var _active_feed_id = false;
4 var _active_feed_offset = false;
5 var _update_timeout = false;
6 var _feedlist_expanded = false;
7
8 function catchup_feed(feed_id, callback) {
9 try {
10
11 var fn = find_feed(last_feeds, feed_id).title;
12
13 if (confirm(__("Mark all articles in %s as read?").replace("%s", fn))) {
14
15 var is_cat = "";
16
17 if (feed_id == -4) is_cat = "true";
18
19 var query = "?op=rpc&subop=catchupFeed&feed_id=" +
20 feed_id + "&is_cat=" + is_cat;
21
22 new Ajax.Request("backend.php", {
23 parameters: query,
24 onComplete: function(transport) {
25 if (callback) callback(transport);
26
27 update();
28 } });
29 }
30
31 } catch (e) {
32 exception_error("catchup_article", e);
33 }
34 }
35
36
37 function catchup_article(article_id, callback) {
38 try {
39 var query = "?op=rpc&subop=catchupSelected" +
40 "&cmode=0&ids=" + article_id;
41
42 new Ajax.Request("backend.php", {
43 parameters: query,
44 onComplete: function(transport) {
45 if (callback) callback(transport);
46 } });
47
48 } catch (e) {
49 exception_error("catchup_article", e);
50 }
51 }
52
53 function set_selected_feed(feed_id) {
54 try {
55 var feeds = $("feeds-content").getElementsByTagName("LI");
56
57 for (var i = 0; i < feeds.length; i++) {
58 if (feeds[i].id == "F-" + feed_id)
59 feeds[i].className = "selected";
60 else
61 feeds[i].className = "";
62 }
63
64 _active_feed_id = feed_id;
65
66 } catch (e) {
67 exception_error("mark_selected_feed", e);
68 }
69 }
70
71 function zoom(article_id) {
72 try {
73 var elem = $('A-' + article_id);
74
75 if (elem) {
76 var divs = elem.getElementsByTagName('DIV');
77
78 for (var i = 0; i < divs.length; i++) {
79 if (divs[i].className == 'excerpt')
80 Element.hide(divs[i]);
81
82 if (divs[i].className == 'content')
83 Element.show(divs[i]);
84 }
85 }
86
87 catchup_article(article_id,
88 function() { update(); });
89
90 } catch (e) {
91 exception_error("zoom", e);
92 }
93 }
94
95 function load_more() {
96 try {
97 viewfeed(_active_feed_id, _active_feed_offset + 10);
98 } catch (e) {
99 exception_error("load_more", e);
100 }
101 }
102
103 function update() {
104 try {
105 console.log('updating feeds...');
106
107 window.clearTimeout(_update_timeout);
108
109 new Ajax.Request("backend.php", {
110 parameters: "?op=rpc&subop=digest-init",
111 onComplete: function(transport) {
112 fatal_error_check(transport);
113 parse_feeds(transport);
114 set_selected_feed(_active_feed_id);
115 } });
116
117 _update_timeout = window.setTimeout('update()', 5*1000);
118 } catch (e) {
119 exception_error("update", e);
120 }
121 }
122
123 function remove_headline_entry(article_id) {
124 try {
125 var elem = $('A-' + article_id);
126
127 if (elem) {
128 elem.parentNode.removeChild(elem);
129 }
130
131 } catch (e) {
132 exception_error("remove_headline_entry", e);
133 }
134 }
135
136 function view(article_id, dismiss_only) {
137 try {
138 remove_headline_entry(article_id);
139
140 catchup_article(article_id,
141 function() { update(); });
142
143 return dismiss_only != true;
144 } catch (e) {
145 exception_error("view", e);
146 }
147 }
148
149 function viewfeed(feed_id, offset) {
150 try {
151
152 if (!feed_id) feed_id = _active_feed_id;
153
154 if (!offset) {
155 offset = 0;
156 } else {
157 offset = _active_feed_offset + offset;
158 }
159
160 var query = "backend.php?op=rpc&subop=digest-update&feed_id=" + feed_id +
161 "&offset=" + offset;
162
163 new Ajax.Request("backend.php", {
164 parameters: query,
165 onComplete: function(transport) {
166 fatal_error_check(transport);
167 parse_headlines(transport, offset == 0);
168 set_selected_feed(feed_id);
169 _active_feed_offset = offset;
170 } });
171
172 } catch (e) {
173 exception_error("view", e);
174 }
175 }
176
177 function find_article(articles, article_id) {
178 try {
179 for (var i = 0; i < articles.length; i++) {
180 if (articles[i].id == article_id)
181 return articles[i];
182 }
183
184 return false;
185
186 } catch (e) {
187 exception_error("find_article", e);
188 }
189 }
190
191 function find_feed(feeds, feed_id) {
192 try {
193 for (var i = 0; i < feeds.length; i++) {
194 if (feeds[i].id == feed_id)
195 return feeds[i];
196 }
197
198 return false;
199
200 } catch (e) {
201 exception_error("find_feed", e);
202 }
203 }
204
205 function get_feed_icon(feed) {
206 try {
207 if (feed.has_icon)
208 return 'icons/' + feed.id + '.ico';
209
210 if (feed.id == -1)
211 return 'images/mark_set.png';
212
213 if (feed.id == -2)
214 return 'images/pub_set.png';
215
216 if (feed.id == -3)
217 return 'images/fresh.png';
218
219 if (feed.id == -4)
220 return 'images/tag.png';
221
222 if (feed.id < -10)
223 return 'images/label.png';
224
225 return 'images/blank_icon.gif';
226
227 } catch (e) {
228 exception_error("get_feed_icon", e);
229 }
230 }
231
232 function add_feed_entry(feed) {
233 try {
234 var icon_part = "";
235
236 icon_part = "<img src='" + get_feed_icon(feed) + "'/>";
237
238 var tmp_html = "<li id=\"F-"+feed.id+"\" " +
239 "onmouseover=\"feed_mi(this)\" onmouseout=\"feed_mo(this)\">" +
240 icon_part +
241 "<a href=\"#\" onclick=\"viewfeed("+feed.id+")\">" + feed.title + "</a>" +
242 "<div class='unread-ctr'>" +
243 "<img onclick=\"catchup_feed("+feed.id+")\" title=\"Dismiss\" class=\"dismiss\" style='display : none' src=\"images/digest_checkbox.png\">" +
244 "<span class=\"unread\">" + feed.unread + "</span>" +
245 "</div>" +
246 "</li>";
247
248 $("feeds-content").innerHTML += tmp_html;
249
250 } catch (e) {
251 exception_error("add_feed_entry", e);
252 }
253 }
254
255 function add_headline_entry(article, feed) {
256 try {
257
258 var icon_part = "";
259
260 icon_part = "<img class='icon' src='" + get_feed_icon(feed) + "'/>";
261
262 var tmp_html = "<li id=\"A-"+article.id+"\">" +
263 icon_part +
264 "<div class='digest-check'>" +
265 "<img title='Set starred' onclick=\"toggleMark(this, "+article.id+")\" src='images/mark_unset.png'>" +
266 "<img title='Set published' onclick=\"togglePub(this, "+article.id+")\" src='images/pub_unset.png'>" +
267 "<img title='Dismiss' onclick=\"view("+article.id+", true)\" class='digest-check' src='images/digest_checkbox.png'>" +
268 "</div>" +
269 "<a target=\"_blank\" href=\""+article.link+"\""+
270 "onclick=\"return view("+article.id+")\" class='title'>" +
271 article.title + "</a>" +
272 "<div class='body'>" +
273 "<div title=\"Click to expand article\" onclick=\"zoom("+article.id+")\" class='excerpt'>" +
274 article.excerpt + "</div>" +
275 "<div style='display : none' class='content'>" +
276 article.content + "</div>" +
277 "<div class='info'><a href=\#\" onclick=\"viewfeed("+feed.id+")\">" +
278 feed.title + "</a> " + " @ " +
279 new Date(article.updated * 1000) + "</div>" +
280 "</div></li>";
281
282 $("headlines-content").innerHTML += tmp_html;
283
284 } catch (e) {
285 exception_error("add_headline_entry", e);
286 }
287 }
288
289 function expand_feeds() {
290 try {
291 _feedlist_expanded = true;
292
293 redraw_feedlist(last_feeds);
294
295 } catch (e) {
296 exception_error("expand_feeds", e);
297 }
298 }
299
300 function redraw_feedlist(feeds) {
301 try {
302
303 $('feeds-content').innerHTML = "";
304
305 var limit = 10;
306
307 if (_feedlist_expanded) limit = feeds.length;
308
309 for (var i = 0; i < Math.min(limit, feeds.length); i++) {
310 add_feed_entry(feeds[i]);
311 }
312
313 if (feeds.length > limit) {
314 $('feeds-content').innerHTML += "<li id='F-MORE-PROMPT'>" +
315 "<img src='images/blank_icon.gif'>" +
316 "<a href=\"#\" onclick=\"expand_feeds()\">" +
317 __("%d more...").replace("%d", feeds.length-10) +
318 "</a>" + "</li>";
319 }
320
321 } catch (e) {
322 exception_error("redraw_feedlist", e);
323 }
324 }
325
326 function parse_feeds(transport) {
327 try {
328
329 if (!transport.responseXML) return;
330
331 var feeds = transport.responseXML.getElementsByTagName('feeds')[0];
332
333 if (feeds) {
334 feeds = eval("(" + feeds.firstChild.nodeValue + ")");
335
336 feeds.sort( function (a,b)
337 {
338 if (b.unread != a.unread)
339 return (b.unread - a.unread)
340 else
341 if (a.title > b.title)
342 return 1;
343 else if (a.title < b.title)
344 return -1;
345 else
346 return 0;
347 });
348
349 last_feeds = feeds;
350
351 redraw_feedlist(feeds);
352 }
353
354 } catch (e) {
355 exception_error("parse_feeds", e);
356 }
357 }
358
359 function parse_headlines(transport, replace) {
360 try {
361 if (!transport.responseXML) return;
362
363 var headlines = transport.responseXML.getElementsByTagName('headlines')[0];
364
365 if (headlines) {
366 headlines = eval("(" + headlines.firstChild.nodeValue + ")");
367
368 if (replace) $('headlines-content').innerHTML = '';
369
370 var pr = $('H-MORE-PROMPT');
371
372 if (pr) pr.parentNode.removeChild(pr);
373
374 for (var i = 0; i < headlines.length; i++) {
375
376 if (!$('A-' + headlines[i].id)) {
377 add_headline_entry(headlines[i],
378 find_feed(last_feeds, headlines[i].feed_id));
379 }
380 }
381
382 if (pr) {
383 $('headlines-content').appendChild(pr);
384 } else {
385 $('headlines-content').innerHTML += "<li id='H-MORE-PROMPT'>" +
386 "<div class='body'><a href=\"javascript:load_more()\">" +
387 __("More articles...") + "</a></div></li>";
388 }
389
390 new Effect.Appear('headlines-content');
391 }
392
393 } catch (e) {
394 exception_error("parse_headlines", e);
395 }
396 }
397
398 function init() {
399 try {
400
401 new Ajax.Request("backend.php", {
402 parameters: "backend.php?op=rpc&subop=digest-init",
403 onComplete: function(transport) {
404 parse_feeds(transport);
405 window.setTimeout('viewfeed(-4)', 100);
406 _update_timeout = window.setTimeout('update()', 5*1000);
407 } });
408
409 } catch (e) {
410 exception_error("digest_init", e);
411 }
412 }
413
414 function tMark_afh_off(effect) {
415 try {
416 var elem = effect.effects[0].element;
417
418 console.log("tMark_afh_off : " + elem.id);
419
420 if (elem) {
421 elem.src = elem.src.replace("mark_set", "mark_unset");
422 elem.alt = __("Star article");
423 Element.show(elem);
424 }
425
426 } catch (e) {
427 exception_error("tMark_afh_off", e);
428 }
429 }
430
431 function tPub_afh_off(effect) {
432 try {
433 var elem = effect.effects[0].element;
434
435 console.log("tPub_afh_off : " + elem.id);
436
437 if (elem) {
438 elem.src = elem.src.replace("pub_set", "pub_unset");
439 elem.alt = __("Publish article");
440 Element.show(elem);
441 }
442
443 } catch (e) {
444 exception_error("tPub_afh_off", e);
445 }
446 }
447
448 function toggleMark(mark_img, id) {
449
450 try {
451
452 var query = "?op=rpc&id=" + id + "&subop=mark";
453
454 query = query + "&afid=" + _active_feed_id;
455 query = query + "&omode=c";
456
457 if (!mark_img) return;
458
459 if (mark_img.src.match("mark_unset")) {
460 mark_img.src = mark_img.src.replace("mark_unset", "mark_set");
461 mark_img.alt = __("Unstar article");
462 query = query + "&mark=1";
463 } else {
464 mark_img.alt = __("Please wait...");
465 query = query + "&mark=0";
466
467 mark_img.src = mark_img.src.replace("mark_set", "mark_unset");
468 mark_img.alt = __("Star article");
469 }
470
471 new Ajax.Request("backend.php", {
472 parameters: query,
473 onComplete: function(transport) {
474 //
475 } });
476
477 } catch (e) {
478 exception_error("toggleMark", e);
479 }
480 }
481
482 function togglePub(mark_img, id, note) {
483
484 try {
485
486 var query = "?op=rpc&id=" + id + "&subop=publ";
487
488 query = query + "&afid=" + _active_feed_id;
489
490 if (note != undefined) {
491 query = query + "&note=" + param_escape(note);
492 } else {
493 query = query + "&note=undefined";
494 }
495
496 query = query + "&omode=c";
497
498 if (!mark_img) return;
499
500 if (mark_img.src.match("pub_unset") || note != undefined) {
501 mark_img.src = mark_img.src.replace("pub_unset", "pub_set");
502 mark_img.alt = __("Unpublish article");
503 query = query + "&pub=1";
504
505 } else {
506 mark_img.alt = __("Please wait...");
507 query = query + "&pub=0";
508
509 mark_img.src = mark_img.src.replace("pub_set", "pub_unset");
510 mark_img.alt = __("Publish article");
511 }
512
513 new Ajax.Request("backend.php", {
514 parameters: query,
515 onComplete: function(transport) {
516 //
517 } });
518
519 } catch (e) {
520 exception_error("togglePub", e);
521 }
522 }
523
524 function fatal_error(code, msg) {
525 try {
526
527 if (code == 6) {
528 window.location.href = "digest.php";
529 } else if (code == 5) {
530 window.location.href = "update.php";
531 } else {
532
533 if (msg == "") msg = "Unknown error";
534
535 console.error("Fatal error: " + code + "\n" +
536 msg);
537
538 }
539
540 } catch (e) {
541 exception_error("fatalError", e);
542 }
543 }
544
545 function fatal_error_check(transport) {
546 try {
547 if (transport.responseXML) {
548 var error = transport.responseXML.getElementsByTagName("error")[0];
549
550 if (error) {
551 var code = error.getAttribute("error-code");
552 var msg = error.getAttribute("error-msg");
553 if (code != 0) {
554 fatal_error(code, msg);
555 return false;
556 }
557 }
558 }
559 } catch (e) {
560 exception_error("fatal_error_check", e);
561 }
562 return true;
563 }
564
565 function feed_mi(elem) {
566 try {
567 var imgs = elem.getElementsByTagName('IMG');
568 var spans = elem.getElementsByTagName('SPAN');
569
570 for (var i = 0; i < imgs.length; i++) {
571 if (imgs[i].className == "dismiss")
572 Element.show(imgs[i]);
573 }
574
575 for (var i = 0; i < spans.length; i++) {
576 if (spans[i].className == "unread")
577 Element.hide(spans[i]);
578 }
579
580
581 } catch (e) {
582 exception_error("feed_mi", e);
583 }
584 }
585
586 function feed_mo(elem) {
587 try {
588 var imgs = elem.getElementsByTagName('IMG');
589 var spans = elem.getElementsByTagName('SPAN');
590
591 for (var i = 0; i < imgs.length; i++) {
592 if (imgs[i].className == "dismiss")
593 Element.hide(imgs[i]);
594 }
595
596 for (var i = 0; i < spans.length; i++) {
597 if (spans[i].className == "unread")
598 Element.show(spans[i]);
599 }
600
601 } catch (e) {
602 exception_error("feed_mo", e);
603 }
604 }