nodebb-plugin-ezoic-infinite 1.4.93 → 1.4.95
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/package.json +1 -1
- package/public/README.md +0 -15
- package/public/library.js +0 -130
- package/public/package.json +0 -21
- package/public/plugin.json +0 -33
- /package/public/{public/admin.js → admin.js} +0 -0
- /package/public/{public/client.js → client.js} +0 -0
- /package/public/{public/style.css → style.css} +0 -0
- /package/public/{public/templates → templates}/admin/plugins/ezoic-infinite.tpl +0 -0
package/package.json
CHANGED
package/public/README.md
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# NodeBB Plugin – Ezoic Infinite (Production)
|
|
2
|
-
|
|
3
|
-
This plugin injects Ezoic placeholders between topics and posts on NodeBB 4.x,
|
|
4
|
-
with full support for infinite scroll.
|
|
5
|
-
|
|
6
|
-
## Key guarantees
|
|
7
|
-
- No duplicate ads back-to-back
|
|
8
|
-
- One showAds call per placeholder
|
|
9
|
-
- Fast reveal (MutationObserver on first child)
|
|
10
|
-
- Safe with ajaxify navigation
|
|
11
|
-
- Works with NodeBB 4.x + Harmony
|
|
12
|
-
|
|
13
|
-
## Notes
|
|
14
|
-
- Placeholders must exist and be selected in Ezoic
|
|
15
|
-
- Use separate ID pools for topics vs messages
|
package/public/library.js
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const meta = require.main.require('./src/meta');
|
|
4
|
-
const groups = require.main.require('./src/groups');
|
|
5
|
-
const db = require.main.require('./src/database');
|
|
6
|
-
|
|
7
|
-
const SETTINGS_KEY = 'ezoic-infinite';
|
|
8
|
-
const plugin = {};
|
|
9
|
-
|
|
10
|
-
function normalizeExcludedGroups(value) {
|
|
11
|
-
if (!value) return [];
|
|
12
|
-
if (Array.isArray(value)) return value;
|
|
13
|
-
return String(value).split(',').map(s => s.trim()).filter(Boolean);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function parseBool(v, def = false) {
|
|
17
|
-
if (v === undefined || v === null || v === '') return def;
|
|
18
|
-
if (typeof v === 'boolean') return v;
|
|
19
|
-
const s = String(v).toLowerCase();
|
|
20
|
-
return s === '1' || s === 'true' || s === 'on' || s === 'yes';
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
async function getAllGroups() {
|
|
24
|
-
let names = await db.getSortedSetRange('groups:createtime', 0, -1);
|
|
25
|
-
if (!names || !names.length) {
|
|
26
|
-
names = await db.getSortedSetRange('groups:visible:createtime', 0, -1);
|
|
27
|
-
}
|
|
28
|
-
const filtered = names.filter(name => !groups.isPrivilegeGroup(name));
|
|
29
|
-
const data = await groups.getGroupsData(filtered);
|
|
30
|
-
// Filter out nulls (groups deleted between the sorted-set read and getGroupsData)
|
|
31
|
-
const valid = data.filter(g => g && g.name);
|
|
32
|
-
valid.sort((a, b) => String(a.name).localeCompare(String(b.name), undefined, { sensitivity: 'base' }));
|
|
33
|
-
return valid;
|
|
34
|
-
}
|
|
35
|
-
let _settingsCache = null;
|
|
36
|
-
let _settingsCacheAt = 0;
|
|
37
|
-
const SETTINGS_TTL = 30000; // 30s
|
|
38
|
-
|
|
39
|
-
async function getSettings() {
|
|
40
|
-
const now = Date.now();
|
|
41
|
-
if (_settingsCache && (now - _settingsCacheAt) < SETTINGS_TTL) return _settingsCache;
|
|
42
|
-
const s = await meta.settings.get(SETTINGS_KEY);
|
|
43
|
-
_settingsCacheAt = Date.now();
|
|
44
|
-
_settingsCache = {
|
|
45
|
-
// Between-post ads (simple blocks) in category topic list
|
|
46
|
-
enableBetweenAds: parseBool(s.enableBetweenAds, true),
|
|
47
|
-
showFirstTopicAd: parseBool(s.showFirstTopicAd, false),
|
|
48
|
-
placeholderIds: (s.placeholderIds || '').trim(),
|
|
49
|
-
intervalPosts: Math.max(1, parseInt(s.intervalPosts, 10) || 6),
|
|
50
|
-
|
|
51
|
-
// Home/categories list ads (between categories on / or /categories)
|
|
52
|
-
enableCategoryAds: parseBool(s.enableCategoryAds, false),
|
|
53
|
-
showFirstCategoryAd: parseBool(s.showFirstCategoryAd, false),
|
|
54
|
-
categoryPlaceholderIds: (s.categoryPlaceholderIds || '').trim(),
|
|
55
|
-
intervalCategories: Math.max(1, parseInt(s.intervalCategories, 10) || 4),
|
|
56
|
-
|
|
57
|
-
// "Ad message" between replies (looks like a post)
|
|
58
|
-
enableMessageAds: parseBool(s.enableMessageAds, false),
|
|
59
|
-
showFirstMessageAd: parseBool(s.showFirstMessageAd, false),
|
|
60
|
-
messagePlaceholderIds: (s.messagePlaceholderIds || '').trim(),
|
|
61
|
-
messageIntervalPosts: Math.max(1, parseInt(s.messageIntervalPosts, 10) || 3),
|
|
62
|
-
|
|
63
|
-
excludedGroups: normalizeExcludedGroups(s.excludedGroups),
|
|
64
|
-
};
|
|
65
|
-
return _settingsCache;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
async function isUserExcluded(uid, excludedGroups) {
|
|
69
|
-
if (!uid || !excludedGroups.length) return false;
|
|
70
|
-
const userGroups = await groups.getUserGroups([uid]);
|
|
71
|
-
return (userGroups[0] || []).some(g => excludedGroups.includes(g.name));
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
plugin.onSettingsSet = function (data) {
|
|
75
|
-
// Invalider le cache dès que les settings de ce plugin sont sauvegardés via l'ACP
|
|
76
|
-
if (data && data.hash === SETTINGS_KEY) {
|
|
77
|
-
_settingsCache = null;
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
plugin.addAdminNavigation = async (header) => {
|
|
82
|
-
header.plugins = header.plugins || [];
|
|
83
|
-
header.plugins.push({
|
|
84
|
-
route: '/plugins/ezoic-infinite',
|
|
85
|
-
icon: 'fa-ad',
|
|
86
|
-
name: 'Ezoic Infinite Ads'
|
|
87
|
-
});
|
|
88
|
-
return header;
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
plugin.init = async ({ router, middleware }) => {
|
|
92
|
-
async function render(req, res) {
|
|
93
|
-
const settings = await getSettings();
|
|
94
|
-
const allGroups = await getAllGroups();
|
|
95
|
-
|
|
96
|
-
res.render('admin/plugins/ezoic-infinite', {
|
|
97
|
-
title: 'Ezoic Infinite Ads',
|
|
98
|
-
...settings,
|
|
99
|
-
enableBetweenAds_checked: settings.enableBetweenAds ? 'checked' : '',
|
|
100
|
-
enableMessageAds_checked: settings.enableMessageAds ? 'checked' : '',
|
|
101
|
-
allGroups,
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
router.get('/admin/plugins/ezoic-infinite', middleware.admin.buildHeader, render);
|
|
106
|
-
router.get('/api/admin/plugins/ezoic-infinite', render);
|
|
107
|
-
|
|
108
|
-
router.get('/api/plugins/ezoic-infinite/config', async (req, res) => {
|
|
109
|
-
const settings = await getSettings();
|
|
110
|
-
const excluded = await isUserExcluded(req.uid, settings.excludedGroups);
|
|
111
|
-
|
|
112
|
-
res.json({
|
|
113
|
-
excluded,
|
|
114
|
-
enableBetweenAds: settings.enableBetweenAds,
|
|
115
|
-
showFirstTopicAd: settings.showFirstTopicAd,
|
|
116
|
-
placeholderIds: settings.placeholderIds,
|
|
117
|
-
intervalPosts: settings.intervalPosts,
|
|
118
|
-
enableCategoryAds: settings.enableCategoryAds,
|
|
119
|
-
showFirstCategoryAd: settings.showFirstCategoryAd,
|
|
120
|
-
categoryPlaceholderIds: settings.categoryPlaceholderIds,
|
|
121
|
-
intervalCategories: settings.intervalCategories,
|
|
122
|
-
enableMessageAds: settings.enableMessageAds,
|
|
123
|
-
showFirstMessageAd: settings.showFirstMessageAd,
|
|
124
|
-
messagePlaceholderIds: settings.messagePlaceholderIds,
|
|
125
|
-
messageIntervalPosts: settings.messageIntervalPosts,
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
module.exports = plugin;
|
package/public/package.json
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "nodebb-plugin-ezoic-infinite",
|
|
3
|
-
"version": "1.4.8",
|
|
4
|
-
"description": "Production-ready Ezoic infinite ads integration for NodeBB 4.x",
|
|
5
|
-
"main": "library.js",
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"keywords": [
|
|
8
|
-
"nodebb",
|
|
9
|
-
"nodebb-plugin",
|
|
10
|
-
"ezoic",
|
|
11
|
-
"ads",
|
|
12
|
-
"infinite-scroll"
|
|
13
|
-
],
|
|
14
|
-
"engines": {
|
|
15
|
-
"nodebb": ">=4.0.0"
|
|
16
|
-
},
|
|
17
|
-
"nbbpm": {
|
|
18
|
-
"compatibility": "^4.0.0"
|
|
19
|
-
},
|
|
20
|
-
"private": false
|
|
21
|
-
}
|
package/public/plugin.json
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "nodebb-plugin-ezoic-infinite",
|
|
3
|
-
"name": "NodeBB Ezoic Infinite Ads",
|
|
4
|
-
"description": "Ezoic ads with infinite scroll using a pool of placeholder IDs",
|
|
5
|
-
"library": "./library.js",
|
|
6
|
-
"hooks": [
|
|
7
|
-
{
|
|
8
|
-
"hook": "static:app.load",
|
|
9
|
-
"method": "init"
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
"hook": "filter:admin.header.build",
|
|
13
|
-
"method": "addAdminNavigation"
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
"hook": "action:settings.set",
|
|
17
|
-
"method": "onSettingsSet"
|
|
18
|
-
}
|
|
19
|
-
],
|
|
20
|
-
"staticDirs": {
|
|
21
|
-
"public": "public"
|
|
22
|
-
},
|
|
23
|
-
"acpScripts": [
|
|
24
|
-
"public/admin.js"
|
|
25
|
-
],
|
|
26
|
-
"scripts": [
|
|
27
|
-
"public/client.js"
|
|
28
|
-
],
|
|
29
|
-
"templates": "public/templates",
|
|
30
|
-
"css": [
|
|
31
|
-
"public/style.css"
|
|
32
|
-
]
|
|
33
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|