nodebb-plugin-ezoic-infinite 0.9.15 → 1.0.0
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/README.md +12 -0
- package/library.js +5 -6
- package/package.json +1 -1
- package/plugin.json +4 -4
- package/public/admin.js +23 -51
- package/public/client.js +15 -13
- package/public/templates/admin/plugins/ezoic-infinite.tpl +10 -3
package/README.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
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/library.js
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
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');
|
|
5
6
|
|
|
6
7
|
const Plugin = {};
|
|
7
8
|
|
|
8
|
-
Plugin.init = async function (
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
router.get('/admin/plugins/ezoic-infinite', middleware.admin.buildHeader, renderAdmin);
|
|
9
|
+
Plugin.init = async function ({ router, middleware }) {
|
|
10
|
+
// Official helper ensures correct ACP behavior under ajaxify
|
|
11
|
+
routeHelpers.setupAdminPageRoute(router, '/admin/plugins/ezoic-infinite', middleware, [], renderAdmin);
|
|
12
12
|
router.get('/api/admin/plugins/ezoic-infinite', renderAdmin);
|
|
13
13
|
};
|
|
14
14
|
|
|
@@ -16,8 +16,7 @@ async function renderAdmin(req, res) {
|
|
|
16
16
|
const settings = await meta.settings.get('ezoic-infinite');
|
|
17
17
|
|
|
18
18
|
let groupNames = [];
|
|
19
|
-
|
|
20
|
-
const candidates = ['groups:createtime', 'groups:visible:createtime', 'groups:system:createtime'];
|
|
19
|
+
const candidates = ['groups:createtime', 'groups:visible:createtime'];
|
|
21
20
|
for (const set of candidates) {
|
|
22
21
|
try {
|
|
23
22
|
groupNames = await groups.getGroupsFromSet(set, 0, -1);
|
package/package.json
CHANGED
package/plugin.json
CHANGED
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
"staticDirs": {
|
|
17
17
|
"public": "public"
|
|
18
18
|
},
|
|
19
|
-
"acpScripts": [
|
|
20
|
-
"public/admin.js"
|
|
21
|
-
],
|
|
22
19
|
"scripts": [
|
|
23
20
|
"public/client.js"
|
|
24
21
|
],
|
|
25
22
|
"css": [
|
|
26
23
|
"public/style.css"
|
|
27
24
|
],
|
|
28
|
-
"templates": "public/templates"
|
|
25
|
+
"templates": "public/templates",
|
|
26
|
+
"modules": {
|
|
27
|
+
"../admin/plugins/ezoic-infinite.js": "public/admin.js"
|
|
28
|
+
}
|
|
29
29
|
}
|
package/public/admin.js
CHANGED
|
@@ -1,55 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const selected = (data.excludedGroups || '').split(',').map(s => s.trim()).filter(Boolean);
|
|
23
|
-
$select.find('option').each(function () {
|
|
24
|
-
$(this).prop('selected', selected.includes($(this).val()));
|
|
25
|
-
});
|
|
1
|
+
define('admin/plugins/ezoic-infinite', ['settings', 'alerts'], function (Settings, alerts) {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const ACP = {};
|
|
5
|
+
|
|
6
|
+
ACP.init = function () {
|
|
7
|
+
const $form = $('.ezoic-infinite-settings');
|
|
8
|
+
|
|
9
|
+
// Charge les settings dans le formulaire
|
|
10
|
+
Settings.load('ezoic-infinite', $form);
|
|
11
|
+
|
|
12
|
+
// Le save_button.tpl déclenche un event "click" sur .save
|
|
13
|
+
// On écoute l'event standard Settings.
|
|
14
|
+
$form.on('click', '.save', function (e) {
|
|
15
|
+
e.preventDefault();
|
|
16
|
+
Settings.save('ezoic-infinite', $form, function (err) {
|
|
17
|
+
if (err) {
|
|
18
|
+
alerts.error(err.message || err);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
alerts.success('Paramètres enregistrés');
|
|
26
22
|
});
|
|
27
23
|
});
|
|
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) {
|
|
46
|
-
app.alertError(err.message || err);
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
app.alertSuccess('Paramètres enregistrés');
|
|
50
|
-
});
|
|
51
|
-
}
|
|
24
|
+
};
|
|
52
25
|
|
|
53
|
-
|
|
54
|
-
load();
|
|
26
|
+
return ACP;
|
|
55
27
|
});
|
package/public/client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* global $, ajaxify, app
|
|
1
|
+
/* global $, ajaxify, app */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
(function () {
|
|
@@ -6,17 +6,15 @@
|
|
|
6
6
|
window.ezoicInfiniteLoaded = true;
|
|
7
7
|
|
|
8
8
|
const SETTINGS_NS = 'ezoic-infinite';
|
|
9
|
-
|
|
10
9
|
let settings = null;
|
|
11
10
|
let pageKey = null;
|
|
12
11
|
|
|
13
12
|
// State per page
|
|
14
|
-
let usedTopic = new Set();
|
|
15
|
-
let usedCat = new Set();
|
|
16
|
-
let fifoTopic = [];
|
|
17
|
-
let fifoCat = [];
|
|
13
|
+
let usedTopic = new Set();
|
|
14
|
+
let usedCat = new Set();
|
|
15
|
+
let fifoTopic = [];
|
|
16
|
+
let fifoCat = [];
|
|
18
17
|
|
|
19
|
-
// Refresh single-flight
|
|
20
18
|
let refreshInFlight = false;
|
|
21
19
|
let refreshQueued = false;
|
|
22
20
|
|
|
@@ -103,14 +101,13 @@
|
|
|
103
101
|
destroyPlaceholder(id);
|
|
104
102
|
}
|
|
105
103
|
|
|
106
|
-
// IMPORTANT: showAds is called ONLY for a single newly injected placeholder id (never a batch)
|
|
107
104
|
function callEzoicSingle(id) {
|
|
108
105
|
if (!id) return;
|
|
109
106
|
|
|
110
107
|
const now = Date.now();
|
|
111
108
|
window.__ezoicLastSingle = window.__ezoicLastSingle || {};
|
|
112
109
|
const last = window.__ezoicLastSingle[id] || 0;
|
|
113
|
-
if (now - last <
|
|
110
|
+
if (now - last < 1200) return;
|
|
114
111
|
window.__ezoicLastSingle[id] = now;
|
|
115
112
|
|
|
116
113
|
try {
|
|
@@ -129,7 +126,6 @@
|
|
|
129
126
|
|
|
130
127
|
window.ezstandalone.cmd.push(function () { run(); });
|
|
131
128
|
|
|
132
|
-
// Retry a few times if ez loads late
|
|
133
129
|
let tries = 0;
|
|
134
130
|
const tick = function () {
|
|
135
131
|
tries++;
|
|
@@ -140,7 +136,6 @@
|
|
|
140
136
|
} catch (e) {}
|
|
141
137
|
}
|
|
142
138
|
|
|
143
|
-
// Auto height: wrapper visible only when placeholder gets children
|
|
144
139
|
function setupAutoHeightOnce() {
|
|
145
140
|
if (window.__ezoicAutoHeight) return;
|
|
146
141
|
window.__ezoicAutoHeight = true;
|
|
@@ -315,8 +310,15 @@
|
|
|
315
310
|
}
|
|
316
311
|
|
|
317
312
|
function loadSettings(cb) {
|
|
318
|
-
|
|
319
|
-
|
|
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 || {};
|
|
320
322
|
cb && cb();
|
|
321
323
|
});
|
|
322
324
|
}
|
|
@@ -5,13 +5,14 @@
|
|
|
5
5
|
Format placeholder : <code><div id="ezoic-pub-ad-placeholder-XXX"></div></code>
|
|
6
6
|
</div>
|
|
7
7
|
|
|
8
|
-
<form
|
|
8
|
+
<form class="ezoic-infinite-settings" role="form">
|
|
9
9
|
<div class="mb-3">
|
|
10
10
|
<label class="form-label">Groupes exclus (pas de pubs pour ces groupes)</label>
|
|
11
11
|
<select multiple class="form-select" name="excludedGroups">
|
|
12
12
|
<!-- BEGIN groups -->
|
|
13
13
|
<option value="{groups.name}">{groups.name}</option>
|
|
14
|
-
<!-- END groups
|
|
14
|
+
<!-- END groups -->
|
|
15
|
+
</select>
|
|
15
16
|
<div class="form-text">Maintenez Ctrl/Cmd pour sélectionner plusieurs groupes. Liste triée par ordre alphabétique.</div>
|
|
16
17
|
</div>
|
|
17
18
|
|
|
@@ -53,6 +54,12 @@
|
|
|
53
54
|
<textarea class="form-control" name="messagePlaceholderIds" rows="6"></textarea>
|
|
54
55
|
</div>
|
|
55
56
|
|
|
56
|
-
|
|
57
|
+
<!-- IMPORT admin/partials/save_button.tpl -->
|
|
57
58
|
</form>
|
|
58
59
|
</div>
|
|
60
|
+
|
|
61
|
+
<script>
|
|
62
|
+
require(['admin/plugins/ezoic-infinite'], function (acp) {
|
|
63
|
+
acp.init();
|
|
64
|
+
});
|
|
65
|
+
</script>
|