nodebb-plugin-onekite-calendar 2.0.63 → 2.0.64
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/lib/api.js +36 -4
- package/lib/realtime.js +10 -0
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/public/client.js +59 -2
package/lib/api.js
CHANGED
|
@@ -838,11 +838,19 @@ api.joinSpecialEvent = async function (req, res) {
|
|
|
838
838
|
ev.participants = JSON.stringify(list);
|
|
839
839
|
await dbLayer.saveSpecialEvent(ev);
|
|
840
840
|
|
|
841
|
+
const names = await usernamesByUids(list);
|
|
842
|
+
|
|
841
843
|
realtime.emitCalendarUpdated({ kind: 'specialEvent', action: 'participants', eid });
|
|
844
|
+
realtime.emitParticipantsUpdated({
|
|
845
|
+
type: 'special',
|
|
846
|
+
id: eid,
|
|
847
|
+
participants: list,
|
|
848
|
+
participantsUsernames: names,
|
|
849
|
+
});
|
|
842
850
|
return res.json({
|
|
843
851
|
ok: true,
|
|
844
852
|
participants: list,
|
|
845
|
-
participantsUsernames:
|
|
853
|
+
participantsUsernames: names,
|
|
846
854
|
});
|
|
847
855
|
};
|
|
848
856
|
|
|
@@ -865,8 +873,16 @@ api.leaveSpecialEvent = async function (req, res) {
|
|
|
865
873
|
ev.participants = JSON.stringify(next);
|
|
866
874
|
await dbLayer.saveSpecialEvent(ev);
|
|
867
875
|
|
|
876
|
+
const names = await usernamesByUids(next);
|
|
877
|
+
|
|
868
878
|
realtime.emitCalendarUpdated({ kind: 'specialEvent', action: 'participants', eid });
|
|
869
|
-
|
|
879
|
+
realtime.emitParticipantsUpdated({
|
|
880
|
+
type: 'special',
|
|
881
|
+
id: eid,
|
|
882
|
+
participants: next,
|
|
883
|
+
participantsUsernames: names,
|
|
884
|
+
});
|
|
885
|
+
return res.json({ ok: true, participants: next, participantsUsernames: names });
|
|
870
886
|
};
|
|
871
887
|
|
|
872
888
|
api.getCapabilities = async function (req, res) {
|
|
@@ -1032,8 +1048,16 @@ api.joinOuting = async function (req, res) {
|
|
|
1032
1048
|
o.participants = JSON.stringify(list);
|
|
1033
1049
|
await dbLayer.saveOuting(o);
|
|
1034
1050
|
|
|
1051
|
+
const names = await usernamesByUids(list);
|
|
1052
|
+
|
|
1035
1053
|
realtime.emitCalendarUpdated({ kind: 'outing', action: 'participants', oid });
|
|
1036
|
-
|
|
1054
|
+
realtime.emitParticipantsUpdated({
|
|
1055
|
+
type: 'outing',
|
|
1056
|
+
id: oid,
|
|
1057
|
+
participants: list,
|
|
1058
|
+
participantsUsernames: names,
|
|
1059
|
+
});
|
|
1060
|
+
return res.json({ ok: true, participants: list, participantsUsernames: names });
|
|
1037
1061
|
};
|
|
1038
1062
|
|
|
1039
1063
|
api.leaveOuting = async function (req, res) {
|
|
@@ -1056,8 +1080,16 @@ api.leaveOuting = async function (req, res) {
|
|
|
1056
1080
|
o.participants = JSON.stringify(next);
|
|
1057
1081
|
await dbLayer.saveOuting(o);
|
|
1058
1082
|
|
|
1083
|
+
const names = await usernamesByUids(next);
|
|
1084
|
+
|
|
1059
1085
|
realtime.emitCalendarUpdated({ kind: 'outing', action: 'participants', oid });
|
|
1060
|
-
|
|
1086
|
+
realtime.emitParticipantsUpdated({
|
|
1087
|
+
type: 'outing',
|
|
1088
|
+
id: oid,
|
|
1089
|
+
participants: next,
|
|
1090
|
+
participantsUsernames: names,
|
|
1091
|
+
});
|
|
1092
|
+
return res.json({ ok: true, participants: next, participantsUsernames: names });
|
|
1061
1093
|
};
|
|
1062
1094
|
|
|
1063
1095
|
api.createOuting = async function (req, res) {
|
package/lib/realtime.js
CHANGED
|
@@ -27,6 +27,16 @@ function emitCalendarUpdated(payload) {
|
|
|
27
27
|
} catch (e) {}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
function emitParticipantsUpdated(payload) {
|
|
31
|
+
try {
|
|
32
|
+
const server = getIO();
|
|
33
|
+
if (!server || !server.sockets || typeof server.sockets.emit !== 'function') return;
|
|
34
|
+
|
|
35
|
+
server.sockets.emit('event:calendar-onekite.participantsUpdated', payload || {});
|
|
36
|
+
} catch (e) {}
|
|
37
|
+
}
|
|
38
|
+
|
|
30
39
|
module.exports = {
|
|
31
40
|
emitCalendarUpdated,
|
|
41
|
+
emitParticipantsUpdated,
|
|
32
42
|
};
|
package/package.json
CHANGED
package/plugin.json
CHANGED
package/public/client.js
CHANGED
|
@@ -1705,7 +1705,7 @@ function toDatetimeLocalValue(date) {
|
|
|
1705
1705
|
const leaveBtn = (canJoinHere && p.isParticipant)
|
|
1706
1706
|
? `<button type="button" class="btn btn-sm btn-danger ms-2 onekite-leave-special" data-eid="${eidPlain}" title="Se retirer" aria-label="Se retirer">−</button>`
|
|
1707
1707
|
: '';
|
|
1708
|
-
const participantsHtml = `<div class="mb-2" id="onekite-participants-special"><strong>Participants</strong>${joinBtn}${leaveBtn}<br>` +
|
|
1708
|
+
const participantsHtml = `<div class="mb-2" id="onekite-participants-special" data-eid="${eidPlain}"><strong>Participants</strong>${joinBtn}${leaveBtn}<br>` +
|
|
1709
1709
|
(participants.length
|
|
1710
1710
|
? participants.map((name) => {
|
|
1711
1711
|
const u = String(name || '').trim();
|
|
@@ -1855,7 +1855,7 @@ function toDatetimeLocalValue(date) {
|
|
|
1855
1855
|
const leaveBtn = (canJoinHere && p.isParticipant)
|
|
1856
1856
|
? `<button type="button" class="btn btn-sm btn-danger ms-2 onekite-leave-outing" data-oid="${oidPlain}" title="Se retirer" aria-label="Se retirer">−</button>`
|
|
1857
1857
|
: '';
|
|
1858
|
-
const participantsHtml = `<div class="mb-2" id="onekite-participants-outing"><strong>Participants</strong>${joinBtn}${leaveBtn}<br>` +
|
|
1858
|
+
const participantsHtml = `<div class="mb-2" id="onekite-participants-outing" data-oid="${oidPlain}"><strong>Participants</strong>${joinBtn}${leaveBtn}<br>` +
|
|
1859
1859
|
(participants.length
|
|
1860
1860
|
? participants.map((name) => {
|
|
1861
1861
|
const u = String(name || '').trim();
|
|
@@ -2846,6 +2846,63 @@ try {
|
|
|
2846
2846
|
scheduleRefetch(cal);
|
|
2847
2847
|
} catch (e) {}
|
|
2848
2848
|
});
|
|
2849
|
+
|
|
2850
|
+
// Live update of participants list in open modals (special events & outings)
|
|
2851
|
+
socket.on('event:calendar-onekite.participantsUpdated', function (payload) {
|
|
2852
|
+
try {
|
|
2853
|
+
const p = payload || {};
|
|
2854
|
+
const type = String(p.type || '').trim();
|
|
2855
|
+
const id = String(p.id || '').trim();
|
|
2856
|
+
if (!type || !id) return;
|
|
2857
|
+
|
|
2858
|
+
const names = Array.isArray(p.participantsUsernames) ? p.participantsUsernames : [];
|
|
2859
|
+
const uids = Array.isArray(p.participants) ? p.participants.map(String) : [];
|
|
2860
|
+
|
|
2861
|
+
const uidNow = String(
|
|
2862
|
+
(window.config && window.config.uid) ||
|
|
2863
|
+
(typeof app !== 'undefined' && app && app.user && app.user.uid) ||
|
|
2864
|
+
(typeof ajaxify !== 'undefined' && ajaxify && ajaxify.data && ajaxify.data.uid) ||
|
|
2865
|
+
''
|
|
2866
|
+
);
|
|
2867
|
+
const isParticipant = uidNow && uids.includes(String(uidNow));
|
|
2868
|
+
|
|
2869
|
+
const sel = (type === 'special') ? '#onekite-participants-special' : (type === 'outing') ? '#onekite-participants-outing' : '';
|
|
2870
|
+
if (!sel) return;
|
|
2871
|
+
const candidates = document.querySelectorAll(sel);
|
|
2872
|
+
if (!candidates || !candidates.length) return;
|
|
2873
|
+
let box = null;
|
|
2874
|
+
for (const el of candidates) {
|
|
2875
|
+
if (!el) continue;
|
|
2876
|
+
const matchId = type === 'special' ? String(el.getAttribute('data-eid') || '') : String(el.getAttribute('data-oid') || '');
|
|
2877
|
+
if (matchId === id) { box = el; break; }
|
|
2878
|
+
}
|
|
2879
|
+
if (!box) return;
|
|
2880
|
+
|
|
2881
|
+
const hasControls = !!box.querySelector('.onekite-join-special, .onekite-leave-special, .onekite-join-outing, .onekite-leave-outing');
|
|
2882
|
+
let controlsHtml = '';
|
|
2883
|
+
if (hasControls && uidNow) {
|
|
2884
|
+
if (type === 'special') {
|
|
2885
|
+
controlsHtml = isParticipant
|
|
2886
|
+
? `<button type="button" class="btn btn-sm btn-danger ms-2 onekite-leave-special" data-eid="${escapeHtml(id)}" title="Se retirer" aria-label="Se retirer">−</button>`
|
|
2887
|
+
: `<button type="button" class="btn btn-sm btn-success ms-2 onekite-join-special" data-eid="${escapeHtml(id)}" title="S'ajouter" aria-label="S'ajouter">+</button>`;
|
|
2888
|
+
} else if (type === 'outing') {
|
|
2889
|
+
controlsHtml = isParticipant
|
|
2890
|
+
? `<button type="button" class="btn btn-sm btn-danger ms-2 onekite-leave-outing" data-oid="${escapeHtml(id)}" title="Se retirer" aria-label="Se retirer">−</button>`
|
|
2891
|
+
: `<button type="button" class="btn btn-sm btn-success ms-2 onekite-join-outing" data-oid="${escapeHtml(id)}" title="S'ajouter" aria-label="S'ajouter">+</button>`;
|
|
2892
|
+
}
|
|
2893
|
+
}
|
|
2894
|
+
|
|
2895
|
+
const links = names.length
|
|
2896
|
+
? names.map((name) => {
|
|
2897
|
+
const u = String(name || '').trim();
|
|
2898
|
+
if (!u) return '';
|
|
2899
|
+
return `<a class="onekite-user-link me-2" href="${window.location.origin}/user/${encodeURIComponent(u)}">${escapeHtml(u)}</a>`;
|
|
2900
|
+
}).filter(Boolean).join('')
|
|
2901
|
+
: `<span class="text-muted">Aucun</span>`;
|
|
2902
|
+
|
|
2903
|
+
box.innerHTML = `<strong>Participants</strong>${controlsHtml}<br>${links}`;
|
|
2904
|
+
} catch (e) {}
|
|
2905
|
+
});
|
|
2849
2906
|
}
|
|
2850
2907
|
} catch (e) {}
|
|
2851
2908
|
|