Chat, scrolling, sockets and timestamps updated

This commit is contained in:
Askar Akhmetkhanov
2024-10-09 17:37:50 +03:00
parent 13f4d43761
commit 4cf909c607
9 changed files with 381 additions and 419 deletions

View File

@@ -2,9 +2,10 @@ import React, { useEffect, useState, useRef } from "react";
import { useNavigate } from "react-router-dom";
import "./css/Chat.css";
import { FaPaperPlane, FaSmile } from "react-icons/fa";
import {get, post} from "../backend/api";
import {displayMessage} from "../backend/notifications/notifications";
import {MessageType} from "../backend/notifications/message";
import { get, post } from "../backend/api";
import { displayMessage } from "../backend/notifications/notifications";
import { MessageType } from "../backend/notifications/message";
import io from "socket.io-client";
const emojis = [
"😀",
@@ -88,8 +89,7 @@ const Chat = () => {
const [myId, setMyId] = useState("");
useEffect(() => {
// const id = parseInt(localStorage.getItem("interlocutorId"), 10) || 0;
const id = localStorage.getItem("interlocutorId")
const id = localStorage.getItem("interlocutorId");
setInterlocutorId(id);
const username = localStorage.getItem("username");
@@ -100,36 +100,24 @@ const Chat = () => {
return () => {};
}
socket.current = new WebSocket("ws://localhost:8080");
socket.current = io("http://localhost:8099");
socket.current.onopen = () => {
console.log("WebSocket connected");
socket.current.send(
JSON.stringify({ type: "register", userId: "yourUserId" })
);
};
socket.current.on("receiveMessage", (message) => {
setMessages((prev) => [...prev, message]);
});
socket.current.onmessage = (event) => {
const receivedData = JSON.parse(event.data);
setMessages((prev) => [...prev, receivedData]);
};
socket.current.onerror = (event) => {
console.error("WebSocket error observed:", event);
};
socket.current.onclose = () => {
console.log("WebSocket closed");
};
socket.current.on("connect_error", (err) => {
console.error("Connection Error:", err.message);
});
return () => {
socket.current.close();
socket.current.disconnect();
};
}, []);
useEffect(() => {
retrieveMessages().then();
}, [myId, interlocutorId])
}, [myId, interlocutorId]);
useEffect(() => {
if (chatRef.current) {
@@ -137,25 +125,24 @@ const Chat = () => {
}
}, [messages]);
// The function for sending message to the DB
async function sendMessageToDB (messageData) {
const { ok, data } = post('/chat/message/' + myId + '/' + interlocutorId, { message: messageData });
async function sendMessageToDB(messageData) {
const { ok, data } = await post(
"/chat/message/" + myId + "/" + interlocutorId,
{ message: messageData }
);
if (!ok) {
displayMessage(data.message, MessageType.ERROR);
}
}
// The function retrieves messages from the DB for the current chat
async function retrieveMessages () {
if (!myId || !interlocutorId) {return;}
const { ok, data } = await get('/chat/item/' + myId + '/' + interlocutorId);
async function retrieveMessages() {
if (!myId || !interlocutorId) return;
const { ok, data } = await get("/chat/item/" + myId + "/" + interlocutorId);
if (!ok) {
displayMessage(data.message, MessageType.ERROR);
return;
}
setMessages(data.chat.messages);
}
@@ -165,15 +152,11 @@ const Chat = () => {
senderId: myId,
recipientId: interlocutorId,
data: newMessage,
timestamp: new Date().toLocaleTimeString(),
timestamp: new Date().toLocaleString(),
};
socket.current.send(JSON.stringify(messageData));
socket.current.emit("sendMessage", messageData);
setMessages((prev) => [...prev, messageData]);
sendMessageToDB(messageData).then();
console.log('format:', messageData);
setNewMessage("");
}
};
@@ -198,8 +181,7 @@ const Chat = () => {
className="home-button"
>
Home
</button>{" "}
{}
</button>
</div>
<div className="chat-messages" ref={chatRef}>
{messages.map((msg, index) => (
@@ -210,8 +192,7 @@ const Chat = () => {
}`}
>
<div className="message-content">
<b>{msg.senderId === myId ? "You" : "They"}:</b>{" "}
{msg.data}
<b>{msg.senderId === myId ? "You" : "They"}:</b> {msg.data}
</div>
<span className="message-timestamp">{msg.timestamp}</span>
</div>

View File

@@ -1,77 +1,86 @@
import React, {useEffect, useState} from "react";
import React, { useEffect, useState } from "react";
import HomeTitle from "../components/home/HomeTitle.jsx";
import ChatsList from "../components/home/ChatsList.jsx";
import Header from "../components/home/Header.jsx";
import {displayMessage} from "../backend/notifications/notifications";
import {MessageType} from "../backend/notifications/message";
import {get, post} from "../backend/api";
import { displayMessage } from "../backend/notifications/notifications";
import { MessageType } from "../backend/notifications/message";
import { get, post } from "../backend/api";
import InputField from "../components/reg/InputField.jsx";
import Search from "../components/home/Search.jsx";
import {URLs} from "../__data__/urls";
import { URLs } from "../__data__/urls";
const Home = () => {
const [chats, setChats] = useState([])
const [interlocutor, setInterlocutor] = useState("")
const [chats, setChats] = useState([]);
const [interlocutor, setInterlocutor] = useState("");
async function retrieveChats() {
const username = localStorage.getItem("username");
if (!username) {
displayMessage("You're not logged in!", MessageType.WARN);
return;
}
const {ok, data} = await get('/chat/list/' + username);
if (!ok) {
displayMessage(data.message, MessageType.ERROR);
return;
}
setChats(data.chats);
async function retrieveChats() {
const username = localStorage.getItem("username");
if (!username) {
displayMessage("You're not logged in!", MessageType.WARN);
return;
}
async function createChat(alias) {
const username = localStorage.getItem("username");
if (!username) {
displayMessage("You're not logged in!", MessageType.WARN);
return;
}
displayMessage("Sent", MessageType.INFO);
const {ok, data} = await post('/chat/item/' + username + '/' + alias);
if (!ok) {
displayMessage(data.message, MessageType.ERROR);
} else {
localStorage.setItem('message', 'Successfully opened chat!');
localStorage.setItem('interlocutorId', alias);
window.location.href = URLs.chat.url;
}
const { ok, data } = await get("/chat/list/" + username);
if (!ok) {
displayMessage(data.message, MessageType.ERROR);
return;
}
useEffect(() => {retrieveChats().then()}, [])
const sortedChats = data.chats.sort((a, b) => {
const lastMessageA = new Date(a.lastMessageTimestamp);
const lastMessageB = new Date(b.lastMessageTimestamp);
return lastMessageB - lastMessageA;
});
return (
<div className="homeWrapper">
<div className="headerPos">
<Header/>
</div>
setChats(sortedChats);
}
<HomeTitle/>
async function createChat(alias) {
const username = localStorage.getItem("username");
if (!username) {
displayMessage("You're not logged in!", MessageType.WARN);
return;
}
<div className="search-input">
<InputField
title="Create new chat"
value={interlocutor}
setValue={setInterlocutor}
placeholder="Enter the username (id)"
/>
</div>
displayMessage("Sent", MessageType.INFO);
<Search search={createChat} item={interlocutor}/>
const { ok, data } = await post("/chat/item/" + username + "/" + alias);
if (!ok) {
displayMessage(data.message, MessageType.ERROR);
} else {
localStorage.setItem("message", "Successfully opened chat!");
localStorage.setItem("interlocutorId", alias);
window.location.href = URLs.chat.url;
}
}
<p>Your chats</p>
<ChatsList chats={chats} />
useEffect(() => {
retrieveChats();
}, []);
return (
<div className="homeWrapper">
<div className="headerPos">
<Header />
</div>
)
}
export default Home
<HomeTitle />
<div className="search-input">
<InputField
title="Create new chat"
value={interlocutor}
setValue={setInterlocutor}
placeholder="Enter the username (id)"
/>
</div>
<Search search={createChat} item={interlocutor} />
<p>Your chats</p>
<ChatsList chats={chats} />
</div>
);
};
export default Home;

View File

@@ -1,3 +1,7 @@
body {
background: linear-gradient(to right, #e0f7fa, #fffde7);
}
.chat-container {
display: flex;
flex-direction: column;
@@ -11,10 +15,13 @@
}
.chat-header {
padding: 10px;
padding: 15px;
background-color: #007bff;
color: white;
text-align: center;
font-weight: bold;
letter-spacing: 1px;
border-bottom: 2px solid #0056b3;
}
.chat-messages {
@@ -24,6 +31,7 @@
padding: 10px;
overflow-y: auto;
background-color: #fff;
max-height: 400px;
}
.message-bubble {
@@ -33,6 +41,12 @@
max-width: 70%;
word-wrap: break-word;
display: inline-block;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
transition: transform 0.2s;
}
.message-bubble:hover {
transform: translateY(-2px);
}
.sent {
@@ -58,8 +72,9 @@
.message-timestamp {
font-size: 10px;
color: #999;
margin-top: 5px;
color: black;
text-align: right;
margin-top: 4px;
display: block;
}