nodebb-plugin-admin-chats 3.4.0 → 3.4.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.
Files changed (2) hide show
  1. package/client.js +52 -29
  2. package/package.json +1 -1
package/client.js CHANGED
@@ -223,8 +223,11 @@ $(document).ready(function() {
223
223
  }
224
224
 
225
225
  roomId = roomId || '';
226
- Chats.destroyAutoComplete(ajaxify.data.roomId);
227
- socket.emit('modules.chats.leave', ajaxify.data.roomId);
226
+ // NodeBB 4.14.9+ (56c6115a61): destroyAutoComplete takes the input element, not a roomId
227
+ Chats.destroyAutoComplete($('[component="chat/main-wrapper"]').find('[component="chat/input"]'));
228
+ if (ajaxify.data.roomId) {
229
+ socket.emit('modules.chats.leave', ajaxify.data.roomId);
230
+ }
228
231
 
229
232
  const url = getAdminChatsPageUrl(roomId);
230
233
  fetch(getAdminChatsDataUrl(roomId), { credentials: 'include' })
@@ -245,12 +248,18 @@ $(document).ready(function() {
245
248
  mainWrapper.find('[data-bs-toggle="tooltip"]').tooltip({ trigger: 'hover', container: '#content' });
246
249
  Chats.setActive(roomId);
247
250
  Chats.addEventListeners();
248
- $(window).trigger('action:chat.loaded');
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'));
249
254
  if (roomId) {
250
255
  ChatsMessages.scrollToBottomAfterImageLoad(mainWrapper.find('[component="chat/message/content"]'));
251
256
  }
252
257
  if (history.pushState) {
253
- history.pushState({ url: url }, null, `${window.location.protocol}//${window.location.host}${config.relative_path || ''}/${url}`);
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);
254
263
  }
255
264
  bindAdminRecentChatsInfiniteScroll();
256
265
  });
@@ -259,18 +268,31 @@ $(document).ready(function() {
259
268
  Chats._adminAllChatsPatched = true;
260
269
  }
261
270
 
262
- // Auto-open chat if roomId is specified in URL
271
+ // Auto-open chat if roomId is specified in URL and the room is not
272
+ // already rendered (server-side render sets data-roomid on the wrapper —
273
+ // re-switching in that case caused a visible list->chat flash on mobile)
263
274
  const currentRoomId = ajaxify && ajaxify.data && ajaxify.data.roomId;
264
- if (currentRoomId && !$('body').hasClass('chat-loaded')) {
275
+ const activeChatId = $('[component="chat/main-wrapper"]').attr('data-roomid') || '';
276
+ if (currentRoomId && String(currentRoomId) !== String(activeChatId)) {
265
277
  setTimeout(function() {
266
278
  Chats.switchChat(currentRoomId);
267
279
  }, 100);
280
+ } else {
281
+ syncChatLoadedState();
268
282
  }
269
283
 
270
284
  bindAdminRecentChatsInfiniteScroll();
271
285
  });
272
286
  }
273
287
 
288
+ // Keep the mobile layout state (body.chat-loaded / nav data-loaded) in sync with
289
+ // the room that is actually rendered, without re-fetching it
290
+ function syncChatLoadedState() {
291
+ const activeChatId = parseInt($('[component="chat/main-wrapper"]').attr('data-roomid'), 10) || 0;
292
+ $('body').toggleClass('chat-loaded', !!activeChatId);
293
+ $('[component="chat/nav-wrapper"]').attr('data-loaded', activeChatId ? '1' : '0');
294
+ }
295
+
274
296
  function replaceAdminEmptyStateText() {
275
297
  if (!hasAdminChatsAccess()) {
276
298
  return;
@@ -675,9 +697,10 @@ $(document).ready(function() {
675
697
  patchForumChatsForAdminAll();
676
698
  bindAdminRecentChatsInfiniteScroll();
677
699
 
678
- // Auto-open chat if roomId is specified in URL and chat is not already loaded
700
+ // Auto-open chat if roomId is specified in URL and that room is not already rendered
679
701
  const currentRoomId = ajaxify && ajaxify.data && ajaxify.data.roomId;
680
- if (currentRoomId && !$('body').hasClass('chat-loaded')) {
702
+ const activeChatId = $('[component="chat/main-wrapper"]').attr('data-roomid') || '';
703
+ if (currentRoomId && String(currentRoomId) !== String(activeChatId)) {
681
704
  setTimeout(function() {
682
705
  require(['forum/chats'], function(Chats) {
683
706
  if (Chats && Chats.switchChat) {
@@ -685,6 +708,8 @@ $(document).ready(function() {
685
708
  }
686
709
  });
687
710
  }, 200);
711
+ } else {
712
+ syncChatLoadedState();
688
713
  }
689
714
  }
690
715
 
@@ -718,6 +743,8 @@ $(document).ready(function() {
718
743
  }
719
744
  });
720
745
  }, 100);
746
+ } else {
747
+ syncChatLoadedState();
721
748
  }
722
749
  }
723
750
  refreshChatUi();
@@ -776,32 +803,28 @@ $(document).ready(function() {
776
803
  }
777
804
  });
778
805
 
779
- // Handle URL changes for internal navigation
806
+ // Handle URL changes for internal navigation (including back/forward gestures).
807
+ // The URL is the source of truth here — ajaxify.data.roomId is stale after popstate.
780
808
  function handleChatNavigation() {
781
809
  if (!isAdminAllChatsPage()) {
782
810
  return;
783
811
  }
784
-
785
- // Try to get roomId from multiple sources
786
- let currentRoomId = ajaxify && ajaxify.data && ajaxify.data.roomId;
787
-
788
- // If not found in ajaxify.data, try to extract from URL
789
- if (!currentRoomId) {
790
- const urlMatch = window.location.pathname.match(/\/chats\/(\d+)/);
791
- if (urlMatch) {
792
- currentRoomId = parseInt(urlMatch[1], 10);
793
- }
794
- }
795
-
796
- const activeChatId = $('[component="chat/main-wrapper"]').attr('data-roomid');
797
-
798
- if (currentRoomId && (!activeChatId || activeChatId !== String(currentRoomId))) {
799
- require(['forum/chats'], function(Chats) {
800
- if (Chats && Chats.switchChat) {
801
- Chats.switchChat(currentRoomId);
802
- }
803
- });
812
+
813
+ const urlMatch = window.location.pathname.match(/\/chats\/(\d+)/);
814
+ const urlRoomId = urlMatch ? parseInt(urlMatch[1], 10) : 0;
815
+ const activeChatId = parseInt($('[component="chat/main-wrapper"]').attr('data-roomid'), 10) || 0;
816
+
817
+ if (urlRoomId === activeChatId) {
818
+ return;
804
819
  }
820
+
821
+ require(['forum/chats'], function(Chats) {
822
+ if (Chats && Chats.switchChat) {
823
+ // urlRoomId 0 -> URL is the chat list: close the open chat and show the list
824
+ // (previously a back-gesture out of a chat left the chat stuck on screen)
825
+ Chats.switchChat(urlRoomId || '');
826
+ }
827
+ });
805
828
  }
806
829
 
807
830
  $(document).on('click', '[data-action="delete"], [data-action="restore"]', function() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-admin-chats",
3
- "version": "3.4.0",
3
+ "version": "3.4.1",
4
4
  "description": "A plugin that allows the administrator to view and manage user chats.",
5
5
  "main": "library.js",
6
6
  "nbbpm": {