viewfeed.js 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184
  1. var active_post_id = false;
  2. var article_cache = new Array();
  3. var vgroup_last_feed = false;
  4. var post_under_pointer = false;
  5. var last_requested_article = false;
  6. var catchup_id_batch = [];
  7. var catchup_timeout_id = false;
  8. var feed_precache_timeout_id = false;
  9. var precache_idle_timeout_id = false;
  10. var cids_requested = [];
  11. var loaded_article_ids = [];
  12. var has_storage = 'sessionStorage' in window && window['sessionStorage'] !== null;
  13. function headlines_callback2(transport, offset, background, infscroll_req) {
  14. try {
  15. handle_rpc_json(transport);
  16. loading_set_progress(25);
  17. console.log("headlines_callback2 [offset=" + offset + "] B:" + background + " I:" + infscroll_req);
  18. var is_cat = false;
  19. var feed_id = false;
  20. var reply = false;
  21. try {
  22. reply = JSON.parse(transport.responseText);
  23. } catch (e) {
  24. console.error(e);
  25. }
  26. if (reply) {
  27. is_cat = reply['headlines']['is_cat'];
  28. feed_id = reply['headlines']['id'];
  29. if (background) {
  30. var content = reply['headlines']['content'];
  31. if (getInitParam("cdm_auto_catchup") == 1) {
  32. content = content + "<div id='headlines-spacer'></div>";
  33. }
  34. cache_headlines(feed_id, is_cat, reply['headlines']['toolbar'], content);
  35. return;
  36. }
  37. setActiveFeedId(feed_id, is_cat);
  38. dijit.getEnclosingWidget(
  39. document.forms["main_toolbar_form"].update).attr('disabled',
  40. is_cat || feed_id <= 0);
  41. try {
  42. if (offset == 0 && infscroll_req == false) {
  43. $("headlines-frame").scrollTop = 0;
  44. }
  45. } catch (e) { };
  46. var headlines_count = reply['headlines-info']['count'];
  47. vgroup_last_feed = reply['headlines-info']['vgroup_last_feed'];
  48. if (parseInt(headlines_count) < getInitParam("default_article_limit")) {
  49. _infscroll_disable = 1;
  50. } else {
  51. _infscroll_disable = 0;
  52. }
  53. var counters = reply['counters'];
  54. var articles = reply['articles'];
  55. //var runtime_info = reply['runtime-info'];
  56. if (offset == 0 && infscroll_req == false) {
  57. loaded_article_ids = [];
  58. dijit.byId("headlines-frame").attr('content',
  59. reply['headlines']['content']);
  60. dijit.byId("headlines-toolbar").attr('content',
  61. reply['headlines']['toolbar']);
  62. $$("#headlines-frame > div[id*=RROW]").each(function(row) {
  63. if (loaded_article_ids.indexOf(row.id) != -1) {
  64. row.parentNode.removeChild(row);
  65. } else {
  66. loaded_article_ids.push(row.id);
  67. }
  68. });
  69. if (getInitParam("cdm_auto_catchup") == 1) {
  70. var hsp = $("headlines-spacer");
  71. if (!hsp) hsp = new Element("DIV", {"id": "headlines-spacer"});
  72. dijit.byId('headlines-frame').domNode.appendChild(hsp);
  73. }
  74. initHeadlinesMenu();
  75. if (_search_query) {
  76. $("feed_title").innerHTML += "<span id='cancel_search'>" +
  77. " (<a href='#' onclick='cancelSearch()'>" + __("Cancel search") + "</a>)" +
  78. "</span>";
  79. }
  80. } else {
  81. if (headlines_count > 0 && feed_id == getActiveFeedId() && is_cat == activeFeedIsCat()) {
  82. console.log("adding some more headlines: " + headlines_count);
  83. var c = dijit.byId("headlines-frame");
  84. var ids = getSelectedArticleIds2();
  85. var new_elems = [];
  86. $("headlines-tmp").innerHTML = reply['headlines']['content'];
  87. var hsp = $("headlines-spacer");
  88. if (hsp)
  89. c.domNode.removeChild(hsp);
  90. $$("#headlines-tmp > div").each(function(row) {
  91. if (row.className == 'cdmFeedTitle') {
  92. row.style.display = 'none';
  93. c.domNode.appendChild(row);
  94. new_elems.push(row);
  95. } else if (loaded_article_ids.indexOf(row.id) == -1) {
  96. row.style.display = 'none';
  97. c.domNode.appendChild(row);
  98. new_elems.push(row);
  99. loaded_article_ids.push(row.id);
  100. } else {
  101. row.parentNode.removeChild(row);
  102. }
  103. });
  104. if (!hsp) hsp = new Element("DIV", {"id": "headlines-spacer"});
  105. fixHeadlinesOrder(getLoadedArticleIds());
  106. if (getInitParam("cdm_auto_catchup") == 1) {
  107. c.domNode.appendChild(hsp);
  108. }
  109. console.log("added " + new_elems.size() + " headlines");
  110. if (new_elems.size() == 0)
  111. _infscroll_disable = true;
  112. console.log("restore selected ids: " + ids);
  113. for (var i = 0; i < ids.length; i++) {
  114. markHeadline(ids[i]);
  115. }
  116. initHeadlinesMenu();
  117. new_elems.each(function(child) {
  118. var cb = dijit.byId(child.id.replace("RROW-", "RCHK-"));
  119. if (cb) cb.destroy();
  120. dojo.parser.parse(child);
  121. if (!Element.visible(child))
  122. new Effect.Appear(child, { duration : 0.5 });
  123. });
  124. } else {
  125. console.log("no new headlines received");
  126. var hsp = $("headlines-spacer");
  127. if (hsp) hsp.innerHTML = "";
  128. }
  129. }
  130. if (headlines_count > 0)
  131. cache_headlines(feed_id, is_cat, reply['headlines']['toolbar'], $("headlines-frame").innerHTML);
  132. if (articles) {
  133. for (var i = 0; i < articles.length; i++) {
  134. var a_id = articles[i]['id'];
  135. cache_set("article:" + a_id, articles[i]['content']);
  136. }
  137. } else {
  138. console.log("no cached articles received");
  139. }
  140. // do not precache stuff after fresh feed
  141. if (feed_id != -3)
  142. precache_headlines();
  143. if (counters)
  144. parse_counters(counters);
  145. else
  146. request_counters();
  147. } else if (transport.responseText) {
  148. console.error("Invalid object received: " + transport.responseText);
  149. dijit.byId("headlines-frame").attr('content', "<div class='whiteBox'>" +
  150. __('Could not update headlines (invalid object received - see error console for details)') +
  151. "</div>");
  152. } else {
  153. notify_error("Error communicating with server.");
  154. }
  155. _infscroll_request_sent = 0;
  156. notify("");
  157. } catch (e) {
  158. exception_error("headlines_callback2", e, transport);
  159. }
  160. }
  161. function render_article(article) {
  162. try {
  163. dijit.byId("headlines-wrap-inner").addChild(
  164. dijit.byId("content-insert"));
  165. var c = dijit.byId("content-insert");
  166. try {
  167. c.domNode.scrollTop = 0;
  168. } catch (e) { };
  169. c.attr('content', article);
  170. correctHeadlinesOffset(getActiveArticleId());
  171. try {
  172. c.focus();
  173. } catch (e) { };
  174. } catch (e) {
  175. exception_error("render_article", e);
  176. }
  177. }
  178. function showArticleInHeadlines(id) {
  179. try {
  180. selectArticles("none");
  181. var crow = $("RROW-" + id);
  182. if (!crow) return;
  183. var article_is_unread = crow.hasClassName("Unread");
  184. crow.removeClassName("Unread");
  185. selectArticles('none');
  186. var view_mode = false;
  187. try {
  188. view_mode = document.forms['main_toolbar_form'].view_mode;
  189. view_mode = view_mode[view_mode.selectedIndex].value;
  190. } catch (e) {
  191. //
  192. }
  193. if (article_is_unread && view_mode == "all_articles") {
  194. cache_headlines(getActiveFeedId(), activeFeedIsCat(), null, $("headlines-frame").innerHTML);
  195. }
  196. markHeadline(id);
  197. if (article_is_unread)
  198. _force_scheduled_update = true;
  199. } catch (e) {
  200. exception_error("showArticleInHeadlines", e);
  201. }
  202. }
  203. function article_callback2(transport, id) {
  204. try {
  205. console.log("article_callback2 " + id);
  206. handle_rpc_json(transport);
  207. var reply = false;
  208. try {
  209. reply = JSON.parse(transport.responseText);
  210. } catch (e) {
  211. console.error(e);
  212. }
  213. if (reply) {
  214. reply.each(function(article) {
  215. if (active_post_id == article['id']) {
  216. render_article(article['content']);
  217. }
  218. cids_requested.remove(article['id']);
  219. cache_set("article:" + article['id'], article['content']);
  220. });
  221. // if (id != last_requested_article) {
  222. // console.log("requested article id is out of sequence, aborting");
  223. // return;
  224. // }
  225. } else {
  226. console.error("Invalid object received: " + transport.responseText);
  227. render_article("<div class='whiteBox'>" +
  228. __('Could not display article (invalid object received - see error console for details)') + "</div>");
  229. }
  230. request_counters();
  231. headlines_scroll_handler($("headlines-frame"));
  232. /* try {
  233. if (!_infscroll_disable &&
  234. $$("#headlines-frame > div[id*=RROW]").last().hasClassName("Selected")) {
  235. loadMoreHeadlines();
  236. }
  237. } catch (e) {
  238. console.warn(e);
  239. } */
  240. notify("");
  241. } catch (e) {
  242. exception_error("article_callback2", e, transport);
  243. }
  244. }
  245. function view(id) {
  246. try {
  247. console.log("loading article: " + id);
  248. var cached_article = cache_get("article:" + id);
  249. console.log("cache check result: " + (cached_article != false));
  250. hideAuxDlg();
  251. var query = "?op=article&method=view&id=" + param_escape(id);
  252. var neighbor_ids = getRelativePostIds(id);
  253. /* only request uncached articles */
  254. var cids_to_request = [];
  255. for (var i = 0; i < neighbor_ids.length; i++) {
  256. if (cids_requested.indexOf(neighbor_ids[i]) == -1)
  257. if (!cache_get("article:" + neighbor_ids[i])) {
  258. cids_to_request.push(neighbor_ids[i]);
  259. cids_requested.push(neighbor_ids[i]);
  260. }
  261. }
  262. console.log("additional ids: " + cids_to_request.toString());
  263. query = query + "&cids=" + cids_to_request.toString();
  264. var crow = $("RROW-" + id);
  265. var article_is_unread = crow.hasClassName("Unread");
  266. active_post_id = id;
  267. showArticleInHeadlines(id);
  268. precache_headlines();
  269. if (cached_article && article_is_unread) {
  270. query = query + "&mode=prefetch";
  271. render_article(cached_article);
  272. } else if (cached_article) {
  273. query = query + "&mode=prefetch_old";
  274. render_article(cached_article);
  275. // if we don't need to request any relative ids, we might as well skip
  276. // the server roundtrip altogether
  277. if (cids_to_request.length == 0) {
  278. /* try {
  279. if (!_infscroll_disable &&
  280. $$("#headlines-frame > div[id*=RROW]").last().hasClassName("Selected")) {
  281. loadMoreHeadlines();
  282. }
  283. } catch (e) {
  284. console.warn(e);
  285. } */
  286. headlines_scroll_handler($("headlines-frame"));
  287. return;
  288. }
  289. }
  290. last_requested_article = id;
  291. console.log(query);
  292. if (article_is_unread) {
  293. decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
  294. }
  295. new Ajax.Request("backend.php", {
  296. parameters: query,
  297. onComplete: function(transport) {
  298. article_callback2(transport, id);
  299. } });
  300. return false;
  301. } catch (e) {
  302. exception_error("view", e);
  303. }
  304. }
  305. function toggleMark(id, client_only) {
  306. try {
  307. var query = "?op=rpc&id=" + id + "&method=mark";
  308. var img = $("FMPIC-" + id);
  309. if (!img) return;
  310. if (img.src.match("mark_unset")) {
  311. img.src = img.src.replace("mark_unset", "mark_set");
  312. img.alt = __("Unstar article");
  313. query = query + "&mark=1";
  314. } else {
  315. img.src = img.src.replace("mark_set", "mark_unset");
  316. img.alt = __("Star article");
  317. query = query + "&mark=0";
  318. }
  319. cache_headlines(getActiveFeedId(), activeFeedIsCat(), null, $("headlines-frame").innerHTML);
  320. if (!client_only) {
  321. new Ajax.Request("backend.php", {
  322. parameters: query,
  323. onComplete: function(transport) {
  324. handle_rpc_json(transport);
  325. } });
  326. }
  327. } catch (e) {
  328. exception_error("toggleMark", e);
  329. }
  330. }
  331. function togglePub(id, client_only, no_effects, note) {
  332. try {
  333. var query = "?op=rpc&id=" + id + "&method=publ";
  334. if (note != undefined) {
  335. query = query + "&note=" + param_escape(note);
  336. } else {
  337. query = query + "&note=undefined";
  338. }
  339. var img = $("FPPIC-" + id);
  340. if (!img) return;
  341. if (img.src.match("pub_unset") || note != undefined) {
  342. img.src = img.src.replace("pub_unset", "pub_set");
  343. img.alt = __("Unpublish article");
  344. query = query + "&pub=1";
  345. } else {
  346. img.src = img.src.replace("pub_set", "pub_unset");
  347. img.alt = __("Publish article");
  348. query = query + "&pub=0";
  349. }
  350. cache_headlines(getActiveFeedId(), activeFeedIsCat(), null, $("headlines-frame").innerHTML);
  351. if (!client_only) {
  352. new Ajax.Request("backend.php", {
  353. parameters: query,
  354. onComplete: function(transport) {
  355. handle_rpc_json(transport);
  356. } });
  357. }
  358. } catch (e) {
  359. exception_error("togglePub", e);
  360. }
  361. }
  362. function moveToPost(mode) {
  363. try {
  364. var rows = getVisibleArticleIds();
  365. var prev_id = false;
  366. var next_id = false;
  367. if (!$('RROW-' + active_post_id)) {
  368. active_post_id = false;
  369. }
  370. if (active_post_id == false) {
  371. next_id = rows[0];
  372. prev_id = rows[rows.length-1]
  373. } else {
  374. for (var i = 0; i < rows.length; i++) {
  375. if (rows[i] == active_post_id) {
  376. // Account for adjacent identical article ids.
  377. if (i > 0) prev_id = rows[i-1];
  378. for (var j = i+1; j < rows.length; j++) {
  379. if (rows[j] != active_post_id) {
  380. next_id = rows[j];
  381. break;
  382. }
  383. }
  384. break;
  385. }
  386. }
  387. }
  388. if (mode == "next") {
  389. if (next_id) {
  390. if (isCdmMode()) {
  391. cdmExpandArticle(next_id);
  392. cdmScrollToArticleId(next_id);
  393. } else {
  394. correctHeadlinesOffset(next_id);
  395. view(next_id, getActiveFeedId());
  396. }
  397. }
  398. }
  399. if (mode == "prev") {
  400. if (prev_id) {
  401. if (isCdmMode()) {
  402. cdmExpandArticle(prev_id);
  403. cdmScrollToArticleId(prev_id);
  404. } else {
  405. correctHeadlinesOffset(prev_id);
  406. view(prev_id, getActiveFeedId());
  407. }
  408. }
  409. }
  410. } catch (e) {
  411. exception_error("moveToPost", e);
  412. }
  413. }
  414. function toggleSelected(id, force_on) {
  415. try {
  416. var cb = dijit.byId("RCHK-" + id);
  417. var row = $("RROW-" + id);
  418. if (row) {
  419. if (row.hasClassName('Selected') && !force_on) {
  420. row.removeClassName('Selected');
  421. if (cb) cb.attr("checked", false);
  422. } else {
  423. row.addClassName('Selected');
  424. if (cb) cb.attr("checked", true);
  425. }
  426. }
  427. } catch (e) {
  428. exception_error("toggleSelected", e);
  429. }
  430. }
  431. function toggleUnread_afh(effect) {
  432. try {
  433. var elem = effect.element;
  434. elem.style.backgroundColor = "";
  435. } catch (e) {
  436. exception_error("toggleUnread_afh", e);
  437. }
  438. }
  439. function toggleUnread(id, cmode, effect) {
  440. try {
  441. var row = $("RROW-" + id);
  442. if (row) {
  443. if (cmode == undefined || cmode == 2) {
  444. if (row.hasClassName("Unread")) {
  445. row.removeClassName("Unread");
  446. if (effect) {
  447. new Effect.Highlight(row, {duration: 1, startcolor: "#fff7d5",
  448. afterFinish: toggleUnread_afh,
  449. queue: { position:'end', scope: 'TMRQ-' + id, limit: 1 } } );
  450. }
  451. } else {
  452. row.addClassName("Unread");
  453. }
  454. } else if (cmode == 0) {
  455. row.removeClassName("Unread");
  456. if (effect) {
  457. new Effect.Highlight(row, {duration: 1, startcolor: "#fff7d5",
  458. afterFinish: toggleUnread_afh,
  459. queue: { position:'end', scope: 'TMRQ-' + id, limit: 1 } } );
  460. }
  461. } else if (cmode == 1) {
  462. row.addClassName("Unread");
  463. }
  464. if (cmode == undefined) cmode = 2;
  465. var query = "?op=rpc&method=catchupSelected" +
  466. "&cmode=" + param_escape(cmode) + "&ids=" + param_escape(id);
  467. // notify_progress("Loading, please wait...");
  468. new Ajax.Request("backend.php", {
  469. parameters: query,
  470. onComplete: function(transport) {
  471. handle_rpc_json(transport);
  472. } });
  473. }
  474. } catch (e) {
  475. exception_error("toggleUnread", e);
  476. }
  477. }
  478. function selectionRemoveLabel(id, ids) {
  479. try {
  480. if (!ids) ids = getSelectedArticleIds2();
  481. if (ids.length == 0) {
  482. alert(__("No articles are selected."));
  483. return;
  484. }
  485. var query = "?op=rpc&method=removeFromLabel&ids=" +
  486. param_escape(ids.toString()) + "&lid=" + param_escape(id);
  487. console.log(query);
  488. new Ajax.Request("backend.php", {
  489. parameters: query,
  490. onComplete: function(transport) {
  491. handle_rpc_json(transport);
  492. show_labels_in_headlines(transport);
  493. } });
  494. } catch (e) {
  495. exception_error("selectionAssignLabel", e);
  496. }
  497. }
  498. function selectionAssignLabel(id, ids) {
  499. try {
  500. if (!ids) ids = getSelectedArticleIds2();
  501. if (ids.length == 0) {
  502. alert(__("No articles are selected."));
  503. return;
  504. }
  505. var query = "?op=rpc&method=assignToLabel&ids=" +
  506. param_escape(ids.toString()) + "&lid=" + param_escape(id);
  507. console.log(query);
  508. new Ajax.Request("backend.php", {
  509. parameters: query,
  510. onComplete: function(transport) {
  511. handle_rpc_json(transport);
  512. show_labels_in_headlines(transport);
  513. } });
  514. } catch (e) {
  515. exception_error("selectionAssignLabel", e);
  516. }
  517. }
  518. function selectionToggleUnread(set_state, callback, no_error) {
  519. try {
  520. var rows = getSelectedArticleIds2();
  521. if (rows.length == 0 && !no_error) {
  522. alert(__("No articles are selected."));
  523. return;
  524. }
  525. for (var i = 0; i < rows.length; i++) {
  526. var row = $("RROW-" + rows[i]);
  527. if (row) {
  528. if (set_state == undefined) {
  529. if (row.hasClassName("Unread")) {
  530. row.removeClassName("Unread");
  531. } else {
  532. row.addClassName("Unread");
  533. }
  534. }
  535. if (set_state == false) {
  536. row.removeClassName("Unread");
  537. }
  538. if (set_state == true) {
  539. row.addClassName("Unread");
  540. }
  541. }
  542. }
  543. if (rows.length > 0) {
  544. var cmode = "";
  545. if (set_state == undefined) {
  546. cmode = "2";
  547. } else if (set_state == true) {
  548. cmode = "1";
  549. } else if (set_state == false) {
  550. cmode = "0";
  551. }
  552. var query = "?op=rpc&method=catchupSelected" +
  553. "&cmode=" + cmode + "&ids=" + param_escape(rows.toString());
  554. notify_progress("Loading, please wait...");
  555. new Ajax.Request("backend.php", {
  556. parameters: query,
  557. onComplete: function(transport) {
  558. handle_rpc_json(transport);
  559. if (callback) callback(transport);
  560. } });
  561. }
  562. } catch (e) {
  563. exception_error("selectionToggleUnread", e);
  564. }
  565. }
  566. function selectionToggleMarked() {
  567. try {
  568. var rows = getSelectedArticleIds2();
  569. if (rows.length == 0) {
  570. alert(__("No articles are selected."));
  571. return;
  572. }
  573. for (var i = 0; i < rows.length; i++) {
  574. toggleMark(rows[i], true, true);
  575. }
  576. if (rows.length > 0) {
  577. var query = "?op=rpc&method=markSelected&ids=" +
  578. param_escape(rows.toString()) + "&cmode=2";
  579. new Ajax.Request("backend.php", {
  580. parameters: query,
  581. onComplete: function(transport) {
  582. handle_rpc_json(transport);
  583. } });
  584. }
  585. } catch (e) {
  586. exception_error("selectionToggleMarked", e);
  587. }
  588. }
  589. function selectionTogglePublished() {
  590. try {
  591. var rows = getSelectedArticleIds2();
  592. if (rows.length == 0) {
  593. alert(__("No articles are selected."));
  594. return;
  595. }
  596. for (var i = 0; i < rows.length; i++) {
  597. togglePub(rows[i], true, true);
  598. }
  599. if (rows.length > 0) {
  600. var query = "?op=rpc&method=publishSelected&ids=" +
  601. param_escape(rows.toString()) + "&cmode=2";
  602. new Ajax.Request("backend.php", {
  603. parameters: query,
  604. onComplete: function(transport) {
  605. handle_rpc_json(transport);
  606. } });
  607. }
  608. } catch (e) {
  609. exception_error("selectionToggleMarked", e);
  610. }
  611. }
  612. function getSelectedArticleIds2() {
  613. var rv = [];
  614. $$("#headlines-frame > div[id*=RROW][class*=Selected]").each(
  615. function(child) {
  616. rv.push(child.id.replace("RROW-", ""));
  617. });
  618. return rv;
  619. }
  620. function getLoadedArticleIds() {
  621. var rv = [];
  622. var children = $$("#headlines-frame > div[id*=RROW-]");
  623. children.each(function(child) {
  624. rv.push(child.id.replace("RROW-", ""));
  625. });
  626. return rv;
  627. }
  628. // mode = all,none,unread,invert,marked,published
  629. function selectArticles(mode) {
  630. try {
  631. var children = $$("#headlines-frame > div[id*=RROW]");
  632. children.each(function(child) {
  633. var id = child.id.replace("RROW-", "");
  634. var cb = dijit.byId("RCHK-" + id);
  635. if (mode == "all") {
  636. child.addClassName("Selected");
  637. if (cb) cb.attr("checked", true);
  638. } else if (mode == "unread") {
  639. if (child.hasClassName("Unread")) {
  640. child.addClassName("Selected");
  641. if (cb) cb.attr("checked", true);
  642. } else {
  643. child.removeClassName("Selected");
  644. if (cb) cb.attr("checked", false);
  645. }
  646. } else if (mode == "marked") {
  647. var img = $("FMPIC-" + child.id.replace("RROW-", ""));
  648. if (img && img.src.match("mark_set")) {
  649. child.addClassName("Selected");
  650. if (cb) cb.attr("checked", true);
  651. } else {
  652. child.removeClassName("Selected");
  653. if (cb) cb.attr("checked", false);
  654. }
  655. } else if (mode == "published") {
  656. var img = $("FPPIC-" + child.id.replace("RROW-", ""));
  657. if (img && img.src.match("pub_set")) {
  658. child.addClassName("Selected");
  659. if (cb) cb.attr("checked", true);
  660. } else {
  661. child.removeClassName("Selected");
  662. if (cb) cb.attr("checked", false);
  663. }
  664. } else if (mode == "invert") {
  665. if (child.hasClassName("Selected")) {
  666. child.removeClassName("Selected");
  667. if (cb) cb.attr("checked", false);
  668. } else {
  669. child.addClassName("Selected");
  670. if (cb) cb.attr("checked", true);
  671. }
  672. } else {
  673. child.removeClassName("Selected");
  674. if (cb) cb.attr("checked", false);
  675. }
  676. });
  677. } catch (e) {
  678. exception_error("selectArticles", e);
  679. }
  680. }
  681. function catchupPage() {
  682. var fn = getFeedName(getActiveFeedId(), activeFeedIsCat());
  683. var str = __("Mark all visible articles in %s as read?");
  684. str = str.replace("%s", fn);
  685. if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
  686. return;
  687. }
  688. selectArticles('all');
  689. selectionToggleUnread(false, 'viewCurrentFeed()', true);
  690. selectArticles('none');
  691. }
  692. function deleteSelection() {
  693. try {
  694. var rows = getSelectedArticleIds2();
  695. if (rows.length == 0) {
  696. alert(__("No articles are selected."));
  697. return;
  698. }
  699. var fn = getFeedName(getActiveFeedId(), activeFeedIsCat());
  700. var str;
  701. if (getActiveFeedId() != 0) {
  702. str = __("Delete %d selected articles in %s?");
  703. } else {
  704. str = __("Delete %d selected articles?");
  705. }
  706. str = str.replace("%d", rows.length);
  707. str = str.replace("%s", fn);
  708. if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
  709. return;
  710. }
  711. query = "?op=rpc&method=delete&ids=" + param_escape(rows);
  712. console.log(query);
  713. new Ajax.Request("backend.php", {
  714. parameters: query,
  715. onComplete: function(transport) {
  716. handle_rpc_json(transport);
  717. viewCurrentFeed();
  718. } });
  719. } catch (e) {
  720. exception_error("deleteSelection", e);
  721. }
  722. }
  723. function archiveSelection() {
  724. try {
  725. var rows = getSelectedArticleIds2();
  726. if (rows.length == 0) {
  727. alert(__("No articles are selected."));
  728. return;
  729. }
  730. var fn = getFeedName(getActiveFeedId(), activeFeedIsCat());
  731. var str;
  732. var op;
  733. if (getActiveFeedId() != 0) {
  734. str = __("Archive %d selected articles in %s?");
  735. op = "archive";
  736. } else {
  737. str = __("Move %d archived articles back?");
  738. op = "unarchive";
  739. }
  740. str = str.replace("%d", rows.length);
  741. str = str.replace("%s", fn);
  742. if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
  743. return;
  744. }
  745. query = "?op=rpc&method="+op+"&ids=" + param_escape(rows);
  746. console.log(query);
  747. for (var i = 0; i < rows.length; i++) {
  748. cache_delete("article:" + rows[i]);
  749. }
  750. new Ajax.Request("backend.php", {
  751. parameters: query,
  752. onComplete: function(transport) {
  753. handle_rpc_json(transport);
  754. viewCurrentFeed();
  755. } });
  756. } catch (e) {
  757. exception_error("archiveSelection", e);
  758. }
  759. }
  760. function catchupSelection() {
  761. try {
  762. var rows = getSelectedArticleIds2();
  763. if (rows.length == 0) {
  764. alert(__("No articles are selected."));
  765. return;
  766. }
  767. var fn = getFeedName(getActiveFeedId(), activeFeedIsCat());
  768. var str = __("Mark %d selected articles in %s as read?");
  769. str = str.replace("%d", rows.length);
  770. str = str.replace("%s", fn);
  771. if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
  772. return;
  773. }
  774. selectionToggleUnread(false, 'viewCurrentFeed()', true);
  775. } catch (e) {
  776. exception_error("catchupSelection", e);
  777. }
  778. }
  779. function editArticleTags(id) {
  780. var query = "backend.php?op=dlg&method=editArticleTags&param=" + param_escape(id);
  781. if (dijit.byId("editTagsDlg"))
  782. dijit.byId("editTagsDlg").destroyRecursive();
  783. dialog = new dijit.Dialog({
  784. id: "editTagsDlg",
  785. title: __("Edit article Tags"),
  786. style: "width: 600px",
  787. execute: function() {
  788. if (this.validate()) {
  789. var query = dojo.objectToQuery(this.attr('value'));
  790. notify_progress("Saving article tags...", true);
  791. new Ajax.Request("backend.php", {
  792. parameters: query,
  793. onComplete: function(transport) {
  794. notify('');
  795. dialog.hide();
  796. var data = JSON.parse(transport.responseText);
  797. if (data) {
  798. var tags_str = article.tags;
  799. var id = tags_str.id;
  800. var tags = $("ATSTR-" + id);
  801. var tooltip = dijit.byId("ATSTRTIP-" + id);
  802. if (tags) tags.innerHTML = tags_str.content;
  803. if (tooltip) tooltip.attr('label', tags_str.content_full);
  804. cache_delete("article:" + id);
  805. }
  806. }});
  807. }
  808. },
  809. href: query,
  810. });
  811. var tmph = dojo.connect(dialog, 'onLoad', function() {
  812. dojo.disconnect(tmph);
  813. new Ajax.Autocompleter('tags_str', 'tags_choices',
  814. "backend.php?op=rpc&method=completeTags",
  815. { tokens: ',', paramName: "search" });
  816. });
  817. dialog.show();
  818. }
  819. function cdmScrollToArticleId(id) {
  820. try {
  821. var ctr = $("headlines-frame");
  822. var e = $("RROW-" + id);
  823. if (!e || !ctr) return;
  824. ctr.scrollTop = e.offsetTop;
  825. } catch (e) {
  826. exception_error("cdmScrollToArticleId", e);
  827. }
  828. }
  829. function getActiveArticleId() {
  830. return active_post_id;
  831. }
  832. function postMouseIn(id) {
  833. post_under_pointer = id;
  834. }
  835. function postMouseOut(id) {
  836. post_under_pointer = false;
  837. }
  838. function headlines_scroll_handler(e) {
  839. try {
  840. var hsp = $("headlines-spacer");
  841. if (!_infscroll_disable) {
  842. if ((hsp && e.scrollTop + e.offsetHeight >= hsp.offsetTop - hsp.offsetHeight) ||
  843. (e.scrollHeight != 0 &&
  844. ((e.scrollTop + e.offsetHeight) / e.scrollHeight >= 0.7))) {
  845. if (hsp)
  846. hsp.innerHTML = "<img src='images/indicator_tiny.gif'> " +
  847. __("Loading, please wait...");
  848. loadMoreHeadlines();
  849. return;
  850. }
  851. } else {
  852. if (hsp) hsp.innerHTML = "";
  853. }
  854. if (getInitParam("cdm_auto_catchup") == 1) {
  855. $$("#headlines-frame > div[id*=RROW][class*=Unread]").each(
  856. function(child) {
  857. if ($("headlines-frame").scrollTop >
  858. (child.offsetTop + child.offsetHeight/2)) {
  859. var id = child.id.replace("RROW-", "");
  860. if (catchup_id_batch.indexOf(id) == -1)
  861. catchup_id_batch.push(id);
  862. //console.log("auto_catchup_batch: " + catchup_id_batch.toString());
  863. }
  864. });
  865. if (catchup_id_batch.length > 0) {
  866. window.clearTimeout(catchup_timeout_id);
  867. if (!_infscroll_request_sent) {
  868. catchup_timeout_id = window.setTimeout('catchupBatchedArticles()',
  869. 2000);
  870. }
  871. }
  872. }
  873. } catch (e) {
  874. console.warn("headlines_scroll_handler: " + e);
  875. }
  876. }
  877. function catchupBatchedArticles() {
  878. try {
  879. if (catchup_id_batch.length > 0 && !_infscroll_request_sent) {
  880. // make a copy of the array
  881. var batch = catchup_id_batch.slice();
  882. var query = "?op=rpc&method=catchupSelected" +
  883. "&cmode=0&ids=" + param_escape(batch.toString());
  884. console.log(query);
  885. new Ajax.Request("backend.php", {
  886. parameters: query,
  887. onComplete: function(transport) {
  888. handle_rpc_json(transport);
  889. batch.each(function(id) {
  890. var elem = $("RROW-" + id);
  891. if (elem) elem.removeClassName("Unread");
  892. catchup_id_batch.remove(id);
  893. });
  894. } });
  895. }
  896. } catch (e) {
  897. exception_error("catchupBatchedArticles", e);
  898. }
  899. }
  900. function catchupRelativeToArticle(below, id) {
  901. try {
  902. if (!id) id = getActiveArticleId();
  903. if (!id) {
  904. alert(__("No article is selected."));
  905. return;
  906. }
  907. var visible_ids = getVisibleArticleIds();
  908. var ids_to_mark = new Array();
  909. if (!below) {
  910. for (var i = 0; i < visible_ids.length; i++) {
  911. if (visible_ids[i] != id) {
  912. var e = $("RROW-" + visible_ids[i]);
  913. if (e && e.hasClassName("Unread")) {
  914. ids_to_mark.push(visible_ids[i]);
  915. }
  916. } else {
  917. break;
  918. }
  919. }
  920. } else {
  921. for (var i = visible_ids.length-1; i >= 0; i--) {
  922. if (visible_ids[i] != id) {
  923. var e = $("RROW-" + visible_ids[i]);
  924. if (e && e.hasClassName("Unread")) {
  925. ids_to_mark.push(visible_ids[i]);
  926. }
  927. } else {
  928. break;
  929. }
  930. }
  931. }
  932. if (ids_to_mark.length == 0) {
  933. alert(__("No articles found to mark"));
  934. } else {
  935. var msg = __("Mark %d article(s) as read?").replace("%d", ids_to_mark.length);
  936. if (getInitParam("confirm_feed_catchup") != 1 || confirm(msg)) {
  937. for (var i = 0; i < ids_to_mark.length; i++) {
  938. var e = $("RROW-" + ids_to_mark[i]);
  939. e.removeClassName("Unread");
  940. }
  941. var query = "?op=rpc&method=catchupSelected" +
  942. "&cmode=0" + "&ids=" + param_escape(ids_to_mark.toString());
  943. new Ajax.Request("backend.php", {
  944. parameters: query,
  945. onComplete: function(transport) {
  946. handle_rpc_json(transport);
  947. } });
  948. }
  949. }
  950. } catch (e) {
  951. exception_error("catchupRelativeToArticle", e);
  952. }
  953. }
  954. function cdmExpandArticle(id) {
  955. try {
  956. hideAuxDlg();
  957. var elem = $("CICD-" + active_post_id);
  958. if (id == active_post_id && Element.visible(elem))
  959. return true;
  960. selectArticles("none");
  961. var old_offset = $("RROW-" + id).offsetTop;
  962. if (active_post_id && elem && !getInitParam("cdm_expanded")) {
  963. Element.hide(elem);
  964. Element.show("CEXC-" + active_post_id);
  965. }
  966. active_post_id = id;
  967. elem = $("CICD-" + id);
  968. if (!Element.visible(elem)) {
  969. Element.show(elem);
  970. Element.hide("CEXC-" + id);
  971. }
  972. var new_offset = $("RROW-" + id).offsetTop;
  973. $("headlines-frame").scrollTop += (new_offset-old_offset);
  974. if ($("RROW-" + id).offsetTop != old_offset)
  975. $("headlines-frame").scrollTop = new_offset;
  976. toggleUnread(id, 0, true);
  977. toggleSelected(id);
  978. } catch (e) {
  979. exception_error("cdmExpandArticle", e);
  980. }
  981. return false;
  982. }
  983. function fixHeadlinesOrder(ids) {
  984. try {
  985. for (var i = 0; i < ids.length; i++) {
  986. var e = $("RROW-" + ids[i]);
  987. if (e) {
  988. if (i % 2 == 0) {
  989. e.removeClassName("even");
  990. e.addClassName("odd");
  991. } else {
  992. e.removeClassName("odd");
  993. e.addClassName("even");
  994. }
  995. }
  996. }
  997. } catch (e) {
  998. exception_error("fixHeadlinesOrder", e);
  999. }
  1000. }
  1001. function getArticleUnderPointer() {
  1002. return post_under_pointer;
  1003. }
  1004. function zoomToArticle(event, id) {
  1005. try {
  1006. var cached_article = cache_get("article: " + id);
  1007. if (dijit.byId("ATAB-" + id))
  1008. if (!event || !event.shiftKey)
  1009. return dijit.byId("content-tabs").selectChild(dijit.byId("ATAB-" + id));
  1010. if (dijit.byId("ATSTRTIP-" + id))
  1011. dijit.byId("ATSTRTIP-" + id).destroyRecursive();
  1012. if (cached_article) {
  1013. //closeArticlePanel();
  1014. var article_pane = new dijit.layout.ContentPane({
  1015. title: __("Loading...") , content: cached_article,
  1016. style: 'padding : 0px;',
  1017. id: 'ATAB-' + id,
  1018. closable: true });
  1019. dijit.byId("content-tabs").addChild(article_pane);
  1020. if (!event || !event.shiftKey)
  1021. dijit.byId("content-tabs").selectChild(article_pane);
  1022. if ($("PTITLE-" + id))
  1023. article_pane.attr('title', $("PTITLE-" + id).innerHTML);
  1024. } else {
  1025. var query = "?op=rpc&method=getArticles&ids=" + param_escape(id);
  1026. notify_progress("Loading, please wait...", true);
  1027. new Ajax.Request("backend.php", {
  1028. parameters: query,
  1029. onComplete: function(transport) {
  1030. notify('');
  1031. var reply = JSON.parse(transport.responseText);
  1032. if (reply) {
  1033. //closeArticlePanel();
  1034. var content = reply[0]['content'];
  1035. var article_pane = new dijit.layout.ContentPane({
  1036. title: "article-" + id , content: content,
  1037. style: 'padding : 0px;',
  1038. id: 'ATAB-' + id,
  1039. closable: true });
  1040. dijit.byId("content-tabs").addChild(article_pane);
  1041. if (!event || !event.shiftKey)
  1042. dijit.byId("content-tabs").selectChild(article_pane);
  1043. if ($("PTITLE-" + id))
  1044. article_pane.attr('title', $("PTITLE-" + id).innerHTML);
  1045. }
  1046. } });
  1047. }
  1048. } catch (e) {
  1049. exception_error("zoomToArticle", e);
  1050. }
  1051. }
  1052. function scrollArticle(offset) {
  1053. try {
  1054. if (!isCdmMode()) {
  1055. var ci = $("content-insert");
  1056. if (ci) {
  1057. ci.scrollTop += offset;
  1058. }
  1059. } else {
  1060. var hi = $("headlines-frame");
  1061. if (hi) {
  1062. hi.scrollTop += offset;
  1063. }
  1064. }
  1065. } catch (e) {
  1066. exception_error("scrollArticle", e);
  1067. }
  1068. }
  1069. function show_labels_in_headlines(transport) {
  1070. try {
  1071. var data = JSON.parse(transport.responseText);
  1072. if (data) {
  1073. data['info-for-headlines'].each(function(elem) {
  1074. var ctr = $("HLLCTR-" + elem.id);
  1075. if (ctr) ctr.innerHTML = elem.labels;
  1076. });
  1077. cache_headlines(getActiveFeedId(), activeFeedIsCat(), null, $("headlines-frame").innerHTML);
  1078. }
  1079. } catch (e) {
  1080. exception_error("show_labels_in_headlines", e);
  1081. }
  1082. }
  1083. /* function toggleHeadlineActions() {
  1084. try {
  1085. var e = $("headlineActionsBody");
  1086. var p = $("headlineActionsDrop");
  1087. if (!Element.visible(e)) {
  1088. Element.show(e);
  1089. } else {
  1090. Element.hide(e);
  1091. }
  1092. e.scrollTop = 0;
  1093. e.style.left = (p.offsetLeft + 1) + "px";
  1094. e.style.top = (p.offsetTop + p.offsetHeight + 2) + "px";
  1095. } catch (e) {
  1096. exception_error("toggleHeadlineActions", e);
  1097. }
  1098. } */
  1099. /* function publishWithNote(id, def_note) {
  1100. try {
  1101. if (!def_note) def_note = '';
  1102. var note = prompt(__("Please enter a note for this article:"), def_note);
  1103. if (note != undefined) {
  1104. togglePub(id, false, false, note);
  1105. }
  1106. } catch (e) {
  1107. exception_error("publishWithNote", e);
  1108. }
  1109. } */
  1110. function dismissArticle(id) {
  1111. try {
  1112. var elem = $("RROW-" + id);
  1113. toggleUnread(id, 0, true);
  1114. new Effect.Fade(elem, {duration : 0.5});
  1115. active_post_id = false;
  1116. } catch (e) {
  1117. exception_error("dismissArticle", e);
  1118. }
  1119. }
  1120. function dismissSelectedArticles() {
  1121. try {
  1122. var ids = getVisibleArticleIds();
  1123. var tmp = [];
  1124. var sel = [];
  1125. for (var i = 0; i < ids.length; i++) {
  1126. var elem = $("RROW-" + ids[i]);
  1127. if (elem.className && elem.hasClassName("Selected") &&
  1128. ids[i] != active_post_id) {
  1129. new Effect.Fade(elem, {duration : 0.5});
  1130. sel.push(ids[i]);
  1131. } else {
  1132. tmp.push(ids[i]);
  1133. }
  1134. }
  1135. if (sel.length > 0)
  1136. selectionToggleUnread(false);
  1137. fixHeadlinesOrder(tmp);
  1138. } catch (e) {
  1139. exception_error("dismissSelectedArticles", e);
  1140. }
  1141. }
  1142. function dismissReadArticles() {
  1143. try {
  1144. var ids = getVisibleArticleIds();
  1145. var tmp = [];
  1146. for (var i = 0; i < ids.length; i++) {
  1147. var elem = $("RROW-" + ids[i]);
  1148. if (elem.className && !elem.hasClassName("Unread") &&
  1149. !elem.hasClassName("Selected")) {
  1150. new Effect.Fade(elem, {duration : 0.5});
  1151. } else {
  1152. tmp.push(ids[i]);
  1153. }
  1154. }
  1155. fixHeadlinesOrder(tmp);
  1156. } catch (e) {
  1157. exception_error("dismissSelectedArticles", e);
  1158. }
  1159. }
  1160. function getVisibleArticleIds() {
  1161. var ids = [];
  1162. try {
  1163. getLoadedArticleIds().each(function(id) {
  1164. var elem = $("RROW-" + id);
  1165. if (elem && Element.visible(elem))
  1166. ids.push(id);
  1167. });
  1168. } catch (e) {
  1169. exception_error("getVisibleArticleIds", e);
  1170. }
  1171. return ids;
  1172. }
  1173. function cdmClicked(event, id) {
  1174. try {
  1175. //var shift_key = event.shiftKey;
  1176. hideAuxDlg();
  1177. if (!event.ctrlKey) {
  1178. if (!getInitParam("cdm_expanded")) {
  1179. return cdmExpandArticle(id);
  1180. } else {
  1181. selectArticles("none");
  1182. toggleSelected(id);
  1183. var elem = $("RROW-" + id);
  1184. var article_is_unread = elem.hasClassName("Unread");
  1185. if (elem)
  1186. elem.removeClassName("Unread");
  1187. active_post_id = id;
  1188. if (article_is_unread) {
  1189. decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
  1190. }
  1191. var query = "?op=rpc&method=catchupSelected" +
  1192. "&cmode=0&ids=" + param_escape(id);
  1193. new Ajax.Request("backend.php", {
  1194. parameters: query,
  1195. onComplete: function(transport) {
  1196. handle_rpc_json(transport);
  1197. } });
  1198. return true;
  1199. }
  1200. } else {
  1201. toggleSelected(id, true);
  1202. var elem = $("RROW-" + id);
  1203. var article_is_unread = elem.hasClassName("Unread");
  1204. if (article_is_unread) {
  1205. decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
  1206. }
  1207. toggleUnread(id, 0, false);
  1208. zoomToArticle(event, id);
  1209. }
  1210. } catch (e) {
  1211. exception_error("cdmClicked");
  1212. }
  1213. return false;
  1214. }
  1215. function postClicked(event, id) {
  1216. try {
  1217. if (!event.ctrlKey) {
  1218. return true;
  1219. } else {
  1220. postOpenInNewTab(event, id);
  1221. return false;
  1222. }
  1223. } catch (e) {
  1224. exception_error("postClicked");
  1225. }
  1226. }
  1227. function hlOpenInNewTab(event, id) {
  1228. toggleUnread(id, 0, false);
  1229. zoomToArticle(event, id);
  1230. }
  1231. function postOpenInNewTab(event, id) {
  1232. closeArticlePanel(id);
  1233. zoomToArticle(event, id);
  1234. }
  1235. function hlClicked(event, id) {
  1236. try {
  1237. if (event.which == 2) {
  1238. view(id);
  1239. return true;
  1240. } else if (event.altKey) {
  1241. openArticleInNewWindow(id);
  1242. } else if (!event.ctrlKey) {
  1243. view(id);
  1244. return false;
  1245. } else {
  1246. toggleSelected(id);
  1247. toggleUnread(id, 0, false);
  1248. zoomToArticle(event, id);
  1249. return false;
  1250. }
  1251. } catch (e) {
  1252. exception_error("hlClicked");
  1253. }
  1254. }
  1255. function getFirstVisibleHeadlineId() {
  1256. var rows = getVisibleArticleIds();
  1257. return rows[0];
  1258. }
  1259. function getLastVisibleHeadlineId() {
  1260. var rows = getVisibleArticleIds();
  1261. return rows[rows.length-1];
  1262. }
  1263. function openArticleInNewWindow(id) {
  1264. toggleUnread(id, 0, false);
  1265. window.open("backend.php?op=article&method=redirect&id=" + id);
  1266. }
  1267. function isCdmMode() {
  1268. return getInitParam("combined_display_mode");
  1269. }
  1270. function markHeadline(id) {
  1271. var row = $("RROW-" + id);
  1272. if (row) {
  1273. var check = dijit.byId("RCHK-" + id);
  1274. if (check) {
  1275. check.attr("checked", true);
  1276. }
  1277. row.addClassName("Selected");
  1278. }
  1279. }
  1280. function getRelativePostIds(id, limit) {
  1281. var tmp = [];
  1282. try {
  1283. if (!limit) limit = 6; //3
  1284. var ids = getVisibleArticleIds();
  1285. for (var i = 0; i < ids.length; i++) {
  1286. if (ids[i] == id) {
  1287. for (var k = 1; k <= limit; k++) {
  1288. //if (i > k-1) tmp.push(ids[i-k]);
  1289. if (i < ids.length-k) tmp.push(ids[i+k]);
  1290. }
  1291. break;
  1292. }
  1293. }
  1294. } catch (e) {
  1295. exception_error("getRelativePostIds", e);
  1296. }
  1297. return tmp;
  1298. }
  1299. function correctHeadlinesOffset(id) {
  1300. try {
  1301. var container = $("headlines-frame");
  1302. var row = $("RROW-" + id);
  1303. if (!container || !row) return;
  1304. var viewport = container.offsetHeight;
  1305. var rel_offset_top = row.offsetTop - container.scrollTop;
  1306. var rel_offset_bottom = row.offsetTop + row.offsetHeight - container.scrollTop;
  1307. //console.log("Rtop: " + rel_offset_top + " Rbtm: " + rel_offset_bottom);
  1308. //console.log("Vport: " + viewport);
  1309. if (rel_offset_top <= 0 || rel_offset_top > viewport) {
  1310. container.scrollTop = row.offsetTop;
  1311. } else if (rel_offset_bottom > viewport) {
  1312. /* doesn't properly work with Opera in some cases because
  1313. Opera fucks up element scrolling */
  1314. container.scrollTop = row.offsetTop + row.offsetHeight - viewport;
  1315. }
  1316. } catch (e) {
  1317. exception_error("correctHeadlinesOffset", e);
  1318. }
  1319. }
  1320. function headlineActionsChange(elem) {
  1321. try {
  1322. eval(elem.value);
  1323. elem.attr('value', 'false');
  1324. } catch (e) {
  1325. exception_error("headlineActionsChange", e);
  1326. }
  1327. }
  1328. function closeArticlePanel() {
  1329. var tabs = dijit.byId("content-tabs");
  1330. var child = tabs.selectedChildWidget;
  1331. if (child && tabs.getIndexOfChild(child) > 0) {
  1332. tabs.removeChild(child);
  1333. child.destroy();
  1334. } else {
  1335. if (dijit.byId("content-insert"))
  1336. dijit.byId("headlines-wrap-inner").removeChild(
  1337. dijit.byId("content-insert"));
  1338. }
  1339. }
  1340. function initHeadlinesMenu() {
  1341. try {
  1342. if (dijit.byId("headlinesMenu"))
  1343. dijit.byId("headlinesMenu").destroyRecursive();
  1344. var ids = [];
  1345. if (!isCdmMode()) {
  1346. nodes = $$("#headlines-frame > div[id*=RROW]");
  1347. } else {
  1348. nodes = $$("#headlines-frame span[id*=RTITLE]");
  1349. }
  1350. nodes.each(function(node) {
  1351. ids.push(node.id);
  1352. });
  1353. var menu = new dijit.Menu({
  1354. id: "headlinesMenu",
  1355. targetNodeIds: ids,
  1356. });
  1357. var tmph = dojo.connect(menu, '_openMyself', function (event) {
  1358. var callerNode = event.target, match = null, tries = 0;
  1359. while (match == null && callerNode && tries <= 3) {
  1360. match = callerNode.id.match("^[A-Z]+[-]([0-9]+)$");
  1361. callerNode = callerNode.parentNode;
  1362. ++tries;
  1363. }
  1364. if (match) this.callerRowId = parseInt(match[1]);
  1365. });
  1366. /* if (!isCdmMode())
  1367. menu.addChild(new dijit.MenuItem({
  1368. label: __("View article"),
  1369. onClick: function(event) {
  1370. view(this.getParent().callerRowId);
  1371. }})); */
  1372. menu.addChild(new dijit.MenuItem({
  1373. label: __("Open original article"),
  1374. onClick: function(event) {
  1375. openArticleInNewWindow(this.getParent().callerRowId);
  1376. }}));
  1377. menu.addChild(new dijit.MenuItem({
  1378. label: __("View in a tt-rss tab"),
  1379. onClick: function(event) {
  1380. hlOpenInNewTab(event, this.getParent().callerRowId);
  1381. }}));
  1382. menu.addChild(new dijit.MenuSeparator());
  1383. menu.addChild(new dijit.MenuItem({
  1384. label: __("Mark above as read"),
  1385. onClick: function(event) {
  1386. catchupRelativeToArticle(0, this.getParent().callerRowId);
  1387. }}));
  1388. menu.addChild(new dijit.MenuItem({
  1389. label: __("Mark below as read"),
  1390. onClick: function(event) {
  1391. catchupRelativeToArticle(1, this.getParent().callerRowId);
  1392. }}));
  1393. var labels = dijit.byId("feedTree").model.getItemsInCategory(-2);
  1394. if (labels) {
  1395. menu.addChild(new dijit.MenuSeparator());
  1396. var labelAddMenu = new dijit.Menu({ownerMenu: menu});
  1397. var labelDelMenu = new dijit.Menu({ownerMenu: menu});
  1398. labels.each(function(label) {
  1399. var id = label.id[0];
  1400. var bare_id = id.substr(id.indexOf(":")+1);
  1401. var name = label.name[0];
  1402. bare_id = -11-bare_id;
  1403. labelAddMenu.addChild(new dijit.MenuItem({
  1404. label: name,
  1405. labelId: bare_id,
  1406. onClick: function(event) {
  1407. var ids = getSelectedArticleIds2();
  1408. // cast to string
  1409. var id = this.getParent().ownerMenu.callerRowId + "";
  1410. ids = ids.size() != 0 && ids.indexOf(id) != -1 ? ids : [id];
  1411. selectionAssignLabel(this.labelId, ids);
  1412. }}));
  1413. labelDelMenu.addChild(new dijit.MenuItem({
  1414. label: name,
  1415. labelId: bare_id,
  1416. onClick: function(event) {
  1417. var ids = getSelectedArticleIds2();
  1418. // cast to string
  1419. var id = this.getParent().ownerMenu.callerRowId + "";
  1420. ids = ids.size() != 0 && ids.indexOf(id) != -1 ? ids : [id];
  1421. selectionRemoveLabel(this.labelId, ids);
  1422. }}));
  1423. });
  1424. menu.addChild(new dijit.PopupMenuItem({
  1425. label: __("Assign label"),
  1426. popup: labelAddMenu,
  1427. }));
  1428. menu.addChild(new dijit.PopupMenuItem({
  1429. label: __("Remove label"),
  1430. popup: labelDelMenu,
  1431. }));
  1432. }
  1433. menu.startup();
  1434. } catch (e) {
  1435. exception_error("initHeadlinesMenu", e);
  1436. }
  1437. }
  1438. function player(elem) {
  1439. var aid = elem.getAttribute("audio-id");
  1440. var status = elem.getAttribute("status");
  1441. var audio = $(aid);
  1442. if (audio) {
  1443. if (status == 0) {
  1444. audio.play();
  1445. status = 1;
  1446. elem.innerHTML = __("Playing...");
  1447. elem.title = __("Click to pause");
  1448. elem.addClassName("playing");
  1449. } else {
  1450. audio.pause();
  1451. status = 0;
  1452. elem.innerHTML = __("Play");
  1453. elem.title = __("Click to play");
  1454. elem.removeClassName("playing");
  1455. }
  1456. elem.setAttribute("status", status);
  1457. } else {
  1458. alert("Your browser doesn't seem to support HTML5 audio.");
  1459. }
  1460. }
  1461. function cache_set(id, obj) {
  1462. //console.log("cache_set: " + id);
  1463. if (has_storage)
  1464. try {
  1465. sessionStorage[id] = obj;
  1466. } catch (e) {
  1467. sessionStorage.clear();
  1468. }
  1469. }
  1470. function cache_get(id) {
  1471. if (has_storage)
  1472. return sessionStorage[id];
  1473. }
  1474. function cache_clear() {
  1475. if (has_storage)
  1476. sessionStorage.clear();
  1477. }
  1478. function cache_delete(id) {
  1479. if (has_storage)
  1480. sessionStorage.removeItem(id);
  1481. }
  1482. function cache_headlines(feed, is_cat, toolbar_obj, content_obj) {
  1483. if (toolbar_obj && content_obj) {
  1484. cache_set("feed:" + feed + ":" + is_cat,
  1485. JSON.stringify({toolbar: toolbar_obj, content: content_obj}));
  1486. } else {
  1487. try {
  1488. obj = cache_get("feed:" + feed + ":" + is_cat);
  1489. if (obj) {
  1490. obj = JSON.parse(obj);
  1491. if (toolbar_obj) obj.toolbar = toolbar_obj;
  1492. if (content_obj) obj.content = content_obj;
  1493. cache_set("feed:" + feed + ":" + is_cat, JSON.stringify(obj));
  1494. }
  1495. } catch (e) {
  1496. console.warn("cache_headlines failed: " + e);
  1497. }
  1498. }
  1499. }
  1500. function render_local_headlines(feed, is_cat, obj) {
  1501. try {
  1502. dijit.byId("headlines-toolbar").attr('content',
  1503. obj.toolbar);
  1504. dijit.byId("headlines-frame").attr('content',
  1505. obj.content);
  1506. dojo.parser.parse('headlines-toolbar');
  1507. $("headlines-frame").scrollTop = 0;
  1508. selectArticles('none');
  1509. setActiveFeedId(feed, is_cat);
  1510. initHeadlinesMenu();
  1511. dijit.getEnclosingWidget(
  1512. document.forms["main_toolbar_form"].update).attr('disabled',
  1513. is_cat || feed <= 0);
  1514. precache_headlines();
  1515. } catch (e) {
  1516. exception_error("render_local_headlines", e);
  1517. }
  1518. }
  1519. function precache_headlines_idle() {
  1520. try {
  1521. if (!feed_precache_timeout_id) {
  1522. if (get_timestamp() - _viewfeed_last > 120) {
  1523. var feeds = dijit.byId("feedTree").getVisibleUnreadFeeds();
  1524. var uncached = [];
  1525. feeds.each(function(item) {
  1526. if (parseInt(item[0]) > 0 && !cache_get("feed:" + item[0] + ":" + item[1]))
  1527. uncached.push(item);
  1528. });
  1529. if (uncached.length > 0) {
  1530. var rf = uncached[Math.floor(Math.random()*uncached.length)];
  1531. viewfeed(rf[0], '', rf[1], 0, true);
  1532. }
  1533. }
  1534. }
  1535. precache_idle_timeout_id = setTimeout("precache_headlines_idle()", 1000*30);
  1536. } catch (e) {
  1537. exception_error("precache_headlines_idle", e);
  1538. }
  1539. }
  1540. function precache_headlines() {
  1541. try {
  1542. if (!feed_precache_timeout_id) {
  1543. feed_precache_timeout_id = window.setTimeout(function() {
  1544. var nuf = getNextUnreadFeed(getActiveFeedId(), activeFeedIsCat());
  1545. var nf = dijit.byId("feedTree").getNextFeed(getActiveFeedId(), activeFeedIsCat());
  1546. if (nuf && !cache_get("feed:" + nuf + ":" + activeFeedIsCat()))
  1547. viewfeed(nuf, '', activeFeedIsCat(), 0, true);
  1548. if (nf && nf[0] != nuf && !cache_get("feed:" + nf[0] + ":" + nf[1]))
  1549. viewfeed(nf[0], '', nf[1], 0, true);
  1550. window.setTimeout(function() {
  1551. feed_precache_timeout_id = false;
  1552. }, 3000);
  1553. }, 1000);
  1554. }
  1555. } catch (e) {
  1556. exception_error("precache_headlines", e);
  1557. }
  1558. }
  1559. function cancelSearch() {
  1560. try {
  1561. _search_query = "";
  1562. viewCurrentFeed();
  1563. } catch (e) {
  1564. exception_error("cancelSearch", e);
  1565. }
  1566. }
  1567. function setSelectionScore() {
  1568. try {
  1569. var ids = getSelectedArticleIds2();
  1570. if (ids.length > 0) {
  1571. console.log(ids);
  1572. var score = prompt(__("Please enter new score for selected articles:"), score);
  1573. if (score != undefined) {
  1574. var query = "op=rpc&method=setScore&id=" + param_escape(ids.toString()) +
  1575. "&score=" + param_escape(score);
  1576. new Ajax.Request("backend.php", {
  1577. parameters: query,
  1578. onComplete: function(transport) {
  1579. var reply = JSON.parse(transport.responseText);
  1580. if (reply) {
  1581. console.log(ids);
  1582. ids.each(function(id) {
  1583. var row = $("RROW-" + id);
  1584. if (row) {
  1585. var pic = row.getElementsByClassName("hlScorePic")[0];
  1586. if (pic) {
  1587. pic.src = pic.src.replace(/score_.*?\.png/,
  1588. reply["score_pic"]);
  1589. pic.setAttribute("score", score);
  1590. }
  1591. }
  1592. });
  1593. }
  1594. } });
  1595. }
  1596. } else {
  1597. alert(__("No articles are selected."));
  1598. }
  1599. } catch (e) {
  1600. exception_error("setSelectionScore", e);
  1601. }
  1602. }
  1603. function changeScore(id, pic) {
  1604. try {
  1605. var score = pic.getAttribute("score");
  1606. var new_score = prompt(__("Please enter new score for this article:"), score);
  1607. if (new_score != undefined) {
  1608. var query = "op=rpc&method=setScore&id=" + param_escape(id) +
  1609. "&score=" + param_escape(new_score);
  1610. new Ajax.Request("backend.php", {
  1611. parameters: query,
  1612. onComplete: function(transport) {
  1613. var reply = JSON.parse(transport.responseText);
  1614. if (reply) {
  1615. pic.src = pic.src.replace(/score_.*?\.png/, reply["score_pic"]);
  1616. pic.setAttribute("score", new_score);
  1617. }
  1618. } });
  1619. }
  1620. } catch (e) {
  1621. exception_error("changeScore", e);
  1622. }
  1623. }