adjusted code to handle getMessage function and other by conversation_id (groups partially are working 😲)

This commit is contained in:
slawk0
2024-11-30 22:29:25 +01:00
parent a805cf3e1a
commit 2f48c7423b
9 changed files with 148 additions and 181 deletions

View File

@@ -153,86 +153,25 @@ async function getUserId(username) {
}
async function insertMessage(
senderUsername,
receiverUsername,
senderId,
conversation_id,
content,
attachmentUrl,
) {
console.log(
`senderUsername: ${senderUsername}, receiverUsername: ${receiverUsername}, content: ${content}, attachmentUrl: ${attachmentUrl} `,
`senderId: ${senderId}, conversation_id: ${conversation_id}, content: ${content}, attachmentUrl: ${attachmentUrl}`,
);
const query = `
WITH sender AS (
SELECT user_id
FROM Accounts
WHERE username = $1
LIMIT 1
),
recipient AS (
SELECT user_id
FROM Accounts
WHERE username = $2
LIMIT 1
),
conversation AS (
SELECT conversation_id
FROM Conversations
WHERE conversation_type = 'direct'
AND EXISTS (
SELECT 1
FROM Memberships
WHERE conversation_id = Conversations.conversation_id
AND user_id = (SELECT user_id FROM sender)
)
AND EXISTS (
SELECT 1
FROM Memberships
WHERE conversation_id = Conversations.conversation_id
AND user_id = (SELECT user_id FROM recipient)
)
LIMIT 1
),
new_conversation AS (
INSERT INTO Conversations (conversation_type)
SELECT 'direct'
WHERE NOT EXISTS (SELECT 1 FROM conversation)
RETURNING conversation_id
),
final_conversation AS (
SELECT conversation_id FROM conversation
UNION ALL
SELECT conversation_id FROM new_conversation
),
insert_memberships AS (
INSERT INTO Memberships (conversation_id, user_id)
SELECT conversation_id, user_id
FROM final_conversation, sender
WHERE NOT EXISTS (
SELECT 1
FROM Memberships
WHERE conversation_id = final_conversation.conversation_id
AND user_id = sender.user_id
)
UNION ALL
SELECT conversation_id, user_id
FROM final_conversation, recipient
WHERE NOT EXISTS (
SELECT 1
FROM Memberships
WHERE conversation_id = final_conversation.conversation_id
AND user_id = recipient.user_id
)
)
INSERT INTO Messages (conversation_id, user_id, content, attachment_url)
SELECT conversation_id, sender.user_id, $3, $4
FROM final_conversation, sender
VALUES ($1, $2, $3, $4)
RETURNING message_id, content, sent_at, attachment_url, user_id AS sender_id, conversation_id;
`;
try {
const result = await client.query(query, [
senderUsername,
receiverUsername,
conversation_id,
senderId,
content,
attachmentUrl,
]);
@@ -314,98 +253,65 @@ async function addMemberToGroupByUsername(conversation_id, username) {
}
}
async function getMessages(user_id, receiverUsername, limit = 50, cursor = 0) {
let query = `
WITH recipient AS (
SELECT user_id
FROM Accounts
WHERE username = $2
),
conversation AS (
SELECT conversation_id
FROM Conversations
WHERE conversation_type = 'direct'
AND EXISTS (
SELECT 1
FROM Memberships
WHERE conversation_id = Conversations.conversation_id
AND user_id = $1
)
AND EXISTS (
SELECT 1
FROM Memberships
WHERE conversation_id = Conversations.conversation_id
AND user_id = (SELECT user_id FROM recipient)
)
LIMIT 1
)
SELECT
m.message_id,
m.content AS message,
m.sent_at,
m.attachment_url,
a.username AS sender,
r.username AS recipient
FROM Messages m
JOIN Accounts a ON m.user_id = a.user_id
JOIN Memberships mem ON m.conversation_id = mem.conversation_id AND mem.user_id = (SELECT user_id FROM recipient)
JOIN Accounts r ON m.user_id = r.user_id
WHERE m.conversation_id = (SELECT conversation_id FROM conversation)
AND m.message_id < $3
ORDER BY m.message_id DESC
LIMIT $4;
async function getMessages(user_id, conversation_id, limit = 50, cursor = 0) {
// Check if the user is a member of the conversation
const checkMembershipQuery = `
SELECT 1 FROM Memberships
WHERE conversation_id = $1 AND user_id = $2
LIMIT 1;
`;
let params = [user_id, receiverUsername, cursor, limit];
if (!cursor) {
query = `
WITH recipient AS (
SELECT user_id
FROM Accounts
WHERE username = $2
),
conversation AS (
SELECT conversation_id
FROM Conversations
WHERE conversation_type = 'direct'
AND EXISTS (
SELECT 1
FROM Memberships
WHERE conversation_id = Conversations.conversation_id
AND user_id = $1
)
AND EXISTS (
SELECT 1
FROM Memberships
WHERE conversation_id = Conversations.conversation_id
AND user_id = (SELECT user_id FROM recipient)
)
LIMIT 1
)
SELECT
m.message_id,
m.content AS message,
m.sent_at,
m.attachment_url,
a.username AS sender,
r.username AS recipient
FROM Messages m
JOIN Accounts a ON m.user_id = a.user_id
JOIN Memberships mem ON m.conversation_id = mem.conversation_id AND mem.user_id = (SELECT user_id FROM recipient)
JOIN Accounts r ON m.user_id = r.user_id
WHERE m.conversation_id = (SELECT conversation_id FROM conversation)
ORDER BY m.message_id DESC
LIMIT $3;
`;
params = [user_id, receiverUsername, limit];
}
try {
const results = await client.query(query, params);
const checkResult = await client.query(checkMembershipQuery, [
conversation_id, // $1
user_id, // $2
]);
if (checkResult.rows.length === 0) {
console.error("User is not a member of the conversation");
return [];
}
let query;
let params;
if (cursor) {
query = `
SELECT
m.message_id,
m.content AS message,
m.sent_at,
m.attachment_url,
a.username AS sender
FROM Messages m
JOIN Accounts a ON m.user_id = a.user_id
WHERE m.conversation_id = $1
AND m.message_id < $2
ORDER BY m.message_id DESC
LIMIT $3;
`;
params = [conversation_id, cursor, limit];
} else {
query = `
SELECT
m.message_id,
m.content AS message,
m.sent_at,
m.attachment_url,
a.username AS sender
FROM Messages m
JOIN Accounts a ON m.user_id = a.user_id
WHERE m.conversation_id = $1
ORDER BY m.message_id DESC
LIMIT $2;
`;
params = [conversation_id, limit];
}
console.log(
`Get messages for user_id: ${user_id}, receiverUsername: ${receiverUsername}`,
`Get messages for user_id: ${user_id}, conversation_id: ${conversation_id}`,
);
const results = await client.query(query, params);
let messages = results.rows;
if (!cursor) {
messages = messages.reverse();
@@ -414,6 +320,7 @@ async function getMessages(user_id, receiverUsername, limit = 50, cursor = 0) {
return messages;
} catch (e) {
console.error("Failed to get messages ", e);
return [];
}
}
@@ -628,9 +535,28 @@ async function getContacts(user_id) {
c.contact_user_id AS user_id,
a.username AS username,
c.last_active,
m.conversation_id,
'direct' AS type
FROM Contacts c
JOIN Accounts a ON a.user_id = c.contact_user_id
JOIN Memberships m ON m.user_id = c.contact_user_id AND m.conversation_id = (
SELECT conversation_id
FROM Conversations
WHERE conversation_type = 'direct'
AND EXISTS (
SELECT 1
FROM Memberships
WHERE conversation_id = Conversations.conversation_id
AND user_id = $1
)
AND EXISTS (
SELECT 1
FROM Memberships
WHERE conversation_id = Conversations.conversation_id
AND user_id = c.contact_user_id
)
LIMIT 1
)
WHERE c.user_id = $1
ORDER BY c.last_active DESC;
`;
@@ -653,10 +579,10 @@ async function getContacts(user_id) {
const contacts = contactsResult.rows;
const groups = groupsResult.rows.map((group) => ({
group_id: group.id,
username: group.username,
last_active: group.last_active,
type: group.type,
conversation_id: group.id,
}));
// Combine contacts and groups
@@ -726,6 +652,24 @@ async function updateContactLastActive(userUsername, receiverUsername) {
}
}
async function getConversationsForUser(user_id) {
const query = `
SELECT conversation_id
FROM Memberships
WHERE user_id = $1;
`;
try {
const result = await client.query(query, [user_id]);
const conversationIds = result.rows.map((row) => row.conversation_id);
console.log("getconversationsforuser: ", conversationIds);
return conversationIds;
} catch (e) {
console.error("Failed to get conversations for user ", e);
return [];
}
}
function getTime() {
return new Date();
}
@@ -747,4 +691,5 @@ module.exports = {
createGroup,
addMemberToGroup,
addMemberToGroupByUsername,
getConversationsForUser,
};

View File

@@ -331,6 +331,9 @@ app.post("/api/chat/groups/add", async (req, res) => {
if (!username) {
return res.status(400).json({ message: "Username not provided" });
}
if (!group_id) {
return res.status(400).json({ message: "group_id not provided" });
}
const result = await addMemberToGroupByUsername(group_id, username);
if (result !== null) {
return res.status(200).json({ message: "Successfully added member" });

View File

@@ -1,5 +1,5 @@
const { Server } = require("socket.io");
const { insertMessage } = require("../db/db");
const { insertMessage, getConversationsForUser } = require("../db/db");
const { isValidUsername } = require("../utils/filter");
const { verifyJwtToken } = require("../auth/jwt");
const console = require("node:console");
@@ -62,21 +62,31 @@ function initializeSocket(io) {
return;
}
socket.join(username); // join username room
try {
const conversations = await getConversationsForUser(socket.user_id);
socket.join(conversations);
} catch (e) {
console.error("(socket) Failed to get user conversations");
}
socket.on("chat message", async (msg, callback) => {
const { message, recipient, attachment_url } = msg;
const sender = username;
const sender = socket.user_id;
if (!message && !attachment_url) {
callback({
status: "error",
tempId: msg.tempId,
message: "No message or attachment provided",
});
return;
}
if (!recipient) {
callback({ status: "error", message: "No recipient provided" });
callback({
status: "error",
tempId: msg.tempId,
message: "No recipient provided",
});
return;
}
@@ -96,16 +106,25 @@ function initializeSocket(io) {
return;
}
const { message_id, timestamp, sender_id } = insertedMessage;
const {
message_id,
content,
sent_at,
sender_id,
conversation_id,
timestamp,
} = insertedMessage;
console.log("(socket) received from chat message", msg);
io.to(username).to(recipient).emit("chat message", {
sender,
message,
message: content,
attachment_url,
recipient,
message_id,
sender_id,
sent_at,
conversation_id,
});
console.log("(socket) sent on 'chat message' socket: ", {
sender,