nodebb-plugin-admin-chats 3.4.1 → 3.4.2
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/client.js +45 -28
- package/library.js +20 -11
- package/package.json +1 -1
package/client.js
CHANGED
|
@@ -230,38 +230,54 @@ $(document).ready(function() {
|
|
|
230
230
|
}
|
|
231
231
|
|
|
232
232
|
const url = getAdminChatsPageUrl(roomId);
|
|
233
|
+
|
|
234
|
+
async function renderAdminChatWindow(payload) {
|
|
235
|
+
const html = await app.parseAndTranslate('partials/chats/message-window', payload);
|
|
236
|
+
const mainWrapper = $('[component="chat/main-wrapper"]');
|
|
237
|
+
mainWrapper.html(html);
|
|
238
|
+
mainWrapper.attr('data-roomid', roomId);
|
|
239
|
+
html.find('.timeago').timeago();
|
|
240
|
+
ajaxify.data = { ...ajaxify.data, ...payload, roomId: roomId };
|
|
241
|
+
ajaxify.updateTitle(ajaxify.data.title);
|
|
242
|
+
$('body').toggleClass('chat-loaded', !!roomId);
|
|
243
|
+
$('[component="chat/nav-wrapper"]').attr('data-loaded', roomId ? '1' : '0');
|
|
244
|
+
mainWrapper.find('[data-bs-toggle="tooltip"]').tooltip({ trigger: 'hover', container: '#content' });
|
|
245
|
+
Chats.setActive(roomId);
|
|
246
|
+
Chats.addEventListeners();
|
|
247
|
+
// Pass the container like core does — listeners (e.g. the emoji
|
|
248
|
+
// plugin's chat button) resolve elements relative to it
|
|
249
|
+
$(window).trigger('action:chat.loaded', $('.chats-full'));
|
|
250
|
+
if (roomId) {
|
|
251
|
+
ChatsMessages.scrollToBottomAfterImageLoad(mainWrapper.find('[component="chat/message/content"]'));
|
|
252
|
+
}
|
|
253
|
+
if (history.pushState) {
|
|
254
|
+
const fullUrl = `${window.location.protocol}//${window.location.host}${config.relative_path || ''}/${url}`;
|
|
255
|
+
// When the address bar already shows the target (e.g. closing a chat
|
|
256
|
+
// after a back-gesture), replace instead of stacking a duplicate entry
|
|
257
|
+
const sameUrl = window.location.href.split('?')[0] === fullUrl.split('?')[0];
|
|
258
|
+
history[sameUrl ? 'replaceState' : 'pushState']({ url: url }, null, fullUrl);
|
|
259
|
+
}
|
|
260
|
+
bindAdminRecentChatsInfiniteScroll();
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (!roomId) {
|
|
264
|
+
// Closing a chat needs no server round-trip — render the empty
|
|
265
|
+
// window from the data we already have (instant back-gesture)
|
|
266
|
+
renderAdminChatWindow({ ...ajaxify.data, roomId: 0, title: '[[pages:chats]]' });
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
|
|
233
270
|
fetch(getAdminChatsDataUrl(roomId), { credentials: 'include' })
|
|
234
271
|
.then(async function(response) {
|
|
235
272
|
if (!response.ok) {
|
|
236
273
|
throw new Error(`Received ${response.status}`);
|
|
237
274
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
html.find('.timeago').timeago();
|
|
245
|
-
ajaxify.data = { ...ajaxify.data, ...payload, roomId: roomId };
|
|
246
|
-
ajaxify.updateTitle(ajaxify.data.title);
|
|
247
|
-
$('body').toggleClass('chat-loaded', !!roomId);
|
|
248
|
-
mainWrapper.find('[data-bs-toggle="tooltip"]').tooltip({ trigger: 'hover', container: '#content' });
|
|
249
|
-
Chats.setActive(roomId);
|
|
250
|
-
Chats.addEventListeners();
|
|
251
|
-
// Pass the container like core does — listeners (e.g. the emoji
|
|
252
|
-
// plugin's chat button) resolve elements relative to it
|
|
253
|
-
$(window).trigger('action:chat.loaded', $('.chats-full'));
|
|
254
|
-
if (roomId) {
|
|
255
|
-
ChatsMessages.scrollToBottomAfterImageLoad(mainWrapper.find('[component="chat/message/content"]'));
|
|
256
|
-
}
|
|
257
|
-
if (history.pushState) {
|
|
258
|
-
const fullUrl = `${window.location.protocol}//${window.location.host}${config.relative_path || ''}/${url}`;
|
|
259
|
-
// When the address bar already shows the target (e.g. closing a chat
|
|
260
|
-
// after a back-gesture), replace instead of stacking a duplicate entry
|
|
261
|
-
const sameUrl = window.location.href.split('?')[0] === fullUrl.split('?')[0];
|
|
262
|
-
history[sameUrl ? 'replaceState' : 'pushState']({ url: url }, null, fullUrl);
|
|
263
|
-
}
|
|
264
|
-
bindAdminRecentChatsInfiniteScroll();
|
|
275
|
+
await renderAdminChatWindow(await response.json());
|
|
276
|
+
})
|
|
277
|
+
.catch(function() {
|
|
278
|
+
// Never leave the user stuck on the list — fall back to a
|
|
279
|
+
// regular ajaxify navigation to the room
|
|
280
|
+
ajaxify.go(url);
|
|
265
281
|
});
|
|
266
282
|
};
|
|
267
283
|
|
|
@@ -375,7 +391,8 @@ $(document).ready(function() {
|
|
|
375
391
|
|
|
376
392
|
// Try admin endpoint first if user has access
|
|
377
393
|
if (hasAdminChatsAccess()) {
|
|
378
|
-
|
|
394
|
+
// switch=1: room data only — no need to rebuild the full room list here
|
|
395
|
+
const adminEndpoint = `${config.relative_path || ''}/api/admin-chats/page/${roomId}?switch=1`;
|
|
379
396
|
try {
|
|
380
397
|
const adminResponse = await fetch(adminEndpoint, {
|
|
381
398
|
headers: {
|
package/library.js
CHANGED
|
@@ -847,7 +847,9 @@ function registerRoutes(app, router, middleware) {
|
|
|
847
847
|
return;
|
|
848
848
|
}
|
|
849
849
|
|
|
850
|
-
const payload = await buildAdminChatsPayload(req
|
|
850
|
+
const payload = await buildAdminChatsPayload(req, {
|
|
851
|
+
isSwitch: parseInt(req.query.switch, 10) === 1,
|
|
852
|
+
});
|
|
851
853
|
res.json(payload);
|
|
852
854
|
} catch (err) {
|
|
853
855
|
res.status(500).json({ status: { code: 'error', message: err.message } });
|
|
@@ -1115,7 +1117,11 @@ async function assertAdminChatsAccess(req, res) {
|
|
|
1115
1117
|
return true;
|
|
1116
1118
|
}
|
|
1117
1119
|
|
|
1118
|
-
async function buildAdminChatsPayload(req) {
|
|
1120
|
+
async function buildAdminChatsPayload(req, options = {}) {
|
|
1121
|
+
// Like core (controllers/accounts/chats.js): when the client only switches
|
|
1122
|
+
// rooms (?switch=1 on the JSON endpoint), skip rebuilding the room list —
|
|
1123
|
+
// scanning every chat room on each switch made room-opening slow on mobile
|
|
1124
|
+
const isSwitch = !!options.isSwitch;
|
|
1119
1125
|
const userslug = await User.getUserField(req.uid, 'userslug');
|
|
1120
1126
|
const [isAdmin, canView, canManage] = await Promise.all([
|
|
1121
1127
|
User.isAdministrator(req.uid),
|
|
@@ -1124,11 +1130,6 @@ async function buildAdminChatsPayload(req) {
|
|
|
1124
1130
|
]);
|
|
1125
1131
|
const adminChatsManage = isAdmin || canManage;
|
|
1126
1132
|
const adminChatsAccess = isAdmin || canView || canManage;
|
|
1127
|
-
const [recentChats, publicRooms, privateRoomCount] = await Promise.all([
|
|
1128
|
-
getAdminRecentChats(req.uid, 0, ADMIN_CHAT_PAGE_SIZE),
|
|
1129
|
-
Messaging.getPublicRooms(req.uid, req.uid),
|
|
1130
|
-
getPrivateRoomCount(),
|
|
1131
|
-
]);
|
|
1132
1133
|
|
|
1133
1134
|
const payload = {
|
|
1134
1135
|
title: '[[pages:chats]]',
|
|
@@ -1138,13 +1139,21 @@ async function buildAdminChatsPayload(req) {
|
|
|
1138
1139
|
adminChatsAccess,
|
|
1139
1140
|
adminChatsIsAdmin: isAdmin,
|
|
1140
1141
|
adminChatsCanManage: adminChatsManage,
|
|
1141
|
-
rooms: recentChats.rooms,
|
|
1142
|
-
nextStart: recentChats.nextStart,
|
|
1143
|
-
publicRooms: publicRooms || [],
|
|
1144
|
-
privateRoomCount,
|
|
1145
1142
|
bodyClasses: ['page-user-chats'],
|
|
1146
1143
|
};
|
|
1147
1144
|
|
|
1145
|
+
if (!isSwitch) {
|
|
1146
|
+
const [recentChats, publicRooms, privateRoomCount] = await Promise.all([
|
|
1147
|
+
getAdminRecentChats(req.uid, 0, ADMIN_CHAT_PAGE_SIZE),
|
|
1148
|
+
Messaging.getPublicRooms(req.uid, req.uid),
|
|
1149
|
+
getPrivateRoomCount(),
|
|
1150
|
+
]);
|
|
1151
|
+
payload.rooms = recentChats.rooms;
|
|
1152
|
+
payload.nextStart = recentChats.nextStart;
|
|
1153
|
+
payload.publicRooms = publicRooms || [];
|
|
1154
|
+
payload.privateRoomCount = privateRoomCount;
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1148
1157
|
const roomId = parseInt(req.params.roomId, 10) || 0;
|
|
1149
1158
|
if (!roomId) {
|
|
1150
1159
|
return payload;
|