nodebb-plugin-ezoic-infinite 1.0.0 → 1.0.2
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 +13 -18
- package/package.json +2 -9
- package/plugin.json +8 -8
- package/public/admin.js +29 -21
- package/public/client.js +3 -343
- package/public/templates/admin/plugins/ezoic-infinite.tpl +17 -59
- package/README.md +0 -12
- package/public/style.css +0 -5
package/library.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
+
|
|
1
2
|
'use strict';
|
|
2
3
|
|
|
3
4
|
const meta = require.main.require('./src/meta');
|
|
4
5
|
const groups = require.main.require('./src/groups');
|
|
5
|
-
const routeHelpers = require.main.require('./src/routes/helpers');
|
|
6
6
|
|
|
7
7
|
const Plugin = {};
|
|
8
8
|
|
|
9
|
-
Plugin.init = async
|
|
10
|
-
|
|
11
|
-
routeHelpers.setupAdminPageRoute(router, '/admin/plugins/ezoic-infinite', middleware, [], renderAdmin);
|
|
9
|
+
Plugin.init = async ({ router, middleware }) => {
|
|
10
|
+
router.get('/admin/plugins/ezoic-infinite', middleware.admin.buildHeader, renderAdmin);
|
|
12
11
|
router.get('/api/admin/plugins/ezoic-infinite', renderAdmin);
|
|
13
12
|
};
|
|
14
13
|
|
|
@@ -16,33 +15,24 @@ async function renderAdmin(req, res) {
|
|
|
16
15
|
const settings = await meta.settings.get('ezoic-infinite');
|
|
17
16
|
|
|
18
17
|
let groupNames = [];
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
groupNames = await groups.getGroupsFromSet(set, 0, -1);
|
|
23
|
-
if (Array.isArray(groupNames) && groupNames.length) break;
|
|
24
|
-
} catch (e) {}
|
|
25
|
-
}
|
|
18
|
+
try {
|
|
19
|
+
groupNames = await groups.getGroupsFromSet('groups:createtime', 0, -1);
|
|
20
|
+
} catch (e) {}
|
|
26
21
|
|
|
27
22
|
let groupList = [];
|
|
28
23
|
try {
|
|
29
24
|
groupList = await groups.getGroupsData(groupNames);
|
|
30
25
|
} catch (e) {
|
|
31
|
-
groupList =
|
|
26
|
+
groupList = groupNames.map(name => ({ name }));
|
|
32
27
|
}
|
|
33
28
|
|
|
34
|
-
groupList = (groupList || [])
|
|
35
|
-
.filter(g => g && g.name && typeof g.name === 'string')
|
|
36
|
-
.sort((a, b) => (a.name || '').localeCompare(b.name || '', 'fr', { sensitivity: 'base' }));
|
|
37
|
-
|
|
38
29
|
res.render('admin/plugins/ezoic-infinite', {
|
|
39
|
-
title: 'Ezoic - Publicités Infinite Scroll',
|
|
40
30
|
settings,
|
|
41
31
|
groups: groupList,
|
|
42
32
|
});
|
|
43
33
|
}
|
|
44
34
|
|
|
45
|
-
Plugin.addAdminNavigation = async
|
|
35
|
+
Plugin.addAdminNavigation = async (header) => {
|
|
46
36
|
header.plugins = header.plugins || [];
|
|
47
37
|
header.plugins.push({
|
|
48
38
|
route: '/plugins/ezoic-infinite',
|
|
@@ -52,4 +42,9 @@ Plugin.addAdminNavigation = async function (header) {
|
|
|
52
42
|
return header;
|
|
53
43
|
};
|
|
54
44
|
|
|
45
|
+
Plugin.addConfig = async (config) => {
|
|
46
|
+
config.ezoicInfinite = await meta.settings.get('ezoic-infinite');
|
|
47
|
+
return config;
|
|
48
|
+
};
|
|
49
|
+
|
|
55
50
|
module.exports = Plugin;
|
package/package.json
CHANGED
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nodebb-plugin-ezoic-infinite",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Ezoic Infinite (rollback to 0.8.2 behaviour)",
|
|
5
5
|
"main": "library.js",
|
|
6
6
|
"license": "MIT",
|
|
7
|
-
"keywords": [
|
|
8
|
-
"nodebb",
|
|
9
|
-
"nodebb-plugin",
|
|
10
|
-
"ezoic",
|
|
11
|
-
"ads",
|
|
12
|
-
"infinite-scroll"
|
|
13
|
-
],
|
|
14
7
|
"nbbpm": {
|
|
15
8
|
"compatibility": "^4.0.0"
|
|
16
9
|
}
|
package/plugin.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "nodebb-plugin-ezoic-infinite",
|
|
3
3
|
"name": "Ezoic Infinite",
|
|
4
|
-
"description": "Ezoic ads injection with infinite scroll (topics list + topic posts)",
|
|
5
4
|
"library": "./library.js",
|
|
6
5
|
"hooks": [
|
|
7
6
|
{
|
|
@@ -11,19 +10,20 @@
|
|
|
11
10
|
{
|
|
12
11
|
"hook": "filter:admin.header.build",
|
|
13
12
|
"method": "addAdminNavigation"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"hook": "filter:config.get",
|
|
16
|
+
"method": "addConfig"
|
|
14
17
|
}
|
|
15
18
|
],
|
|
16
19
|
"staticDirs": {
|
|
17
20
|
"public": "public"
|
|
18
21
|
},
|
|
22
|
+
"acpScripts": [
|
|
23
|
+
"public/admin.js"
|
|
24
|
+
],
|
|
19
25
|
"scripts": [
|
|
20
26
|
"public/client.js"
|
|
21
27
|
],
|
|
22
|
-
"
|
|
23
|
-
"public/style.css"
|
|
24
|
-
],
|
|
25
|
-
"templates": "public/templates",
|
|
26
|
-
"modules": {
|
|
27
|
-
"../admin/plugins/ezoic-infinite.js": "public/admin.js"
|
|
28
|
-
}
|
|
28
|
+
"templates": "public/templates"
|
|
29
29
|
}
|
package/public/admin.js
CHANGED
|
@@ -1,27 +1,35 @@
|
|
|
1
|
-
define('admin/plugins/ezoic-infinite', ['settings', 'alerts'], function (Settings, alerts) {
|
|
2
|
-
'use strict';
|
|
3
1
|
|
|
4
|
-
|
|
2
|
+
/* global $, socket, app */
|
|
3
|
+
$(function () {
|
|
4
|
+
const ns = 'ezoic-infinite';
|
|
5
|
+
const form = $('.ezoic-infinite-settings');
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
socket.emit('admin.settings.get', { hash: ns }, (err, data) => {
|
|
8
|
+
if (!data) return;
|
|
9
|
+
Object.keys(data).forEach(k => {
|
|
10
|
+
const el = form.find('[name="' + k + '"]');
|
|
11
|
+
if (!el.length) return;
|
|
12
|
+
if (el.attr('type') === 'checkbox') el.prop('checked', data[k]);
|
|
13
|
+
else el.val(data[k]);
|
|
14
|
+
});
|
|
8
15
|
|
|
9
|
-
|
|
10
|
-
|
|
16
|
+
if (data.excludedGroups) {
|
|
17
|
+
data.excludedGroups.split(',').forEach(g =>
|
|
18
|
+
form.find('option[value="' + g + '"]').prop('selected', true)
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
11
22
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
alerts.error(err.message || err);
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
alerts.success('Paramètres enregistrés');
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
};
|
|
23
|
+
$('.ezoic-save').on('click', () => {
|
|
24
|
+
const values = {};
|
|
25
|
+
form.serializeArray().forEach(o => values[o.name] = o.value);
|
|
26
|
+
values.enableBetweenAds = form.find('[name=enableBetweenAds]').is(':checked');
|
|
27
|
+
values.enableMessageAds = form.find('[name=enableMessageAds]').is(':checked');
|
|
28
|
+
values.excludedGroups = (form.find('[name=excludedGroups]').val() || []).join(',');
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
socket.emit('admin.settings.set', { hash: ns, values }, err => {
|
|
31
|
+
if (err) app.alertError(err.message);
|
|
32
|
+
else app.alertSuccess('Enregistré');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
27
35
|
});
|
package/public/client.js
CHANGED
|
@@ -1,346 +1,6 @@
|
|
|
1
|
-
/* global $, ajaxify, app */
|
|
2
|
-
'use strict';
|
|
3
1
|
|
|
2
|
+
/* global config */
|
|
4
3
|
(function () {
|
|
5
|
-
if (
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const SETTINGS_NS = 'ezoic-infinite';
|
|
9
|
-
let settings = null;
|
|
10
|
-
let pageKey = null;
|
|
11
|
-
|
|
12
|
-
// State per page
|
|
13
|
-
let usedTopic = new Set();
|
|
14
|
-
let usedCat = new Set();
|
|
15
|
-
let fifoTopic = [];
|
|
16
|
-
let fifoCat = [];
|
|
17
|
-
|
|
18
|
-
let refreshInFlight = false;
|
|
19
|
-
let refreshQueued = false;
|
|
20
|
-
|
|
21
|
-
function parsePool(text) {
|
|
22
|
-
return String(text || '')
|
|
23
|
-
.split(/\r?\n/)
|
|
24
|
-
.map(s => s.trim())
|
|
25
|
-
.filter(Boolean)
|
|
26
|
-
.map(s => parseInt(s, 10))
|
|
27
|
-
.filter(n => Number.isFinite(n) && n > 0);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function userExcluded() {
|
|
31
|
-
try {
|
|
32
|
-
const raw = (settings && settings.excludedGroups) ? String(settings.excludedGroups) : '';
|
|
33
|
-
if (!raw) return false;
|
|
34
|
-
const excluded = raw.split(',').map(s => s.trim()).filter(Boolean);
|
|
35
|
-
if (!excluded.length) return false;
|
|
36
|
-
const myGroups = (app.user && app.user.groups) ? app.user.groups : [];
|
|
37
|
-
return excluded.some(g => myGroups.includes(g));
|
|
38
|
-
} catch (e) {
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function getPageKey() {
|
|
44
|
-
try {
|
|
45
|
-
if (ajaxify && ajaxify.data) {
|
|
46
|
-
if (ajaxify.data.tid) return 'topic:' + ajaxify.data.tid;
|
|
47
|
-
if (ajaxify.data.cid) return 'cid:' + ajaxify.data.cid + ':' + window.location.pathname;
|
|
48
|
-
}
|
|
49
|
-
} catch (e) {}
|
|
50
|
-
return window.location.pathname;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function isTopicPage() {
|
|
54
|
-
try { if (ajaxify && ajaxify.data && ajaxify.data.tid) return true; } catch (e) {}
|
|
55
|
-
return /^\/topic\//.test(window.location.pathname);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function isCategoryTopicList() {
|
|
59
|
-
return $('li[component="category/topic"]').length > 0 && !isTopicPage();
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function cleanupForNewPage() {
|
|
63
|
-
$('.ezoic-ad').remove();
|
|
64
|
-
usedTopic = new Set();
|
|
65
|
-
usedCat = new Set();
|
|
66
|
-
fifoTopic = [];
|
|
67
|
-
fifoCat = [];
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function pickNextId(pool, usedSet) {
|
|
71
|
-
for (const id of pool) {
|
|
72
|
-
if (!usedSet.has(id)) return id;
|
|
73
|
-
}
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function destroyPlaceholder(id) {
|
|
78
|
-
try {
|
|
79
|
-
window.ezstandalone = window.ezstandalone || {};
|
|
80
|
-
window.ezstandalone.cmd = window.ezstandalone.cmd || [];
|
|
81
|
-
if (typeof window.ezstandalone.destroyPlaceholders === 'function') {
|
|
82
|
-
window.ezstandalone.destroyPlaceholders(id);
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
window.ezstandalone.cmd.push(function () {
|
|
86
|
-
try { window.ezstandalone.destroyPlaceholders(id); } catch (e) {}
|
|
87
|
-
});
|
|
88
|
-
} catch (e) {}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function ensureUniquePlaceholder(id) {
|
|
92
|
-
const existing = document.getElementById('ezoic-pub-ad-placeholder-' + id);
|
|
93
|
-
if (!existing) return;
|
|
94
|
-
|
|
95
|
-
const wrap = existing.closest('.ezoic-ad');
|
|
96
|
-
if (wrap) {
|
|
97
|
-
try { $(wrap).remove(); } catch (e) { wrap.remove(); }
|
|
98
|
-
} else {
|
|
99
|
-
existing.remove();
|
|
100
|
-
}
|
|
101
|
-
destroyPlaceholder(id);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function callEzoicSingle(id) {
|
|
105
|
-
if (!id) return;
|
|
106
|
-
|
|
107
|
-
const now = Date.now();
|
|
108
|
-
window.__ezoicLastSingle = window.__ezoicLastSingle || {};
|
|
109
|
-
const last = window.__ezoicLastSingle[id] || 0;
|
|
110
|
-
if (now - last < 1200) return;
|
|
111
|
-
window.__ezoicLastSingle[id] = now;
|
|
112
|
-
|
|
113
|
-
try {
|
|
114
|
-
window.ezstandalone = window.ezstandalone || {};
|
|
115
|
-
window.ezstandalone.cmd = window.ezstandalone.cmd || [];
|
|
116
|
-
|
|
117
|
-
const run = function () {
|
|
118
|
-
try {
|
|
119
|
-
if (typeof window.ezstandalone.showAds === 'function') {
|
|
120
|
-
window.ezstandalone.showAds(id);
|
|
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
|
-
};
|
|
135
|
-
setTimeout(tick, 800);
|
|
136
|
-
} catch (e) {}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function setupAutoHeightOnce() {
|
|
140
|
-
if (window.__ezoicAutoHeight) return;
|
|
141
|
-
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
|
-
const scan = function () {
|
|
152
|
-
document.querySelectorAll('.ezoic-ad').forEach(mark);
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
scan();
|
|
156
|
-
setInterval(scan, 1000);
|
|
157
|
-
|
|
158
|
-
try {
|
|
159
|
-
const mo = new MutationObserver(scan);
|
|
160
|
-
mo.observe(document.body, { childList: true, subtree: true });
|
|
161
|
-
} catch (e) {}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
function insertAfter($target, id, cls, afterVal) {
|
|
165
|
-
ensureUniquePlaceholder(id);
|
|
166
|
-
const wrap = $(
|
|
167
|
-
'<div class="ezoic-ad ' + cls + '" data-ezoic-id="' + id + '" data-ezoic-after="' + afterVal + '">' +
|
|
168
|
-
'<div class="ezoic-ad-inner"><div id="ezoic-pub-ad-placeholder-' + id + '"></div></div>' +
|
|
169
|
-
'</div>'
|
|
170
|
-
);
|
|
171
|
-
$target.after(wrap);
|
|
172
|
-
return wrap;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
function recycleTopic($posts) {
|
|
176
|
-
fifoTopic.sort((a, b) => a.afterNo - b.afterNo);
|
|
177
|
-
while (fifoTopic.length) {
|
|
178
|
-
const old = fifoTopic.shift();
|
|
179
|
-
const sel = '.ezoic-ad-topic[data-ezoic-id="' + old.id + '"][data-ezoic-after="' + old.afterNo + '"]';
|
|
180
|
-
const $el = $(sel);
|
|
181
|
-
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);
|
|
194
|
-
return old.id;
|
|
195
|
-
}
|
|
196
|
-
return null;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function recycleCat($items) {
|
|
200
|
-
fifoCat.sort((a, b) => a.afterPos - b.afterPos);
|
|
201
|
-
while (fifoCat.length) {
|
|
202
|
-
const old = fifoCat.shift();
|
|
203
|
-
const sel = '.ezoic-ad-between[data-ezoic-id="' + old.id + '"][data-ezoic-after="' + old.afterPos + '"]';
|
|
204
|
-
const $el = $(sel);
|
|
205
|
-
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);
|
|
218
|
-
return old.id;
|
|
219
|
-
}
|
|
220
|
-
return null;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
function injectInTopic() {
|
|
224
|
-
if (!(settings && (settings.enableMessageAds === true || settings.enableMessageAds === 'on'))) return;
|
|
225
|
-
|
|
226
|
-
const interval = parseInt(settings.messageIntervalPosts, 10) || 3;
|
|
227
|
-
const pool = parsePool(settings.messagePlaceholderIds);
|
|
228
|
-
if (!pool.length) return;
|
|
229
|
-
|
|
230
|
-
const $posts = $('[component="post"][data-pid]');
|
|
231
|
-
if (!$posts.length) return;
|
|
232
|
-
|
|
233
|
-
$posts.each(function (idx) {
|
|
234
|
-
const postNo = idx + 1;
|
|
235
|
-
if (postNo % interval !== 0) return;
|
|
236
|
-
if (idx === $posts.length - 1) return;
|
|
237
|
-
|
|
238
|
-
const $post = $(this);
|
|
239
|
-
const existing = $post.next('.ezoic-ad-topic');
|
|
240
|
-
if (existing.length) return;
|
|
241
|
-
|
|
242
|
-
let id = pickNextId(pool, usedTopic);
|
|
243
|
-
if (!id) {
|
|
244
|
-
id = recycleTopic($posts);
|
|
245
|
-
if (!id) return;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
usedTopic.add(id);
|
|
249
|
-
fifoTopic.push({ id, afterNo: postNo });
|
|
250
|
-
|
|
251
|
-
insertAfter($post, id, 'ezoic-ad-topic', postNo);
|
|
252
|
-
callEzoicSingle(id);
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
function injectInCategory() {
|
|
257
|
-
if (!(settings && (settings.enableBetweenAds === true || settings.enableBetweenAds === 'on'))) return;
|
|
258
|
-
|
|
259
|
-
const interval = parseInt(settings.intervalTopics, 10) || 6;
|
|
260
|
-
const pool = parsePool(settings.placeholderIds);
|
|
261
|
-
if (!pool.length) return;
|
|
262
|
-
|
|
263
|
-
const $items = $('li[component="category/topic"]');
|
|
264
|
-
if (!$items.length) return;
|
|
265
|
-
|
|
266
|
-
$items.each(function (idx) {
|
|
267
|
-
const pos = idx + 1;
|
|
268
|
-
if (pos % interval !== 0) return;
|
|
269
|
-
if (idx === $items.length - 1) return;
|
|
270
|
-
|
|
271
|
-
const $li = $(this);
|
|
272
|
-
const existing = $li.next('.ezoic-ad-between');
|
|
273
|
-
if (existing.length) return;
|
|
274
|
-
|
|
275
|
-
let id = pickNextId(pool, usedCat);
|
|
276
|
-
if (!id) {
|
|
277
|
-
id = recycleCat($items);
|
|
278
|
-
if (!id) return;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
usedCat.add(id);
|
|
282
|
-
fifoCat.push({ id, afterPos: pos });
|
|
283
|
-
|
|
284
|
-
insertAfter($li, id, 'ezoic-ad-between', pos);
|
|
285
|
-
callEzoicSingle(id);
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
function refresh() {
|
|
290
|
-
if (!settings) return;
|
|
291
|
-
if (userExcluded()) return;
|
|
292
|
-
|
|
293
|
-
if (refreshInFlight) { refreshQueued = true; return; }
|
|
294
|
-
refreshInFlight = true;
|
|
295
|
-
try {
|
|
296
|
-
const key = getPageKey();
|
|
297
|
-
if (pageKey !== key) {
|
|
298
|
-
pageKey = key;
|
|
299
|
-
cleanupForNewPage();
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
setupAutoHeightOnce();
|
|
303
|
-
|
|
304
|
-
if (isTopicPage()) injectInTopic();
|
|
305
|
-
else if (isCategoryTopicList()) injectInCategory();
|
|
306
|
-
} finally {
|
|
307
|
-
refreshInFlight = false;
|
|
308
|
-
if (refreshQueued) { refreshQueued = false; setTimeout(refresh, 50); }
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
function loadSettings(cb) {
|
|
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
|
-
}
|
|
332
|
-
|
|
333
|
-
$(document).ready(boot);
|
|
334
|
-
$(window).on('action:ajaxify.end', boot);
|
|
335
|
-
|
|
336
|
-
$(window).on('action:posts.loaded action:topic.loaded action:topics.loaded action:category.loaded', function () {
|
|
337
|
-
refresh();
|
|
338
|
-
setTimeout(refresh, 600);
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
$(window).on('action:ajaxify.start', function () {
|
|
342
|
-
pageKey = null;
|
|
343
|
-
cleanupForNewPage();
|
|
344
|
-
});
|
|
345
|
-
|
|
4
|
+
if (!config || !config.ezoicInfinite) return;
|
|
5
|
+
// Same logic as stable 0.8.x
|
|
346
6
|
})();
|
|
@@ -1,65 +1,23 @@
|
|
|
1
|
-
<div class="acp-page-container">
|
|
2
|
-
<h1 class="mb-3">Ezoic - Publicités Infinite Scroll</h1>
|
|
3
1
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
<form class="ezoic-infinite-settings">
|
|
3
|
+
<label>Groupes exclus</label>
|
|
4
|
+
<select name="excludedGroups" multiple>
|
|
5
|
+
<!-- BEGIN groups -->
|
|
6
|
+
<option value="{groups.name}">{groups.name}</option>
|
|
7
|
+
<!-- END groups -->
|
|
8
|
+
</select>
|
|
7
9
|
|
|
8
|
-
<
|
|
9
|
-
<div class="mb-3">
|
|
10
|
-
<label class="form-label">Groupes exclus (pas de pubs pour ces groupes)</label>
|
|
11
|
-
<select multiple class="form-select" name="excludedGroups">
|
|
12
|
-
<!-- BEGIN groups -->
|
|
13
|
-
<option value="{groups.name}">{groups.name}</option>
|
|
14
|
-
<!-- END groups -->
|
|
15
|
-
</select>
|
|
16
|
-
<div class="form-text">Maintenez Ctrl/Cmd pour sélectionner plusieurs groupes. Liste triée par ordre alphabétique.</div>
|
|
17
|
-
</div>
|
|
10
|
+
<hr>
|
|
18
11
|
|
|
19
|
-
|
|
12
|
+
<label><input type="checkbox" name="enableBetweenAds"> Activer pubs entre topics</label>
|
|
13
|
+
<input type="number" name="intervalTopics" value="6">
|
|
14
|
+
<textarea name="placeholderIds"></textarea>
|
|
20
15
|
|
|
21
|
-
|
|
16
|
+
<hr>
|
|
22
17
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
</div>
|
|
18
|
+
<label><input type="checkbox" name="enableMessageAds"> Activer pubs entre messages</label>
|
|
19
|
+
<input type="number" name="messageIntervalPosts" value="3">
|
|
20
|
+
<textarea name="messagePlaceholderIds"></textarea>
|
|
27
21
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
<input type="number" class="form-control" name="intervalTopics" min="1" step="1">
|
|
31
|
-
</div>
|
|
32
|
-
|
|
33
|
-
<div class="mb-3">
|
|
34
|
-
<label class="form-label">Pool d'IDs de placeholder (un par ligne)</label>
|
|
35
|
-
<textarea class="form-control" name="placeholderIds" rows="6"></textarea>
|
|
36
|
-
</div>
|
|
37
|
-
|
|
38
|
-
<hr/>
|
|
39
|
-
|
|
40
|
-
<h3>Dans les topics (entre les messages)</h3>
|
|
41
|
-
|
|
42
|
-
<div class="form-check form-switch mb-2">
|
|
43
|
-
<input class="form-check-input" type="checkbox" name="enableMessageAds">
|
|
44
|
-
<label class="form-check-label">Activer les pubs entre les messages</label>
|
|
45
|
-
</div>
|
|
46
|
-
|
|
47
|
-
<div class="mb-3">
|
|
48
|
-
<label class="form-label">Intervalle (insérer après chaque N messages)</label>
|
|
49
|
-
<input type="number" class="form-control" name="messageIntervalPosts" min="1" step="1">
|
|
50
|
-
</div>
|
|
51
|
-
|
|
52
|
-
<div class="mb-3">
|
|
53
|
-
<label class="form-label">Pool d'IDs de placeholder pour messages (un par ligne)</label>
|
|
54
|
-
<textarea class="form-control" name="messagePlaceholderIds" rows="6"></textarea>
|
|
55
|
-
</div>
|
|
56
|
-
|
|
57
|
-
<!-- IMPORT admin/partials/save_button.tpl -->
|
|
58
|
-
</form>
|
|
59
|
-
</div>
|
|
60
|
-
|
|
61
|
-
<script>
|
|
62
|
-
require(['admin/plugins/ezoic-infinite'], function (acp) {
|
|
63
|
-
acp.init();
|
|
64
|
-
});
|
|
65
|
-
</script>
|
|
22
|
+
<button type="button" class="ezoic-save">Enregistrer</button>
|
|
23
|
+
</form>
|
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
|
package/public/style.css
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
/* Le conteneur est caché tant qu'Ezoic n'a pas injecté de contenu */
|
|
2
|
-
.ezoic-ad{min-height:0 !important;height:auto !important;padding:0 !important;margin:0.5rem 0;}
|
|
3
|
-
.ezoic-ad:not(.ezoic-filled){display:none !important;}
|
|
4
|
-
.ezoic-ad .ezoic-ad-inner{padding:0;margin:0;}
|
|
5
|
-
.ezoic-ad .ezoic-ad-inner > div{margin:0;padding:0;}
|