diff --git a/client/src/components/chat/chatArea/MessagesArea.tsx b/client/src/components/chat/chatArea/MessagesArea.tsx index 7315083..30cc03d 100644 --- a/client/src/components/chat/chatArea/MessagesArea.tsx +++ b/client/src/components/chat/chatArea/MessagesArea.tsx @@ -111,6 +111,7 @@ function MessagesArea() { type: 'direct', last_active: new Date().toString(), last_message: msg.message, + last_message_id: msg.message_id, last_message_sender: msg.sender, last_message_time: new Date().toString(), }, @@ -153,6 +154,7 @@ function MessagesArea() { type: 'direct', last_active: new Date().toString(), last_message: msg.message, + last_message_id: msg.message_id, last_message_sender: msg.sender, last_message_time: new Date().toString(), }, @@ -184,6 +186,18 @@ function MessagesArea() { (message) => message.message_id !== msg.message_id, ), ); + setContactsList((prevContacts) => { + return prevContacts.map((contact) => + contact.last_message_id === msg.message_id + ? { + ...contact, + last_active: new Date().toString(), + last_message: 'message deleted', + last_message_time: new Date().toString(), + } + : contact, + ); + }); }, ); diff --git a/client/src/components/chat/leftSidebar/ContactsList.tsx b/client/src/components/chat/leftSidebar/ContactsList.tsx index e3ec93a..b053db2 100644 --- a/client/src/components/chat/leftSidebar/ContactsList.tsx +++ b/client/src/components/chat/leftSidebar/ContactsList.tsx @@ -12,7 +12,7 @@ import { AlertDialogTitle, AlertDialogTrigger, } from '@/components/ui/alert-dialog.tsx'; -import { Dot, Paperclip } from 'lucide-react'; +import { Ellipsis, Paperclip } from 'lucide-react'; import LastActiveTime from '@/components/chat/leftSidebar/LastActiveTime.tsx'; import { ContactsProps } from '@/types/types.ts'; import { useChat } from '@/context/chat/useChat.ts'; @@ -96,14 +96,14 @@ function ContactsList() { const ContactItem = ({ contact }: { contact: ContactsProps }) => (
  • { initializeContact(contact); updateContactStatus(contact, true); }} > -
    -
    +
    +
    {contact.username} {contact.type === 'group' && ( @@ -113,81 +113,77 @@ function ContactsList() { className="ml-2 invert w-5" /> )} +

    + {contact.read ? '•' : '•'} +

    -
    - - {contact.last_message?.length > 0 ? ( - contact.last_message?.length > 15 ? ( -
    - {contact.last_message?.substring(0, 12) + '...'} - -
    - ) : ( -
    - {contact.last_message} -
    - ) - ) : contact.last_message_time ? ( -
    - attachment - -
    - ) : null} -
    - -
    -
    -
    -
    -

    - {contact.read ? '' : '•'} -

    -
    - {contact.type === 'group' ? ( - - + {contact.type === 'group' ? ( + + + + + + + + Leave Group? + + + Are you sure you want to leave this group? + + + + Cancel + { + e.stopPropagation(); + removeContact(contact.id, contact.conversation_id); + }} + className="bg-red-600 hover:bg-red-500" + > + Leave Group + + + + + ) : ( - - - - - Leave Group? - - - Are you sure you want to leave this group? - - - - Cancel - { - e.stopPropagation(); - removeContact(contact.id, contact.conversation_id); - }} - className="bg-red-600 hover:bg-red-500" - > - Leave Group - - - - - ) : ( - - )} + )} +
    + +
    +
    + {contact.last_message?.length > 0 ? ( + contact.last_message?.length > 16 ? ( +
    + {contact.last_message?.substring(0, 16)} + +
    + ) : ( + contact.last_message + ) + ) : contact.last_message_time ? ( +
    + attachment +
    + ) : null} +
    + +
    +
  • ); diff --git a/client/src/components/chat/leftSidebar/LastActiveTime.tsx b/client/src/components/chat/leftSidebar/LastActiveTime.tsx index 79a3ea0..e7d96bb 100644 --- a/client/src/components/chat/leftSidebar/LastActiveTime.tsx +++ b/client/src/components/chat/leftSidebar/LastActiveTime.tsx @@ -1,5 +1,5 @@ import { useState, useEffect } from 'react'; -import { formatDistanceToNow, differenceInSeconds } from 'date-fns'; +import { differenceInSeconds, formatDistanceToNowStrict } from 'date-fns'; import { ContactsProps } from '@/types/types.ts'; @@ -23,7 +23,7 @@ const LastActiveTime = ({ contact }: LastActiveTimeProps) => { return; } - setTimeAgo(formatDistanceToNow(lastActiveDate)); + setTimeAgo(formatDistanceToNowStrict(lastActiveDate)); }; updateTime(); @@ -32,7 +32,7 @@ const LastActiveTime = ({ contact }: LastActiveTimeProps) => { return () => clearInterval(intervalId); }, [contact?.last_message]); - return {timeAgo}; + return {timeAgo}; }; export default LastActiveTime; diff --git a/client/src/types/types.ts b/client/src/types/types.ts index 1ae871f..614e726 100644 --- a/client/src/types/types.ts +++ b/client/src/types/types.ts @@ -23,6 +23,7 @@ export type ContactsProps = { conversation_id: string; last_active: string; last_message: string; + last_message_id: number; last_message_time: string; last_message_sender: string; }; diff --git a/client/src/utils/ProtectedRoutes.tsx b/client/src/utils/ProtectedRoutes.tsx index 0688b76..60e3a65 100644 --- a/client/src/utils/ProtectedRoutes.tsx +++ b/client/src/utils/ProtectedRoutes.tsx @@ -4,13 +4,13 @@ import { AuthContext } from './AuthProvider'; import LoadingScreen from '../components/LoadingScreen'; function ProtectedRoutes() { - const { authorized } = useContext(AuthContext); + const { authorized, user } = useContext(AuthContext); if (authorized === null) { return ; } - return authorized ? : ; + return authorized && user ? : ; } export default ProtectedRoutes; diff --git a/server/db/db.js b/server/db/db.js index 103480a..299b521 100644 --- a/server/db/db.js +++ b/server/db/db.js @@ -631,40 +631,22 @@ async function insertContact(initiatorId, receiverId, contactUsername, read) { return null; } - // Retrieve the last message, last active time, and last message sender - const lastMessageQuery = ` - SELECT DISTINCT ON (m.conversation_id) - m.content AS last_message, - m.sent_at AS last_message_time, - a.username AS last_message_sender - FROM Messages m - JOIN Accounts a ON m.user_id = a.user_id - WHERE m.conversation_id = $1 - ORDER BY m.conversation_id, m.sent_at DESC - `; - const lastMessageResult = await client.query(lastMessageQuery, [ - conversation_id, - ]); - let lastMessage, lastMessageTime, lastMessageSender; + // Retrieve the last message and related information + const latestMessage = await getLatestMessage(conversation_id); - if (lastMessageResult.rows.length > 0) { - lastMessage = lastMessageResult.rows[0].last_message; - lastMessageTime = lastMessageResult.rows[0].last_message_time; - lastMessageSender = lastMessageResult.rows[0].last_message_sender; - } - - // Return formatted result with contact's user_id, last message, last active time, and last message sender + // Return formatted result with all message information including message_id return { id: contact.contact_id, - user_id: receiverId, // Now using the contact's user_id instead of the initiator's + user_id: receiverId, username: contactUsername, last_active: contact.last_active, conversation_id: contact.conversation_id, type: "direct", read: contact.read, - last_message: lastMessage || null, - last_message_time: lastMessageTime || null, - last_message_sender: lastMessageSender || null, + last_message_id: latestMessage.message_id, + last_message: latestMessage.last_message, + last_message_time: latestMessage.last_message_time, + last_message_sender: latestMessage.last_message_sender, }; } catch (error) { console.error("Failed to insert contact:", error); @@ -675,6 +657,7 @@ async function insertContact(initiatorId, receiverId, contactUsername, read) { async function getLatestMessage(conversation_id) { const query = ` SELECT DISTINCT ON (m.conversation_id) + m.message_id, m.content AS last_message, m.sent_at AS last_message_time, a.username AS last_message_sender @@ -689,13 +672,15 @@ async function getLatestMessage(conversation_id) { const result = await client.query(query, [conversation_id]); return { - last_message: result.rows[0].last_message || null, - last_message_time: result.rows[0].last_message_time || null, - last_message_sender: result.rows[0].last_message_sender || null, + message_id: result.rows[0]?.message_id || null, + last_message: result.rows[0]?.last_message || null, + last_message_time: result.rows[0]?.last_message_time || null, + last_message_sender: result.rows[0]?.last_message_sender || null, }; } catch (error) { console.error("Failed to get latest message:", error); return { + message_id: null, last_message: null, last_message_time: null, last_message_sender: null, @@ -764,11 +749,9 @@ async function getContacts(user_id) { `; try { - // Execute the query with the user_id parameter const contactsResult = await client.query(contactsQuery, [user_id]); - console.log(contactsResult.rows); // Debugging: log the results to verify - // Map the results to a more friendly format and fetch the latest message for each conversation + // Map the results to include the latest message and message_id const contacts = await Promise.all( contactsResult.rows.map(async (row) => { const latestMessage = await getLatestMessage(row.conversation_id); @@ -780,9 +763,10 @@ async function getContacts(user_id) { conversation_id: row.conversation_id, type: row.type, read: row.read, - last_message: latestMessage.last_message || null, - last_message_time: latestMessage.last_message_time || null, - last_message_sender: latestMessage.last_message_sender || null, + last_message_id: latestMessage.message_id, + last_message: latestMessage.last_message, + last_message_time: latestMessage.last_message_time, + last_message_sender: latestMessage.last_message_sender, }; }), );