nodebb-plugin-ezoic-infinite 1.4.47 → 1.4.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/public/client.js +55 -37
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.4.47",
3
+ "version": "1.4.49",
4
4
  "description": "Production-ready Ezoic infinite ads integration for NodeBB 4.x",
5
5
  "main": "library.js",
6
6
  "license": "MIT",
package/public/client.js CHANGED
@@ -26,11 +26,6 @@
26
26
  usedPosts: new Set(),
27
27
  usedCategories: new Set(),
28
28
 
29
- // wrappers currently on page (FIFO for recycling)
30
- liveBetween: [],
31
- liveMessage: [],
32
- liveCategory: [],
33
-
34
29
  lastShowById: new Map(),
35
30
  pendingById: new Set(),
36
31
  definedIds: new Set(),
@@ -39,7 +34,6 @@
39
34
  timer: null,
40
35
 
41
36
  obs: null,
42
- canShowAds: true,
43
37
  activeTimeouts: new Set(),
44
38
  lastScrollRun: 0,
45
39
  __scrollBound: false,
@@ -325,6 +319,56 @@
325
319
  return filled;
326
320
  }
327
321
 
322
+ // Appeler showAds() en batch selon recommandations Ezoic
323
+ // Au lieu de showAds(id1), showAds(id2)... faire showAds(id1, id2, id3...)
324
+ let batchShowAdsTimer = null;
325
+ const pendingShowAdsIds = new Set();
326
+
327
+ function scheduleShowAdsBatch(id) {
328
+ if (!id) return;
329
+
330
+ // CRITIQUE: Si cet ID a déjà été défini (sessionDefinedIds), le détruire d'abord
331
+ if (sessionDefinedIds.has(id)) {
332
+ try {
333
+ destroyPlaceholderIds([id]);
334
+ sessionDefinedIds.delete(id);
335
+ } catch (e) {}
336
+ }
337
+
338
+ // Throttle: ne pas rappeler le même ID trop vite
339
+ const now = Date.now(), last = state.lastShowById.get(id) || 0;
340
+ if (now - last < 3500) return;
341
+
342
+ // Ajouter à la batch
343
+ pendingShowAdsIds.add(id);
344
+
345
+ // Debounce: attendre 100ms pour collecter tous les IDs
346
+ clearTimeout(batchShowAdsTimer);
347
+ batchShowAdsTimer = setTimeout(() => {
348
+ if (pendingShowAdsIds.size === 0) return;
349
+
350
+ const idsArray = Array.from(pendingShowAdsIds);
351
+ pendingShowAdsIds.clear();
352
+
353
+ // Appeler showAds avec TOUS les IDs en une fois
354
+ try {
355
+ window.ezstandalone = window.ezstandalone || {};
356
+ window.ezstandalone.cmd = window.ezstandalone.cmd || [];
357
+ window.ezstandalone.cmd.push(function() {
358
+ if (typeof window.ezstandalone.showAds === 'function') {
359
+ // Appel batch: showAds(id1, id2, id3...)
360
+ window.ezstandalone.showAds(...idsArray);
361
+ // Tracker tous les IDs
362
+ idsArray.forEach(id => {
363
+ state.lastShowById.set(id, Date.now());
364
+ sessionDefinedIds.add(id);
365
+ });
366
+ }
367
+ });
368
+ } catch (e) {}
369
+ }, 100);
370
+ }
371
+
328
372
  function callShowAdsWhenReady(id) {
329
373
  if (!id) return;
330
374
 
@@ -357,10 +401,8 @@
357
401
  const el = document.getElementById(phId);
358
402
  if (el && el.isConnected) {
359
403
  // CRITIQUE: Vérifier que le placeholder est VISIBLE
360
-
361
-
404
+
362
405
  // Si on arrive ici, soit visible, soit timeout
363
-
364
406
 
365
407
  // Si doCall() réussit, Ezoic est chargé et showAds a été appelé → sortir
366
408
  if (doCall()) {
@@ -368,23 +410,6 @@
368
410
  return;
369
411
  }
370
412
 
371
- // Ezoic n'est pas encore chargé → attendre via cmd queue
372
- state.pendingById.add(id);
373
-
374
- window.ezstandalone = window.ezstandalone || {};
375
- window.ezstandalone.cmd = window.ezstandalone.cmd || [];
376
- window.ezstandalone.cmd.push(() => {
377
- try {
378
- if (typeof window.ezstandalone.showAds === 'function') {
379
- state.pendingById.delete(id);
380
- state.lastShowById.set(id, Date.now());
381
- window.ezstandalone.showAds(id);
382
- sessionDefinedIds.add(id);
383
- }
384
- } catch (e) {}
385
- });
386
- // cmd.push suffit - pas besoin de tick() qui crée des doublons
387
- return;
388
413
  }
389
414
 
390
415
  if (attempts < 100) {
@@ -540,10 +565,6 @@
540
565
  state.usedTopics.clear();
541
566
  state.usedPosts.clear();
542
567
  state.usedCategories.clear();
543
- state.liveBetween = [];
544
- state.liveMessage = [];
545
- state.liveCategory = [];
546
-
547
568
  state.lastShowById.clear();
548
569
  // CRITIQUE: Vider pendingById pour annuler tous les showAds en cours
549
570
  // Sinon Ezoic essaie d'accéder aux placeholders pendant que NodeBB vide le DOM
@@ -560,12 +581,12 @@
560
581
  try { clearTimeout(id); } catch (e) {}
561
582
  });
562
583
  state.activeTimeouts.clear();
563
-
584
+
564
585
  // Vider aussi pendingById pour annuler les showAds en attente
565
586
  state.pendingById.clear();
566
587
 
567
588
  if (state.obs) { state.obs.disconnect(); state.obs = null; }
568
- state.canShowAds = false;
589
+
569
590
  state.scheduled = false;
570
591
  clearTimeout(state.timer);
571
592
  state.timer = null;
@@ -675,10 +696,7 @@
675
696
  // CRITIQUE: Attendre 300ms avant de permettre l'insertion de nouveaux placeholders
676
697
  // pour laisser les anciens showAds() (en cours) se terminer ou échouer proprement
677
698
  // Sinon race condition: NodeBB vide le DOM pendant que Ezoic essaie d'accéder aux placeholders
678
- state.canShowAds = false;
679
- setTimeout(() => {
680
699
  state.canShowAds = true;
681
- }, 2000);
682
700
  });
683
701
 
684
702
  $(window).on('action:category.loaded.ezoicInfinite', () => {
@@ -705,8 +723,8 @@
705
723
  }
706
724
 
707
725
  function bindScroll() {
708
- if (state.__scrollBound) return;
709
- state.__scrollBound = true;
726
+ if (state.lastScrollRun > 0) return;
727
+ state.lastScrollRun = Date.now();
710
728
  let ticking = false;
711
729
  window.addEventListener('scroll', () => {
712
730
  if (ticking) return;