nodebb-plugin-admin-chats 2.1.0 → 2.1.1

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
@@ -18,6 +18,10 @@ A professional administration plugin for NodeBB that allows administrators to mo
18
18
  * **ID**: `nodebb-plugin-admin-chats`
19
19
  * **Compatibility**: NodeBB versions `^3.0.0` or `^4.0.0`
20
20
 
21
+ ### Chat Route Behavior (`/chats`)
22
+ NodeBB exposes a core route at `/chats` (and `/chats/:roomId/:index?`) that redirects logged-in users to their personal chat page under `/user/:userslug/chats/...`.
23
+ This plugin also rewrites chat notification links to use `/user/:userslug/chats/...`, ensuring admins land on the correct user-scoped chat view when opening notifications.
24
+
21
25
  ### Implemented Hooks
22
26
  The plugin utilizes several filters to elevate administrator permissions:
23
27
 
@@ -54,3 +58,4 @@ The plugin includes a `client.js` script that:
54
58
 
55
59
  ---
56
60
  *Developed by [palmoni5](https://github.com/palmoni5/nodebb-plugin-admin-chats).*
61
+
package/client.js CHANGED
@@ -160,6 +160,14 @@ $(document).ready(function() {
160
160
  Chats._adminAllChatsPatched = true;
161
161
  }
162
162
 
163
+ // Auto-open chat if roomId is specified in URL
164
+ const currentRoomId = ajaxify && ajaxify.data && ajaxify.data.roomId;
165
+ if (currentRoomId && !$('body').hasClass('chat-loaded')) {
166
+ setTimeout(function() {
167
+ Chats.switchChat(currentRoomId);
168
+ }, 100);
169
+ }
170
+
163
171
  bindAdminRecentChatsInfiniteScroll();
164
172
  });
165
173
  }
