sourabhrealtime
Version:
ROBUST RICH TEXT EDITOR: Single-pane contentEditable with direct text selection formatting, speech features, undo/redo, professional UI - Perfect TipTap alternative
97 lines (82 loc) • 3.09 kB
JavaScript
// Fixed invitation system for real-time notifications
export class InvitationSystem {
constructor() {
this.invitations = new Map(); // userId -> invitations[]
this.userSockets = new Map(); // userId -> socketId
this.socketUsers = new Map(); // socketId -> userId
}
// Register user socket
registerUser(userId, socketId) {
this.userSockets.set(userId, socketId);
this.socketUsers.set(socketId, userId);
console.log(`User ${userId} registered with socket ${socketId}`);
}
// Unregister user socket
unregisterUser(socketId) {
const userId = this.socketUsers.get(socketId);
if (userId) {
this.userSockets.delete(userId);
this.socketUsers.delete(socketId);
console.log(`User ${userId} unregistered from socket ${socketId}`);
}
}
// Send invitation
sendInvitation(io, invitation) {
// Store invitation
if (!this.invitations.has(invitation.invitedUserId)) {
this.invitations.set(invitation.invitedUserId, []);
}
this.invitations.get(invitation.invitedUserId).push(invitation);
// Send real-time notification to user if online
const userSocketId = this.userSockets.get(invitation.invitedUserId);
if (userSocketId) {
io.to(userSocketId).emit('invitation-received', invitation);
console.log(`Invitation sent to user ${invitation.invitedUserId} via socket ${userSocketId}`);
} else {
console.log(`User ${invitation.invitedUserId} is offline, invitation stored`);
}
return invitation;
}
// Get user invitations
getUserInvitations(userId) {
return this.invitations.get(userId) || [];
}
// Accept invitation
acceptInvitation(userId, invitationId) {
const userInvitations = this.invitations.get(userId) || [];
const invitation = userInvitations.find(inv => inv.id === invitationId);
if (invitation && invitation.status === 'pending') {
invitation.status = 'accepted';
invitation.acceptedAt = Date.now();
return { success: true, invitation };
}
return { success: false, message: 'Invitation not found or already processed' };
}
// Decline invitation
declineInvitation(userId, invitationId) {
const userInvitations = this.invitations.get(userId) || [];
const invitation = userInvitations.find(inv => inv.id === invitationId);
if (invitation && invitation.status === 'pending') {
invitation.status = 'declined';
invitation.declinedAt = Date.now();
return { success: true, invitation };
}
return { success: false, message: 'Invitation not found or already processed' };
}
// Get all invitations (admin)
getAllInvitations() {
const allInvitations = [];
for (const [userId, invitations] of this.invitations.entries()) {
allInvitations.push(...invitations.map(inv => ({ ...inv, userId })));
}
return allInvitations;
}
// Check if user is online
isUserOnline(userId) {
return this.userSockets.has(userId);
}
// Get online users
getOnlineUsers() {
return Array.from(this.userSockets.keys());
}
}