ajout de pastille pour les amis dans global chat et recuperation des messages recents

This commit is contained in:
2026-01-27 02:15:31 +01:00
parent db7062c34a
commit 3047f7593b
4 changed files with 73 additions and 5 deletions
+24
View File
@@ -178,6 +178,29 @@ async function declineFriendRequest(userId, fromUserId) {
} }
} }
/**
* Get list of friend IDs for a user (for quick lookup)
*/
async function getFriendIds(userId) {
try {
const result = await query(
`SELECT
CASE
WHEN f.id_user1 = $1 THEN f.id_user2
ELSE f.id_user1
END as friend_id
FROM friendship f
WHERE (f.id_user1 = $1 OR f.id_user2 = $1)
AND f.status = 'accepted'`,
[userId]
);
return result.rows.map(row => row.friend_id);
} catch (err) {
console.error('Get friend IDs error:', err);
return [];
}
}
/** /**
* Remove a friend * Remove a friend
*/ */
@@ -207,6 +230,7 @@ async function removeFriend(userId, friendId) {
export default { export default {
getFriends, getFriends,
getFriendIds,
getPendingRequests, getPendingRequests,
searchUsers, searchUsers,
sendFriendRequest, sendFriendRequest,
+20 -2
View File
@@ -1,5 +1,6 @@
import jwt from 'jsonwebtoken'; import jwt from 'jsonwebtoken';
import chatService from './global_chat.js'; import chatService from './global_chat.js';
import friendsService from './friends.js';
function setupSocketIO(io) function setupSocketIO(io)
{ {
@@ -21,11 +22,27 @@ function setupSocketIO(io)
} }
}); });
io.on('connection', (socket) => io.on('connection', async (socket) =>
{ {
console.log(`User connected: ${socket.user.username}`); console.log(`User connected: ${socket.user.username}`);
socket.join('general-chat'); socket.join('general-chat');
// Send recent messages and friend IDs on connection
try {
const [recentMessages, friendIds] = await Promise.all([
chatService.getRecentMessages(50),
friendsService.getFriendIds(socket.user.userId)
]);
socket.emit('chat-init', {
messages: recentMessages,
friendIds: friendIds
});
} catch (err) {
console.error('Error fetching initial data:', err);
}
socket.on('chat-message', async(data) => socket.on('chat-message', async(data) =>
{ {
try try
@@ -33,7 +50,8 @@ function setupSocketIO(io)
const message = await chatService.saveMessage(socket.user.userId, data.content); const message = await chatService.saveMessage(socket.user.userId, data.content);
socket.broadcast.to('general-chat').emit('chat-message', socket.broadcast.to('general-chat').emit('chat-message',
{ {
id:message.id, id: message.id,
sender_id: socket.user.userId,
username: socket.user.username, username: socket.user.username,
content: message.content, content: message.content,
created_at: message.created_at created_at: message.created_at
+19 -3
View File
@@ -16,6 +16,7 @@ export class GlobalChat extends Window {
this.socket = null; this.socket = null;
this.connected = false; this.connected = false;
this.friendIds = new Set();
this.buildUI(); this.buildUI();
this.bindEvents(); this.bindEvents();
@@ -100,15 +101,17 @@ export class GlobalChat extends Window {
* @param {string} username - User name * @param {string} username - User name
* @param {string} content - Message content * @param {string} content - Message content
* @param {boolean} isOwn - Is this the current user's message * @param {boolean} isOwn - Is this the current user's message
* @param {boolean} isFriend - Is this user a friend
*/ */
addChatMessage(username, content, isOwn = false) { addChatMessage(username, content, isOwn = false, isFriend = false) {
const msg = this.createElement('div', CSS.CHAT_MESSAGE); const msg = this.createElement('div', CSS.CHAT_MESSAGE);
if (isOwn) { if (isOwn) {
msg.classList.add('chat__message--own'); msg.classList.add('chat__message--own');
} }
msg.innerHTML = `<strong>${this.escapeHtml(username)}:</strong> ${this.escapeHtml(content)}`; const friendIndicator = isFriend ? '<span class="chat__friend-indicator"></span>' : '';
msg.innerHTML = `${friendIndicator}<strong>${this.escapeHtml(username)}:</strong> ${this.escapeHtml(content)}`;
this.output.appendChild(msg); this.output.appendChild(msg);
this.scrollToBottom(); this.scrollToBottom();
} }
@@ -252,8 +255,21 @@ export class GlobalChat extends Window {
eventBus.emit(Events.CHAT_DISCONNECTED, { reason }); eventBus.emit(Events.CHAT_DISCONNECTED, { reason });
}); });
// Handle initial data (recent messages + friend IDs)
this.socket.on('chat-init', (data) => {
console.log('Received chat init data:', data.messages.length, 'messages');
this.friendIds = new Set(data.friendIds || []);
// Display recent messages
data.messages.forEach(msg => {
const isFriend = this.friendIds.has(msg.sender_id);
this.addChatMessage(msg.username, msg.content, false, isFriend);
});
});
this.socket.on('chat-message', (msg) => { this.socket.on('chat-message', (msg) => {
this.addChatMessage(msg.username, msg.content); const isFriend = this.friendIds.has(msg.sender_id);
this.addChatMessage(msg.username, msg.content, false, isFriend);
eventBus.emit(Events.CHAT_MESSAGE_RECEIVED, msg); eventBus.emit(Events.CHAT_MESSAGE_RECEIVED, msg);
}); });
} }
+10
View File
@@ -382,6 +382,16 @@ body {
align-self: flex-end; align-self: flex-end;
} }
.chat__friend-indicator {
display: inline-block;
width: 8px;
height: 8px;
background-color: var(--color-success);
border-radius: 50%;
margin-right: var(--spacing-xs);
vertical-align: middle;
}
.chat__system { .chat__system {
color: var(--color-text-muted); color: var(--color-text-muted);
font-size: var(--font-size-sm); font-size: var(--font-size-sm);