From a1468d4f9c40e616d3c369daa599f8c06930aca2 Mon Sep 17 00:00:00 2001 From: Somnath Chattaraj Date: Sun, 6 Oct 2024 23:35:24 +0530 Subject: [PATCH] Changed the messaging UI --- frontend/package.json | 4 +- .../src/components/chatroomui/chatroom.jsx | 202 +++++++++++------- frontend/src/components/routes/mainroute.jsx | 1 + frontend/tailwind.config.js | 3 + frontend/vite.config.js | 16 +- 5 files changed, 135 insertions(+), 91 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index f16f4d7..9bebcef 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -33,8 +33,8 @@ "eslint-plugin-react": "^7.34.3", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.7", - "postcss": "^8.4.40", - "tailwindcss": "^3.4.7", + "postcss": "^8.4.47", + "tailwindcss": "^3.4.13", "vite": "^5.3.4" } } diff --git a/frontend/src/components/chatroomui/chatroom.jsx b/frontend/src/components/chatroomui/chatroom.jsx index bdc5bc9..fa89d1d 100644 --- a/frontend/src/components/chatroomui/chatroom.jsx +++ b/frontend/src/components/chatroomui/chatroom.jsx @@ -1,53 +1,81 @@ -import React from "react"; +import React, { useContext, useEffect, useRef, useState } from "react"; import { chatRoomApi } from "../contexts/chatRoomApi"; -import { useContext,useEffect, useState } from "react"; -import useWebSocket from "react-use-websocket" +import useWebSocket from "react-use-websocket"; import { ReadyState } from "react-use-websocket"; -import { Navigate } from "react-router-dom"; -const Chatroom = ()=>{ - const { roomId,userId } = useContext(chatRoomApi); + +const Chatroom = () => { + const { roomId, userId } = useContext(chatRoomApi); const [allMsg, setAllMsg] = useState([]); - const [myMsg,setMyMsg] = useState(""); - //making the connections - const { sendJsonMessage, lastMessage, lastJsonMessage, readyState } = useWebSocket('ws://localhost:8080') - //initial query to join the room + const [myMsg, setMyMsg] = useState(""); + const messageEndRef = useRef(null); // For auto-scroll + + // WebSocket connection + const { sendJsonMessage, lastJsonMessage, readyState } = useWebSocket('ws://localhost:8080'); + + // Initial query to join the room useEffect(() => { - console.log(roomId); const tosend = { type: "joinRoom", data: { userId: userId, roomId: roomId, } - } + }; sendJsonMessage(tosend); - return ()=>{ + }, [roomId, userId, sendJsonMessage]); - } - },[]); - //checking on last message + // Handling incoming messages useEffect(() => { - if (lastJsonMessage != null) { - if (lastJsonMessage.type == "error") { - alert("Room not connected...") - } - if (lastJsonMessage.type == "newMessage") { - if(lastJsonMessage.data.roomId == roomId) - { - const data = lastJsonMessage.data.message; - setAllMsg(prev => { - return prev.concat( - { - senderId: data.senderId, - message: data.content, - at:data.timestamp, - } - ); - }) - } + if (lastJsonMessage !== null) { + if (lastJsonMessage.type === "error") { + alert("Room not connected..."); + } else if (lastJsonMessage.type === "newMessage" && lastJsonMessage.data.roomId === roomId) { + const data = lastJsonMessage.data.message; + setAllMsg(prev => [...prev, { + senderId: data.senderId, + message: data.content, + at: data.timestamp, + }]); } } - }, [lastJsonMessage]) + }, [lastJsonMessage, roomId]); + + // Auto-scroll to the bottom when messages are updated + useEffect(() => { + if (messageEndRef.current) { + messageEndRef.current.scrollIntoView({ behavior: "smooth" }); + } + }, [allMsg]); + + // Submit message function + const submit = () => { + const tosend = { + type: "sendMessage", + data: { + roomId: roomId, + userId: userId, + message: myMsg + } + }; + sendJsonMessage(tosend); + setAllMsg(prev => [...prev, { + senderId: "you", + message: myMsg, + at: new Date().toISOString(), + }]); + setMyMsg(""); // Clear input field + }; + + // Format date + const formatDate = (isoString) => { + const date = new Date(isoString); + return new Intl.DateTimeFormat('en-US', { + weekday: 'short', + hour: 'numeric', + minute: 'numeric', + hour12: true + }).format(date); + }; const constatus = { [ReadyState.CONNECTING]: 'Connecting', @@ -57,55 +85,63 @@ const Chatroom = ()=>{ [ReadyState.UNINSTANTIATED]: 'Uninstantiated', }[readyState]; - const submit = ()=>{ - const tosend = { - type:"sendMessage", - data : { - roomId:roomId, - userId:userId, - message:myMsg - }} - sendJsonMessage(tosend,true); - setAllMsg(prev => { - return prev.concat( - { - senderId: "you", - message: tosend.data.message, - at: Date().toString(), - } - );}) - } - return ( -
-
-

