nodebb-plugin-discord-onekite 1.0.3 → 1.0.5
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
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
# nodebb-plugin-discord-onekite (NodeBB v4.x) — v1.0.
|
|
1
|
+
# nodebb-plugin-discord-onekite (NodeBB v4.x) — v1.0.4
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
- Uses `modules` mapping so `require('admin/plugins/discord-onekite')` always resolves.
|
|
5
|
-
- Multi-select uses `name="cids[]"` so selections persist.
|
|
6
|
-
- Also hooks `action:ajaxify.end` as a fallback in admin to re-init after navigation.
|
|
3
|
+
This version follows the most compatible ACP pattern used by many official/community plugins:
|
|
7
4
|
|
|
8
|
-
|
|
5
|
+
- Templates are in `templates/` (not `static/templates/`)
|
|
6
|
+
- ACP script is loaded via `acpScripts` and runs globally on `action:ajaxify.end`
|
|
7
|
+
- No reliance on `modules` name matching
|
package/library.js
CHANGED
|
@@ -21,7 +21,6 @@ function normalizeCids(value) {
|
|
|
21
21
|
|
|
22
22
|
async function getSettings() {
|
|
23
23
|
const s = await meta.settings.get(SETTINGS_KEY);
|
|
24
|
-
// Note: when select name is cids[], nodebb may save it as array or comma string; normalize handles both.
|
|
25
24
|
return {
|
|
26
25
|
webhookUrl: (s && s.webhookUrl) ? String(s.webhookUrl).trim() : '',
|
|
27
26
|
notifyReplies: !!(s && (s.notifyReplies === true || s.notifyReplies === 'on' || s.notifyReplies === 'true')),
|
|
@@ -30,7 +29,7 @@ async function getSettings() {
|
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
function cidAllowed(topicCid, allowedCids) {
|
|
33
|
-
if (!allowedCids || allowedCids.length === 0) return true;
|
|
32
|
+
if (!allowedCids || allowedCids.length === 0) return true;
|
|
34
33
|
return allowedCids.includes(String(topicCid));
|
|
35
34
|
}
|
|
36
35
|
|
package/package.json
CHANGED
package/plugin.json
CHANGED
|
@@ -9,8 +9,6 @@
|
|
|
9
9
|
{ "hook": "action:topic.save", "method": "onTopicSave" },
|
|
10
10
|
{ "hook": "action:post.save", "method": "onPostSave" }
|
|
11
11
|
],
|
|
12
|
-
"templates": "
|
|
13
|
-
"
|
|
14
|
-
"../admin/plugins/discord-onekite.js": "./static/lib/admin.js"
|
|
15
|
-
}
|
|
12
|
+
"templates": "templates",
|
|
13
|
+
"acpScripts": ["static/lib/admin.js"]
|
|
16
14
|
}
|
package/static/lib/admin.js
CHANGED
|
@@ -1,83 +1,67 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/* global $, app, ajaxify */
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
function normalizeCids(v) {
|
|
9
|
-
if (!v) return [];
|
|
10
|
-
if (Array.isArray(v)) return v.map(String).filter(Boolean);
|
|
11
|
-
if (typeof v === 'string') return v.split(',').map(s => s.trim()).filter(Boolean);
|
|
12
|
-
return [];
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async function loadCategoriesIntoSelect(savedCids) {
|
|
16
|
-
const $select = $('#cids');
|
|
17
|
-
if (!$select.length) return;
|
|
18
|
-
|
|
19
|
-
const res = await api.get('/categories');
|
|
20
|
-
|
|
21
|
-
// Depending on endpoint, categories may be at res.categories or res.category
|
|
22
|
-
const categories = (res && (res.categories || res.category || res.data || [])) || [];
|
|
23
|
-
const list = Array.isArray(categories) ? categories : [];
|
|
24
|
-
|
|
25
|
-
$select.empty();
|
|
26
|
-
list
|
|
27
|
-
.filter(c => c && typeof c.cid !== 'undefined' && c.name)
|
|
28
|
-
.forEach(c => {
|
|
29
|
-
const cid = String(c.cid);
|
|
30
|
-
const $opt = $('<option />').val(cid).text(c.name);
|
|
31
|
-
if (savedCids.includes(cid)) $opt.prop('selected', true);
|
|
32
|
-
$opt.appendTo($select);
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
ACP.init = async function () {
|
|
37
|
-
// NodeBB will call init() on page load for template admin/plugins/discord-onekite.
|
|
38
|
-
// But ACP is ajaxified; ensure we don't double-bind.
|
|
39
|
-
if (initialized) {
|
|
4
|
+
(function () {
|
|
5
|
+
function initOnekiteACP() {
|
|
6
|
+
if (!ajaxify || !ajaxify.data || ajaxify.data.template !== 'admin/plugins/discord-onekite') {
|
|
40
7
|
return;
|
|
41
8
|
}
|
|
42
|
-
initialized = true;
|
|
43
9
|
|
|
44
|
-
|
|
45
|
-
|
|
10
|
+
// Use NodeBB's AMD loader to access core helpers
|
|
11
|
+
require(['settings', 'api'], function (settings, api) {
|
|
12
|
+
const $form = $('.discord-onekite-settings');
|
|
13
|
+
if (!$form.length) return;
|
|
46
14
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
});
|
|
15
|
+
// Avoid double-binding
|
|
16
|
+
if ($form.data('onekite-initialized')) return;
|
|
17
|
+
$form.data('onekite-initialized', true);
|
|
51
18
|
|
|
52
|
-
|
|
19
|
+
function normalizeCids(v) {
|
|
20
|
+
if (!v) return [];
|
|
21
|
+
if (Array.isArray(v)) return v.map(String).filter(Boolean);
|
|
22
|
+
if (typeof v === 'string') return v.split(',').map(s => s.trim()).filter(Boolean);
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
53
25
|
|
|
54
|
-
|
|
55
|
-
|
|
26
|
+
// Load saved settings into the form
|
|
27
|
+
settings.load('discord-onekite', $form);
|
|
56
28
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
// eslint-disable-next-line no-console
|
|
62
|
-
console.error('[discord-onekite] categories load failed', e);
|
|
63
|
-
app.alertError('Impossible de charger la liste des catégories.');
|
|
64
|
-
}
|
|
29
|
+
// Get raw settings so we can pre-select categories
|
|
30
|
+
settings.get('discord-onekite', function (saved) {
|
|
31
|
+
saved = saved || {};
|
|
32
|
+
const savedCids = normalizeCids(saved.cids);
|
|
65
33
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
34
|
+
// Load categories (admin should have access)
|
|
35
|
+
api.get('/categories').then(function (res) {
|
|
36
|
+
const categories = (res && res.categories) ? res.categories : [];
|
|
37
|
+
const $select = $('#cids');
|
|
38
|
+
$select.empty();
|
|
39
|
+
|
|
40
|
+
categories
|
|
41
|
+
.filter(c => c && typeof c.cid !== 'undefined' && c.name)
|
|
42
|
+
.forEach(c => {
|
|
43
|
+
const cid = String(c.cid);
|
|
44
|
+
const $opt = $('<option/>').val(cid).text(c.name);
|
|
45
|
+
if (savedCids.includes(cid)) $opt.prop('selected', true);
|
|
46
|
+
$opt.appendTo($select);
|
|
47
|
+
});
|
|
48
|
+
}).catch(function (e) {
|
|
49
|
+
// eslint-disable-next-line no-console
|
|
50
|
+
console.error('[discord-onekite] GET /api/categories failed', e);
|
|
51
|
+
if (app && app.alertError) app.alertError('Impossible de charger les catégories (GET /api/categories).');
|
|
52
|
+
});
|
|
70
53
|
});
|
|
71
|
-
});
|
|
72
|
-
};
|
|
73
54
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
55
|
+
// Save
|
|
56
|
+
$('#save').off('click.discordOnekite').on('click.discordOnekite', function () {
|
|
57
|
+
settings.save('discord-onekite', $form, function () {
|
|
58
|
+
if (app && app.alertSuccess) app.alertSuccess('Paramètres enregistrés !');
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
81
63
|
|
|
82
|
-
|
|
83
|
-
|
|
64
|
+
// Run on initial load and after ajax navigation in ACP
|
|
65
|
+
$(window).on('action:ajaxify.end', initOnekiteACP);
|
|
66
|
+
$(initOnekiteACP);
|
|
67
|
+
})();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<div class="acp-page-container">
|
|
2
2
|
<h4>Discord Onekite</h4>
|
|
3
3
|
<p class="text-muted">
|
|
4
|
-
|
|
4
|
+
Notifications Discord via webhook.
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
<form role="form" class="discord-onekite-settings">
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
<div class="mb-3">
|
|
21
21
|
<label class="form-label" for="cids">Catégories à notifier</label>
|
|
22
|
-
<select class="form-select" id="cids" name="cids
|
|
22
|
+
<select class="form-select" id="cids" name="cids" multiple size="12"></select>
|
|
23
23
|
<p class="form-text text-muted">
|
|
24
24
|
Si aucune catégorie n’est sélectionnée : <strong>toutes les catégories</strong> seront notifiées.
|
|
25
25
|
</p>
|