remove msg
This commit is contained in:
parent
95757dd169
commit
9e05f941ab
@ -155,4 +155,45 @@ export class MessageService {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static async deleteMessage(userId: string, messageId: string, roomId: string): Promise<ApiResponse> {
|
||||
try {
|
||||
const message = await prisma.message.findFirst({
|
||||
where: {
|
||||
id: messageId,
|
||||
userId: userId,
|
||||
roomId: roomId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!message) {
|
||||
return {
|
||||
success: false,
|
||||
error: "Message not found or you don't have permission to delete it",
|
||||
status: 403,
|
||||
};
|
||||
}
|
||||
|
||||
await prisma.message.delete({
|
||||
where: {
|
||||
id: messageId,
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
messageId,
|
||||
roomId,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Delete message error:", error);
|
||||
return {
|
||||
success: false,
|
||||
error: "Failed to delete message",
|
||||
status: 500,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,8 @@ export const handleConnection = async (io: Server, socket: AuthenticatedSocket)
|
||||
|
||||
socket.on("send_message", (data: SendMessageRequest) => handleSendMessage(io, socket, data));
|
||||
|
||||
socket.on("delete_message", (data) => handleDeleteMessage(io, socket, data));
|
||||
|
||||
socket.on("react_to_message", (data: ReactToMessageRequest) => handleReactToMessage(io, socket, data));
|
||||
|
||||
socket.on("typing_start", (data: { roomId: string; username: string }) => handleTypingStart(io, socket, data));
|
||||
@ -139,6 +141,24 @@ const handleSendMessage = async (io: Server, socket: AuthenticatedSocket, data:
|
||||
}
|
||||
};
|
||||
|
||||
const handleDeleteMessage = async (io: Server, socket: AuthenticatedSocket, data: { messageId: string; roomId: string }) => {
|
||||
try {
|
||||
const result = await MessageService.deleteMessage(socket.userId, data.messageId, data.roomId);
|
||||
|
||||
if (result.success) {
|
||||
io.to(data.roomId).emit("message_deleted", {
|
||||
messageId: data.messageId,
|
||||
roomId: data.roomId,
|
||||
});
|
||||
} else {
|
||||
socket.emit("error", { message: result.error });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error handling delete message: ${error}`);
|
||||
socket.emit("error", { message: "Failed to delete message" });
|
||||
}
|
||||
};
|
||||
|
||||
const handleReactToMessage = async (io: Server, socket: AuthenticatedSocket, data: ReactToMessageRequest) => {
|
||||
try {
|
||||
const result = await MessageService.reactToMessage(socket.userId, data);
|
||||
|
||||
@ -44,7 +44,7 @@ export const ChatApp: FC = () => {
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<div className="flex-1 flex items-center justify-center text-gray-500">
|
||||
<div className="flex-1 flex items-center justify-center text-gray-500 dark:bg-gray-800 dark:text-gray-400">
|
||||
<div className="text-center">
|
||||
<h2 className="text-xl font-semibold mb-2">
|
||||
Welcome to Chat App
|
||||
|
||||
@ -2,8 +2,9 @@ import { cn } from '@/lib/utils';
|
||||
import { useAuthStore } from '@/stores/authStore';
|
||||
import { useSocketStore } from '@/stores/socketStore';
|
||||
import type { Message, MessageReaction } from '@/types';
|
||||
import { Heart, Smile, ThumbsUp } from 'lucide-react';
|
||||
import { Heart, Smile, ThumbsUp, Trash2 } from 'lucide-react';
|
||||
import { useMemo, useRef, useState, type FC } from 'react';
|
||||
import { toast } from 'sonner';
|
||||
import { Button } from './ui/button';
|
||||
import { Popover, PopoverContent, PopoverTrigger } from './ui/popover';
|
||||
|
||||
@ -27,6 +28,19 @@ export const MessageCard: FC<{ message: Message }> = ({ message }) => {
|
||||
return reactions.some((r) => r.type === type && r.userId === user?.id);
|
||||
};
|
||||
|
||||
const handleDeleteMessage = () => {
|
||||
if (confirm('Are you sure you want to delete this message?')) {
|
||||
if (socket) {
|
||||
socket.emit('delete_message', {
|
||||
messageId: message.id,
|
||||
roomId: message.roomId,
|
||||
});
|
||||
setShowReactions(false);
|
||||
toast.info('Message deleted successfully');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const formatTime = (dateString: string) => {
|
||||
return new Date(dateString).toLocaleTimeString([], {
|
||||
hour: '2-digit',
|
||||
@ -157,6 +171,16 @@ export const MessageCard: FC<{ message: Message }> = ({ message }) => {
|
||||
>
|
||||
<Smile className="h-5 w-5 text-yellow-500" />
|
||||
</Button>
|
||||
{isCurrentUser && (
|
||||
<Button
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
className="rounded-full p-2"
|
||||
onClick={handleDeleteMessage}
|
||||
>
|
||||
<Trash2 className="h-5 w-5 text-gray-500" />
|
||||
</Button>
|
||||
)}
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
|
||||
@ -14,7 +14,7 @@ type MessageListProps = {
|
||||
};
|
||||
|
||||
export const MessageList: FC<MessageListProps> = ({ roomId }) => {
|
||||
const { messages, setMessages } = useChatStore();
|
||||
const { messages, setMessages, removeMessage } = useChatStore();
|
||||
const { socket } = useSocketStore();
|
||||
const { user } = useAuthStore();
|
||||
const [lastMessageId, setLastMessageId] = useState<string | null>(null);
|
||||
@ -96,6 +96,25 @@ export const MessageList: FC<MessageListProps> = ({ roomId }) => {
|
||||
}
|
||||
}, [socket, user, roomId, roomMessages]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!socket) return;
|
||||
|
||||
const handleMessageDeleted = (data: {
|
||||
messageId: string;
|
||||
roomId: string;
|
||||
}) => {
|
||||
if (data.roomId === roomId) {
|
||||
removeMessage(data.messageId, data.roomId);
|
||||
}
|
||||
};
|
||||
|
||||
socket.on('message_deleted', handleMessageDeleted);
|
||||
|
||||
return () => {
|
||||
socket.off('message_deleted', handleMessageDeleted);
|
||||
};
|
||||
}, [socket, roomId, removeMessage]);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex-1 flex items-center justify-center dark:bg-gray-900">
|
||||
|
||||
@ -16,6 +16,7 @@ type ChatState = {
|
||||
setSelectedRoom: (roomId: string | null) => void;
|
||||
setMessages: (roomId: string, messages: Message[]) => void;
|
||||
addMessage: (message: Message) => void;
|
||||
removeMessage: (messageId: string, roomId: string) => void;
|
||||
updateMessageReactions: (
|
||||
messageId: string,
|
||||
reactions: MessageReaction[]
|
||||
@ -73,6 +74,21 @@ export const useChatStore = create<ChatState>()(
|
||||
}));
|
||||
},
|
||||
|
||||
removeMessage: (messageId, roomId) => {
|
||||
set((state) => {
|
||||
if (!state.messages[roomId]) return state;
|
||||
|
||||
return {
|
||||
messages: {
|
||||
...state.messages,
|
||||
[roomId]: state.messages[roomId].filter(
|
||||
(message) => message.id !== messageId
|
||||
),
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
updateMessageReactions: (messageId, reactions) => {
|
||||
set((state) => {
|
||||
const newMessages = { ...state.messages };
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user