nodebb-plugin-ezoic-infinite 1.4.46 → 1.4.48

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 +58 -26
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.4.46",
3
+ "version": "1.4.48",
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
@@ -39,7 +39,6 @@
39
39
  timer: null,
40
40
 
41
41
  obs: null,
42
- canShowAds: true,
43
42
  activeTimeouts: new Set(),
44
43
  lastScrollRun: 0,
45
44
  __scrollBound: false,
@@ -325,6 +324,56 @@
325
324
  return filled;
326
325
  }
327
326
 
327
+ // Appeler showAds() en batch selon recommandations Ezoic
328
+ // Au lieu de showAds(id1), showAds(id2)... faire showAds(id1, id2, id3...)
329
+ let batchShowAdsTimer = null;
330
+ const pendingShowAdsIds = new Set();
331
+
332
+ function scheduleShowAdsBatch(id) {
333
+ if (!id) return;
334
+
335
+ // CRITIQUE: Si cet ID a déjà été défini (sessionDefinedIds), le détruire d'abord
336
+ if (sessionDefinedIds.has(id)) {
337
+ try {
338
+ destroyPlaceholderIds([id]);
339
+ sessionDefinedIds.delete(id);
340
+ } catch (e) {}
341
+ }
342
+
343
+ // Throttle: ne pas rappeler le même ID trop vite
344
+ const now = Date.now(), last = state.lastShowById.get(id) || 0;
345
+ if (now - last < 3500) return;
346
+
347
+ // Ajouter à la batch
348
+ pendingShowAdsIds.add(id);
349
+
350
+ // Debounce: attendre 100ms pour collecter tous les IDs
351
+ clearTimeout(batchShowAdsTimer);
352
+ batchShowAdsTimer = setTimeout(() => {
353
+ if (pendingShowAdsIds.size === 0) return;
354
+
355
+ const idsArray = Array.from(pendingShowAdsIds);
356
+ pendingShowAdsIds.clear();
357
+
358
+ // Appeler showAds avec TOUS les IDs en une fois
359
+ try {
360
+ window.ezstandalone = window.ezstandalone || {};
361
+ window.ezstandalone.cmd = window.ezstandalone.cmd || [];
362
+ window.ezstandalone.cmd.push(function() {
363
+ if (typeof window.ezstandalone.showAds === 'function') {
364
+ // Appel batch: showAds(id1, id2, id3...)
365
+ window.ezstandalone.showAds(...idsArray);
366
+ // Tracker tous les IDs
367
+ idsArray.forEach(id => {
368
+ state.lastShowById.set(id, Date.now());
369
+ sessionDefinedIds.add(id);
370
+ });
371
+ }
372
+ });
373
+ } catch (e) {}
374
+ }, 100);
375
+ }
376
+
328
377
  function callShowAdsWhenReady(id) {
329
378
  if (!id) return;
330
379
 
@@ -357,10 +406,8 @@
357
406
  const el = document.getElementById(phId);
358
407
  if (el && el.isConnected) {
359
408
  // CRITIQUE: Vérifier que le placeholder est VISIBLE
360
-
361
-
409
+
362
410
  // Si on arrive ici, soit visible, soit timeout
363
-
364
411
 
365
412
  // Si doCall() réussit, Ezoic est chargé et showAds a été appelé → sortir
366
413
  if (doCall()) {
@@ -368,23 +415,6 @@
368
415
  return;
369
416
  }
370
417
 
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
418
  }
389
419
 
390
420
  if (attempts < 100) {
@@ -556,11 +586,16 @@
556
586
 
557
587
  // CRITIQUE: Annuler TOUS les timeouts en cours pour éviter que les anciens
558
588
  // showAds() continuent à s'exécuter après la navigation
559
- state.activeTimeouts.forEach(id => clearTimeout(id));
589
+ state.activeTimeouts.forEach(id => {
590
+ try { clearTimeout(id); } catch (e) {}
591
+ });
560
592
  state.activeTimeouts.clear();
561
593
 
594
+ // Vider aussi pendingById pour annuler les showAds en attente
595
+ state.pendingById.clear();
596
+
562
597
  if (state.obs) { state.obs.disconnect(); state.obs = null; }
563
- state.canShowAds = false;
598
+
564
599
  state.scheduled = false;
565
600
  clearTimeout(state.timer);
566
601
  state.timer = null;
@@ -670,10 +705,7 @@
670
705
  // CRITIQUE: Attendre 300ms avant de permettre l'insertion de nouveaux placeholders
671
706
  // pour laisser les anciens showAds() (en cours) se terminer ou échouer proprement
672
707
  // Sinon race condition: NodeBB vide le DOM pendant que Ezoic essaie d'accéder aux placeholders
673
- state.canShowAds = false;
674
- setTimeout(() => {
675
708
  state.canShowAds = true;
676
- }, 500);
677
709
  });
678
710
 
679
711
  $(window).on('action:category.loaded.ezoicInfinite', () => {