code refactor, added animated message deletion, remove message button is not displayed only where you can actually use it
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { axiosClient } from '../App.tsx';
|
import { axiosClient } from '../App.tsx';
|
||||||
import { ChatMessages } from '../pages/Chat.tsx';
|
import { ChatMessagesProps } from '../pages/Chat.tsx';
|
||||||
import { ContactsProps } from '../pages/Chat.tsx';
|
import { ContactsProps } from '../pages/Chat.tsx';
|
||||||
|
|
||||||
export async function getContactsList(): Promise<ContactsProps[]> {
|
export async function getContactsList(): Promise<ContactsProps[]> {
|
||||||
@@ -43,7 +43,7 @@ export async function getMessages(
|
|||||||
contact: string | null,
|
contact: string | null,
|
||||||
cursor: number | null = 0,
|
cursor: number | null = 0,
|
||||||
limit: number = 50,
|
limit: number = 50,
|
||||||
): Promise<{ messages: ChatMessages[] }> {
|
): Promise<{ messages: ChatMessagesProps[] }> {
|
||||||
if (contact === null || cursor === null) {
|
if (contact === null || cursor === null) {
|
||||||
return { messages: [] };
|
return { messages: [] };
|
||||||
}
|
}
|
||||||
|
|||||||
68
client/src/components/chat/AnimatedMessage.tsx
Normal file
68
client/src/components/chat/AnimatedMessage.tsx
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
|
import { Trash2 } from 'lucide-react';
|
||||||
|
import AttachmentPreview from './AttachmentPreview';
|
||||||
|
import { ChatMessagesProps } from '@/pages/Chat.tsx';
|
||||||
|
|
||||||
|
type AnimatedMessageProps = {
|
||||||
|
message: ChatMessagesProps;
|
||||||
|
isAdmin: boolean;
|
||||||
|
currentUsername: string | null;
|
||||||
|
onDelete: (messageId: number) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const AnimatedMessage = ({
|
||||||
|
message,
|
||||||
|
isAdmin,
|
||||||
|
currentUsername,
|
||||||
|
onDelete,
|
||||||
|
}: AnimatedMessageProps) => {
|
||||||
|
const [isRemoving, setIsRemoving] = useState(false);
|
||||||
|
|
||||||
|
const handleDelete = () => {
|
||||||
|
setIsRemoving(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
onDelete(message.message_id);
|
||||||
|
}, 300);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<li
|
||||||
|
className={`whitespace-pre-wrap ml-2 rounded p-1 group transition-all duration-300 ${
|
||||||
|
message.pending ? 'text-gray-400' : 'hover:bg-gray-900'
|
||||||
|
} ${isRemoving ? 'opacity-0 -translate-x-full' : 'opacity-100'}`}
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
title={`${new Intl.DateTimeFormat('en-GB', {
|
||||||
|
timeStyle: 'medium',
|
||||||
|
dateStyle: 'short',
|
||||||
|
})?.format(message.sent_at)}`}
|
||||||
|
>
|
||||||
|
{message.sender}: {message.message}
|
||||||
|
</span>
|
||||||
|
{message.attachment_urls && (
|
||||||
|
<div className="mt-2 flex flex-col gap-2">
|
||||||
|
{message.attachment_urls.length > 0
|
||||||
|
? message.attachment_urls.map((url, index) => (
|
||||||
|
<AttachmentPreview
|
||||||
|
key={`${message.message_id}-${index}`}
|
||||||
|
url={url}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{message.sender === currentUsername || isAdmin ? (
|
||||||
|
<Trash2
|
||||||
|
className="opacity-0 group-hover:opacity-100 h-5 w-5 ml-2 flex-shrink-0 cursor-pointer text-gray-400 hover:text-red-500 transition-colors duration-200"
|
||||||
|
onClick={handleDelete}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AnimatedMessage;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { getContactsList } from '../../api/contactsApi.tsx';
|
import { getContactsList } from '../../api/contactsApi.tsx';
|
||||||
import { ChatMessages, ContactsProps } from '../../pages/Chat.tsx';
|
import { ChatMessagesProps, ContactsProps } from '../../pages/Chat.tsx';
|
||||||
import { socket } from '../../socket/socket.tsx';
|
import { socket } from '../../socket/socket.tsx';
|
||||||
import GroupIcon from '../../../assets/group.svg';
|
import GroupIcon from '../../../assets/group.svg';
|
||||||
import {
|
import {
|
||||||
@@ -21,7 +21,7 @@ type ContactsListProps = {
|
|||||||
contactsList: ContactsProps[];
|
contactsList: ContactsProps[];
|
||||||
setCurrentContact: React.Dispatch<React.SetStateAction<ContactsProps | null>>;
|
setCurrentContact: React.Dispatch<React.SetStateAction<ContactsProps | null>>;
|
||||||
updateContactStatus: (contactObj: ContactsProps, read: boolean) => void;
|
updateContactStatus: (contactObj: ContactsProps, read: boolean) => void;
|
||||||
setMessages: React.Dispatch<React.SetStateAction<ChatMessages[]>>;
|
setMessages: React.Dispatch<React.SetStateAction<ChatMessagesProps[]>>;
|
||||||
currentContact: ContactsProps | null;
|
currentContact: ContactsProps | null;
|
||||||
setErrorMessage: React.Dispatch<React.SetStateAction<string | null>>;
|
setErrorMessage: React.Dispatch<React.SetStateAction<string | null>>;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { useRef, useCallback, useEffect, useState } from 'react';
|
|||||||
import { useForm, SubmitHandler } from 'react-hook-form';
|
import { useForm, SubmitHandler } from 'react-hook-form';
|
||||||
import type { KeyboardEventHandler } from 'react';
|
import type { KeyboardEventHandler } from 'react';
|
||||||
import { socket } from '../../socket/socket.tsx';
|
import { socket } from '../../socket/socket.tsx';
|
||||||
import { ChatMessages, ContactsProps } from '../../pages/Chat.tsx';
|
import { ChatMessagesProps, ContactsProps } from '../../pages/Chat.tsx';
|
||||||
import { axiosClient } from '../../App.tsx';
|
import { axiosClient } from '../../App.tsx';
|
||||||
import { File, Paperclip, X } from 'lucide-react';
|
import { File, Paperclip, X } from 'lucide-react';
|
||||||
import LoadingWheel from '@/components/chat/LoadingWheel.tsx';
|
import LoadingWheel from '@/components/chat/LoadingWheel.tsx';
|
||||||
@@ -14,7 +14,7 @@ type Input = {
|
|||||||
|
|
||||||
type MessageFormProps = {
|
type MessageFormProps = {
|
||||||
contact: ContactsProps;
|
contact: ContactsProps;
|
||||||
messages: ChatMessages[];
|
messages: ChatMessagesProps[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type FileWithPreview = {
|
type FileWithPreview = {
|
||||||
|
|||||||
@@ -3,22 +3,22 @@ import { socket } from '../../socket/socket.tsx';
|
|||||||
import { useOutletContext } from 'react-router-dom';
|
import { useOutletContext } from 'react-router-dom';
|
||||||
import { sendContact } from '../../api/contactsApi.tsx';
|
import { sendContact } from '../../api/contactsApi.tsx';
|
||||||
import LoadingWheel from './LoadingWheel.tsx';
|
import LoadingWheel from './LoadingWheel.tsx';
|
||||||
import { ChatMessages } from '../../pages/Chat.tsx';
|
import { ChatMessagesProps, MeProps } from '../../pages/Chat.tsx';
|
||||||
import { ContactsProps } from '../../pages/Chat.tsx';
|
import { ContactsProps } from '../../pages/Chat.tsx';
|
||||||
import { Trash2 } from 'lucide-react';
|
|
||||||
import AttachmentPreview from './AttachmentPreview.tsx';
|
|
||||||
import { UsernameType } from '@/utils/ProtectedRoutes.tsx';
|
import { UsernameType } from '@/utils/ProtectedRoutes.tsx';
|
||||||
|
import AnimatedMessage from '@/components/chat/AnimatedMessage.tsx';
|
||||||
|
|
||||||
type MessagesAreaProps = {
|
type MessagesAreaProps = {
|
||||||
messages: ChatMessages[];
|
messages: ChatMessagesProps[];
|
||||||
setMessages: React.Dispatch<React.SetStateAction<ChatMessages[]>>;
|
setMessages: React.Dispatch<React.SetStateAction<ChatMessagesProps[]>>;
|
||||||
currentContact: ContactsProps | null;
|
currentContact: ContactsProps | null;
|
||||||
updateContactStatus: (contact: ContactsProps, read: boolean) => void;
|
updateContactStatus: (contact: ContactsProps, read: boolean) => void;
|
||||||
messageHandler: (msg: ChatMessages) => void;
|
messageHandler: (msg: ChatMessagesProps) => void;
|
||||||
setContactsList: React.Dispatch<React.SetStateAction<ContactsProps[]>>;
|
setContactsList: React.Dispatch<React.SetStateAction<ContactsProps[]>>;
|
||||||
fetchPreviousMessages: (contact: string | null) => Promise<void>;
|
fetchPreviousMessages: (contact: string | null) => Promise<void>;
|
||||||
errorMessage: string | null;
|
errorMessage: string | null;
|
||||||
contactsList: ContactsProps[];
|
contactsList: ContactsProps[];
|
||||||
|
me: MeProps;
|
||||||
};
|
};
|
||||||
|
|
||||||
function MessagesArea({
|
function MessagesArea({
|
||||||
@@ -31,6 +31,7 @@ function MessagesArea({
|
|||||||
errorMessage,
|
errorMessage,
|
||||||
setMessages,
|
setMessages,
|
||||||
contactsList,
|
contactsList,
|
||||||
|
me,
|
||||||
}: MessagesAreaProps) {
|
}: MessagesAreaProps) {
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const user: UsernameType = useOutletContext();
|
const user: UsernameType = useOutletContext();
|
||||||
@@ -73,7 +74,6 @@ function MessagesArea({
|
|||||||
|
|
||||||
const deleteMessage = async (message_id: number) => {
|
const deleteMessage = async (message_id: number) => {
|
||||||
try {
|
try {
|
||||||
console.log('delete message: ', message_id);
|
|
||||||
socket?.emit(
|
socket?.emit(
|
||||||
'delete message',
|
'delete message',
|
||||||
{
|
{
|
||||||
@@ -101,7 +101,7 @@ function MessagesArea({
|
|||||||
currentContainer.addEventListener('scroll', handleScroll);
|
currentContainer.addEventListener('scroll', handleScroll);
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.on('chat message', (msg: ChatMessages) => {
|
socket.on('chat message', (msg: ChatMessagesProps) => {
|
||||||
console.log('Received message: ', msg);
|
console.log('Received message: ', msg);
|
||||||
if (
|
if (
|
||||||
msg.conversation_id !== currentContact?.conversation_id &&
|
msg.conversation_id !== currentContact?.conversation_id &&
|
||||||
@@ -233,52 +233,20 @@ function MessagesArea({
|
|||||||
scrollToBottom();
|
scrollToBottom();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const messageList = messages.map((msg: ChatMessages) => (
|
|
||||||
<li
|
|
||||||
className={`whitespace-pre-wrap ml-2 rounded p-1 group ${
|
|
||||||
msg.pending ? 'text-gray-400' : 'hover:bg-gray-900'
|
|
||||||
}`}
|
|
||||||
key={msg.message_id}
|
|
||||||
>
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<div>
|
|
||||||
<span
|
|
||||||
title={`${new Intl.DateTimeFormat('en-Gb', {
|
|
||||||
timeStyle: 'medium',
|
|
||||||
dateStyle: 'short',
|
|
||||||
})?.format(msg.sent_at)}`}
|
|
||||||
>
|
|
||||||
{msg.sender}: {msg.message}
|
|
||||||
</span>
|
|
||||||
{msg.attachment_urls && (
|
|
||||||
<div className="mt-2 flex flex-col gap-2">
|
|
||||||
{msg.attachment_urls.length > 0
|
|
||||||
? msg.attachment_urls.map((url, index) => (
|
|
||||||
<AttachmentPreview
|
|
||||||
key={`${msg.message_id}-${index}`}
|
|
||||||
url={url}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
: null}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<Trash2
|
|
||||||
className="opacity-0 group-hover:opacity-100 h-5 w-5 ml-2 flex-shrink-0 cursor-pointer text-gray-400 hover:text-red-500"
|
|
||||||
onClick={() => {
|
|
||||||
deleteMessage(msg.message_id);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
));
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={containerRef} className="flex flex-col h-full overflow-y-auto">
|
<div ref={containerRef} className="flex flex-col h-full overflow-y-auto">
|
||||||
<p className="text-center text-gray-400">{errorMessage}</p>
|
<p className="text-center text-gray-400">{errorMessage}</p>
|
||||||
<ul className="flex-grow list-none">
|
<ul className="flex-grow list-none">
|
||||||
{isLoading ? <LoadingWheel /> : null}
|
{isLoading ? <LoadingWheel /> : null}
|
||||||
{messageList}
|
{messages.map((msg: ChatMessagesProps) => (
|
||||||
|
<AnimatedMessage
|
||||||
|
key={msg.message_id}
|
||||||
|
message={msg}
|
||||||
|
isAdmin={me.isGroupAdmin || me.isGroupOwner}
|
||||||
|
currentUsername={user.username}
|
||||||
|
onDelete={deleteMessage}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { axiosClient } from '@/App.tsx';
|
import { axiosClient } from '@/App.tsx';
|
||||||
import { ContactsProps } from '@/pages/Chat.tsx';
|
import { ContactsProps, MeProps } from '@/pages/Chat.tsx';
|
||||||
import { socket } from '@/socket/socket.tsx';
|
import { socket } from '@/socket/socket.tsx';
|
||||||
import { Crown, Sword } from 'lucide-react';
|
import { Crown, Sword } from 'lucide-react';
|
||||||
import {
|
import {
|
||||||
@@ -22,22 +22,17 @@ type ParticipantsProps = {
|
|||||||
type ParticipantsBarProps = {
|
type ParticipantsBarProps = {
|
||||||
initializeContact: (contact: ContactsProps) => void;
|
initializeContact: (contact: ContactsProps) => void;
|
||||||
currentContact: ContactsProps | null;
|
currentContact: ContactsProps | null;
|
||||||
};
|
setMe: React.Dispatch<React.SetStateAction<MeProps>>;
|
||||||
|
me: MeProps;
|
||||||
type MeProps = {
|
|
||||||
isGroupAdmin: boolean;
|
|
||||||
iGroupOwner: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function ParticipantsBar({
|
function ParticipantsBar({
|
||||||
initializeContact,
|
initializeContact,
|
||||||
currentContact,
|
currentContact,
|
||||||
|
setMe,
|
||||||
|
me,
|
||||||
}: ParticipantsBarProps) {
|
}: ParticipantsBarProps) {
|
||||||
const [participants, setParticipants] = useState<ParticipantsProps[]>([]);
|
const [participants, setParticipants] = useState<ParticipantsProps[]>([]);
|
||||||
const [me, setMe] = useState<MeProps>({
|
|
||||||
isGroupAdmin: false,
|
|
||||||
iGroupOwner: false,
|
|
||||||
});
|
|
||||||
const user: UsernameType = useOutletContext();
|
const user: UsernameType = useOutletContext();
|
||||||
|
|
||||||
const getParticipants = async () => {
|
const getParticipants = async () => {
|
||||||
@@ -122,7 +117,7 @@ function ParticipantsBar({
|
|||||||
participant.user_id === user.user_id && participant.isowner,
|
participant.user_id === user.user_id && participant.isowner,
|
||||||
);
|
);
|
||||||
|
|
||||||
setMe({ isGroupAdmin: userIsAdmin, iGroupOwner: userIsOwner });
|
setMe({ isGroupAdmin: userIsAdmin, isGroupOwner: userIsOwner });
|
||||||
}
|
}
|
||||||
}, [participants, user?.user_id]);
|
}, [participants, user?.user_id]);
|
||||||
|
|
||||||
@@ -216,6 +211,9 @@ function ParticipantsBar({
|
|||||||
}) => {
|
}) => {
|
||||||
console.log('(socket) removed administrator: ', msg);
|
console.log('(socket) removed administrator: ', msg);
|
||||||
if (msg.group_id === currentContact.conversation_id) {
|
if (msg.group_id === currentContact.conversation_id) {
|
||||||
|
if (msg.user_id === user?.user_id) {
|
||||||
|
setMe({ isGroupAdmin: false, isGroupOwner: false });
|
||||||
|
}
|
||||||
setParticipants((prevMembers) =>
|
setParticipants((prevMembers) =>
|
||||||
prevMembers.map((member) =>
|
prevMembers.map((member) =>
|
||||||
member.user_id === msg.user_id
|
member.user_id === msg.user_id
|
||||||
@@ -262,7 +260,7 @@ function ParticipantsBar({
|
|||||||
</ContextMenuTrigger>
|
</ContextMenuTrigger>
|
||||||
{user.user_id !== participant.user_id &&
|
{user.user_id !== participant.user_id &&
|
||||||
me.isGroupAdmin &&
|
me.isGroupAdmin &&
|
||||||
(!participant.isadmin || me.iGroupOwner) ? (
|
(!participant.isadmin || me.isGroupOwner) ? (
|
||||||
<ContextMenuContent className="p-0">
|
<ContextMenuContent className="p-0">
|
||||||
<ContextMenuItem
|
<ContextMenuItem
|
||||||
className="bg-zinc-900 text-white outline-1 hover:bg-zinc-800 hover:cursor-pointer"
|
className="bg-zinc-900 text-white outline-1 hover:bg-zinc-800 hover:cursor-pointer"
|
||||||
|
|||||||
@@ -11,7 +11,12 @@ import { getMessages, setContactStatus } from '../api/contactsApi.tsx';
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import ParticipantsBar from '@/components/chat/ParticipantsBar.tsx';
|
import ParticipantsBar from '@/components/chat/ParticipantsBar.tsx';
|
||||||
|
|
||||||
export type ChatMessages = {
|
export type MeProps = {
|
||||||
|
isGroupAdmin: boolean;
|
||||||
|
isGroupOwner: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ChatMessagesProps = {
|
||||||
sender: string;
|
sender: string;
|
||||||
message: string;
|
message: string;
|
||||||
recipient: string; // conversation_id
|
recipient: string; // conversation_id
|
||||||
@@ -39,9 +44,13 @@ function Chat() {
|
|||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
const [cursor, setCursor] = useState<number>(0);
|
const [cursor, setCursor] = useState<number>(0);
|
||||||
const [messages, setMessages] = useState<ChatMessages[]>([]);
|
const [messages, setMessages] = useState<ChatMessagesProps[]>([]);
|
||||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||||
const [hasMoreMessages, setHasMoreMessages] = useState<boolean>(true);
|
const [hasMoreMessages, setHasMoreMessages] = useState<boolean>(true);
|
||||||
|
const [me, setMe] = useState<MeProps>({
|
||||||
|
isGroupAdmin: false,
|
||||||
|
isGroupOwner: false,
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const token = Cookies.get('token');
|
const token = Cookies.get('token');
|
||||||
@@ -161,7 +170,7 @@ function Chat() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function messageHandler(msg: ChatMessages) {
|
function messageHandler(msg: ChatMessagesProps) {
|
||||||
setMessages((prevMessages) => {
|
setMessages((prevMessages) => {
|
||||||
// Check if the message already exists in the state
|
// Check if the message already exists in the state
|
||||||
if (!prevMessages.some((m) => m.message_id === msg.message_id)) {
|
if (!prevMessages.some((m) => m.message_id === msg.message_id)) {
|
||||||
@@ -236,6 +245,7 @@ function Chat() {
|
|||||||
fetchPreviousMessages={fetchPreviousMessages}
|
fetchPreviousMessages={fetchPreviousMessages}
|
||||||
errorMessage={errorMessage}
|
errorMessage={errorMessage}
|
||||||
contactsList={contactsList}
|
contactsList={contactsList}
|
||||||
|
me={me}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -243,6 +253,8 @@ function Chat() {
|
|||||||
{currentContact?.type == 'group' ? (
|
{currentContact?.type == 'group' ? (
|
||||||
<div className="w-80 bg-[#1E1E1E] flex-shrink-0">
|
<div className="w-80 bg-[#1E1E1E] flex-shrink-0">
|
||||||
<ParticipantsBar
|
<ParticipantsBar
|
||||||
|
setMe={setMe}
|
||||||
|
me={me}
|
||||||
initializeContact={initializeContact}
|
initializeContact={initializeContact}
|
||||||
currentContact={currentContact}
|
currentContact={currentContact}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -810,7 +810,7 @@ async function contactSuggestion(username) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteMessage(user_id, message_id) {
|
async function deleteMessage(user_id, conversation_id, message_id) {
|
||||||
const checkMessageOwnershipQuery = `
|
const checkMessageOwnershipQuery = `
|
||||||
SELECT user_id FROM Messages WHERE message_id = $1;
|
SELECT user_id FROM Messages WHERE message_id = $1;
|
||||||
`;
|
`;
|
||||||
@@ -820,17 +820,19 @@ async function deleteMessage(user_id, message_id) {
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const checkResult = await client.query(checkMessageOwnershipQuery, [
|
const isAdminResult = await isAdmin(user_id, conversation_id);
|
||||||
message_id,
|
if (!isAdminResult) {
|
||||||
]);
|
const ownershipResult = await client.query(checkMessageOwnershipQuery, [
|
||||||
if (checkResult.rows.length === 0) {
|
message_id,
|
||||||
return { message: "Message not found." };
|
]);
|
||||||
}
|
if (ownershipResult.rows.length === 0) {
|
||||||
|
return { message: "Message not found." };
|
||||||
const messageOwnerId = checkResult.rows[0].user_id;
|
}
|
||||||
if (user_id !== messageOwnerId) {
|
const messageOwnerId = ownershipResult.rows[0].user_id;
|
||||||
console.error("User is not authorized to delete this message");
|
if (user_id !== messageOwnerId) {
|
||||||
return { message: "It's not your message bro" };
|
console.error("User is not authorized to delete this message");
|
||||||
|
return { message: "It's not your message bro" };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const deleteResult = await client.query(deleteMessageQuery, [message_id]);
|
const deleteResult = await client.query(deleteMessageQuery, [message_id]);
|
||||||
if (deleteResult.rowCount > 0) {
|
if (deleteResult.rowCount > 0) {
|
||||||
|
|||||||
@@ -179,7 +179,6 @@ function initializeSocket(io) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
socket.on("delete message", async (msg, callback) => {
|
socket.on("delete message", async (msg, callback) => {
|
||||||
console.log("(socket) delete message for message_id: ", msg);
|
|
||||||
const { conversation_id, message_id } = msg;
|
const { conversation_id, message_id } = msg;
|
||||||
if (!message_id) {
|
if (!message_id) {
|
||||||
return callback({ status: "error", message: "No message id provided" });
|
return callback({ status: "error", message: "No message id provided" });
|
||||||
@@ -191,7 +190,11 @@ function initializeSocket(io) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await deleteMessage(socket.user_id, message_id);
|
const result = await deleteMessage(
|
||||||
|
socket.user_id,
|
||||||
|
conversation_id,
|
||||||
|
message_id,
|
||||||
|
);
|
||||||
if (result?.message !== undefined) {
|
if (result?.message !== undefined) {
|
||||||
return callback({ status: "error", message: result.message });
|
return callback({ status: "error", message: result.message });
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user