topiclive.user.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. // ==UserScript==
  2. // @name TopicLive
  3. // @description Charge les nouveaux messages d'un topic de JVC en direct
  4. // @author kiwec
  5. // @downloadURL https://git.kiwec.net/kiwec/TopicLive/raw/master/topiclive.user.js
  6. // @updateURL https://git.kiwec.net/kiwec/TopicLive/raw/master/topiclive.user.js
  7. // @match https://www.jeuxvideo.com/*
  8. // @match https://m.jeuxvideo.com/*
  9. // @run-at document-end
  10. // @require https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
  11. // @version 5.4.3
  12. // @grant none
  13. // @noframes
  14. // ==/UserScript==
  15. class Page {
  16. constructor($page) {
  17. // TL.log('Nouvelle page.');
  18. this.$page = $page;
  19. }
  20. obtenirMessages() {
  21. // TL.log('page.obtenirMessages()');
  22. const msgs = [];
  23. this.trouver(`${TL.class_msg}:not(.msg-pseudo-blacklist)`).each(function() {
  24. msgs.push(new Message($(this)));
  25. });
  26. return msgs;
  27. }
  28. // Appele quand il y a des nouveaux messages
  29. maj() {
  30. TL.log('Nouveaux messages ! Execution favicon/son/spoilers');
  31. if(localStorage.topiclive_son == 'true') {
  32. try { TL.son.play(); }
  33. catch(err) { TL.log(`### Erreur son : ${err}`); }
  34. }
  35. try { if(!TL.ongletActif) TL.favicon.maj(`${TL.nvxMessages}`); }
  36. catch(err) { TL.log(`### Erreur favicon (maj) : ${err}`); }
  37. try { this.Transformation(); }
  38. catch(err) { TL.log(`### Erreur jsli.Transformation() : ${err}`); }
  39. // Nettoyage des anciens messages
  40. const nb_messages = $(`${TL.class_msg}:not(.msg-pseudo-blacklist)`).size();
  41. if(nb_messages > 100) {
  42. $(`${TL.class_msg}:not(.msg-pseudo-blacklist)`)
  43. .slice(0, nb_messages - 100)
  44. .remove();
  45. }
  46. TL.log('Envoi de topiclive:doneprocessing');
  47. dispatchEvent(new CustomEvent('topiclive:doneprocessing', {
  48. 'detail': { jvcake: TL.jvCake }
  49. }));
  50. }
  51. scan() {
  52. // TL.log('Scan de la page');
  53. TL.ajaxTs = this.trouver('#ajax_timestamp_liste_messages').val();
  54. TL.ajaxHash = this.trouver('#ajax_hash_liste_messages').val();
  55. // Maj du nombre de connectes
  56. $('.nb-connect-fofo').text(this.trouver('.nb-connect-fofo').text());
  57. if($(TL.class_msg).length === 0 || $(TL.class_page_fin).length !== 0) {
  58. TL.log('Pas sur une derniere page : loop');
  59. TL.majUrl(this);
  60. TL.loop();
  61. return;
  62. }
  63. let messages_a_afficher = [];
  64. // TL.log('Verification des nouveaux messages et editions');
  65. const nvMsgs = this.obtenirMessages();
  66. try {
  67. for(let nvMsg of nvMsgs) {
  68. // TODO: On n'a pas besoin de ce hack. On sait que les IDs
  69. // s'incrémentent, il faut juste tenir compte de 8 liste
  70. // d'IDs différents, car il y a 8 listes séparées d'IDs qui
  71. // s'incrémentent (logique de sharing de JVC). On peut donc
  72. // en théorie retirer le check de contenu des messages et
  73. // avoir des résultats plus stables.
  74. let nv = true;
  75. for(let ancienMsg of TL.messages) {
  76. if(TL.estMP) {
  77. if(ancienMsg.trouver('.bloc-spoil-jv').length !== 0) {
  78. const ancienneDate = ancienMsg.trouver(TL.class_date).text();
  79. const nouvelleDate = nvMsg.trouver(TL.class_date).text();
  80. if(ancienneDate == nouvelleDate) {
  81. nv = false;
  82. break;
  83. }
  84. } else if(ancienMsg.$message.text() == nvMsg.$message.text()) {
  85. nv = false;
  86. break;
  87. }
  88. } else {
  89. if(ancienMsg.id_message == nvMsg.id_message) {
  90. nv = false;
  91. ancienMsg.update(nvMsg);
  92. break;
  93. }
  94. }
  95. }
  96. if(nv) {
  97. // TL.log('Nouveau message !');
  98. TL.messages.push(nvMsg);
  99. TL.nvxMessages++;
  100. nvMsg.$message.hide();
  101. nvMsg.fixAvatar();
  102. nvMsg.fixBlacklist();
  103. nvMsg.fixCitation();
  104. nvMsg.fixDeroulerCitation();
  105. if(TL.mobile) {
  106. nvMsg.fixMobile();
  107. }
  108. $(`${TL.class_pagination}:last`).before(nvMsg.$message);
  109. const evt = {
  110. message: nvMsg,
  111. cancelled: false
  112. };
  113. messages_a_afficher.push(evt);
  114. dispatchEvent(new CustomEvent('topiclive:newmessage', {
  115. 'detail': {
  116. id: nvMsg.id_message,
  117. jvcake: TL.jvCake,
  118. cancel: () => { evt.cancelled = true; }
  119. }
  120. }));
  121. }
  122. }
  123. } catch(err) { TL.log(`Erreur nouveaux messages : ${err}`); }
  124. TL.majUrl(this);
  125. if(messages_a_afficher.length > 0) {
  126. setTimeout(() => {
  127. let maj = false;
  128. for(let msg of messages_a_afficher) {
  129. if(msg.cancelled) {
  130. TL.nvxMessages--;
  131. } else {
  132. TL.log(`Affichage du message ${msg.message.id_message}`);
  133. msg.message.$message.fadeIn('slow');
  134. maj = true;
  135. }
  136. }
  137. if(maj) {
  138. this.maj();
  139. }
  140. }, 1000);
  141. }
  142. TL.loop();
  143. }
  144. // Version perso de JvCare
  145. Transformation() {
  146. $('.JvCare').each(function () {
  147. const $span = $(this);
  148. let classes = $span.attr('class');
  149. const href = TL.jvCake(classes);
  150. // Suppression de JvCare
  151. classes = classes.split(' ');
  152. const index = classes.indexOf('JvCare');
  153. classes.splice(index, index + 2);
  154. classes.unshift('xXx');
  155. classes = classes.join(' ');
  156. $span.replaceWith(`<a href="${href}" class="${classes}">${$span.html()}</a>`);
  157. });
  158. // Fix temporaire des avatars
  159. $('.user-avatar-msg').each(function () {
  160. const $elem = $(this);
  161. const newsrc = $elem.attr('data-srcset');
  162. if(newsrc != 'undefined') {
  163. $elem.attr('src', newsrc);
  164. $elem.removeAttr('data-srcset');
  165. }
  166. });
  167. }
  168. trouver(chose) {
  169. // TL.log('Page.trouver : ' + chose);
  170. return this.$page.find(chose);
  171. }
  172. }
  173. class TLOption {
  174. constructor(nom, id) {
  175. this.actif = localStorage[id] == 'true';
  176. this.nom = nom;
  177. this.id = id;
  178. this.injecter();
  179. }
  180. injecter() {
  181. // Ajout de l'option aux options JVC
  182. let option = `<li><span class="pull-left">TopicLive - ${this.nom}</span>`;
  183. option += `<input type="checkbox" class="input-on-off" id="${this.id}" `;
  184. option += this.actif ? 'checked>' : '>';
  185. option += `<label for="${this.id}" class="btn-on-off"></label></li>`;
  186. $('.menu-user-forum').append(option);
  187. // Register des events lors du toggle de l'option
  188. this.bouton = $(`#${this.id}`);
  189. this.bouton.change(() => {
  190. this.actif = !this.actif;
  191. localStorage[this.id] = this.actif;
  192. });
  193. }
  194. }
  195. class Message {
  196. constructor($message) {
  197. if(TL.estMP) {
  198. this.id_message = 'MP';
  199. } else if(TL.mobile) {
  200. let id = $message.attr('id');
  201. id = id.slice(id.indexOf('_') + 1);
  202. this.id_message = parseInt(id, 10);
  203. } else {
  204. this.id_message = parseInt($message.attr('data-id'), 10);
  205. }
  206. this.date = $(TL.class_date, $message).text().replace(/[\r\n]|#[0-9]+$/g, '');
  207. this.edition = $message.find('.info-edition-msg').text();
  208. this.$message = $message;
  209. this.pseudo = $('.bloc-pseudo-msg', $message).text().replace(/[\r\n]/g, '');
  210. this.supprime = false;
  211. }
  212. fixAvatar() {
  213. let avatar = this.trouver('.user-avatar-msg');
  214. avatar.attr('src', avatar.data('src'));
  215. }
  216. fixBlacklist() {
  217. this.trouver('.bloc-options-msg > .picto-msg-tronche, .msg-pseudo-blacklist .btn-blacklist-cancel').on('click', function () {
  218. $.ajax({
  219. url: '/forums/ajax_forum_blacklist.php',
  220. data: {
  221. id_alias_msg: this.$message.attr('data-id-alias'),
  222. action: this.$message.attr('data-action'),
  223. ajax_hash: $('#ajax_hash_preference_user')
  224. },
  225. dataType: 'json',
  226. success({erreur}) {
  227. if(erreur && erreur.length) {
  228. TL.alert(erreur);
  229. } else {
  230. document.location.reload();
  231. }
  232. }
  233. });
  234. });
  235. }
  236. fixCitation() {
  237. TL.log(`Obtention de la citation du message ${this.id_message}`);
  238. this.$message.find('.bloc-options-msg .picto-msg-quote').on('click', () => {
  239. $.ajax({
  240. type: 'POST',
  241. url: '/forums/ajax_citation.php',
  242. data: {
  243. id_message: this.id_message,
  244. ajax_timestamp: TL.ajaxTs,
  245. ajax_hash: TL.ajaxHash
  246. },
  247. dataType: 'json',
  248. timeout: 5000,
  249. success: ({txt}) => {
  250. TL.log(`Citation du message ${this.id_message} recue avec succes`);
  251. const $msg = TL.formu.obtenirMessage();
  252. let nvmsg = `> Le ${this.date} ${this.pseudo} a écrit :\n>`;
  253. nvmsg += `${txt.split('\n').join('\n> ')}\n\n`;
  254. if($msg.val() === '') {
  255. $msg.val(nvmsg);
  256. } else {
  257. $msg.val(`${$msg.val()}\n\n${nvmsg}`);
  258. }
  259. },
  260. error: this.fixCitation.bind(this)
  261. });
  262. });
  263. }
  264. fixDeroulerCitation() {
  265. this.trouver('blockquote').click(function() {
  266. $(this).attr('data-visible', '1');
  267. });
  268. }
  269. fixMobile() {
  270. this.trouver('.message').addClass('show-all');
  271. }
  272. trouver(chose) {
  273. return this.$message.find(chose);
  274. }
  275. update(nvMessage) {
  276. if(this.edition == nvMessage.edition) return;
  277. TL.log(`Message ${this.id_message} edite : mise a jour`);
  278. this.edition = nvMessage.edition;
  279. this.trouver(TL.class_contenu).html(nvMessage.trouver(TL.class_contenu).html());
  280. dispatchEvent(new CustomEvent('topiclive:edition', {
  281. 'detail': {
  282. id: this.id_message,
  283. jvcake: TL.jvCake
  284. }
  285. }));
  286. // Clignotement du messages
  287. const defColor = this.$message.css('backgroundColor');
  288. this.$message.animate({
  289. backgroundColor: '#FF9900'
  290. }, 50);
  291. this.$message.animate({
  292. backgroundColor: defColor
  293. }, 500);
  294. }
  295. }
  296. class Formulaire {
  297. constructor() {
  298. // TL.log('Nouveau formulaire.');
  299. this.hook();
  300. }
  301. afficherErreurs(msg) {
  302. if(typeof msg !== 'undefined') {
  303. let message_erreur = '';
  304. for(let i = 0; i < msg.length; i++) {
  305. message_erreur += msg[i];
  306. if(i < msg.length) message_erreur += '<br />';
  307. }
  308. TL.alert(message_erreur);
  309. }
  310. }
  311. envoyer(e) {
  312. // Si le message est invalide selon JVC
  313. if(typeof e !== 'undefined' && typeof e.errors !== 'undefined' && e.errors.length) {
  314. this.afficherErreurs(e.erreurs);
  315. } else {
  316. TL.log('Message valide. Envoi en cours');
  317. this.trouver('.btn-poster-msg').attr('disabled', 'disabled');
  318. this.trouver('.conteneur-editor').fadeOut();
  319. window.clearTimeout(TL.idanalyse);
  320. $.ajax({
  321. type: 'POST',
  322. url: TL.url,
  323. data: this.obtenirFormulaire().serializeArray(),
  324. timeout: 5000,
  325. success: data => {
  326. switch(typeof data) {
  327. case 'object':
  328. // MaJ du formulaire via JSON
  329. if(data.hidden_reset) {
  330. this.trouver('input[type="hidden"]').remove();
  331. this.obtenirFormulaire().append(data.hidden_reset);
  332. }
  333. // Erreur lors de l'envoi du message
  334. if(data.errors) {
  335. this.afficherErreurs(data.errors);
  336. this.trouver('.btn-poster-msg').removeAttr('disabled');
  337. this.trouver('.conteneur-editor').fadeIn();
  338. }
  339. // Redirection via JSON (wtf)
  340. if(data.redirect_uri) {
  341. TL.log(`Redirection du formulaire vers ${data.redirect_uri}`);
  342. TL.url = data.redirect_uri;
  343. TL.GET(this.verifEnvoi.bind(this));
  344. }
  345. break;
  346. case 'string':
  347. this.verifEnvoi($(data.substring(data.indexOf('<!DOCTYPE html>'))));
  348. break;
  349. case 'undefined': /* falls through */
  350. default:
  351. TL.alert('Erreur inconnue lors de l\'envoi du message.');
  352. this.trouver('.btn-poster-msg').removeAttr('disabled');
  353. this.trouver('.conteneur-editor').fadeIn();
  354. break;
  355. }
  356. TL.loop();
  357. },
  358. error: err => TL.alert(`Erreur lors de l'envoi du message : ${err}`)
  359. });
  360. }
  361. }
  362. hook() {
  363. // Remplacement du bouton de post
  364. const $form = this.obtenirFormulaire();
  365. const $bouton = $form.find('.btn-poster-msg');
  366. $bouton.off();
  367. $bouton.removeAttr('data-push');
  368. $bouton.attr('type', 'button');
  369. $bouton.on('click', this.verifMessage.bind(this));
  370. }
  371. maj($nvform) {
  372. TL.log('Mise a jour du formulaire');
  373. const $form = this.obtenirFormulaire();
  374. const $cap = this.obtenirCaptcha($form);
  375. const $ncap = this.obtenirCaptcha($nvform);
  376. // Remplacement hashs formulaire
  377. this.trouver('input[type="hidden"]').remove();
  378. $nvform.find('input[type="hidden"]').each(function() {
  379. $form.append($(this));
  380. });
  381. // Reactivation des boutons
  382. this.trouver('.btn-poster-msg').removeAttr('disabled');
  383. this.trouver('.conteneur-editor').fadeIn();
  384. // Remplacement du captcha
  385. $cap.remove();
  386. this.trouver('.jv-editor').after($ncap);
  387. // Maj banniere erreur
  388. this.trouver('.alert-danger').remove();
  389. this.trouver('.row:first').before($nvform.find('.alert-danger'));
  390. // Remplacement du message (JVC n'effacera pas le message en erreur)
  391. this.obtenirMessage().val(this.obtenirMessage($nvform).val());
  392. this.hook();
  393. }
  394. obtenirCaptcha($form) {
  395. if(typeof $form === 'undefined') $form = this.obtenirFormulaire();
  396. return $form.find('.jv-editor').next('div');
  397. }
  398. obtenirMessage($form) {
  399. if(typeof $form == 'undefined') $form = this.obtenirFormulaire();
  400. return $form.find(TL.estMP ? '#message' : '#message_topic');
  401. }
  402. obtenirFormulaire($page) {
  403. if(typeof $page === 'undefined') $page = $(document);
  404. return $page.find(TL.estMP ? '#repondre-mp > form' : '.form-post-message');
  405. }
  406. verifEnvoi(data) {
  407. const nvPage = new Page(data);
  408. const $formu = this.obtenirFormulaire(nvPage.$page);
  409. this.maj($formu);
  410. TL.majUrl(nvPage);
  411. nvPage.scan();
  412. }
  413. verifMessage() {
  414. TL.log('Verification du message avant envoi');
  415. if(TL.estMP) {
  416. this.envoyer();
  417. } else {
  418. $.ajax({
  419. type: 'POST',
  420. url: '/forums/ajax_check_poste_message.php',
  421. data: {
  422. id_topic, /* globals id_topic */
  423. new_message: this.obtenirMessage().val(),
  424. ajax_timestamp: TL.ajaxTs,
  425. ajax_hash: TL.ajaxHash
  426. },
  427. dataType: 'json',
  428. timeout: 5000,
  429. success: this.envoyer.bind(this),
  430. error: this.verifMessage.bind(this)
  431. });
  432. }
  433. return false;
  434. }
  435. trouver(chose) {
  436. return this.obtenirFormulaire().find(chose);
  437. }
  438. }
  439. // Code de Spawnkill
  440. class Favicon {
  441. constructor() {
  442. try {
  443. this.canv = $('<canvas>').get(0);
  444. this.canv.width = 192;
  445. this.canv.height = 192;
  446. this.context = this.canv.getContext('2d');
  447. this.context.font = 'bold 120px Courier New';
  448. this.context.textBaseline = 'bottom';
  449. this.image = new Image();
  450. this.image.src = 'https://www.jeuxvideo.com/favicon.png';
  451. this.maj('');
  452. } catch(err) {
  453. TL.log(`### Erreur init favicon : ${err}`);
  454. }
  455. }
  456. clear() {
  457. this.context.clearRect(0, 0, this.canv.width, this.canv.height);
  458. this.context.drawImage(this.image, 0, 0);
  459. }
  460. maj(txt) {
  461. this.clear();
  462. if(txt !== '')
  463. {
  464. this.context.fillStyle = 'red';
  465. this.context.fillRect(0, 0, this.context.measureText(txt).width + 36, 132);
  466. this.context.fillStyle = 'white';
  467. this.context.fillText(txt, 12, 132);
  468. }
  469. this.replace();
  470. }
  471. replace() {
  472. $('link[rel*="icon"]').remove();
  473. this.lien = $('<link>', {
  474. href: this.canv.toDataURL('image/png'),
  475. rel: 'shortcut icon',
  476. type: 'image/png'
  477. });
  478. $('head').append(this.lien);
  479. }
  480. }
  481. class TopicLive {
  482. constructor() {
  483. this.log('Initialisation');
  484. this.instance = 0;
  485. this.ongletActif = true;
  486. }
  487. ajouterOptions() {
  488. if(this.mobile) return;
  489. this.options = {
  490. optionSon: new TLOption('Son', 'topiclive_son')
  491. };
  492. }
  493. charger() {
  494. if(this.oldInstance != this.instance) {
  495. this.log('Nouvelle instance detectee : arret du chargement');
  496. return;
  497. }
  498. TL.GET(data => {
  499. new Page(data).scan();
  500. });
  501. }
  502. // Sera initialise a chaque changement de page
  503. init() {
  504. if(typeof $ === 'undefined') {
  505. return this.log('### jQuery introuvable !');
  506. }
  507. this.instance++;
  508. this.ajaxTs = $('#ajax_timestamp_liste_messages').val();
  509. this.ajaxHash = $('#ajax_hash_liste_messages').val();
  510. this.estMP = $('.mp-page').length;
  511. this.url = this.estMP ? document.URL.substring(0, document.URL.indexOf('&')) : document.URL;
  512. this.mobile = document.URL.includes('//m.jeuxvideo.com');
  513. this.class_msg = this.mobile ? '.post' : '.bloc-message-forum';
  514. this.class_num_page = this.mobile ? '.num-page' : '.page-active';
  515. this.class_page_fin = this.mobile ? '.right-elt > a' : '.pagi-fin-actif';
  516. this.class_date = this.mobile ? '.date-post' : '.bloc-date-msg';
  517. this.class_contenu = this.mobile ? '.contenu' : '.bloc-contenu';
  518. this.class_pagination = this.mobile ? '.pagination-b' : '.bloc-pagi-default';
  519. this.ajouterOptions();
  520. // Actif sur les URL de forums ou de messages privés, tant qu'il y a un
  521. // message dans la page.
  522. // -> Sera compatible respeed, sans pour autant s'exécuter sur des pages
  523. // non supportées (ex. GTA)
  524. const analysable = (document.URL.match(/\/forums\/\d/) || document.URL.match(/\/messages-prives\//));
  525. if(analysable && $(this.class_msg).length > 0) {
  526. this.log('TopicLive actif sur cette page.');
  527. this.page = new Page($(document));
  528. this.formu = new Formulaire();
  529. this.messages = this.page.obtenirMessages();
  530. this.nvxMessages = 0;
  531. this.page.scan();
  532. this.loop();
  533. } else {
  534. this.log('TopicLive sera inactif sur cette page');
  535. }
  536. }
  537. // Ne sera pas initialise a chaque changement de page
  538. initStatic() {
  539. this.favicon = new Favicon();
  540. this.son = new Audio('https://git.kiwec.net/kiwec/TopicLive/raw/master/notification.ogg');
  541. this.suivreOnglets();
  542. this.init();
  543. addEventListener('instantclick:newpage', this.init.bind(this));
  544. $("head").append("<style type='text/css'>\
  545. .topiclive-loading:after { content: ' ○' }\
  546. .topiclive-loaded:after { content: ' ●' }\
  547. </style>");
  548. this.log('Fin de l\'initialisation');
  549. }
  550. // Transforme une classe chiffree par JvCare en un lien
  551. jvCake(classe) {
  552. const base16 = '0A12B34C56D78E9F';
  553. let lien = '';
  554. const s = classe.split(' ')[1];
  555. for (let i = 0; i < s.length; i += 2) {
  556. lien += String.fromCharCode(base16.indexOf(s.charAt(i)) * 16 + base16.indexOf(s.charAt(i + 1)));
  557. }
  558. return lien;
  559. }
  560. alert(message) {
  561. /* globals modal */
  562. try {
  563. modal('erreur', { message });
  564. this.log(message);
  565. } catch(err) {
  566. this.log('### Fonction modal() inaccessible');
  567. alert(message);
  568. }
  569. }
  570. log(message) {
  571. console.log(`[TopicLive] ${message}`);
  572. }
  573. loop() {
  574. if(typeof this.idanalyse !== 'undefined') window.clearTimeout(this.idanalyse);
  575. let duree = this.ongletActif ? 5000 : 10000;
  576. if(this.mobile)
  577. duree = 10000;
  578. this.oldInstance = this.instance;
  579. this.idanalyse = setTimeout(this.charger.bind(this), duree);
  580. }
  581. majUrl(page) {
  582. if(this.estMP) return;
  583. const $bouton = page.trouver(this.class_page_fin);
  584. const numPage = page.trouver(`${this.class_num_page}:first`).text();
  585. const testUrl = this.url.split('-');
  586. // Si le bouton page suivante est present
  587. if($bouton.length > 0) {
  588. TL.log('Nouvelle URL (loop)');
  589. this.messages = [];
  590. if($bouton.prop('tagName') == 'A') {
  591. this.url = $bouton.attr('href');
  592. } else {
  593. this.url = this.jvCake($bouton.attr('class'));
  594. }
  595. // Si la page n'est pas la meme (ex. post d'un message sur nouvelle page)
  596. } else if(testUrl[3] != numPage) {
  597. TL.log('Nouvelle URL (formulaire)');
  598. this.messages = [];
  599. testUrl[3] = numPage;
  600. this.url = testUrl.join('-');
  601. }
  602. }
  603. suivreOnglets() {
  604. $(window).bind('focus', () => {
  605. if(!this.ongletActif) {
  606. this.ongletActif = true;
  607. this.favicon.maj('');
  608. this.nvxMessages = 0;
  609. }
  610. });
  611. $(window).bind('blur', () => {
  612. if(this.ongletActif) {
  613. this.ongletActif = false;
  614. this.favicon.maj('');
  615. this.nvxMessages = 0;
  616. }
  617. });
  618. }
  619. GET(cb) {
  620. const blocChargement = this.mobile ? $('.bloc-nom-sujet:last > span') : $('#bloc-formulaire-forum .titre-bloc');
  621. blocChargement.addClass('topiclive-loading');
  622. window.clearTimeout(this.idanalyse);
  623. $.ajax({
  624. type: 'GET',
  625. url: this.url,
  626. timeout: 5000,
  627. success: data => {
  628. if(this.oldInstance != this.instance) {
  629. this.log('Nouvelle instance detectee : arret du chargement');
  630. return;
  631. }
  632. blocChargement.removeClass('topiclive-loading');
  633. blocChargement.addClass('topiclive-loaded');
  634. cb($(data.substring(data.indexOf('<!DOCTYPE html>'))));
  635. setTimeout(() => { blocChargement.removeClass('topiclive-loaded'); }, 100);
  636. TL.loop();
  637. },
  638. error() {
  639. TL.loop();
  640. }
  641. });
  642. }
  643. }
  644. var TL = new TopicLive();
  645. TL.initStatic();