mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-29 18:16:17 +01:00 
			
		
		
		
	refactor(socket.io): deprecate SocketModules.chats.typing in favour of api.chats.toggleTyping
This commit is contained in:
		| @@ -202,6 +202,8 @@ paths: | ||||
|     $ref: 'write/chats/roomId/state.yaml' | ||||
|   /chats/{roomId}/watch: | ||||
|     $ref: 'write/chats/roomId/watch.yaml' | ||||
|   /chats/{roomId}/typing: | ||||
|     $ref: 'write/chats/roomId/typing.yaml' | ||||
|   /chats/{roomId}/users: | ||||
|     $ref: 'write/chats/roomId/users.yaml' | ||||
|   /chats/{roomId}/users/{uid}: | ||||
|   | ||||
| @@ -5,6 +5,8 @@ get: | ||||
|   description: > | ||||
|     This operation retrieves a list of pinned messages for a given chat room. | ||||
|     This call will always return a maximum of 50 items, of which the result set can be offset based on the passed-in `start` parameter. | ||||
|  | ||||
|     N.B. The calling user must be in the chat room for this call to succeed. | ||||
|   parameters: | ||||
|     - in: path | ||||
|       name: roomId | ||||
|   | ||||
							
								
								
									
										39
									
								
								public/openapi/write/chats/roomId/typing.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								public/openapi/write/chats/roomId/typing.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| put: | ||||