- connection status {constatus} -
- room id : {roomId? roomId : "null"} +
+
+ {/* Header */} +
+

+ Connection Status: {constatus} +

+
+ Room ID: {roomId || "null"}
-

-
-
- lastMessage:{JSON.stringify(lastJsonMessage)} -
-
-

Messages:

- {allMsg.length? allMsg.map((data,index)=>{ - return ( -
-
senderId : {data.senderId}
-
massage: {data.message}
-
at : {data.at}
-
- ) - }):"no message"} -
-
- setMyMsg(e.target.value)}/> - +
+ + {/* Messages */} +
+ {allMsg.length ? ( + allMsg.map((data, index) => ( + data.senderId !== userId ? ( +
+
{data.senderId === "you" ? "You" : data.senderId}
+
+ {data.message} +
+
Sent at: {formatDate(data.at)}
+
+ ) : null + )) + ) : ( +
No messages yet
+ )} +
+
+ + {/* Input Section */} +
+ setMyMsg(e.target.value)} + className="flex-1 p-3 rounded-lg bg-gray-700 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-yellow-400" + /> + +
- ) -} -export default Chatroom; \ No newline at end of file + ); +}; + +export default Chatroom; diff --git a/frontend/src/components/routes/mainroute.jsx b/frontend/src/components/routes/mainroute.jsx index 4c2cb8f..67a4736 100644 --- a/frontend/src/components/routes/mainroute.jsx +++ b/frontend/src/components/routes/mainroute.jsx @@ -1,6 +1,7 @@ import { createBrowserRouter, Navigate } from "react-router-dom"; import { Mainbuttons, Createroom, Joinroom } from "../chatroomui/main"; import Chatroom from "../chatroomui/chatroom"; +import Chatroom1 from "../chatroomui/chatroom1"; import { Outlet } from "react-router-dom"; import { chatRoomApi } from "../contexts/chatRoomApi"; import { useState } from "react"; diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js index 89a305e..982dcd8 100644 --- a/frontend/tailwind.config.js +++ b/frontend/tailwind.config.js @@ -3,9 +3,12 @@ export default { content: [ "./index.html", "./src/**/*.{js,ts,jsx,tsx}", + "./src/components/chatroomui/*.{js,ts,jsx,tsx}", + ], theme: { extend: {}, }, + purge: ['./src/**/*.{js,jsx,ts,tsx}', './public/index.html'], plugins: [], } \ No newline at end of file diff --git a/frontend/vite.config.js b/frontend/vite.config.js index 5a33944..0b98b5a 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -1,7 +1,11 @@ -import { defineConfig } from 'vite' -import react from '@vitejs/plugin-react' - -// https://vitejs.dev/config/ +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; +import tailwindcss from "tailwindcss"; export default defineConfig({ - plugins: [react()], -}) +plugins: [react()], + css: { + postcss: { + plugins: [tailwindcss()], + }, + }, +}); \ No newline at end of file