From f0775651b96cbdfddb579ff27ee59c9245ef427e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 14 Jul 2023 13:01:41 -0400 Subject: [PATCH] only update user list if its open --- public/src/client/chats.js | 7 ------- public/src/client/chats/user-list.js | 30 ++++++++++++++++++++++++++++ src/api/chats.js | 5 ++++- src/socket.io/index.js | 17 ---------------- src/socket.io/modules.js | 8 +------- 5 files changed, 35 insertions(+), 32 deletions(-) diff --git a/public/src/client/chats.js b/public/src/client/chats.js index 100d24dab3..8593d501a5 100644 --- a/public/src/client/chats.js +++ b/public/src/client/chats.js @@ -29,7 +29,6 @@ define('forum/chats', [ let newMessage = false; let chatNavWrapper = null; - let userListEl = null; $(window).on('action:ajaxify.start', function () { Chats.destroyAutoComplete(ajaxify.data.roomId); @@ -48,7 +47,6 @@ define('forum/chats', [ socket.emit('modules.chats.enterPublic', ajaxify.data.publicRooms.map(r => r.roomId)); const env = utils.findBootstrapEnvironment(); chatNavWrapper = $('[component="chat/nav-wrapper"]'); - userListEl = $('[component="chat/user/list"]'); if (!Chats.initialised) { Chats.addSocketListeners(); Chats.addGlobalEventListeners(); @@ -469,7 +467,6 @@ define('forum/chats', [ const mainWrapper = components.get('chat/main-wrapper'); mainWrapper.html(html); chatNavWrapper = $('[component="chat/nav-wrapper"]'); - userListEl = $('[component="chat/user/list"]'); html.find('.timeago').timeago(); ajaxify.data = { ...ajaxify.data, ...payload, roomId: roomId }; ajaxify.updateTitle(ajaxify.data.title); @@ -528,10 +525,6 @@ define('forum/chats', [ Chats.increasePublicRoomUnreadCount(chatNavWrapper.find('[data-roomid=' + data.roomId + ']')); }); - socket.on('event:chats.user-online', function (data) { - userListEl.find(`[data-uid="${data.uid}"]`).toggleClass('online', !!data.state); - }); - socket.on('event:user_status_change', function (data) { app.updateUserStatus($('.chats-list [data-uid="' + data.uid + '"] [component="user/status"]'), data.status); }); diff --git a/public/src/client/chats/user-list.js b/public/src/client/chats/user-list.js index cd4b5a8f50..419e699032 100644 --- a/public/src/client/chats/user-list.js +++ b/public/src/client/chats/user-list.js @@ -4,6 +4,8 @@ define('forum/chats/user-list', ['api'], function (api) { const userList = {}; + let updateInterval = 0; + userList.init = function (roomId, container) { const userListEl = container.find('[component="chat/user/list"]'); if (!userListEl.length) { @@ -11,13 +13,41 @@ define('forum/chats/user-list', ['api'], function (api) { } container.find('[component="chat/user/list/btn"]').on('click', () => { userListEl.toggleClass('hidden'); + if (userListEl.hasClass('hidden')) { + stopUpdating(); + } else { + startUpdating(roomId, userListEl); + } }); + $(window).off('action:ajaxify.start', stopUpdating) + .one('action:ajaxify.start', stopUpdating); + userList.addInfiniteScrollHandler(roomId, userListEl, async (listEl, data) => { listEl.append(await app.parseAndTranslate('partials/chats/user-list', 'users', data)); }); }; + function startUpdating(roomId, userListEl) { + updateInterval = setInterval(() => { + updateUserList(roomId, userListEl); + }, 5000); + } + + function stopUpdating() { + if (updateInterval) { + clearInterval(updateInterval); + updateInterval = 0; + } + } + + async function updateUserList(roomId, userListEl) { + if (ajaxify.data.template.chats && app.isFocused && userListEl.scrollTop() === 0 && !userListEl.hasClass('hidden')) { + const data = await api.get(`/chats/${roomId}/users`, { start: 0 }); + userListEl.html(await app.parseAndTranslate('partials/chats/user-list', 'users', data)); + } + } + userList.addInfiniteScrollHandler = function (roomId, listEl, callback) { listEl.on('scroll', utils.debounce(async () => { const bottom = (listEl[0].scrollHeight - listEl.height()) * 0.85; diff --git a/src/api/chats.js b/src/api/chats.js index 0fd0092bec..2d9c31a1fe 100644 --- a/src/api/chats.js +++ b/src/api/chats.js @@ -168,18 +168,21 @@ chatsAPI.mark = async (caller, data) => { chatsAPI.users = async (caller, data) => { const start = data.hasOwnProperty('start') ? data.start : 0; const stop = start + 39; - const [isOwner, isUserInRoom, users] = await Promise.all([ + const io = require('../socket.io'); + const [isOwner, isUserInRoom, users, onlineUids] = await Promise.all([ messaging.isRoomOwner(caller.uid, data.roomId), messaging.isUserInRoom(caller.uid, data.roomId), messaging.getUsersInRoomFromSet( `chat:room:${data.roomId}:uids:online`, data.roomId, start, stop, true ), + io.getUidsInRoom(`chat_room_${data.roomId}`), ]); if (!isUserInRoom) { throw new Error('[[error:no-privileges]]'); } users.forEach((user) => { user.canKick = isOwner && (parseInt(user.uid, 10) !== parseInt(caller.uid, 10)); + user.online = parseInt(user.uid, 10) === parseInt(caller.uid, 10) || onlineUids.includes(String(user.uid)); }); return { users }; }; diff --git a/src/socket.io/index.js b/src/socket.io/index.js index 50ae9b25f6..858223f07d 100644 --- a/src/socket.io/index.js +++ b/src/socket.io/index.js @@ -97,10 +97,6 @@ function onConnection(socket) { socket.on('disconnect', () => { onDisconnect(socket); }); - - socket.on('disconnecting', () => { - onDisconnecting(socket); - }); } function onDisconnect(socket) { @@ -108,19 +104,6 @@ function onDisconnect(socket) { plugins.hooks.fire('action:sockets.disconnect', { socket: socket }); } -async function onDisconnecting(socket) { - if (socket.uid > 0) { - for (const roomName of socket.rooms) { - if (roomName.startsWith('chat_room') && !roomName.includes('public')) { - Sockets.server.in(roomName).emit('event:chats.user-online', { - uid: socket.uid, - state: 0, - }); - } - } - } -} - async function onConnect(socket) { try { await validateSession(socket, '[[error:invalid-session]]'); diff --git a/src/socket.io/modules.js b/src/socket.io/modules.js index f0a71eb2fa..559bbdd5be 100644 --- a/src/socket.io/modules.js +++ b/src/socket.io/modules.js @@ -106,18 +106,12 @@ async function joinLeave(socket, roomIds, method, prefix = 'chat_room') { Messaging.isUserInRoom(socket.uid, roomIds), Messaging.getRoomsData(roomIds, ['public', 'groups']), ]); - const io = require('./index'); + await Promise.all(roomIds.map(async (roomId, idx) => { const isPublic = roomData[idx] && roomData[idx].public; const roomGroups = roomData[idx] && roomData[idx].groups; if (isAdmin || (inRooms[idx] && (!isPublic || await groups.isMemberOfAny(socket.uid, roomGroups)))) { socket[method](`${prefix}_${roomId}`); - if (prefix === 'chat_room') { - io.in(`chat_room_${roomId}`).emit('event:chats.user-online', { - uid: socket.uid, - state: method === 'join' ? 1 : 0, - }); - } } })); }