@@ -471,6 +479,18 @@ $(document).ready(function() {
471
479
  if (isAdminAllChatsPage()) {
472
480
  patchForumChatsForAdminAll();
473
481
  bindAdminRecentChatsInfiniteScroll();
482
+
483
+ // Auto-open chat if roomId is specified in URL and chat is not already loaded
484
+ const currentRoomId = ajaxify && ajaxify.data && ajaxify.data.roomId;
485
+ if (currentRoomId && !$('body').hasClass('chat-loaded')) {
486
+ setTimeout(function() {
487
+ require(['forum/chats'], function(Chats) {
488
+ if (Chats && Chats.switchChat) {
489
+ Chats.switchChat(currentRoomId);
490
+ }
491
+ });
492
+ }, 200);
493
+ }
474
494
  }
475
495
 
476
496
  const url = data && data.url ? data.url : '';
@@ -478,6 +498,11 @@ $(document).ready(function() {
478
498
  refreshChatUi();
479
499
  setTimeout(refreshChatUi, 500);
480
500
  setTimeout(refreshChatUi, 1200);
501
+
502
+ // Handle chat navigation for internal URL changes
503
+ if (url.match(/^chats\/\d+/)) {
504
+ setTimeout(handleChatNavigation, 300);
505
+ }
481
506
  }
482
507
  });
483
508
 
@@ -485,6 +510,20 @@ $(document).ready(function() {
485
510
  if (isAdminAllChatsPage()) {
486
511
  patchForumChatsForAdminAll();
487
512
  bindAdminRecentChatsInfiniteScroll();
513
+
514
+ // Auto-open chat if roomId is specified in URL and no chat is currently active
515
+ const currentRoomId = ajaxify && ajaxify.data && ajaxify.data.roomId;
516
+ const activeChatId = $('[component="chat/main-wrapper"]').attr('data-roomid');
517
+
518
+ if (currentRoomId && (!activeChatId || activeChatId !== String(currentRoomId))) {
519
+ setTimeout(function() {
520
+ require(['forum/chats'], function(Chats) {
521
+ if (Chats && Chats.switchChat) {
522
+ Chats.switchChat(currentRoomId);
523
+ }
524
+ });
525
+ }, 100);
526
+ }
488
527
  }
489
528
  refreshChatUi();
490
529
  setTimeout(refreshChatUi, 200);
@@ -499,6 +538,41 @@ $(document).ready(function() {
499
538
  setTimeout(refreshChatUi, 0);
500
539
  });
501
540
 
541
+ // Handle browser back/forward navigation
542
+ $(window).on('popstate', function() {
543
+ if (isAdminAllChatsPage()) {
544
+ setTimeout(handleChatNavigation, 100);
545
+ }
546
+ });
547
+
548
+ // Handle URL changes for internal navigation
549
+ function handleChatNavigation() {
550
+ if (!isAdminAllChatsPage()) {
551
+ return;
552
+ }
553
+
554
+ // Try to get roomId from multiple sources
555
+ let currentRoomId = ajaxify && ajaxify.data && ajaxify.data.roomId;
556
+
557
+ // If not found in ajaxify.data, try to extract from URL
558
+ if (!currentRoomId) {
559
+ const urlMatch = window.location.pathname.match(/\/chats\/(\d+)/);
560
+ if (urlMatch) {
561
+ currentRoomId = parseInt(urlMatch[1], 10);
562
+ }
563
+ }
564
+
565
+ const activeChatId = $('[component="chat/main-wrapper"]').attr('data-roomid');
566
+
567
+ if (currentRoomId && (!activeChatId || activeChatId !== String(currentRoomId))) {
568
+ require(['forum/chats'], function(Chats) {
569
+ if (Chats && Chats.switchChat) {
570
+ Chats.switchChat(currentRoomId);
571
+ }
572
+ });
573
+ }
574
+ }
575
+
502
576
  $(document).on('click', '.admin-chat-lock-toggle-item', async function(ev) {
503
577
  ev.preventDefault();
504
578
 
package/library.js CHANGED
@@ -43,6 +43,63 @@ plugin.init = async function (params) {
43
43
  overrideCoreChatRedirect(params.controllers);
44
44
  };
45
45
 
46
+ plugin.filterNotificationCreate = async function (data) {
47
+ if (!data || !data.data) {
48
+ return data;
49
+ }
50
+
51
+ const notification = data.data;
52
+
53
+ // Check if this is a chat notification with path like /chats/123
54
+ if (notification.path && notification.path.match(/^\/chats\/\d+/)) {
55
+ const chatMatch = notification.path.match(/^\/chats\/(\d+)(?:\/(\d+))?$/);
56
+ if (chatMatch && notification && notification.uid) {
57
+ const roomId = chatMatch[1];
58
+ const index = chatMatch[2];
59
+
60
+ // Get the user's slug to redirect to their personal chat page
61
+ const userSlug = await User.getUserField(notification.uid, 'userslug');
62
+ if (userSlug) {
63
+ notification.path = `/user/${userSlug}/chats/${roomId}${index ? `/${index}` : ''}`;
64
+ }
65
+ }
66
+ }
67
+
68
+ return data;
69
+ };
70
+
71
+ plugin.filterUserNotificationsGetNotifications = async function (data) {
72
+ if (!data || !data.uid || !Array.isArray(data.notifications) || !data.notifications.length) {
73
+ return data;
74
+ }
75
+
76
+ const userSlug = await User.getUserField(data.uid, 'userslug');
77
+ if (!userSlug) {
78
+ return data;
79
+ }
80
+
81
+ const userPathRegex = /\/user\/[^/]+\/chats\//;
82
+ const chatPathRegex = /\/chats\/(\d+)(?:\/(\d+))?(?=$|[/?#])/;
83
+
84
+ data.notifications.forEach((notification) => {
85
+ if (!notification || !notification.path) {
86
+ return;
87
+ }
88
+ if (userPathRegex.test(notification.path)) {
89
+ return;
90
+ }
91
+ const match = notification.path.match(chatPathRegex);
92
+ if (!match) {
93
+ return;
94
+ }
95
+ const roomId = match[1];
96
+ const index = match[2];
97
+ const replacement = `/user/${userSlug}/chats/${roomId}${index ? `/${index}` : ''}`;
98
+ notification.path = notification.path.replace(chatPathRegex, replacement);
99
+ });
100
+
101
+ return data;
102
+ };
46
103
  plugin.addScripts = async function (data) {
47
104
  let isHebrew = false;
48
105
 
@@ -393,6 +450,15 @@ function registerRoutes(app, router, middleware) {
393
450
 
394
451
  const pageController = async (req, res, next) => {
395
452
  try {
453
+ // If user is not admin, redirect to user-specific chat URL
454
+ if (req.uid && !await User.isAdministrator(req.uid)) {
455
+ const userSlug = await User.getUserField(req.uid, 'userslug');
456
+ if (userSlug && req.params.roomId) {
457
+ const redirectUrl = `${req.baseUrl || ''}/user/${userSlug}/chats/${req.params.roomId}${req.params.index ? `/${req.params.index}` : ''}`;
458
+ return res.redirect(redirectUrl);
459
+ }
460
+ }
461
+
396
462
  await renderAdminChatsPage(req, res, next);
397
463
  } catch (err) {
398
464
  next(err);
@@ -834,3 +900,5 @@ function getRoomId(payload) {
834
900
 
835
901
  module.exports = plugin;
836
902
 
903
+
904
+
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "nodebb-plugin-admin-chats",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "A plugin that allows the administrator to view and manage user chats.",
5
5
  "main": "library.js",
6
6
  "dependencies": {
7
- "lodash": "^4.17.0"
7
+ "lodash": "^4.17.21"
8
8
  },
9
9
  "nbbpm": {
10
- "compatibility": "^3.0.0 || ^4.0.0"
10
+ "compatibility": "^4.0.0"
11
11
  }
12
12
  }
package/plugin.json CHANGED
@@ -63,6 +63,17 @@
63
63
  {
64
64
  "hook": "filter:scripts.get",
65
65
  "method": "addScripts"
66
+ },
67
+ {
68
+ "hook": "filter:notifications.create",
69
+ "method": "filterNotificationCreate"
70
+ },
71
+ {
72
+ "hook": "filter:user.notifications.getNotifications",
73
+ "method": "filterUserNotificationsGetNotifications"
66
74
  }
67
75
  ]
68
76
  }
77
+
78
+
79
+