conversations, unread count, autoscrolling to recent messages, cursor in text bar
This commit is contained in:
@@ -3,6 +3,7 @@ const { Message, User } = require('../models');
|
||||
const { authenticateToken } = require('../middleware/auth');
|
||||
const logger = require('../utils/logger');
|
||||
const { emitNewMessage, emitMessageRead } = require('../sockets/messageSocket');
|
||||
const { Op } = require('sequelize');
|
||||
const router = express.Router();
|
||||
|
||||
// Get all messages for the current user (inbox)
|
||||
@@ -38,6 +39,100 @@ router.get('/', authenticateToken, async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Get conversations grouped by user pairs
|
||||
router.get('/conversations', authenticateToken, async (req, res) => {
|
||||
try {
|
||||
const userId = req.user.id;
|
||||
|
||||
// Fetch all messages where user is sender or receiver
|
||||
const allMessages = await Message.findAll({
|
||||
where: {
|
||||
[Op.or]: [
|
||||
{ senderId: userId },
|
||||
{ receiverId: userId }
|
||||
]
|
||||
},
|
||||
include: [
|
||||
{
|
||||
model: User,
|
||||
as: 'sender',
|
||||
attributes: ['id', 'firstName', 'lastName', 'profileImage']
|
||||
},
|
||||
{
|
||||
model: User,
|
||||
as: 'receiver',
|
||||
attributes: ['id', 'firstName', 'lastName', 'profileImage']
|
||||
}
|
||||
],
|
||||
order: [['createdAt', 'DESC']]
|
||||
});
|
||||
|
||||
// Group messages by conversation partner
|
||||
const conversationsMap = new Map();
|
||||
|
||||
allMessages.forEach(message => {
|
||||
// Determine the conversation partner
|
||||
const partnerId = message.senderId === userId ? message.receiverId : message.senderId;
|
||||
const partner = message.senderId === userId ? message.receiver : message.sender;
|
||||
|
||||
if (!conversationsMap.has(partnerId)) {
|
||||
conversationsMap.set(partnerId, {
|
||||
partnerId,
|
||||
partner: partner ? {
|
||||
id: partner.id,
|
||||
firstName: partner.firstName,
|
||||
lastName: partner.lastName,
|
||||
profileImage: partner.profileImage
|
||||
} : null,
|
||||
lastMessage: null,
|
||||
lastMessageAt: null,
|
||||
unreadCount: 0
|
||||
});
|
||||
}
|
||||
|
||||
const conversation = conversationsMap.get(partnerId);
|
||||
|
||||
// Count unread messages (only those received by current user)
|
||||
if (message.receiverId === userId && !message.isRead) {
|
||||
conversation.unreadCount++;
|
||||
}
|
||||
|
||||
// Keep the most recent message (messages are already sorted DESC)
|
||||
if (!conversation.lastMessage) {
|
||||
conversation.lastMessage = {
|
||||
id: message.id,
|
||||
content: message.content,
|
||||
senderId: message.senderId,
|
||||
createdAt: message.createdAt,
|
||||
isRead: message.isRead
|
||||
};
|
||||
conversation.lastMessageAt = message.createdAt;
|
||||
}
|
||||
});
|
||||
|
||||
// Convert to array and sort by most recent message first
|
||||
const conversations = Array.from(conversationsMap.values())
|
||||
.filter(conv => conv.partner !== null) // Filter out conversations with deleted users
|
||||
.sort((a, b) => new Date(b.lastMessageAt) - new Date(a.lastMessageAt));
|
||||
|
||||
const reqLogger = logger.withRequestId(req.id);
|
||||
reqLogger.info("Conversations fetched", {
|
||||
userId: req.user.id,
|
||||
conversationCount: conversations.length
|
||||
});
|
||||
|
||||
res.json(conversations);
|
||||
} catch (error) {
|
||||
const reqLogger = logger.withRequestId(req.id);
|
||||
reqLogger.error("Conversations fetch failed", {
|
||||
error: error.message,
|
||||
stack: error.stack,
|
||||
userId: req.user.id
|
||||
});
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// Get sent messages
|
||||
router.get('/sent', authenticateToken, async (req, res) => {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user