The version of vichan running on lainchan.org
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

340 rindas
9.8KB

  1. /*
  2. * auto-reload.js
  3. * https://github.com/savetheinternet/Tinyboard/blob/master/js/auto-reload.js
  4. *
  5. * Brings AJAX to Tinyboard.
  6. *
  7. * Released under the MIT license
  8. * Copyright (c) 2012 Michael Save <savetheinternet@tinyboard.org>
  9. * Copyright (c) 2013-2014 Marcin Łabanowski <marcin@6irc.net>
  10. * Copyright (c) 2013 undido <firekid109@hotmail.com>
  11. * Copyright (c) 2014-2015 Fredrick Brennan <admin@8chan.co>
  12. *
  13. * Usage:
  14. * $config['additional_javascript'][] = 'js/jquery.min.js';
  15. * //$config['additional_javascript'][] = 'js/titlebar-notifications.js';
  16. * $config['additional_javascript'][] = 'js/auto-reload.js';
  17. *
  18. */
  19. // From http://stackoverflow.com/a/14035162
  20. $.fn.scrollStopped = function(callback) {
  21. $(this).scroll(function(){
  22. var self = this, $this = $(self);
  23. if ($this.data('scrollTimeout')) {
  24. clearTimeout($this.data('scrollTimeout'));
  25. }
  26. $this.data('scrollTimeout', setTimeout(callback,250,self));
  27. });
  28. };
  29. function makeIcon(mode){
  30. var favicon = $("link[rel='shortcut icon']");
  31. if (!favicon.length) {
  32. var favicon = $('<link rel="shortcut icon"></link>').appendTo('head');
  33. }
  34. $("link[rel='shortcut icon']").attr("href", configRoot+"static/favicon"+(mode?"-"+mode:"")+".ico");
  35. }
  36. +function(){
  37. var notify = false;
  38. auto_reload_enabled = true; // for watch.js to interop
  39. $(document).ready(function(){
  40. if($('div.banner').length == 0)
  41. {
  42. return; // not index
  43. }
  44. if($(".post.op").size() != 1)
  45. {
  46. return; //not thread page
  47. }
  48. // Adds Options panel item
  49. if (typeof localStorage.auto_thread_update === 'undefined') {
  50. localStorage.auto_thread_update = 'true'; //default value
  51. }
  52. if (window.Options && Options.get_tab('general')) {
  53. Options.extend_tab("general", "<fieldset id='auto-update-fs'><legend>"+_("Auto update")+"</legend>"
  54. + ('<label id="auto-thread-update"><input type="checkbox">' + _('Auto update thread') + '</label>')
  55. + ('<label id="auto_thread_desktop_notifications"><input type="checkbox">' + _('Show desktop notifications when users quote me') + '</label>')
  56. + ('<label id="auto_thread_desktop_notifications_all"><input type="checkbox">' + _('Show desktop notifications on all replies') + '</label>')
  57. + '</fieldset>');
  58. $('#auto-thread-update>input').on('click', function() {
  59. if ($('#auto-thread-update>input').is(':checked')) {
  60. localStorage.auto_thread_update = 'true';
  61. } else {
  62. localStorage.auto_thread_update = 'false';
  63. }
  64. });
  65. $('#auto_thread_desktop_notifications>input,#auto_thread_desktop_notifications_all>input').on('click', function() {
  66. if (!("Notification" in window)) return;
  67. var setting = $(this).parent().attr('id');
  68. if ($(this).is(':checked')) {
  69. Notification.requestPermission(function(permission){
  70. if (permission === "granted") {
  71. localStorage[setting] = 'true';
  72. }
  73. });
  74. if (Notification.permission === "granted") {
  75. localStorage[setting] = 'true';
  76. }
  77. } else {
  78. localStorage[setting] = 'false';
  79. }
  80. });
  81. if (localStorage.auto_thread_update === 'true') {
  82. $('#auto-thread-update>input').prop('checked', true);
  83. }
  84. if (localStorage.auto_thread_desktop_notifications === 'true') {
  85. $('#auto_thread_desktop_notifications>input').prop('checked', true);
  86. notify = "mention";
  87. }
  88. if (localStorage.auto_thread_desktop_notifications_all === 'true') {
  89. $('#auto_thread_desktop_notifications_all>input').prop('checked', true);
  90. notify = "all";
  91. }
  92. }
  93. // not thread
  94. if (active_page != 'thread')
  95. return;
  96. var countdown_interval;
  97. // Add an update link
  98. $(".threadlinks span:last-child").append("<span id='updater'><a href='#' id='update_thread'>["+_("Update")+"]</a> (<input type='checkbox' id='auto_update_status'> "+_("Auto")+") <span id='update_secs'></span></span>");
  99. // Set the updater checkbox according to user setting
  100. if (localStorage.auto_thread_update === 'true') {
  101. $('#auto_update_status').prop('checked', true);
  102. }
  103. // Grab the settings
  104. var settings = new script_settings('auto-reload');
  105. var poll_interval_mindelay = settings.get('min_delay_bottom', 5000);
  106. var poll_interval_maxdelay = settings.get('max_delay', 600000);
  107. var poll_interval_errordelay = settings.get('error_delay', 30000);
  108. // number of ms to wait before reloading
  109. var poll_interval_delay = poll_interval_mindelay;
  110. var poll_current_time = poll_interval_delay;
  111. var end_of_page = false;
  112. var new_posts = 0;
  113. var first_new_post = null;
  114. var title = document.title;
  115. if (typeof update_title == "undefined") {
  116. var update_title = function() {
  117. if (new_posts) {
  118. document.title = "("+new_posts+") "+title;
  119. } else {
  120. document.title = title;
  121. makeIcon(false);
  122. }
  123. };
  124. }
  125. if (typeof add_title_collector != "undefined")
  126. add_title_collector(function(){
  127. return new_posts;
  128. });
  129. var window_active = true;
  130. $(window).focus(function() {
  131. window_active = true;
  132. recheck_activated();
  133. // Reset the delay if needed
  134. if(settings.get('reset_focus', true)) {
  135. poll_interval_delay = poll_interval_mindelay;
  136. }
  137. });
  138. $(window).blur(function() {
  139. window_active = false;
  140. });
  141. $('#auto_update_status').click(function() {
  142. if($("#auto_update_status").is(':checked')) {
  143. auto_update(poll_interval_mindelay);
  144. } else {
  145. stop_auto_update();
  146. $('#update_secs').text("");
  147. }
  148. });
  149. var decrement_timer = function() {
  150. poll_current_time = poll_current_time - 1000;
  151. $('#update_secs').text(poll_current_time/1000);
  152. if (poll_current_time <= 0) {
  153. poll(manualUpdate = false);
  154. }
  155. }
  156. var recheck_activated = function(end_of_page) {
  157. if (typeof end_of_page == "undefined") var end_of_page = false;
  158. if (end_of_page || (new_posts && window_active &&
  159. $(window).scrollTop() + $(window).height() >=
  160. $('div.boardlist.bottom').position().top)) {
  161. new_posts = 0;
  162. }
  163. update_title();
  164. first_new_post = null;
  165. };
  166. // automatically updates the thread after a specified delay
  167. var auto_update = function(delay) {
  168. clearInterval(countdown_interval);
  169. poll_current_time = delay;
  170. countdown_interval = setInterval(decrement_timer, 1000);
  171. $('#update_secs').text(poll_current_time/1000);
  172. }
  173. var stop_auto_update = function() {
  174. clearInterval(countdown_interval);
  175. }
  176. var epoch = (new Date).getTime();
  177. var epochold = epoch;
  178. var timeDiff = function (delay) {
  179. if((epoch-epochold) > delay) {
  180. epochold = epoch = (new Date).getTime();
  181. return true;
  182. }else{
  183. epoch = (new Date).getTime();
  184. return;
  185. }
  186. }
  187. var poll = function(manualUpdate) {
  188. stop_auto_update();
  189. $('#update_secs').text(_("Updating..."));
  190. $.ajax({
  191. url: document.location,
  192. success: function(data) {
  193. var loaded_posts = 0; // the number of new posts loaded in this update
  194. $(data).find('div.post.reply').each(function() {
  195. var id = $(this).attr('id');
  196. if($('#' + id).length == 0) {
  197. if (!new_posts) {
  198. first_new_post = this;
  199. makeIcon('reply');
  200. if (notify === "all" || (notify === "mention" && $(this).find('.own_post').length)) {
  201. var body = $(this).children('.body').html().replace(/<br\s*[\/]?>/gi, "\n");
  202. var n = new Notification("New reply to "+$('title').text(), {body: $('<div/>').html(body).text()});
  203. }
  204. }
  205. if ($("div.post").length > 1){
  206. $(this).parent().insertAfter($('div.post:not(.post-hover):last').parent().next()).after('<br class="clear">');
  207. }
  208. else {
  209. $(this).insertAfter($('div.post:not(.post-hover):last')).after('<br class="clear">');
  210. }
  211. new_posts++;
  212. loaded_posts++;
  213. $(document).trigger('new_post', this);
  214. recheck_activated();
  215. }
  216. });
  217. time_loaded = Date.now(); // interop with watch.js
  218. if ($('#auto_update_status').is(':checked')) {
  219. // If there are no new posts, double the delay. Otherwise set it to the min.
  220. if(loaded_posts == 0) {
  221. // if the update was manual, don't increase the delay
  222. if (manualUpdate == false) {
  223. poll_interval_delay *= 2;
  224. // Don't increase the delay beyond the maximum
  225. if(poll_interval_delay > poll_interval_maxdelay) {
  226. poll_interval_delay = poll_interval_maxdelay;
  227. }
  228. }
  229. } else {
  230. poll_interval_delay = poll_interval_mindelay;
  231. }
  232. auto_update(poll_interval_delay);
  233. } else {
  234. // Decide the message to show if auto update is disabled
  235. if (loaded_posts > 0)
  236. $('#update_secs').text(fmt(_("Thread updated with {0} new post(s)"), [loaded_posts]));
  237. else
  238. $('#update_secs').text(_("No new posts found"));
  239. }
  240. },
  241. error: function(xhr, status_text, error_text) {
  242. if (status_text == "error") {
  243. if (error_text == "Not Found") {
  244. $('#update_secs').text(_("Thread deleted or pruned"));
  245. $('#auto_update_status').prop('checked', false);
  246. $('#auto_update_status').prop('disabled', true); // disable updates if thread is deleted
  247. return;
  248. } else {
  249. $('#update_secs').text("Error: "+error_text);
  250. }
  251. } else if (status_text) {
  252. $('#update_secs').text(_("Error: ")+status_text);
  253. } else {
  254. $('#update_secs').text(_("Unknown error"));
  255. }
  256. // Keep trying to update
  257. if ($('#auto_update_status').is(':checked')) {
  258. poll_interval_delay = poll_interval_errordelay;
  259. auto_update(poll_interval_delay);
  260. }
  261. }
  262. });
  263. return false;
  264. };
  265. $(post).on('submit', function(e){
  266. poll(manualUpdate = true);
  267. dothis(this);
  268. });
  269. $(window).scrollStopped(function() {
  270. // if the newest post is not visible
  271. if($(this).scrollTop() + $(this).height() <
  272. $('div.post:last').position().top + $('div.post:last').height()) {
  273. end_of_page = false;
  274. } else {
  275. if($("#auto_update_status").is(':checked') && timeDiff(poll_interval_mindelay)) {
  276. poll(manualUpdate = true);
  277. }
  278. end_of_page = true;
  279. }
  280. recheck_activated(end_of_page);
  281. });
  282. $('#update_thread').on('click', function() { poll(manualUpdate = true); return false; });
  283. if($("#auto_update_status").is(':checked')) {
  284. auto_update(poll_interval_delay);
  285. }
  286. });
  287. }();