nodebb-plugin-ezoic-infinite 0.5.6 → 0.5.8

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 +85 -48
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "0.5.6",
3
+ "version": "0.5.8",
4
4
  "description": "Ezoic ads with infinite scroll using a pool of placeholder IDs",
5
5
  "main": "library.js",
6
6
  "license": "MIT",
package/public/client.js CHANGED
@@ -7,6 +7,10 @@ let cachedConfig;
7
7
  let lastFetch = 0;
8
8
  let debounceTimer;
9
9
 
10
+ let lastSignature = null;
11
+ let inFlight = false;
12
+ let rerunRequested = false;
13
+
10
14
  async function fetchConfig() {
11
15
  if (cachedConfig && Date.now() - lastFetch < 10000) return cachedConfig;
12
16
  const res = await fetch('/api/plugins/ezoic-infinite/config', { credentials: 'same-origin' });
@@ -40,6 +44,8 @@ function getTopicPosts() {
40
44
  }
41
45
 
42
46
  function getCategoryTopicItems() {
47
+ // Only on category topic list pages
48
+ if (!ajaxify || !ajaxify.data || ajaxify.data.template !== 'category') return $();
43
49
  return $('li[component="category/topic"]').not('.ezoic-ad-topic');
44
50
  }
45
51
 
@@ -47,14 +53,11 @@ function tagName($el) {
47
53
  return ($el && $el.length ? (($el.prop('tagName') || '').toUpperCase()) : '');
48
54
  }
49
55
 
50
- function removePlaceholdersByPool(pool) {
51
- pool.forEach(id => $('[id="ezoic-pub-ad-placeholder-' + id + '"]').remove());
52
- }
53
-
54
- function removeAdWrappers() {
56
+ function removeExistingEzoicNodes() {
55
57
  $('.ezoic-ad-post').remove();
56
58
  $('.ezoic-ad-between').remove();
57
59
  $('.ezoic-ad-topic').remove();
60
+ $('[id^="ezoic-pub-ad-placeholder-"]').remove();
58
61
  }
59
62
 
60
63
  function computeWindowSlots(totalItems, interval, poolSize) {
@@ -127,70 +130,104 @@ function uniqueConcat(a, b) {
127
130
  return out;
128
131
  }
129
132
 
133
+ function ezoicCall(ids) {
134
+ if (!ids || !ids.length) return;
135
+
136
+ window.ezstandalone = window.ezstandalone || {};
137
+ window.ezstandalone.cmd = window.ezstandalone.cmd || [];
138
+
139
+ window.ezstandalone.cmd.push(function () {
140
+ try {
141
+ if (typeof window.ezstandalone.destroyPlaceholders === 'function') {
142
+ window.ezstandalone.destroyPlaceholders.apply(window.ezstandalone, ids);
143
+ }
144
+ } catch (e) {}
145
+
146
+ try {
147
+ if (typeof window.ezstandalone.showAds === 'function') {
148
+ window.ezstandalone.showAds.apply(window.ezstandalone, ids);
149
+ }
150
+ } catch (e) {}
151
+ });
152
+ }
153
+
154
+ function computeSignature($posts, $topicItems) {
155
+ if ($posts.length) {
156
+ const lastPid = $posts.last().attr('data-pid') || '';
157
+ return 'topic:' + $posts.length + ':' + lastPid;
158
+ }
159
+ if ($topicItems.length) {
160
+ const lastTid = $topicItems.last().attr('data-tid') || '';
161
+ return 'category:' + $topicItems.length + ':' + lastTid;
162
+ }
163
+ return 'none';
164
+ }
165
+
130
166
  async function refreshAds() {
131
- let cfg;
132
- try { cfg = await fetchConfig(); } catch (e) { return; }
133
- if (!cfg || cfg.excluded) return;
167
+ if (inFlight) { rerunRequested = true; return; }
168
+ inFlight = true;
134
169
 
135
- const betweenPool = parsePool(cfg.placeholderIds);
136
- const betweenInterval = Math.max(1, parseInt(cfg.intervalPosts, 10) || 6);
170
+ try {
171
+ const cfg = await fetchConfig();
172
+ if (!cfg || cfg.excluded) return;
137
173
 
138
- const messagePool = parsePool(cfg.messagePlaceholderIds);
139
- const messageInterval = Math.max(1, parseInt(cfg.messageIntervalPosts, 10) || 3);
174
+ const betweenPool = parsePool(cfg.placeholderIds);
175
+ const betweenInterval = Math.max(1, parseInt(cfg.intervalPosts, 10) || 6);
140
176
 
141
- const $posts = getTopicPosts();
142
- const $topicItems = getCategoryTopicItems();
177
+ const messagePool = parsePool(cfg.messagePlaceholderIds);
178
+ const messageInterval = Math.max(1, parseInt(cfg.messageIntervalPosts, 10) || 3);
143
179
 
144
- if (!$posts.length && !$topicItems.length) return;
180
+ const $posts = getTopicPosts();
181
+ const $topicItems = getCategoryTopicItems();
145
182
 
146
- removeAdWrappers();
147
- removePlaceholdersByPool(uniqueConcat(betweenPool, messagePool));
183
+ if (!$posts.length && !$topicItems.length) return;
148
184
 
149
- const combinedUnique = uniqueConcat(betweenPool, messagePool);
185
+ const signature = computeSignature($posts, $topicItems);
186
+ if (signature === lastSignature) return;
187
+ lastSignature = signature;
150
188
 
151
- const activeIds = [];
189
+ removeExistingEzoicNodes();
190
+
191
+ const combinedUnique = uniqueConcat(betweenPool, messagePool);
192
+ const activeIds = [];
152
193
 
153
- // Category topic list page: inject between topic items
154
- if (!$posts.length && $topicItems.length) {
155
- if (cfg.enableBetweenAds && betweenPool.length) {
156
- activeIds.push(...insertBetweenGeneric($topicItems, combinedUnique.slice(0, betweenPool.length), betweenInterval, 'ezoic-ad-topic'));
194
+ if (!$posts.length && $topicItems.length) {
195
+ if (cfg.enableBetweenAds && betweenPool.length) {
196
+ activeIds.push(...insertBetweenGeneric($topicItems, combinedUnique.slice(0, betweenPool.length), betweenInterval, 'ezoic-ad-topic'));
197
+ }
157
198
  }
158
- }
159
199
 
160
- // Topic page: inject between replies + message ads
161
- if ($posts.length) {
162
- let cursor = 0;
200
+ if ($posts.length) {
201
+ let cursor = 0;
163
202
 
164
- if (cfg.enableBetweenAds && betweenPool.length) {
165
- const idsForBetween = combinedUnique.slice(cursor, cursor + betweenPool.length);
166
- cursor += idsForBetween.length;
167
- activeIds.push(...insertBetweenGeneric($posts, idsForBetween, betweenInterval, 'ezoic-ad-between'));
168
- }
203
+ if (cfg.enableBetweenAds && betweenPool.length) {
204
+ const idsForBetween = combinedUnique.slice(cursor, cursor + betweenPool.length);
205
+ cursor += idsForBetween.length;
206
+ activeIds.push(...insertBetweenGeneric($posts, idsForBetween, betweenInterval, 'ezoic-ad-between'));
207
+ }
169
208
 
170
- if (cfg.enableMessageAds && messagePool.length) {
171
- const idsForMessage = combinedUnique.slice(cursor, cursor + messagePool.length);
172
- cursor += idsForMessage.length;
173
- activeIds.push(...insertAdMessagesBetweenReplies($posts, idsForMessage, messageInterval));
209
+ if (cfg.enableMessageAds && messagePool.length) {
210
+ const idsForMessage = combinedUnique.slice(cursor, cursor + messagePool.length);
211
+ cursor += idsForMessage.length;
212
+ activeIds.push(...insertAdMessagesBetweenReplies($posts, idsForMessage, messageInterval));
213
+ }
174
214
  }
175
- }
176
215
 
177
- if (activeIds.length && window.ezstandalone && typeof window.ezstandalone.destroyPlaceholders === 'function') {
178
- try { window.ezstandalone.destroyPlaceholders(); } catch (e) {}
216
+ ezoicCall(activeIds);
217
+ } finally {
218
+ inFlight = false;
219
+ if (rerunRequested) {
220
+ rerunRequested = false;
221
+ setTimeout(refreshAds, 50);
222
+ }
179
223
  }
180
- activeIds.forEach(id => {
181
- try {
182
- if (window.ezstandalone && typeof window.ezstandalone.showAds === 'function') {
183
- window.ezstandalone.showAds(id);
184
- }
185
- } catch (e) {}
186
- });
187
224
  }
188
225
 
189
226
  function debounceRefresh() {
190
227
  clearTimeout(debounceTimer);
191
- debounceTimer = setTimeout(refreshAds, 150);
228
+ debounceTimer = setTimeout(refreshAds, 220);
192
229
  }
193
230
 
194
231
  $(document).ready(debounceRefresh);
195
232
  $(window).on('action:ajaxify.end action:posts.loaded action:topic.loaded', debounceRefresh);
196
- setTimeout(debounceRefresh, 1500);
233
+ setTimeout(debounceRefresh, 2200);