nodebb-plugin-ezoic-infinite 0.9.16 → 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 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
@@ -1,52 +1,29 @@
1
1
  'use strict';
2
2
 
3
3
  const meta = require.main.require('./src/meta');
4
- const db = require.main.require('./src/database');
5
4
  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 function (params) {
10
- const { router, middleware } = params;
11
-
12
- 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);
13
12
  router.get('/api/admin/plugins/ezoic-infinite', renderAdmin);
14
13
  };
15
14
 
16
- async function getAllGroupNames() {
17
- const keys = [
18
- 'groups:createtime',
19
- 'groups:visible:createtime',
20
- 'groups:system:createtime',
21
- 'groups:alphabetical',
22
- 'groups:visible:alphabetical',
23
- ];
24
-
25
- for (const key of keys) {
26
- try {
27
- const names = await db.getSortedSetRange(key, 0, -1);
28
- if (Array.isArray(names) && names.length) {
29
- return names;
30
- }
31
- } catch (e) {}
32
- }
15
+ async function renderAdmin(req, res) {
16
+ const settings = await meta.settings.get('ezoic-infinite');
33
17
 
34
- // Last resort: ask groups module for any known set
18
+ let groupNames = [];
35
19
  const candidates = ['groups:createtime', 'groups:visible:createtime'];
36
20
  for (const set of candidates) {
37
21
  try {
38
- const names = await groups.getGroupsFromSet(set, 0, -1);
39
- if (Array.isArray(names) && names.length) return names;
22
+ groupNames = await groups.getGroupsFromSet(set, 0, -1);
23
+ if (Array.isArray(groupNames) && groupNames.length) break;
40
24
  } catch (e) {}
41
25
  }
42
26
 
43
- return [];
44
- }
45
-
46
- async function renderAdmin(req, res) {
47
- const settings = await meta.settings.get('ezoic-infinite');
48
-
49
- const groupNames = await getAllGroupNames();
50
27
  let groupList = [];
51
28
  try {
52
29
  groupList = await groups.getGroupsData(groupNames);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "0.9.16",
3
+ "version": "1.0.0",
4
4
  "description": "Injection de publicités Ezoic entre les topics et entre les messages avec infinite scroll (NodeBB 4.x).",
5
5
  "main": "library.js",
6
6
  "license": "MIT",
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
- /* 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
- 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
- $('.ezoic-infinite-save').on('click', save);
54
- load();
26
+ return ACP;
55
27
  });
package/public/client.js CHANGED
@@ -1,4 +1,4 @@
1
- /* global $, ajaxify, app, socket */
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(); // ids currently in DOM (topic)
15
- let usedCat = new Set(); // ids currently in DOM (category)
16
- let fifoTopic = []; // [{id, afterNo}]
17
- let fifoCat = []; // [{id, afterPos}]
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 < 800) return;
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
- socket.emit('admin.settings.get', { hash: SETTINGS_NS }, function (err, data) {
319
- settings = data || {};
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&nbsp;: <code>&lt;div id="ezoic-pub-ad-placeholder-XXX"&gt;&lt;/div&gt;</code>
6
6
  </div>
7
7
 
8
- <form role="form" class="ezoic-infinite-settings">
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 --></select>
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
- <button type="button" class="btn btn-primary ezoic-infinite-save">Enregistrer</button>
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>