|   tags: | ||||
|     - chats | ||||
|   summary: update typing state in chat room | ||||
|   description: > | ||||
|     This operation updates the typing state in a given chat room, so that other users in the room see that that user is typing. | ||||
|  | ||||
|     N.B. The calling user must be in the chat room for this call to succeed. | ||||
|   parameters: | ||||
|     - in: path | ||||
|       name: roomId | ||||
|       schema: | ||||
|         type: number | ||||
|       required: true | ||||
|       description: a valid room id | ||||
|       example: 1 | ||||
|   requestBody: | ||||
|     required: true | ||||
|     content: | ||||
|       application/json: | ||||
|         schema: | ||||
|           type: object | ||||
|           properties: | ||||
|             typing: | ||||
|               type: boolean | ||||
|               example: true | ||||
|           required: | ||||
|             - typing | ||||
|   responses: | ||||
|     '200': | ||||
|       description: Chat room typing state updated. | ||||
|       content: | ||||
|         application/json: | ||||
|           schema: | ||||
|             type: object | ||||
|             properties: | ||||
|               status: | ||||
|                 $ref: ../../../components/schemas/Status.yaml#/Status | ||||
|               response: {} | ||||
| @@ -391,11 +391,7 @@ define('forum/chats', [ | ||||
| 	Chats.addTypingHandler = function (parent, roomId) { | ||||
| 		const textarea = parent.find('[component="chat/input"]'); | ||||
| 		function emitTyping(typing) { | ||||
| 			socket.emit('modules.chats.typing', { | ||||
| 				roomId: roomId, | ||||
| 				typing: typing, | ||||
| 				username: app.user.username, | ||||
| 			}); | ||||
| 			api.put(`/chats/${roomId}/typing`, { typing }).catch(alerts.error); | ||||
| 		} | ||||
|  | ||||
| 		textarea.on('focus', () => textarea.val() && emitTyping(true)); | ||||
| @@ -744,7 +740,7 @@ define('forum/chats', [ | ||||
| 		}); | ||||
|  | ||||
| 		socket.on('event:chats.typing', async (data) => { | ||||
| 			if (chatModule.isFromBlockedUser(data.uid)) { | ||||
| 			if (data.uid === app.user.uid || chatModule.isFromBlockedUser(data.uid)) { | ||||
| 				return; | ||||
| 			} | ||||
| 			chatModule.updateTypingUserList($(`[component="chat/main-wrapper"][data-roomid="${data.roomId}"]`), data); | ||||
|   | ||||
| @@ -245,7 +245,7 @@ define('chat', [ | ||||
| 	}; | ||||
|  | ||||
| 	module.onUserTyping = function (data) { | ||||
| 		if (module.isFromBlockedUser(data.uid)) { | ||||
| 		if (data.uid === app.user.uid || module.isFromBlockedUser(data.uid)) { | ||||
| 			return; | ||||
| 		} | ||||
| 		const modal = module.getModal(data.roomId); | ||||
|   | ||||
| @@ -10,7 +10,9 @@ const messaging = require('../messaging'); | ||||
| const notifications = require('../notifications'); | ||||
| const privileges = require('../privileges'); | ||||
| const plugins = require('../plugins'); | ||||
| const utils = require('../utils'); | ||||
|  | ||||
| const websockets = require('../socket.io'); | ||||
| const socketHelpers = require('../socket.io/helpers'); | ||||
|  | ||||
| const chatsAPI = module.exports; | ||||
| @@ -207,6 +209,27 @@ chatsAPI.watch = async (caller, { roomId, state }) => { | ||||
| 	await messaging.setUserNotificationSetting(caller.uid, roomId, state); | ||||
| }; | ||||
|  | ||||
| chatsAPI.toggleTyping = async (caller, { roomId, typing }) => { | ||||
| 	if (!utils.isNumber(roomId) || typeof typing !== 'boolean') { | ||||
| 		throw new Error('[[error:invalid-data]]'); | ||||
| 	} | ||||
|  | ||||
| 	const [isInRoom, username] = await Promise.all([ | ||||
| 		messaging.isUserInRoom(caller.uid, roomId), | ||||
| 		user.getUserField(caller.uid, 'username'), | ||||
| 	]); | ||||
| 	if (!isInRoom) { | ||||
| 		throw new Error('[[error:no-privileges]]'); | ||||
| 	} | ||||
|  | ||||
| 	websockets.in(`chat_room_${roomId}`).emit('event:chats.typing', { | ||||
| 		uid: caller.uid, | ||||
| 		roomId, | ||||
| 		typing, | ||||
| 		username, | ||||
| 	}); | ||||
| }; | ||||
|  | ||||
| chatsAPI.users = async (caller, data) => { | ||||
| 	const start = data.hasOwnProperty('start') ? data.start : 0; | ||||
| 	const stop = start + 39; | ||||
|   | ||||
| @@ -95,6 +95,13 @@ Chats.watch = async (req, res) => { | ||||
| 	helpers.formatApiResponse(200, res); | ||||
| }; | ||||
|  | ||||
| Chats.toggleTyping = async (req, res) => { | ||||
| 	const { typing } = req.body; | ||||
|  | ||||
| 	await api.chats.toggleTyping(req, { typing, ...req.params }); | ||||
| 	helpers.formatApiResponse(200, res); | ||||
| }; | ||||
|  | ||||
| Chats.users = async (req, res) => { | ||||
| 	const { roomId } = req.params; | ||||
| 	const start = parseInt(req.query.start, 10) || 0; | ||||
|   | ||||
| @@ -27,6 +27,8 @@ module.exports = function () { | ||||
| 	setupApiRoute(router, 'put', '/:roomId/watch', [...middlewares, middleware.assert.room, middleware.checkRequired.bind(null, ['value'])], controllers.write.chats.watch); | ||||
| 	setupApiRoute(router, 'delete', '/:roomId/watch', [...middlewares, middleware.assert.room], controllers.write.chats.watch); | ||||
|  | ||||
| 	setupApiRoute(router, 'put', '/:roomId/typing', [...middlewares, middleware.assert.room], controllers.write.chats.toggleTyping); | ||||
|  | ||||
| 	setupApiRoute(router, 'get', '/:roomId/users', [...middlewares, middleware.assert.room], controllers.write.chats.users); | ||||
| 	setupApiRoute(router, 'post', '/:roomId/users', [...middlewares, middleware.assert.room, middleware.checkRequired.bind(null, ['uids'])], controllers.write.chats.invite); | ||||
| 	setupApiRoute(router, 'delete', '/:roomId/users', [...middlewares, middleware.assert.room, middleware.checkRequired.bind(null, ['uids'])], controllers.write.chats.kick); | ||||
|   | ||||
| @@ -213,19 +213,16 @@ SocketModules.chats.loadPinnedMessages = async (socket, data) => { | ||||
| }; | ||||
|  | ||||
| SocketModules.chats.typing = async (socket, data) => { | ||||
| 	if (!data || !utils.isNumber(data.roomId) || typeof data.typing !== 'boolean') { | ||||
| 	sockets.warnDeprecated(socket, 'PUT /api/v3/chats/:roomId/typing'); | ||||
|  | ||||
| 	if (!data) { | ||||
| 		throw new Error('[[error:invalid-data]]'); | ||||
| 	} | ||||
| 	const isInRoom = await Messaging.isUserInRoom(socket.uid, data.roomId); | ||||
| 	if (!isInRoom) { | ||||
| 		throw new Error('[[error:no-privileges]]'); | ||||
| 	} | ||||
| 	socket.to(`chat_room_${data.roomId}`).emit('event:chats.typing', { | ||||
| 		uid: socket.uid, | ||||
| 		roomId: data.roomId, | ||||
| 		typing: data.typing, | ||||
| 		username: validator.escape(String(data.username)), | ||||
| 	}); | ||||
|  | ||||
| 	// `username` is now inferred from caller uid | ||||
| 	delete data.username; | ||||
|  | ||||
| 	await api.chats.toggleTyping(socket, data); | ||||
| }; | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user