/* * Copyright (c) 2022. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ import {MemorySocketEventMessage} from "../../../../modules/memory-event-bus/socket"; import {SocketInterface} from "../../../../modules/socket"; import {ChatMessage} from "@chamesu/common/domains/chat/message"; import {RecordEvent, RecordEventOptions} from "../../../../modules/socket/event"; export type RoomSubscribeEvent = 'users' | 'messages'; function createMessageMemoryTemplate(roomId: string, message: Partial, event: string) : MemorySocketEventMessage { return { event, payload: { id: message.id, type: 'chatMessage', meta: { roomId }, data: message } }; } export interface RoomEventOptions extends RecordEventOptions { socketRoomKey: string, socketUserKey: string, socketSubscriptionKey: string } export class RoomEvent extends RecordEvent { constructor(public readonly options : RoomEventOptions) { super(options); } //-------------------------------------------------------------------- public emitMessageCreated(roomId: string, message: ChatMessage) { let redisMessage : MemorySocketEventMessage = createMessageMemoryTemplate(roomId, message, 'messageCreated'); redisMessage.room = this.getFullSocketRoomSubscriptionKey(roomId, 'messages'); this.publish(redisMessage); } public emitMessageUpdated(roomId: string, message: ChatMessage) { let redisMessage : MemorySocketEventMessage = createMessageMemoryTemplate(roomId, message, 'messageUpdated'); redisMessage.room = this.getFullSocketRoomSubscriptionKey(roomId, 'messages'); this.publish(redisMessage); } public emitMessageDeleted(roomId: string, message: ChatMessage) { let redisMessage : MemorySocketEventMessage = createMessageMemoryTemplate(roomId, message, 'messageDeleted'); redisMessage.room = this.getFullSocketRoomSubscriptionKey(roomId, 'messages'); this.publish(redisMessage); } //-------------------------------------------------------------------- public emitConnectionClose(roomId: string, socketId: string) { console.log('connection close' + socketId); let redisMessage : MemorySocketEventMessage = { room: socketId, event: 'connectionClose', payload: { type: 'room', id: roomId } } this.publish(redisMessage); } public emitUserOnline(roomId: string, userId: number) { let redisMessage : MemorySocketEventMessage = { room: this.getFullSocketRoomSubscriptionKey(roomId, 'users'), event: 'userOnline', payload: { id: userId, type: 'user', meta: { roomId, firstSeen: Date.now() } } }; this.publish(redisMessage); } public async emitUserOffline(roomId: string, userId: number) { let redisMessage : MemorySocketEventMessage = { room: this.getFullSocketRoomSubscriptionKey(roomId, 'users'), event: 'userOffline', payload: { id: userId, type: 'user', meta: { roomId } } }; this.publish(redisMessage); } public async emitUserMessageTyping(roomId: string, userId: number) { let redisMessage : MemorySocketEventMessage = { room: this.getFullSocketRoomSubscriptionKey(roomId, 'messages'), event: 'userTyping', payload: { id: userId, type: 'user', meta: { roomId } } }; this.publish(redisMessage); } //-------------------------------------------------------------------- public subscribeAsSocket(socket: SocketInterface, roomId: string, event: RoomSubscribeEvent) { const subscriptionKey = this.getFullSocketRoomSubscriptionKey(roomId, event); socket.join(subscriptionKey); } public unsubscribeAsSocket(socket: SocketInterface, roomId: string, event: RoomSubscribeEvent) { const subscriptionKey = this.getFullSocketRoomSubscriptionKey(roomId, event); socket.leave(subscriptionKey); } //-------------------------------------------------------------------- public getFullSocketUserKey(userId: number) { return this.options.socketUserKey + ':' + userId; } public getFullSocketRoomKey(roomId: string) { return this.options.socketRoomKey + ':' + roomId; } public getFullSocketRoomUserKey(roomId: string, userId: number) { return this.getFullSocketRoomKey(roomId) + ':' + this.getFullSocketUserKey(userId); } public getFullSocketSubscriptionKey(event: RoomSubscribeEvent) { return this.options.socketSubscriptionKey + ':' + event; } public getFullSocketRoomSubscriptionKey(roomId: string, event: RoomSubscribeEvent) { return this.getFullSocketRoomKey(roomId) + ':' + this.getFullSocketSubscriptionKey(event); } } let roomEvent : RoomEvent | undefined; export function useChatRoomEvent(socketNamespaceName?: string) : RoomEvent { if(typeof roomEvent !== 'undefined') { return roomEvent; } if(typeof socketNamespaceName == 'undefined') { throw new Error('No namespace name injected in room event handlder...'); } roomEvent = new RoomEvent({ socketNamespace: socketNamespaceName, socketRoomKey: 'room', socketUserKey: 'user', socketSubscriptionKey: 'subscription' }); return roomEvent; }