nodebb-plugin-ezoic-infinite 1.4.3 → 1.4.4

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 +41 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.4.3",
3
+ "version": "1.4.4",
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
@@ -37,6 +37,9 @@
37
37
  pendingById: new Set(),
38
38
  retryById: new Map(),
39
39
  retryTimer: null,
40
+ retryQueue: [],
41
+ retryQueueSet: new Set(),
42
+ retryQueueRunning: false,
40
43
 
41
44
  scheduled: false,
42
45
  timer: null,
@@ -251,6 +254,33 @@
251
254
  state.retryTimer = setTimeout(refillUnfilled, delay);
252
255
  }
253
256
 
257
+ function enqueueRetry(id) {
258
+ if (!id) return;
259
+ if (state.retryQueueSet.has(id)) return;
260
+ state.retryQueueSet.add(id);
261
+ state.retryQueue.push(id);
262
+ processRetryQueue();
263
+ }
264
+
265
+ function processRetryQueue() {
266
+ if (state.retryQueueRunning) return;
267
+ state.retryQueueRunning = true;
268
+
269
+ const step = () => {
270
+ const id = state.retryQueue.shift();
271
+ if (!id) {
272
+ state.retryQueueRunning = false;
273
+ return;
274
+ }
275
+ state.retryQueueSet.delete(id);
276
+ callShowAdsWhenReady(id);
277
+ setTimeout(step, 950);
278
+ };
279
+
280
+ step();
281
+ }
282
+
283
+
254
284
  function refillUnfilled() {
255
285
  const wraps = Array.from(document.querySelectorAll(`.${WRAP_CLASS}`));
256
286
  let scheduledAny = false;
@@ -273,7 +303,7 @@
273
303
  if (r && (r.top > window.innerHeight + 1200 || r.bottom < -1200)) continue;
274
304
 
275
305
  state.retryById.set(id, tries + 1);
276
- callShowAdsWhenReady(id);
306
+ enqueueRetry(id);
277
307
  scheduledAny = true;
278
308
  }
279
309
 
@@ -392,6 +422,12 @@
392
422
  const el = items[afterPos - 1];
393
423
  if (!el || !el.isConnected) continue;
394
424
 
425
+ // Prevent adjacent ads (DOM-based, robust against virtualization)
426
+ const nextSibling = el.nextElementSibling;
427
+ if (nextSibling && nextSibling.classList && nextSibling.classList.contains(WRAP_CLASS)) {
428
+ continue;
429
+ }
430
+
395
431
  // Prevent back-to-back at load
396
432
  const prevWrap = findWrap(kindClass, afterPos - 1);
397
433
  if (prevWrap) continue;
@@ -411,6 +447,7 @@
411
447
  destroyPlaceholderIds([id]);
412
448
  wrap = pick.recycled.wrap;
413
449
  if (!moveWrapAfter(wrap, el, kindClass, afterPos)) continue;
450
+ setTimeout(() => { enqueueRetry(id); }, 250);
414
451
  } else {
415
452
  usedSet.add(id);
416
453
  wrap = insertAfter(el, id, kindClass, afterPos);
@@ -418,7 +455,9 @@
418
455
  }
419
456
 
420
457
  liveArr.push({ id, wrap });
421
- callShowAdsWhenReady(id);
458
+ if (!(pick.recycled && pick.recycled.wrap)) {
459
+ callShowAdsWhenReady(id);
460
+ }
422
461
  inserted += 1;
423
462
  }
424
463
  return inserted;