From 7234acc0d4eead161b32a936f679b9d4cf8c59d6 Mon Sep 17 00:00:00 2001 From: NotII <46204250+NotII@users.noreply.github.com> Date: Mon, 24 Mar 2025 00:30:01 +0000 Subject: [PATCH 1/4] woohoo --- components/dashboard/ChatDetail.tsx | 85 ++-- lib/server-service.ts | 2 +- package-lock.json | 648 +++++++++++++++++++++++----- package.json | 6 +- tsconfig.json | 24 +- 5 files changed, 629 insertions(+), 136 deletions(-) diff --git a/components/dashboard/ChatDetail.tsx b/components/dashboard/ChatDetail.tsx index fe5d9bf..8f45329 100644 --- a/components/dashboard/ChatDetail.tsx +++ b/components/dashboard/ChatDetail.tsx @@ -253,17 +253,26 @@ export default function ChatDetail({ chatId }: { chatId: string }) { // Use clientFetch instead of direct axios calls const response = await clientFetch(`/chats/${chatId}?markAsRead=true`); - if ( - response && - Array.isArray(response.messages) && - response.messages.length !== messages.length - ) { + if (response && Array.isArray(response.messages)) { + // Check if there are new messages + const hasNewMessages = response.messages.length > messages.length; + + // Always update messages to ensure we have the latest state setMessages(response.messages); - // Only auto-scroll if we're already near the bottom - if (isNearBottom()) { - setTimeout(() => { - scrollToBottom(); - }, 100); + + // If there are new messages and we're near the bottom, scroll down + if (hasNewMessages && isNearBottom()) { + setTimeout(scrollToBottom, 100); + } + + // Play notification sound if there are new buyer messages + if (hasNewMessages) { + const newMessages = response.messages.slice(messages.length); + const hasNewBuyerMessages = newMessages.some(msg => msg.sender === 'buyer'); + + if (hasNewBuyerMessages) { + playNotificationSound(); + } } } } catch (error) { @@ -281,16 +290,37 @@ export default function ChatDetail({ chatId }: { chatId: string }) { }; }, [chatId, chatData, messages.length]); + // Handle form submit for sending messages + const handleSendMessage = (e: React.FormEvent) => { + e.preventDefault(); + if (!message.trim()) return; + sendMessage(); + }; + + // Handle keyboard shortcuts for sending message + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter' && !e.shiftKey) { + e.preventDefault(); + if (message.trim()) { + sendMessage(); + } + } + }; + // Send a message const sendMessage = async () => { - if (!message.trim()) return; + if (!message.trim() || !chatId) return; + + // Save the message text and clear input immediately + const messageText = message.trim(); + setMessage(""); // Create temporary message to show immediately const tempId = `temp-${Date.now()}`; const tempMessage: Message = { _id: tempId, sender: 'vendor', - content: message.trim(), + content: messageText, attachments: [], read: true, createdAt: new Date().toISOString(), @@ -298,30 +328,33 @@ export default function ChatDetail({ chatId }: { chatId: string }) { vendorId: chat?.vendorId || '', }; + // Update messages array with temp message setMessages(prev => [...prev, tempMessage]); - scrollToBottom(); - // Clear input - setMessage(""); + // Scroll to bottom + setTimeout(scrollToBottom, 50); try { - // Use clientFetch instead of direct axios calls + // Use clientFetch to send message to server const response = await clientFetch(`/chats/${chatId}/message`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ - content: message.trim(), + content: messageText, attachments: [] }), }); - // Replace temp message with real one from server - setMessages(prev => - prev.filter(m => m._id !== tempId) - .concat(response) - ); + // Replace temp message with server response + setMessages(prevMessages => { + const updatedMessages = prevMessages.filter(m => m._id !== tempId); + return [...updatedMessages, response]; + }); + + // Force a refresh of the entire chat to ensure consistency + fetchChatData(); } catch (error) { console.error("Error sending message:", error); toast.error("Failed to send message"); @@ -331,12 +364,6 @@ export default function ChatDetail({ chatId }: { chatId: string }) { } }; - // Handle form submit for sending messages - const handleSendMessage = (e: React.FormEvent) => { - e.preventDefault(); - sendMessage(); - }; - const handleBackClick = () => { router.push("/dashboard/chats"); }; @@ -563,6 +590,8 @@ export default function ChatDetail({ chatId }: { chatId: string }) { placeholder="Type your message..." disabled={sending} className="flex-1" + onKeyDown={handleKeyDown} + autoFocus />