partialy implemented private messaging
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
|
||||
const { Server } = require('socket.io');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const jwtSecret = process.env.JWT_SECRET;
|
||||
const { db } = require('./db.js');
|
||||
|
||||
function initializeSocket(server) {
|
||||
const io = new Server(server, {
|
||||
cookie: {
|
||||
@@ -32,18 +32,23 @@ function initializeSocket(server) {
|
||||
if (!socket.user) {
|
||||
console.log('User not authenticated');
|
||||
socket.disconnect();
|
||||
return
|
||||
return;
|
||||
}
|
||||
const username = socket.user.username;
|
||||
console.log(username + ' connected');
|
||||
|
||||
// Join a room with the user's username
|
||||
socket.join(username);
|
||||
|
||||
loadInitialMessages(socket);
|
||||
|
||||
// chat message event
|
||||
socket.on('chat message', async (msg) => {
|
||||
socket.on('chat message', async (msgData) => {
|
||||
const { content, recipient } = msgData;
|
||||
let insertedId;
|
||||
try {
|
||||
// Insert the new message into the database
|
||||
const result = await db.query('INSERT INTO messages (content, username) VALUES ($1, $2) RETURNING id', [msg, username]);
|
||||
const result = await db.query('INSERT INTO messages (content, username, recipient) VALUES ($1, $2, $3) RETURNING id', [content, username, recipient]);
|
||||
insertedId = result.rows[0].id;
|
||||
} catch (err) {
|
||||
console.error('Error inserting message:', err);
|
||||
@@ -52,16 +57,16 @@ function initializeSocket(server) {
|
||||
|
||||
// Fetch the newly inserted message from the database
|
||||
try {
|
||||
const query = 'SELECT id, content, username FROM messages WHERE id = $1';
|
||||
const query = 'SELECT id, content, username, recipient FROM messages WHERE id = $1';
|
||||
const result = await db.query(query, [insertedId]);
|
||||
|
||||
if (result.rows.length > 0) {
|
||||
const newMessage = result.rows[0];
|
||||
const formattedMessage = `${newMessage.username}: ${newMessage.content}`;
|
||||
const formattedMessage = `${newMessage.username} to ${newMessage.recipient}: ${newMessage.content}`;
|
||||
console.log(formattedMessage);
|
||||
|
||||
// Emit the message to all connected clients
|
||||
io.emit('chat message', formattedMessage, newMessage.id);
|
||||
// Emit message to the sender's and recipient's rooms
|
||||
io.to(username).to(recipient).emit('chat message', formattedMessage);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error fetching inserted message:', err);
|
||||
@@ -70,35 +75,38 @@ function initializeSocket(server) {
|
||||
// The connection state recovery logic remains unchanged
|
||||
if (!socket.recovered) {
|
||||
try {
|
||||
const query = 'SELECT id, content, username FROM messages WHERE id > $1 ORDER BY id ASC';
|
||||
const query = 'SELECT id, content, username, recipient FROM messages WHERE id > $1 ORDER BY id ASC';
|
||||
const values = [socket.handshake.auth.serverOffset || 0];
|
||||
const result = await db.query(query, values);
|
||||
|
||||
for (const row of result.rows) {
|
||||
socket.emit('chat message', `${row.username}: ${row.content}`, row.id);
|
||||
if (row.username === username || row.recipient === username) {
|
||||
socket.emit('chat message', `${row.username} to ${row.recipient}: ${row.content}`);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error retrieving messages:', e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// disconnect event
|
||||
socket.on('disconnect', () => {
|
||||
console.log(username + ' have disconnected');
|
||||
console.log(username + ' has disconnected');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
return io;
|
||||
}
|
||||
|
||||
async function loadInitialMessages(socket) {
|
||||
const username = socket.user.username;
|
||||
try {
|
||||
const query = 'SELECT id, content, username FROM messages ORDER BY id DESC LIMIT 50';
|
||||
const result = await db.query(query);
|
||||
const query = 'SELECT id, content, username, recipient FROM messages WHERE username = $1 OR recipient = $1 ORDER BY id DESC LIMIT 50';
|
||||
const result = await db.query(query, [username]);
|
||||
|
||||
for (const row of result.rows.reverse()) {
|
||||
socket.emit('chat message', `${row.username}: ${row.content}`, row.id);
|
||||
socket.emit('chat message', `${row.username} to ${row.recipient}: ${row.content}`, row.id);
|
||||
}
|
||||
|
||||
// Set the server offset to the latest message id
|
||||
|
||||
@@ -1,19 +1,25 @@
|
||||
const form = document.getElementById('form');
|
||||
const input = document.getElementById('input');
|
||||
const recipientInput = document.createElement('input'); // New input for recipient
|
||||
const messages = document.getElementById('messages');
|
||||
document.getElementById('logout').onclick = logout;
|
||||
window.onload = function() {
|
||||
|
||||
window.onload = function() {
|
||||
document.getElementById('input').focus();
|
||||
}
|
||||
|
||||
|
||||
recipientInput.type = 'text';
|
||||
recipientInput.id = 'recipient';
|
||||
recipientInput.placeholder = 'Recipient username';
|
||||
form.insertBefore(recipientInput, input);
|
||||
|
||||
function logout() {
|
||||
cookieStore.delete('token');
|
||||
cookieStore.delete('io');
|
||||
location.reload();
|
||||
}
|
||||
|
||||
|
||||
// Function to get the token
|
||||
async function getToken() {
|
||||
try {
|
||||
const response = await fetch('/auth/token');
|
||||
@@ -26,7 +32,7 @@ async function getToken() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// Initialize socket connection
|
||||
|
||||
async function initializeSocket() {
|
||||
const token = await getToken();
|
||||
if (!token) {
|
||||
@@ -55,8 +61,11 @@ async function initializeSocket() {
|
||||
|
||||
form.addEventListener('submit', (e) => {
|
||||
e.preventDefault();
|
||||
if (input.value) {
|
||||
socket.emit('chat message', input.value);
|
||||
if (input.value && recipientInput.value) {
|
||||
socket.emit('chat message', {
|
||||
content: input.value,
|
||||
recipient: recipientInput.value
|
||||
});
|
||||
input.value = '';
|
||||
}
|
||||
});
|
||||
|
||||
@@ -7,24 +7,24 @@
|
||||
body { margin: 0; padding-bottom: 3rem; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }
|
||||
|
||||
#form { background: rgba(0, 0, 0, 0.15); padding: 0.25rem; position: fixed; bottom: 0; left: 0; right: 0; display: flex; height: 3rem; box-sizing: border-box; backdrop-filter: blur(10px); }
|
||||
#input { border: none; padding: 0 1rem; flex-grow: 1; border-radius: 2rem; margin: 0.25rem; }
|
||||
#input:focus { outline: none; }
|
||||
#input, #recipient { border: none; padding: 0 1rem; flex-grow: 1; border-radius: 2rem; margin: 0.25rem; }
|
||||
#input:focus, #recipient:focus { outline: none; }
|
||||
#form > button { background: #333; border: none; padding: 0 1rem; margin: 0.25rem; border-radius: 3px; outline: none; color: #fff; }
|
||||
|
||||
#messages { list-style-type: none; margin: 0; padding: 0; }
|
||||
#messages > li { padding: 0.5rem 1rem; }
|
||||
#messages > li:nth-child(odd) { background: #efefef; }
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<ul id="messages"></ul>
|
||||
|
||||
<form id="form" action="">
|
||||
<input id="recipient" autocomplete="off" placeholder="Recipient username"/>
|
||||
<input id="input" autocomplete="off" placeholder="Enter message"/>
|
||||
<button>Send</button>
|
||||
<button id="logout" onclick="logout()">Logout</button>
|
||||
<button type="submit">Send</button>
|
||||
<button id="logout" type="button">Logout</button>
|
||||
</form>
|
||||
|
||||
<script src="/socket.io/socket.io.js"></script>
|
||||
|
||||
Reference in New Issue
Block a user