nodebb-plugin-ezoic-infinite 1.0.0 → 1.0.1
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.
- package/library.js +9 -4
- package/package.json +2 -2
- package/plugin.json +8 -4
- package/public/admin.js +48 -23
- package/public/client.js +70 -167
- package/public/style.css +0 -2
- package/public/templates/admin/plugins/ezoic-infinite.tpl +11 -27
- package/README.md +0 -12
package/library.js
CHANGED
|
@@ -2,13 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
const meta = require.main.require('./src/meta');
|
|
4
4
|
const groups = require.main.require('./src/groups');
|
|
5
|
-
const routeHelpers = require.main.require('./src/routes/helpers');
|
|
6
5
|
|
|
7
6
|
const Plugin = {};
|
|
8
7
|
|
|
9
8
|
Plugin.init = async function ({ router, middleware }) {
|
|
10
|
-
|
|
11
|
-
routeHelpers.setupAdminPageRoute(router, '/admin/plugins/ezoic-infinite', middleware, [], renderAdmin);
|
|
9
|
+
router.get('/admin/plugins/ezoic-infinite', middleware.admin.buildHeader, renderAdmin);
|
|
12
10
|
router.get('/api/admin/plugins/ezoic-infinite', renderAdmin);
|
|
13
11
|
};
|
|
14
12
|
|
|
@@ -32,7 +30,7 @@ async function renderAdmin(req, res) {
|
|
|
32
30
|
}
|
|
33
31
|
|
|
34
32
|
groupList = (groupList || [])
|
|
35
|
-
.filter(g => g && g.name
|
|
33
|
+
.filter(g => g && g.name)
|
|
36
34
|
.sort((a, b) => (a.name || '').localeCompare(b.name || '', 'fr', { sensitivity: 'base' }));
|
|
37
35
|
|
|
38
36
|
res.render('admin/plugins/ezoic-infinite', {
|
|
@@ -52,4 +50,11 @@ Plugin.addAdminNavigation = async function (header) {
|
|
|
52
50
|
return header;
|
|
53
51
|
};
|
|
54
52
|
|
|
53
|
+
// Expose settings to client without any admin API calls
|
|
54
|
+
Plugin.addConfig = async function (config) {
|
|
55
|
+
const settings = await meta.settings.get('ezoic-infinite');
|
|
56
|
+
config.ezoicInfinite = settings || {};
|
|
57
|
+
return config;
|
|
58
|
+
};
|
|
59
|
+
|
|
55
60
|
module.exports = Plugin;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nodebb-plugin-ezoic-infinite",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Ezoic ads injection for NodeBB 4.x (rebased to 0.8.3 style).",
|
|
5
5
|
"main": "library.js",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"keywords": [
|
package/plugin.json
CHANGED
|
@@ -11,19 +11,23 @@
|
|
|
11
11
|
{
|
|
12
12
|
"hook": "filter:admin.header.build",
|
|
13
13
|
"method": "addAdminNavigation"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"hook": "filter:config.get",
|
|
17
|
+
"method": "addConfig"
|
|
14
18
|
}
|
|
15
19
|
],
|
|
16
20
|
"staticDirs": {
|
|
17
21
|
"public": "public"
|
|
18
22
|
},
|
|
23
|
+
"acpScripts": [
|
|
24
|
+
"public/admin.js"
|
|
25
|
+
],
|
|
19
26
|
"scripts": [
|
|
20
27
|
"public/client.js"
|
|
21
28
|
],
|
|
22
29
|
"css": [
|
|
23
30
|
"public/style.css"
|
|
24
31
|
],
|
|
25
|
-
"templates": "public/templates"
|
|
26
|
-
"modules": {
|
|
27
|
-
"../admin/plugins/ezoic-infinite.js": "public/admin.js"
|
|
28
|
-
}
|
|
32
|
+
"templates": "public/templates"
|
|
29
33
|
}
|
package/public/admin.js
CHANGED
|
@@ -1,27 +1,52 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
/* global $, app, socket */
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
$(document).ready(function () {
|
|
5
|
+
const namespace = 'ezoic-infinite';
|
|
6
|
+
|
|
7
|
+
function load() {
|
|
8
|
+
socket.emit('admin.settings.get', { hash: namespace }, function (err, data) {
|
|
9
|
+
if (err) return;
|
|
10
|
+
data = data || {};
|
|
11
|
+
|
|
12
|
+
const form = $('.ezoic-infinite-settings');
|
|
13
|
+
|
|
14
|
+
form.find('[name="enableBetweenAds"]').prop('checked', data.enableBetweenAds === true || data.enableBetweenAds === 'on');
|
|
15
|
+
form.find('[name="intervalTopics"]').val(parseInt(data.intervalTopics, 10) || 6);
|
|
16
|
+
form.find('[name="placeholderIds"]').val(data.placeholderIds || '');
|
|
17
|
+
|
|
18
|
+
form.find('[name="enableMessageAds"]').prop('checked', data.enableMessageAds === true || data.enableMessageAds === 'on');
|
|
19
|
+
form.find('[name="messageIntervalPosts"]').val(parseInt(data.messageIntervalPosts, 10) || 3);
|
|
20
|
+
form.find('[name="messagePlaceholderIds"]').val(data.messagePlaceholderIds || '');
|
|
21
|
+
|
|
22
|
+
// Do NOT clear groups; server rendered
|
|
23
|
+
const selected = (data.excludedGroups || '').split(',').map(s => s.trim()).filter(Boolean);
|
|
24
|
+
form.find('[name="excludedGroups"] option').each(function () {
|
|
25
|
+
$(this).prop('selected', selected.includes($(this).val()));
|
|
22
26
|
});
|
|
23
27
|
});
|
|
24
|
-
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function save() {
|
|
31
|
+
const form = $('.ezoic-infinite-settings');
|
|
32
|
+
const payload = {
|
|
33
|
+
enableBetweenAds: form.find('[name="enableBetweenAds"]').is(':checked'),
|
|
34
|
+
intervalTopics: parseInt(form.find('[name="intervalTopics"]').val(), 10) || 6,
|
|
35
|
+
placeholderIds: form.find('[name="placeholderIds"]').val() || '',
|
|
36
|
+
|
|
37
|
+
enableMessageAds: form.find('[name="enableMessageAds"]').is(':checked'),
|
|
38
|
+
messageIntervalPosts: parseInt(form.find('[name="messageIntervalPosts"]').val(), 10) || 3,
|
|
39
|
+
messagePlaceholderIds: form.find('[name="messagePlaceholderIds"]').val() || '',
|
|
40
|
+
|
|
41
|
+
excludedGroups: (form.find('[name="excludedGroups"]').val() || []).join(','),
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
socket.emit('admin.settings.set', { hash: namespace, values: payload }, function (err) {
|
|
45
|
+
if (err) { app.alertError(err.message || err); return; }
|
|
46
|
+
app.alertSuccess('Paramètres enregistrés');
|
|
47
|
+
});
|
|
48
|
+
}
|
|
25
49
|
|
|
26
|
-
|
|
50
|
+
$('.ezoic-infinite-save').on('click', save);
|
|
51
|
+
load();
|
|
27
52
|
});
|
package/public/client.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
/* global $, ajaxify, app */
|
|
1
|
+
/* global $, ajaxify, app, config */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
(function () {
|
|
5
5
|
if (window.ezoicInfiniteLoaded) return;
|
|
6
6
|
window.ezoicInfiniteLoaded = true;
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
let settings = null;
|
|
8
|
+
let settings = (window.config && window.config.ezoicInfinite) ? window.config.ezoicInfinite : {};
|
|
10
9
|
let pageKey = null;
|
|
11
10
|
|
|
12
|
-
// State per page
|
|
13
11
|
let usedTopic = new Set();
|
|
14
12
|
let usedCat = new Set();
|
|
15
13
|
let fifoTopic = [];
|
|
@@ -18,6 +16,10 @@
|
|
|
18
16
|
let refreshInFlight = false;
|
|
19
17
|
let refreshQueued = false;
|
|
20
18
|
|
|
19
|
+
function reloadSettingsFromConfig() {
|
|
20
|
+
settings = (window.config && window.config.ezoicInfinite) ? window.config.ezoicInfinite : (settings || {});
|
|
21
|
+
}
|
|
22
|
+
|
|
21
23
|
function parsePool(text) {
|
|
22
24
|
return String(text || '')
|
|
23
25
|
.split(/\r?\n/)
|
|
@@ -29,15 +31,13 @@
|
|
|
29
31
|
|
|
30
32
|
function userExcluded() {
|
|
31
33
|
try {
|
|
32
|
-
const raw =
|
|
34
|
+
const raw = settings && settings.excludedGroups ? String(settings.excludedGroups) : '';
|
|
33
35
|
if (!raw) return false;
|
|
34
36
|
const excluded = raw.split(',').map(s => s.trim()).filter(Boolean);
|
|
35
37
|
if (!excluded.length) return false;
|
|
36
38
|
const myGroups = (app.user && app.user.groups) ? app.user.groups : [];
|
|
37
39
|
return excluded.some(g => myGroups.includes(g));
|
|
38
|
-
} catch (e) {
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
40
|
+
} catch (e) { return false; }
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
function getPageKey() {
|
|
@@ -61,16 +61,12 @@
|
|
|
61
61
|
|
|
62
62
|
function cleanupForNewPage() {
|
|
63
63
|
$('.ezoic-ad').remove();
|
|
64
|
-
usedTopic = new Set();
|
|
65
|
-
|
|
66
|
-
fifoTopic = [];
|
|
67
|
-
fifoCat = [];
|
|
64
|
+
usedTopic = new Set(); usedCat = new Set();
|
|
65
|
+
fifoTopic = []; fifoCat = [];
|
|
68
66
|
}
|
|
69
67
|
|
|
70
68
|
function pickNextId(pool, usedSet) {
|
|
71
|
-
for (const id of pool)
|
|
72
|
-
if (!usedSet.has(id)) return id;
|
|
73
|
-
}
|
|
69
|
+
for (const id of pool) if (!usedSet.has(id)) return id;
|
|
74
70
|
return null;
|
|
75
71
|
}
|
|
76
72
|
|
|
@@ -91,74 +87,49 @@
|
|
|
91
87
|
function ensureUniquePlaceholder(id) {
|
|
92
88
|
const existing = document.getElementById('ezoic-pub-ad-placeholder-' + id);
|
|
93
89
|
if (!existing) return;
|
|
94
|
-
|
|
95
90
|
const wrap = existing.closest('.ezoic-ad');
|
|
96
|
-
if (wrap)
|
|
97
|
-
try { $(wrap).remove(); } catch (e) { wrap.remove(); }
|
|
98
|
-
} else {
|
|
99
|
-
existing.remove();
|
|
100
|
-
}
|
|
91
|
+
if (wrap) $(wrap).remove(); else existing.remove();
|
|
101
92
|
destroyPlaceholder(id);
|
|
102
93
|
}
|
|
103
94
|
|
|
104
95
|
function callEzoicSingle(id) {
|
|
105
96
|
if (!id) return;
|
|
106
|
-
|
|
107
97
|
const now = Date.now();
|
|
108
98
|
window.__ezoicLastSingle = window.__ezoicLastSingle || {};
|
|
109
|
-
|
|
110
|
-
if (now - last < 1200) return;
|
|
99
|
+
if (now - (window.__ezoicLastSingle[id] || 0) < 1200) return;
|
|
111
100
|
window.__ezoicLastSingle[id] = now;
|
|
112
101
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
102
|
+
window.ezstandalone = window.ezstandalone || {};
|
|
103
|
+
window.ezstandalone.cmd = window.ezstandalone.cmd || [];
|
|
104
|
+
const run = function () {
|
|
105
|
+
if (typeof window.ezstandalone.showAds === 'function') {
|
|
106
|
+
window.ezstandalone.showAds(id);
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
return false;
|
|
110
|
+
};
|
|
111
|
+
window.ezstandalone.cmd.push(function () { try { run(); } catch (e) {} });
|
|
116
112
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return true;
|
|
122
|
-
}
|
|
123
|
-
} catch (e) {}
|
|
124
|
-
return false;
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
window.ezstandalone.cmd.push(function () { run(); });
|
|
128
|
-
|
|
129
|
-
let tries = 0;
|
|
130
|
-
const tick = function () {
|
|
131
|
-
tries++;
|
|
132
|
-
if (run() || tries >= 8) return;
|
|
133
|
-
setTimeout(tick, 800);
|
|
134
|
-
};
|
|
113
|
+
let tries = 0;
|
|
114
|
+
(function tick() {
|
|
115
|
+
tries++;
|
|
116
|
+
try { if (run() || tries >= 8) return; } catch (e) {}
|
|
135
117
|
setTimeout(tick, 800);
|
|
136
|
-
}
|
|
118
|
+
})();
|
|
137
119
|
}
|
|
138
120
|
|
|
139
121
|
function setupAutoHeightOnce() {
|
|
140
122
|
if (window.__ezoicAutoHeight) return;
|
|
141
123
|
window.__ezoicAutoHeight = true;
|
|
142
|
-
|
|
143
|
-
const mark = function (wrap) {
|
|
144
|
-
if (!wrap) return;
|
|
145
|
-
const ph = wrap.querySelector('[id^="ezoic-pub-ad-placeholder-"]');
|
|
146
|
-
if (ph && ph.children && ph.children.length) {
|
|
147
|
-
wrap.classList.add('ezoic-filled');
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
|
|
151
124
|
const scan = function () {
|
|
152
|
-
document.querySelectorAll('.ezoic-ad').forEach(
|
|
125
|
+
document.querySelectorAll('.ezoic-ad').forEach((wrap) => {
|
|
126
|
+
const ph = wrap.querySelector('[id^="ezoic-pub-ad-placeholder-"]');
|
|
127
|
+
if (ph && ph.children && ph.children.length) wrap.classList.add('ezoic-filled');
|
|
128
|
+
});
|
|
153
129
|
};
|
|
154
|
-
|
|
155
130
|
scan();
|
|
156
131
|
setInterval(scan, 1000);
|
|
157
|
-
|
|
158
|
-
try {
|
|
159
|
-
const mo = new MutationObserver(scan);
|
|
160
|
-
mo.observe(document.body, { childList: true, subtree: true });
|
|
161
|
-
} catch (e) {}
|
|
132
|
+
try { new MutationObserver(scan).observe(document.body, { childList: true, subtree: true }); } catch (e) {}
|
|
162
133
|
}
|
|
163
134
|
|
|
164
135
|
function insertAfter($target, id, cls, afterVal) {
|
|
@@ -169,52 +140,27 @@
|
|
|
169
140
|
'</div>'
|
|
170
141
|
);
|
|
171
142
|
$target.after(wrap);
|
|
172
|
-
return wrap;
|
|
173
143
|
}
|
|
174
144
|
|
|
175
145
|
function recycleTopic($posts) {
|
|
176
|
-
fifoTopic.sort((a,
|
|
146
|
+
fifoTopic.sort((a,b)=>a.afterNo-b.afterNo);
|
|
177
147
|
while (fifoTopic.length) {
|
|
178
|
-
const old
|
|
179
|
-
const
|
|
180
|
-
const $el = $(sel);
|
|
148
|
+
const old=fifoTopic.shift();
|
|
149
|
+
const $el=$('.ezoic-ad-topic[data-ezoic-id="'+old.id+'"][data-ezoic-after="'+old.afterNo+'"]');
|
|
181
150
|
if (!$el.length) continue;
|
|
182
|
-
|
|
183
|
-
try {
|
|
184
|
-
const $last = $posts.last();
|
|
185
|
-
if ($last.length && $el.prev().is($last)) {
|
|
186
|
-
fifoTopic.push(old);
|
|
187
|
-
return null;
|
|
188
|
-
}
|
|
189
|
-
} catch (e) {}
|
|
190
|
-
|
|
191
|
-
$el.remove();
|
|
192
|
-
usedTopic.delete(old.id);
|
|
193
|
-
destroyPlaceholder(old.id);
|
|
151
|
+
$el.remove(); usedTopic.delete(old.id); destroyPlaceholder(old.id);
|
|
194
152
|
return old.id;
|
|
195
153
|
}
|
|
196
154
|
return null;
|
|
197
155
|
}
|
|
198
156
|
|
|
199
157
|
function recycleCat($items) {
|
|
200
|
-
fifoCat.sort((a,
|
|
158
|
+
fifoCat.sort((a,b)=>a.afterPos-b.afterPos);
|
|
201
159
|
while (fifoCat.length) {
|
|
202
|
-
const old
|
|
203
|
-
const
|
|
204
|
-
const $el = $(sel);
|
|
160
|
+
const old=fifoCat.shift();
|
|
161
|
+
const $el=$('.ezoic-ad-between[data-ezoic-id="'+old.id+'"][data-ezoic-after="'+old.afterPos+'"]');
|
|
205
162
|
if (!$el.length) continue;
|
|
206
|
-
|
|
207
|
-
try {
|
|
208
|
-
const $last = $items.last();
|
|
209
|
-
if ($last.length && $el.prev().is($last)) {
|
|
210
|
-
fifoCat.push(old);
|
|
211
|
-
return null;
|
|
212
|
-
}
|
|
213
|
-
} catch (e) {}
|
|
214
|
-
|
|
215
|
-
$el.remove();
|
|
216
|
-
usedCat.delete(old.id);
|
|
217
|
-
destroyPlaceholder(old.id);
|
|
163
|
+
$el.remove(); usedCat.delete(old.id); destroyPlaceholder(old.id);
|
|
218
164
|
return old.id;
|
|
219
165
|
}
|
|
220
166
|
return null;
|
|
@@ -222,125 +168,82 @@
|
|
|
222
168
|
|
|
223
169
|
function injectInTopic() {
|
|
224
170
|
if (!(settings && (settings.enableMessageAds === true || settings.enableMessageAds === 'on'))) return;
|
|
225
|
-
|
|
226
|
-
const interval = parseInt(settings.messageIntervalPosts, 10) || 3;
|
|
171
|
+
const interval = parseInt(settings.messageIntervalPosts,10) || 3;
|
|
227
172
|
const pool = parsePool(settings.messagePlaceholderIds);
|
|
228
173
|
if (!pool.length) return;
|
|
229
174
|
|
|
230
175
|
const $posts = $('[component="post"][data-pid]');
|
|
231
176
|
if (!$posts.length) return;
|
|
232
177
|
|
|
233
|
-
$posts.each(function
|
|
234
|
-
const
|
|
235
|
-
if (
|
|
236
|
-
if (idx === $posts.length
|
|
178
|
+
$posts.each(function(idx){
|
|
179
|
+
const no=idx+1;
|
|
180
|
+
if (no % interval !== 0) return;
|
|
181
|
+
if (idx === $posts.length-1) return;
|
|
237
182
|
|
|
238
|
-
const $post
|
|
239
|
-
|
|
240
|
-
if (existing.length) return;
|
|
183
|
+
const $post=$(this);
|
|
184
|
+
if ($post.next('.ezoic-ad-topic').length) return;
|
|
241
185
|
|
|
242
|
-
let id
|
|
243
|
-
if (!id) {
|
|
244
|
-
id = recycleTopic($posts);
|
|
245
|
-
if (!id) return;
|
|
246
|
-
}
|
|
186
|
+
let id=pickNextId(pool, usedTopic);
|
|
187
|
+
if (!id) { id=recycleTopic($posts); if (!id) return; }
|
|
247
188
|
|
|
248
|
-
usedTopic.add(id);
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
insertAfter($post, id, 'ezoic-ad-topic', postNo);
|
|
189
|
+
usedTopic.add(id); fifoTopic.push({id, afterNo:no});
|
|
190
|
+
insertAfter($post, id, 'ezoic-ad-topic', no);
|
|
252
191
|
callEzoicSingle(id);
|
|
253
192
|
});
|
|
254
193
|
}
|
|
255
194
|
|
|
256
195
|
function injectInCategory() {
|
|
257
196
|
if (!(settings && (settings.enableBetweenAds === true || settings.enableBetweenAds === 'on'))) return;
|
|
258
|
-
|
|
259
|
-
const interval = parseInt(settings.intervalTopics, 10) || 6;
|
|
197
|
+
const interval = parseInt(settings.intervalTopics,10) || 6;
|
|
260
198
|
const pool = parsePool(settings.placeholderIds);
|
|
261
199
|
if (!pool.length) return;
|
|
262
200
|
|
|
263
201
|
const $items = $('li[component="category/topic"]');
|
|
264
202
|
if (!$items.length) return;
|
|
265
203
|
|
|
266
|
-
$items.each(function
|
|
267
|
-
const pos
|
|
204
|
+
$items.each(function(idx){
|
|
205
|
+
const pos=idx+1;
|
|
268
206
|
if (pos % interval !== 0) return;
|
|
269
|
-
if (idx === $items.length
|
|
207
|
+
if (idx === $items.length-1) return;
|
|
270
208
|
|
|
271
|
-
const $li
|
|
272
|
-
|
|
273
|
-
if (existing.length) return;
|
|
209
|
+
const $li=$(this);
|
|
210
|
+
if ($li.next('.ezoic-ad-between').length) return;
|
|
274
211
|
|
|
275
|
-
let id
|
|
276
|
-
if (!id) {
|
|
277
|
-
id = recycleCat($items);
|
|
278
|
-
if (!id) return;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
usedCat.add(id);
|
|
282
|
-
fifoCat.push({ id, afterPos: pos });
|
|
212
|
+
let id=pickNextId(pool, usedCat);
|
|
213
|
+
if (!id) { id=recycleCat($items); if (!id) return; }
|
|
283
214
|
|
|
215
|
+
usedCat.add(id); fifoCat.push({id, afterPos:pos});
|
|
284
216
|
insertAfter($li, id, 'ezoic-ad-between', pos);
|
|
285
217
|
callEzoicSingle(id);
|
|
286
218
|
});
|
|
287
219
|
}
|
|
288
220
|
|
|
289
221
|
function refresh() {
|
|
222
|
+
reloadSettingsFromConfig();
|
|
290
223
|
if (!settings) return;
|
|
291
224
|
if (userExcluded()) return;
|
|
292
225
|
|
|
293
226
|
if (refreshInFlight) { refreshQueued = true; return; }
|
|
294
227
|
refreshInFlight = true;
|
|
295
228
|
try {
|
|
296
|
-
const key
|
|
297
|
-
if (pageKey !== key) {
|
|
298
|
-
pageKey = key;
|
|
299
|
-
cleanupForNewPage();
|
|
300
|
-
}
|
|
301
|
-
|
|
229
|
+
const key=getPageKey();
|
|
230
|
+
if (pageKey !== key) { pageKey=key; cleanupForNewPage(); }
|
|
302
231
|
setupAutoHeightOnce();
|
|
303
|
-
|
|
304
232
|
if (isTopicPage()) injectInTopic();
|
|
305
233
|
else if (isCategoryTopicList()) injectInCategory();
|
|
306
234
|
} finally {
|
|
307
|
-
refreshInFlight
|
|
308
|
-
if (refreshQueued) { refreshQueued
|
|
235
|
+
refreshInFlight=false;
|
|
236
|
+
if (refreshQueued) { refreshQueued=false; setTimeout(refresh, 50); }
|
|
309
237
|
}
|
|
310
238
|
}
|
|
311
239
|
|
|
312
|
-
function
|
|
313
|
-
// Use public settings endpoint to avoid any admin socket calls on frontend
|
|
314
|
-
const base = (window.config && window.config.relative_path) ? window.config.relative_path : '';
|
|
315
|
-
$.get(base + '/api/admin/settings/' + SETTINGS_NS).done(function (data) {
|
|
316
|
-
// If access denied, settings stays null; plugin won't inject
|
|
317
|
-
settings = (data && data.settings) ? data.settings : data;
|
|
318
|
-
cb && cb();
|
|
319
|
-
}).fail(function () {
|
|
320
|
-
// Fallback: try window.ajaxify data if available
|
|
321
|
-
settings = settings || {};
|
|
322
|
-
cb && cb();
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
function boot() {
|
|
327
|
-
loadSettings(function () {
|
|
328
|
-
refresh();
|
|
329
|
-
setTimeout(refresh, 1200);
|
|
330
|
-
});
|
|
331
|
-
}
|
|
240
|
+
function boot() { refresh(); setTimeout(refresh, 1200); }
|
|
332
241
|
|
|
333
242
|
$(document).ready(boot);
|
|
334
243
|
$(window).on('action:ajaxify.end', boot);
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
refresh();
|
|
338
|
-
setTimeout(refresh, 600);
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
$(window).on('action:ajaxify.start', function () {
|
|
342
|
-
pageKey = null;
|
|
343
|
-
cleanupForNewPage();
|
|
244
|
+
$(window).on('action:posts.loaded action:topics.loaded action:topic.loaded action:category.loaded', function(){
|
|
245
|
+
refresh(); setTimeout(refresh, 600);
|
|
344
246
|
});
|
|
247
|
+
$(window).on('action:ajaxify.start', function(){ pageKey=null; cleanupForNewPage(); });
|
|
345
248
|
|
|
346
249
|
})();
|
package/public/style.css
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* Le conteneur est caché tant qu'Ezoic n'a pas injecté de contenu */
|
|
2
1
|
.ezoic-ad{min-height:0 !important;height:auto !important;padding:0 !important;margin:0.5rem 0;}
|
|
3
2
|
.ezoic-ad:not(.ezoic-filled){display:none !important;}
|
|
4
3
|
.ezoic-ad .ezoic-ad-inner{padding:0;margin:0;}
|
|
5
|
-
.ezoic-ad .ezoic-ad-inner > div{margin:0;padding:0;}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
<div class="acp-page-container">
|
|
2
2
|
<h1 class="mb-3">Ezoic - Publicités Infinite Scroll</h1>
|
|
3
3
|
|
|
4
|
-
<
|
|
5
|
-
Format placeholder : <code><div id="ezoic-pub-ad-placeholder-XXX"></div></code>
|
|
6
|
-
</div>
|
|
7
|
-
|
|
8
|
-
<form class="ezoic-infinite-settings" role="form">
|
|
4
|
+
<form role="form" class="ezoic-infinite-settings">
|
|
9
5
|
<div class="mb-3">
|
|
10
6
|
<label class="form-label">Groupes exclus (pas de pubs pour ces groupes)</label>
|
|
11
7
|
<select multiple class="form-select" name="excludedGroups">
|
|
@@ -13,53 +9,41 @@
|
|
|
13
9
|
<option value="{groups.name}">{groups.name}</option>
|
|
14
10
|
<!-- END groups -->
|
|
15
11
|
</select>
|
|
16
|
-
<div class="form-text">
|
|
12
|
+
<div class="form-text">Liste triée par ordre alphabétique.</div>
|
|
17
13
|
</div>
|
|
18
14
|
|
|
19
15
|
<hr/>
|
|
20
16
|
|
|
21
17
|
<h3>Entre les topics dans une catégorie (liste des sujets)</h3>
|
|
22
|
-
|
|
23
18
|
<div class="form-check form-switch mb-2">
|
|
24
19
|
<input class="form-check-input" type="checkbox" name="enableBetweenAds">
|
|
25
|
-
<label class="form-check-label">Activer
|
|
20
|
+
<label class="form-check-label">Activer</label>
|
|
26
21
|
</div>
|
|
27
|
-
|
|
28
22
|
<div class="mb-3">
|
|
29
|
-
<label class="form-label">Intervalle (
|
|
23
|
+
<label class="form-label">Intervalle (après chaque N topics)</label>
|
|
30
24
|
<input type="number" class="form-control" name="intervalTopics" min="1" step="1">
|
|
31
25
|
</div>
|
|
32
|
-
|
|
33
26
|
<div class="mb-3">
|
|
34
|
-
<label class="form-label">Pool d'IDs
|
|
35
|
-
<textarea class="form-control" name="placeholderIds" rows="
|
|
27
|
+
<label class="form-label">Pool d'IDs placeholder (un par ligne)</label>
|
|
28
|
+
<textarea class="form-control" name="placeholderIds" rows="5"></textarea>
|
|
36
29
|
</div>
|
|
37
30
|
|
|
38
31
|
<hr/>
|
|
39
32
|
|
|
40
33
|
<h3>Dans les topics (entre les messages)</h3>
|
|
41
|
-
|
|
42
34
|
<div class="form-check form-switch mb-2">
|
|
43
35
|
<input class="form-check-input" type="checkbox" name="enableMessageAds">
|
|
44
|
-
<label class="form-check-label">Activer
|
|
36
|
+
<label class="form-check-label">Activer</label>
|
|
45
37
|
</div>
|
|
46
|
-
|
|
47
38
|
<div class="mb-3">
|
|
48
|
-
<label class="form-label">Intervalle (
|
|
39
|
+
<label class="form-label">Intervalle (après chaque N messages)</label>
|
|
49
40
|
<input type="number" class="form-control" name="messageIntervalPosts" min="1" step="1">
|
|
50
41
|
</div>
|
|
51
|
-
|
|
52
42
|
<div class="mb-3">
|
|
53
|
-
<label class="form-label">Pool d'IDs
|
|
54
|
-
<textarea class="form-control" name="messagePlaceholderIds" rows="
|
|
43
|
+
<label class="form-label">Pool d'IDs placeholder messages (un par ligne)</label>
|
|
44
|
+
<textarea class="form-control" name="messagePlaceholderIds" rows="5"></textarea>
|
|
55
45
|
</div>
|
|
56
46
|
|
|
57
|
-
|
|
47
|
+
<button type="button" class="btn btn-primary ezoic-infinite-save">Enregistrer</button>
|
|
58
48
|
</form>
|
|
59
49
|
</div>
|
|
60
|
-
|
|
61
|
-
<script>
|
|
62
|
-
require(['admin/plugins/ezoic-infinite'], function (acp) {
|
|
63
|
-
acp.init();
|
|
64
|
-
});
|
|
65
|
-
</script>
|
package/README.md
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
nodebb-plugin-ezoic-infinite v1.0.0
|
|
2
|
-
==================================
|
|
3
|
-
|
|
4
|
-
ACP (NodeBB 4.x official pattern):
|
|
5
|
-
- routeHelpers.setupAdminPageRoute
|
|
6
|
-
- Settings framework (Settings.load/save)
|
|
7
|
-
- server-rendered groups (no dynamic fetch)
|
|
8
|
-
|
|
9
|
-
Frontend:
|
|
10
|
-
- inject ads between topics list + between posts in topic
|
|
11
|
-
- showAds called one placeholder id at a time (no batch)
|
|
12
|
-
- FIFO recycling pool on same page
|