import { DyNTS_SingletonService } from '../../../_services/base/singleton.service'; import { DyNTS_GlobalService } from '../../../_services/core/global.service'; import { DyFM_Log } from '@futdevpro/fsm-dynamo'; import { DyFM_Msg_EventKey } from '@futdevpro/fsm-dynamo/messaging'; /** * Messaging Events Service * Handles real-time socket events for messaging */ export class DyNTS_Msg_Events_Service extends DyNTS_SingletonService { static getInstance(): DyNTS_Msg_Events_Service { return DyNTS_Msg_Events_Service.getSingletonInstance(); } /** * Get socket server instance * Override this in extended classes to provide custom socket server */ protected getSocketServer(): any | null { // Default: no socket server (messaging works without real-time events) return null; } /** * Emit message sent event */ emitMessageSent(message: any, conversationId: string): void { try { const socketServer = this.getSocketServer(); if (socketServer && socketServer.emitToRoom) { // Emit to conversation room socketServer.emitToRoom( `conversation:${conversationId}`, DyFM_Msg_EventKey.messageSent, message ); } } catch (error) { DyFM_Log.error('Failed to emit message sent event', error); } } /** * Emit message updated event */ emitMessageUpdated(message: any, conversationId: string): void { try { const socketServer = this.getSocketServer(); if (socketServer && socketServer.emitToRoom) { socketServer.emitToRoom( `conversation:${conversationId}`, DyFM_Msg_EventKey.messageUpdated, message ); } } catch (error) { DyFM_Log.error('Failed to emit message updated event', error); } } /** * Emit typing indicator */ emitTypingIndicator( userId: string, conversationId: string, isTyping: boolean ): void { try { const socketServer = this.getSocketServer(); if (socketServer && socketServer.emitToRoom) { const eventKey = isTyping ? DyFM_Msg_EventKey.typingStart : DyFM_Msg_EventKey.typingStop; socketServer.emitToRoom( `conversation:${conversationId}`, eventKey, { userId, conversationId } ); } } catch (error) { DyFM_Log.error('Failed to emit typing indicator', error); } } /** * Emit conversation created event */ emitConversationCreated(conversation: any, participantIds: string[]): void { try { const socketServer = this.getSocketServer(); if (socketServer && socketServer.emitToUser) { // Emit to each participant participantIds.forEach(userId => { socketServer.emitToUser( userId, DyFM_Msg_EventKey.conversationCreated, conversation ); }); } } catch (error) { DyFM_Log.error('Failed to emit conversation created event', error); } } /** * Emit message deleted event */ emitMessageDeleted(messageId: string, conversationId: string): void { try { const socketServer = this.getSocketServer(); if (socketServer && socketServer.emitToRoom) { socketServer.emitToRoom( `conversation:${conversationId}`, DyFM_Msg_EventKey.messageDeleted, { messageId, conversationId } ); } } catch (error) { DyFM_Log.error('Failed to emit message deleted event', error); } } /** * Emit conversation updated event */ emitConversationUpdated(conversation: any): void { try { const socketServer = this.getSocketServer(); if (socketServer && socketServer.emitToRoom) { const participantIds = conversation.participants?.map((p: any) => p.userId) || []; participantIds.forEach(userId => { socketServer.emitToUser( userId, DyFM_Msg_EventKey.conversationUpdated, conversation ); }); } } catch (error) { DyFM_Log.error('Failed to emit conversation updated event', error); } } /** * Emit conversation deleted event */ emitConversationDeleted(conversationId: string): void { try { const socketServer = this.getSocketServer(); if (socketServer && socketServer.emitToRoom) { socketServer.emitToRoom( `conversation:${conversationId}`, DyFM_Msg_EventKey.conversationDeleted, { conversationId } ); } } catch (error) { DyFM_Log.error('Failed to emit conversation deleted event', error); } } /** * Emit participant added event */ emitParticipantAdded(conversationId: string, userId: string): void { try { const socketServer = this.getSocketServer(); if (socketServer && socketServer.emitToUser) { socketServer.emitToUser( userId, DyFM_Msg_EventKey.participantAdded, { conversationId, userId } ); } } catch (error) { DyFM_Log.error('Failed to emit participant added event', error); } } /** * Emit participant removed event */ emitParticipantRemoved(conversationId: string, userId: string): void { try { const socketServer = this.getSocketServer(); if (socketServer && socketServer.emitToUser) { socketServer.emitToUser( userId, DyFM_Msg_EventKey.participantRemoved, { conversationId, userId } ); } } catch (error) { DyFM_Log.error('Failed to emit participant removed event', error); } } /** * Emit message read event */ emitMessageRead(messageId: string, userId: string, conversationId: string): void { try { const socketServer = this.getSocketServer(); if (socketServer && socketServer.emitToRoom) { socketServer.emitToRoom( `conversation:${conversationId}`, DyFM_Msg_EventKey.messageRead, { messageId, userId, conversationId } ); } } catch (error) { DyFM_Log.error('Failed to emit message read event', error); } } /** * Emit reaction added event */ emitReactionAdded(messageId: string, reaction: any): void { try { const socketServer = this.getSocketServer(); if (socketServer && socketServer.emitToRoom) { socketServer.emitToRoom( `conversation:${reaction.conversationId || 'unknown'}`, DyFM_Msg_EventKey.reactionAdded, { messageId, reaction } ); } } catch (error) { DyFM_Log.error('Failed to emit reaction added event', error); } } /** * Emit reaction removed event */ emitReactionRemoved(messageId: string, userId: string, emoji: string): void { try { const socketServer = this.getSocketServer(); if (socketServer && socketServer.emitToRoom) { socketServer.emitToRoom( `conversation:${userId}`, // This should be conversationId, but we don't have it DyFM_Msg_EventKey.reactionRemoved, { messageId, userId, emoji } ); } } catch (error) { DyFM_Log.error('Failed to emit reaction removed event', error); } } }