]> git.wh0rd.org Git - tt-rss.git/blob - viewfeed.js
enable tags support in CDM
[tt-rss.git] / viewfeed.js
1 var active_post_id = false;
2 var _catchup_callback_func = false;
3 var last_article_view = false;
4 var active_real_feed_id = false;
5
6 var _tag_active_post_id = false;
7 var _tag_active_feed_id = false;
8 var _tag_active_cdm = false;
9
10 // FIXME: kludge, to restore scrollTop after tag editor terminates
11 var _tag_cdm_scroll = false;
12
13 // FIXME: kludges, needs proper implementation
14 var _reload_feedlist_after_view = false;
15
16 var _cdm_wd_timeout = false;
17 var _cdm_wd_vishist = new Array();
18
19 function catchup_callback() {
20         if (xmlhttp_rpc.readyState == 4) {
21                 try {
22                         debug("catchup_callback");
23                         if (_catchup_callback_func) {
24                                 setTimeout(_catchup_callback_func, 100);        
25                         }
26                         all_counters_callback();
27                 } catch (e) {
28                         exception_error("catchup_callback", e);
29                 }
30         }
31 }
32
33 function headlines_callback() {
34         if (xmlhttp.readyState == 4) {
35                 debug("headlines_callback");
36                 var f = document.getElementById("headlines-frame");
37                 try {
38                         f.scrollTop = 0;
39                 } catch (e) { };
40                 f.innerHTML = xmlhttp.responseText;
41                 update_all_counters();
42                 if (typeof correctPNG != 'undefined') {
43                         correctPNG();
44                 }
45
46                 if (_cdm_wd_timeout) window.clearTimeout(_cdm_wd_timeout);
47
48                 if (!document.getElementById("headlinesList")) {
49                         debug("starting CDM watchdog");
50                         _cdm_wd_timeout = window.setTimeout("cdmWatchdog()", 5000);
51                         _cdm_wd_vishist = new Array();
52                 }
53
54                 if (_tag_cdm_scroll) {
55                         try {
56                                 document.getElementById("headlinesInnerContainer").scrollTop = _tag_cdm_scroll;
57                                 _tag_cdm_scroll = false;
58                         } catch (e) { }
59                 }
60
61                 notify("");
62         }
63 }
64
65 function article_callback() {
66         if (xmlhttp.readyState == 4) {
67                 debug("article_callback");
68                 var f = document.getElementById("content-frame");
69                 try {
70                         f.scrollTop = 0;
71                 } catch (e) { };
72                 f.innerHTML = xmlhttp.responseText;
73
74                 var date = new Date();
75                 last_article_view = date.getTime() / 1000;
76
77                 if (typeof correctPNG != 'undefined') {
78                         correctPNG();
79                 }
80
81                 if (_reload_feedlist_after_view) {
82                         setTimeout('updateFeedList(false, false)', 50);                 
83                         _reload_feedlist_after_view = false;
84                 } else {
85                         update_all_counters();
86                 }
87         }
88 }
89
90 function view(id, feed_id, skip_history) {
91         
92         try {
93                 debug("loading article: " + id + "/" + feed_id);
94
95                 active_real_feed_id = feed_id;
96
97                 if (!skip_history) {
98                         history_push("ARTICLE:" + id + ":" + feed_id);
99                 }
100         
101                 enableHotkeys();
102         
103                 active_post_id = id; 
104                 //setActiveFeedId(feed_id);
105
106                 var query = "backend.php?op=view&id=" + param_escape(id) +
107                         "&feed=" + param_escape(feed_id);
108
109                 var date = new Date();
110
111                 if (!xmlhttp_ready(xmlhttp) && last_article_view < date.getTime() / 1000 - 15) {
112                         debug("<b>xmlhttp seems to be stuck at view, aborting</b>");
113                         xmlhttp.abort();
114                 }
115
116                 if (xmlhttp_ready(xmlhttp)) {
117
118                         cleanSelected("headlinesList");
119
120                         var crow = document.getElementById("RROW-" + active_post_id);
121                         crow.className = crow.className.replace("Unread", "");
122
123                         var upd_img_pic = document.getElementById("FUPDPIC-" + active_post_id);
124
125                         if (upd_img_pic) {
126                                 upd_img_pic.src = "images/blank_icon.gif";
127                         }
128
129                         selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', false);
130                         markHeadline(active_post_id);
131
132                         xmlhttp.open("GET", query, true);
133                         xmlhttp.onreadystatechange=article_callback;
134                         xmlhttp.send(null);
135                 } else {
136                         debug("xmlhttp busy (@view)");
137                         printLockingError();
138                 }  
139
140         } catch (e) {
141                 exception_error("view", e);
142         }
143 }
144
145 function toggleMark(id) {
146
147         if (!xmlhttp_ready(xmlhttp_rpc)) {
148                 printLockingError();
149                 return;
150         }
151
152         var query = "backend.php?op=rpc&id=" + id + "&subop=mark";
153
154         var mark_img = document.getElementById("FMARKPIC-" + id);
155         var vfeedu = document.getElementById("FEEDU--1");
156         var crow = document.getElementById("RROW-" + id);
157
158         if (mark_img.alt != "Reset mark") {
159                 mark_img.src = "images/mark_set.png";
160                 mark_img.alt = "Reset mark";
161                 query = query + "&mark=1";
162
163                 if (vfeedu && crow.className.match("Unread")) {
164                         vfeedu.innerHTML = (+vfeedu.innerHTML) + 1;
165                 }
166
167         } else {
168                 mark_img.src = "images/mark_unset.png";
169                 mark_img.alt = "Set mark";
170                 query = query + "&mark=0";
171
172                 if (vfeedu && crow.className.match("Unread")) {
173                         vfeedu.innerHTML = (+vfeedu.innerHTML) - 1;
174                 }
175
176         }
177
178         var vfeedctr = document.getElementById("FEEDCTR--1");
179         var vfeedr = document.getElementById("FEEDR--1");
180
181         if (vfeedu && vfeedctr) {
182                 if ((+vfeedu.innerHTML) > 0) {
183                         if (crow.className.match("Unread") && !vfeedr.className.match("Unread")) {
184                                 vfeedr.className = vfeedr.className + "Unread";
185                                 vfeedctr.className = "odd";
186                         }
187                 } else {
188                         vfeedctr.className = "invisible";
189                         vfeedr.className = vfeedr.className.replace("Unread", "");
190                 }
191         }
192
193         debug("toggle starred for aid " + id);
194
195         new Ajax.Request(query);
196
197 }
198
199 function moveToPost(mode) {
200
201         // check for combined mode
202         if (!document.getElementById("headlinesList"))
203                 return;
204
205         var rows = getVisibleHeadlineIds();
206
207         var prev_id;
208         var next_id;
209
210         if (!document.getElementById('RROW-' + active_post_id)) {
211                 active_post_id = false;
212         }
213
214         if (active_post_id == false) {
215                 next_id = getFirstVisibleHeadlineId();
216                 prev_id = getLastVisibleHeadlineId();
217         } else {        
218                 for (var i = 0; i < rows.length; i++) {
219                         if (rows[i] == active_post_id) {
220                                 prev_id = rows[i-1];
221                                 next_id = rows[i+1];                    
222                         }
223                 }
224         }
225
226         if (mode == "next") {
227                 if (next_id != undefined) {
228                         view(next_id, getActiveFeedId());
229                 }
230         }
231
232         if (mode == "prev") {
233                 if ( prev_id != undefined) {
234                         view(prev_id, getActiveFeedId());
235                 }
236         } 
237 }
238
239 function toggleUnread(id, cmode) {
240         try {
241                 if (!xmlhttp_ready(xmlhttp_rpc)) {
242                         printLockingError();
243                         return;
244                 }
245         
246                 var row = document.getElementById("RROW-" + id);
247                 if (row) {
248                         var nc = row.className;
249                         nc = nc.replace("Unread", "");
250                         nc = nc.replace("Selected", "");
251
252                         if (row.className.match("Unread")) {
253                                 row.className = nc;
254                         } else {
255                                 row.className = nc + "Unread";
256                         }
257
258                         if (!cmode) cmode = 2;
259
260                         var query = "backend.php?op=rpc&subop=catchupSelected&ids=" +
261                                 param_escape(id) + "&cmode=" + param_escape(cmode);
262
263                         xmlhttp_rpc.open("GET", query, true);
264                         xmlhttp_rpc.onreadystatechange=all_counters_callback;
265                         xmlhttp_rpc.send(null);
266
267                 }
268
269
270         } catch (e) {
271                 exception_error("toggleUnread", e);
272         }
273 }
274
275 function selectionToggleUnread(cdm_mode, set_state, callback_func) {
276         try {
277                 if (!xmlhttp_ready(xmlhttp_rpc)) {
278                         printLockingError();
279                         return;
280                 }
281         
282                 var rows;
283
284                 if (cdm_mode) {
285                         rows = cdmGetSelectedArticles();
286                 } else {        
287                         rows = getSelectedTableRowIds("headlinesList", "RROW", "RCHK");
288                 }
289
290                 for (i = 0; i < rows.length; i++) {
291                         var row = document.getElementById("RROW-" + rows[i]);
292                         if (row) {
293                                 var nc = row.className;
294                                 nc = nc.replace("Unread", "");
295                                 nc = nc.replace("Selected", "");
296
297                                 if (row.className.match("Unread")) {
298                                         row.className = nc + "Selected";
299                                 } else {
300                                         row.className = nc + "UnreadSelected";
301                                 }
302                         }
303                 }
304
305                 if (rows.length > 0) {
306
307                         var cmode = "";
308
309                         if (set_state == undefined) {
310                                 cmode = "2";
311                         } else if (set_state == true) {
312                                 cmode = "1";
313                         } else if (set_state == false) {
314                                 cmode = "0";
315                         }
316
317                         var query = "backend.php?op=rpc&subop=catchupSelected&ids=" +
318                                 param_escape(rows.toString()) + "&cmode=" + cmode;
319
320                         _catchup_callback_func = callback_func;
321
322                         xmlhttp_rpc.open("GET", query, true);
323                         xmlhttp_rpc.onreadystatechange=catchup_callback;
324                         xmlhttp_rpc.send(null);
325
326                 }
327
328         } catch (e) {
329                 exception_error("selectionToggleUnread", e);
330         }
331 }
332
333 function selectionToggleMarked(cdm_mode) {
334         try {
335                 if (!xmlhttp_ready(xmlhttp_rpc)) {
336                         printLockingError();
337                         return;
338                 }
339         
340                 var rows;
341                 
342                 if (cdm_mode) {
343                         rows = cdmGetSelectedArticles();
344                 } else {        
345                         rows = getSelectedTableRowIds("headlinesList", "RROW", "RCHK");
346                 }       
347
348                 for (i = 0; i < rows.length; i++) {
349                         var row = document.getElementById("RROW-" + rows[i]);
350                         var mark_img = document.getElementById("FMARKPIC-" + rows[i]);
351
352                         if (row && mark_img) {
353
354                                 if (mark_img.alt == "Set mark") {
355                                         mark_img.src = "images/mark_set.png";
356                                         mark_img.alt = "Reset mark";
357                                         mark_img.setAttribute('onclick', 
358                                                 'javascript:toggleMark('+rows[i]+', false)');
359
360                                 } else {
361                                         mark_img.src = "images/mark_unset.png";
362                                         mark_img.alt = "Set mark";
363                                         mark_img.setAttribute('onclick', 
364                                                 'javascript:toggleMark('+rows[i]+', true)');
365                                 }
366                         }
367                 }
368
369                 if (rows.length > 0) {
370
371                         var query = "backend.php?op=rpc&subop=markSelected&ids=" +
372                                 param_escape(rows.toString()) + "&cmode=2";
373
374                         xmlhttp_rpc.open("GET", query, true);
375                         xmlhttp_rpc.onreadystatechange=all_counters_callback;
376                         xmlhttp_rpc.send(null);
377
378                 }
379
380         } catch (e) {
381                 exception_error("selectionToggleMarked", e);
382         }
383 }
384
385 function cdmGetSelectedArticles() {
386         var sel_articles = new Array();
387         var container = document.getElementById("headlinesInnerContainer");
388
389         for (i = 0; i < container.childNodes.length; i++) {
390                 var child = container.childNodes[i];
391
392                 if (child.id.match("RROW-") && child.className.match("Selected")) {
393                         var c_id = child.id.replace("RROW-", "");
394                         sel_articles.push(c_id);
395                 }
396         }
397
398         return sel_articles;
399 }
400
401 // mode = all,none,unread
402 function cdmSelectArticles(mode) {
403         var container = document.getElementById("headlinesInnerContainer");
404
405         for (i = 0; i < container.childNodes.length; i++) {
406                 var child = container.childNodes[i];
407
408                 if (child.id.match("RROW-")) {
409                         var aid = child.id.replace("RROW-", "");
410
411                         var cb = document.getElementById("RCHK-" + aid);
412
413                         if (mode == "all") {
414                                 if (!child.className.match("Selected")) {
415                                         child.className = child.className + "Selected";
416                                         cb.checked = true;
417                                 }
418                         } else if (mode == "unread") {
419                                 if (child.className.match("Unread") && !child.className.match("Selected")) {
420                                         child.className = child.className + "Selected";
421                                         cb.checked = true;
422                                 }
423                         } else {
424                                 child.className = child.className.replace("Selected", "");
425                                 cb.checked = false;
426                         }
427                 }               
428         }
429 }
430
431 function catchupPage() {
432
433         if (document.getElementById("headlinesList")) {
434                 selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', true, 'Unread', true);
435                 selectionToggleUnread(false, false, 'viewCurrentFeed()');
436                 selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', false);
437         } else {
438                 cdmSelectArticles('all');
439                 selectionToggleUnread(true, false, 'viewCurrentFeed()')
440                 cdmSelectArticles('none');
441         }
442 }
443
444 function labelFromSearch(search, search_mode, match_on, feed_id, is_cat) {
445
446         if (!xmlhttp_ready(xmlhttp_rpc)) {
447                 printLockingError();
448         }
449
450         var title = prompt("Please enter label title:", "");
451
452         if (title) {
453
454                 var query = "backend.php?op=labelFromSearch&search=" + param_escape(search) +
455                         "&smode=" + param_escape(search_mode) + "&match=" + param_escape(match_on) +
456                         "&feed=" + param_escape(feed_id) + "&is_cat=" + param_escape(is_cat) + 
457                         "&title=" + param_escape(title);
458
459                 debug("LFS: " + query);
460         
461                 xmlhttp_rpc.open("GET", query, true);
462                 xmlhttp_rpc.onreadystatechange=dlg_frefresh_callback;
463                 xmlhttp_rpc.send(null);
464         }
465
466 }
467
468 function editArticleTags(id, feed_id, cdm_enabled) {
469         _tag_active_post_id = id;
470         _tag_active_feed_id = feed_id;
471         _tag_active_cdm = cdm_enabled;
472         try {
473                 _tag_cdm_scroll = document.getElementById("headlinesInnerContainer").scrollTop;
474         } catch (e) { }
475         displayDlg('editArticleTags', id);
476 }
477
478
479 function tag_saved_callback() {
480         if (xmlhttp_rpc.readyState == 4) {
481                 try {
482                         debug("in tag_saved_callback");
483
484                         closeInfoBox();
485                         notify("");
486
487                         if (tagsAreDisplayed()) {
488                                 _reload_feedlist_after_view = true;
489                         }
490
491                         if (!_tag_active_cdm) {
492                                 if (active_post_id == _tag_active_post_id) {
493                                         debug("reloading current article");
494                                         view(_tag_active_post_id, _tag_active_feed_id);                 
495                                 }
496                         } else {
497                                 debug("reloading current feed");
498                                 viewCurrentFeed();
499                         }
500
501                 } catch (e) {
502                         exception_error("catchup_callback", e);
503                 }
504         }
505 }
506
507 function editTagsSave() {
508
509         if (!xmlhttp_ready(xmlhttp_rpc)) {
510                 printLockingError();
511         }
512
513         notify("Saving article tags...");
514
515         var form = document.forms["tag_edit_form"];
516
517         var query = Form.serialize("tag_edit_form");
518
519         xmlhttp_rpc.open("GET", "backend.php?op=rpc&subop=setArticleTags&" + query, true);                      
520         xmlhttp_rpc.onreadystatechange=tag_saved_callback;
521         xmlhttp_rpc.send(null);
522
523 }
524
525 function editTagsInsert() {
526         try {
527
528                 var form = document.forms["tag_edit_form"];
529
530                 var found_tags = form.found_tags;
531                 var tags_str = form.tags_str;
532
533                 var tag = found_tags[found_tags.selectedIndex].value;
534
535                 if (tags_str.value.length > 0 && 
536                                 tags_str.value.lastIndexOf(", ") != tags_str.value.length - 2) {
537
538                         tags_str.value = tags_str.value + ", ";
539                 }
540
541                 tags_str.value = tags_str.value + tag + ", ";
542
543                 found_tags.selectedIndex = 0;
544                 
545         } catch (e) {
546                 exception_error(e, "editTagsInsert");
547         }
548 }
549
550 function cdmWatchdog() {
551
552         try {
553
554                 var ctr = document.getElementById("headlinesInnerContainer");
555
556                 if (!ctr.hasChildNodes()) return;
557
558                 var ids = new Array();
559
560                 var e = ctr.firstChild;
561
562                 while (e) {
563                         if (e.className && e.className == "cdmArticleUnread" && e.id &&
564                                         e.id.match("RROW-")) {
565
566                                 // article fits in viewport OR article is longer than viewport and
567                                 // its bottom is visible
568
569                                 if (ctr.scrollTop <= e.offsetTop && e.offsetTop + e.offsetHeight <=
570                                                 ctr.scrollTop + ctr.offsetHeight) {
571
572 //                                      debug(e.id + " is visible " + e.offsetTop + "." + 
573 //                                              (e.offsetTop + e.offsetHeight) + " vs " + ctr.scrollTop + "." +
574 //                                              (ctr.scrollTop + ctr.offsetHeight));
575
576                                         ids.push(e.id.replace("RROW-", ""));
577
578                                 } else if (e.offsetHeight > ctr.offsetHeight &&
579                                                 e.offsetTop + e.offsetHeight >= ctr.scrollTop &&
580                                                 e.offsetTop + e.offsetHeight <= ctr.scrollTop + ctr.offsetHeight) {
581
582                                         ids.push(e.id.replace("RROW-", "")); 
583
584                                 }
585
586                         }
587
588                         e = e.nextSibling;
589                 }
590
591                 debug("cdmWatchdog, ids= " + ids.toString());
592
593                 if (ids.length > 0 && xmlhttp_ready(xmlhttp_rpc)) {
594
595                         for (var i = 0; i < ids.length; i++) {
596                                 var e = document.getElementById("RROW-" + ids[i]);
597                                 if (e) {
598                                         e.className = e.className.replace("Unread", "");
599                                 }
600                         }
601
602                         var query = "backend.php?op=rpc&subop=catchupSelected&ids=" +
603                                 param_escape(ids.toString()) + "&cmode=0";
604
605                         xmlhttp_rpc.open("GET", query, true);
606                         xmlhttp_rpc.onreadystatechange=all_counters_callback;
607                         xmlhttp_rpc.send(null);
608
609                 }
610
611                 _cdm_wd_timeout = window.setTimeout("cdmWatchdog()", 5000);
612
613         } catch (e) {
614                 exception_error(e, "cdmWatchdog");
615         }
616
617 }