diff --git a/public/language/en-GB/modules.json b/public/language/en-GB/modules.json index 29ba02726f..f4b473992a 100644 --- a/public/language/en-GB/modules.json +++ b/public/language/en-GB/modules.json @@ -48,6 +48,7 @@ "chat.add-user": "Add User", "chat.notification-settings": "Notification Settings", "chat.default-notification-setting": "Default Notification Setting", + "chat.join-leave-messages": "Join/Leave Messages", "chat.notification-setting-room-default": "Room Default", "chat.notification-setting-none": "No notifications", "chat.notification-setting-at-mention-only": "@mention only", diff --git a/public/openapi/components/schemas/Chats.yaml b/public/openapi/components/schemas/Chats.yaml index dc84aca4ef..036b937158 100644 --- a/public/openapi/components/schemas/Chats.yaml +++ b/public/openapi/components/schemas/Chats.yaml @@ -27,6 +27,10 @@ RoomObject: description: Timestamp of when room was created notificationSetting: type: number + description: The notification setting for the room, 0 = no notifications, 1 = only mentions, 2 = all messages + joinLeaveMessages: + type: number + description: Whether join/leave messages are enabled in the room MessageObject: type: object properties: diff --git a/public/openapi/read/user/userslug/chats/roomid.yaml b/public/openapi/read/user/userslug/chats/roomid.yaml index 5c5fd1c296..73c4a62da9 100644 --- a/public/openapi/read/user/userslug/chats/roomid.yaml +++ b/public/openapi/read/user/userslug/chats/roomid.yaml @@ -56,6 +56,8 @@ get: type: array notificationOptionsIcon: type: string + joinLeaveMessages: + type: number messages: type: array items: @@ -360,6 +362,8 @@ get: type: string notificationSetting: type: number + joinLeaveMessages: + type: number publicRooms: type: array items: diff --git a/public/openapi/write/chats/roomId/messages/mid.yaml b/public/openapi/write/chats/roomId/messages/mid.yaml index 5053f1546d..dfa06e7811 100644 --- a/public/openapi/write/chats/roomId/messages/mid.yaml +++ b/public/openapi/write/chats/roomId/messages/mid.yaml @@ -49,7 +49,7 @@ put: type: number required: true description: a valid message id - example: 5 + example: 3 requestBody: required: true content: @@ -92,7 +92,7 @@ delete: type: number required: true description: a valid message id - example: 5 + example: 3 responses: '200': description: Message successfully deleted @@ -125,7 +125,7 @@ post: type: number required: true description: a valid message id - example: 5 + example: 3 responses: '200': description: message successfully restored diff --git a/public/openapi/write/chats/roomId/messages/mid/ip.yaml b/public/openapi/write/chats/roomId/messages/mid/ip.yaml index 0d2a82cba9..1730542213 100644 --- a/public/openapi/write/chats/roomId/messages/mid/ip.yaml +++ b/public/openapi/write/chats/roomId/messages/mid/ip.yaml @@ -17,7 +17,7 @@ get: type: string required: true description: a valid chat message id - example: 5 + example: 3 responses: '200': description: Chat message ip address retrieved diff --git a/public/src/client/chats/manage.js b/public/src/client/chats/manage.js index 2ab92c4295..f2e5cbc04c 100644 --- a/public/src/client/chats/manage.js +++ b/public/src/client/chats/manage.js @@ -75,12 +75,16 @@ define('forum/chats/manage', [ modal.find('[component="chat/manage/save"]').on('click', () => { const notifSettingEl = modal.find('[component="chat/room/notification/setting"]'); + const joinLeaveMessagesEl = modal.find('[component="chat/room/join-leave-messages"]'); + api.put(`/chats/${roomId}`, { groups: modal.find('[component="chat/room/groups"]').val(), notificationSetting: notifSettingEl.val(), + joinLeaveMessages: joinLeaveMessagesEl.is(':checked') ? 1 : 0, }).then((payload) => { ajaxify.data.groups = payload.groups; ajaxify.data.notificationSetting = payload.notificationSetting; + ajaxify.data.joinLeaveMessages = payload.joinLeaveMessages; const roomDefaultOption = payload.notificationOptions[0]; $('[component="chat/notification/setting"] [data-icon]').first().attr( 'data-icon', roomDefaultOption.icon diff --git a/src/api/chats.js b/src/api/chats.js index e1538c4426..5099479b51 100644 --- a/src/api/chats.js +++ b/src/api/chats.js @@ -162,9 +162,17 @@ chatsAPI.update = async (caller, data) => { await db.setObjectField(`chat:room:${data.roomId}`, 'groups', JSON.stringify(data.groups)); } } - if (data.hasOwnProperty('notificationSetting') && isAdmin) { - await db.setObjectField(`chat:room:${data.roomId}`, 'notificationSetting', data.notificationSetting); + if (isAdmin) { + const updateData = {}; + if (data.hasOwnProperty('notificationSetting')) { + updateData.notificationSetting = data.notificationSetting; + } + if (data.hasOwnProperty('joinLeaveMessages')) { + updateData.joinLeaveMessages = data.joinLeaveMessages; + } + await db.setObject(`chat:room:${data.roomId}`, updateData); } + const loadedRoom = await messaging.loadRoom(caller.uid, { roomId: data.roomId, }); diff --git a/src/messaging/rooms.js b/src/messaging/rooms.js index 8b57b81da7..4bf4deed2c 100644 --- a/src/messaging/rooms.js +++ b/src/messaging/rooms.js @@ -22,7 +22,7 @@ const roomUidCache = cacheCreate({ }); const intFields = [ - 'roomId', 'timestamp', 'userCount', 'messageCount', + 'roomId', 'timestamp', 'userCount', 'messageCount', 'joinLeaveMessages', ]; module.exports = function (Messaging) { @@ -88,6 +88,7 @@ module.exports = function (Messaging) { timestamp: now, notificationSetting: data.notificationSetting, messageCount: 0, + joinLeaveMessages: 0, }; if (data.hasOwnProperty('roomName') && data.roomName) { @@ -280,12 +281,22 @@ module.exports = function (Messaging) { async function addUidsToRoom(uids, roomId) { const now = Date.now(); const timestamps = uids.map(() => now); + await Promise.all([ db.sortedSetAdd(`chat:room:${roomId}:uids`, timestamps, uids), db.sortedSetAdd(`chat:room:${roomId}:uids:online`, timestamps, uids), ]); await updateUserCount([roomId]); - await Promise.all(uids.map(uid => Messaging.addSystemMessage('user-join', uid, roomId))); + if (await joinLeaveMessagesEnabled(roomId)) { + await Promise.all( + uids.map(uid => Messaging.addSystemMessage('user-join', uid, roomId)) + ); + } + } + + async function joinLeaveMessagesEnabled(roomId) { + const roomData = await Messaging.getRoomData(roomId, ['joinLeaveMessages']); + return roomData && roomData.joinLeaveMessages === 1; } Messaging.removeUsersFromRoom = async (uid, uids, roomId) => { @@ -319,7 +330,9 @@ module.exports = function (Messaging) { } Messaging.leaveRoom = async (uids, roomId) => { - const isInRoom = await Promise.all(uids.map(uid => Messaging.isUserInRoom(uid, roomId))); + const isInRoom = await Promise.all( + uids.map(uid => Messaging.isUserInRoom(uid, roomId)) + ); uids = uids.filter((uid, index) => isInRoom[index]); const keys = uids @@ -334,8 +347,11 @@ module.exports = function (Messaging) { ], uids), db.sortedSetsRemove(keys, roomId), ]); - - await Promise.all(uids.map(uid => Messaging.addSystemMessage('user-leave', uid, roomId))); + if (await joinLeaveMessagesEnabled(roomId)) { + await Promise.all( + uids.map(uid => Messaging.addSystemMessage('user-leave', uid, roomId)) + ); + } await updateOwner(roomId); await updateUserCount([roomId]); }; @@ -357,10 +373,13 @@ module.exports = function (Messaging) { ], roomIds), ]); - await Promise.all( - roomIds.map(roomId => updateOwner(roomId)) - .concat(roomIds.map(roomId => Messaging.addSystemMessage('user-leave', uid, roomId))) - ); + await Promise.all(roomIds.map(async (roomId) => { + await updateOwner(roomId); + if (await joinLeaveMessagesEnabled(roomId)) { + await Messaging.addSystemMessage('user-leave', uid, roomId); + } + })); + await updateUserCount(roomIds); }; diff --git a/src/views/modals/manage-room.tpl b/src/views/modals/manage-room.tpl index 08c96ccb0b..55f9390de7 100644 --- a/src/views/modals/manage-room.tpl +++ b/src/views/modals/manage-room.tpl @@ -1,6 +1,6 @@