Skip to content

Commit

Permalink
feature: Enabling Private Chat functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
gisubizo Jovan authored and gisubizo Jovan committed May 30, 2024
1 parent 1e8164b commit e4d2af2
Show file tree
Hide file tree
Showing 21 changed files with 826 additions and 20 deletions.
19 changes: 16 additions & 3 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,14 @@ <h1>Eagles E-commerce Chat Room</h1>
<div class="user-name">
<span><i class="fa-regular fa-user"></i></span> <input type="text" class="userName" id="user-name">
</div>
<div class="seller-selector">
<button><a style="text-decoration: none ; background-color: #007bff; float: right; width: 200px;" href="./chats/page">Talk to our sellers Privately</a></button>
</div>
<div class="chat-room" id="chat-room">

<div class="messages" id="messages"></div>
<form class="send-message" id="send-message">
<textarea class="message-input" id="message-input" placeholder="Start typing.."></textarea>
<textarea class="message-input" id="message-input" placeholder="Type here"></textarea>
<button type="submit">Send <span><i class="fa-regular fa-paper-plane"></i></span></button>
</form>
</div>
Expand All @@ -182,8 +186,9 @@ <h1>Eagles E-commerce Chat Room</h1>
const chatRoomSection = document.getElementById("chatRoom");
const verifyToken = document.getElementById("TokenVerfication");
const verifyTokenForm = document.getElementById("verifyToken");
const port = window.location.port

const url = "https://eagles-ec-be-development.onrender.com/api/v1/users/login";
const url = `http://localhost:${port}/api/v1/users/login`;
const loginUser = async (email, password) => {
try {
const response = await fetch(url, {
Expand Down Expand Up @@ -250,7 +255,7 @@ <h1>Eagles E-commerce Chat Room</h1>
const { id, name } = decodedToken;
userNameInput.value = name;
userId = id;
console.log(decodedToken);

} catch (error) {
console.error("Error parsing token:", error.message);
}
Expand Down Expand Up @@ -304,5 +309,13 @@ <h1>Eagles E-commerce Chat Room</h1>


</script>
<script src="/socket.io/socket.io.js"></script>
<script src="login.js"></script>
<script src="client.js"></script>
<!-- <script>
const localURL = process.env.local_url
const serverURL = process.env.server_url
fetch(`${localURL}/`)
</script> -->
</body>
</html>
234 changes: 234 additions & 0 deletions public/private.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css" integrity="sha512-SnH5WK+bZxgPHs44uWIX+LLJAJ9/2PkPKZ5QiAj6Ta86w+fsb2TkcmfRyVX3pBnMFcV7oQPJkl9QevSCWr3W6A==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<title>Eagles Private Chat</title>
<style>
body {
display: flex;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
}
#container {
display: flex;
width: 100%;
height: 100%;
}
#sidebar {
width: 33.33%;
background-color: #fff;
overflow: auto;
}
#sidebar h4 {
margin: 1rem;
font-weight: bold;
}
#sidebar ul {
list-style: none;
padding: 0;
margin: 0;
border-top: 1px solid #ddd;
}
#sidebar li {
padding: 0.5rem 1rem;
cursor: pointer;
border-bottom: 1px solid #ddd;
}
#sidebar li:hover {
background-color: #f0f0f0;
}
#main-chat-area {
width: 66.67%;
display: flex;
flex-direction: column;
background-color: #f0f0f0;
}
#main-chat-area h4 {
margin: 1rem;
font-weight: bold;
}
#chat-messages {
flex-grow: 1;
padding: 1rem;
overflow: auto;
}
#chat-messages p {
padding: 0.5rem;
border-radius: 0.25rem;
max-width: 50%;
}
#chat-messages .message-left {
background-color: #007bff;
color: #fff;
}
#chat-messages .message-right {
background-color: #28a745;
color: #fff;
margin-left: auto;
}
#input-div {
margin: 1rem;
display: none;
}
#input-message {
flex-grow: 1;
width: 90%;
padding: 0.5rem;
border: 1px solid #ddd;
border-radius: 0.25rem;
}
#send-button {
padding: 0.5rem;
float: right;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 0.25rem;
cursor: pointer;
}
#send-button:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<div id="container">
<!-- Sidebar for chat list -->
<div id="sidebar">
<h4>Chats with Our Sellers</h4>
<ul id="user-list">
<!-- Seller list -->


</ul>
</div>

<!-- Main chat area -->
<div id="main-chat-area">
<h4 id="chat-title"> Chat with Our Sellers </h4>
<div id="chat-messages">
<!-- Messages will go here -->


</div>
<!-- Message input -->
<div id="input-div">
<input id="input-message" type="text" placeholder="Type a message">
<button type="submit" id="send-button">Send</button>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.7.5/socket.io.js"
integrity="sha512-luMnTJZ7oEchNDZAtQhgjomP1eZefnl82ruTH/3Oj/Yu5qYtwL7+dVRccACS/Snp1lFXq188XFipHKYE75IaQQ=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
const socket = io();
const port = window.location.port;
const token = localStorage.getItem("loginToken");
const decodedToken = JSON.parse(atob(token.split(".")[1]));
const messageInput = document.getElementById("input-message");
const sendMessageBtn = document.getElementById("send-button");
const sellers_list = document.getElementById('user-list')
const chat_title = document.getElementById("chat-title")
let chat_area = document.getElementById("chat-messages")
const message_section = document.getElementById("input-div")
let receiverId;

const Seller_URL = `http://localhost:${port}/api/v1/users/sellers`

const addMessageToUi = (isSender, data) => {
const date = new Date(data.createdAt);
const hours = date.getHours();
const minutes = date.getMinutes();
const formattedTime = `${hours}:${minutes < 10 ? '0' + minutes : minutes}`;

const element = `<p class=" ${isSender? "message-right" : "message-right" }">
${data.message}<span style="float: right">${formattedTime}</span>
</p>`

chat_area.innerHTML += element
chat_area.scrollTop = chat_area.scrollHeight;
}
const addPastMessageToUi = (isSender, data) =>{

data.forEach(data =>{
const date = new Date(data.createdAt);
const hours = date.getHours();
const minutes = date.getMinutes();

const formattedTime = `${hours}:${minutes < 10 ? '0' + minutes : minutes}`;
const element = `<p class=" ${isSender? "message-right" : "message-right" }">
${data.message}<span style="float: right">${formattedTime}</span>
</p>`
chat_area.innerHTML += element
chat_area.scrollTop = chat_area.scrollHeight;
}
)



}

const fetchSellers = async () => {
const response = await fetch(`${Seller_URL}`);
const data = await response.json();
return data;

}
fetchSellers().then(
resp => resp.data.forEach(seller =>{
const receiver = document.createElement('li')
receiver.dataset.id = seller.id
receiver.textContent = seller.name;
sellers_list.appendChild(receiver)
// Onclick on single seller to retrieve the messages

receiver.addEventListener("click", (e) => {
e.preventDefault()
const i = `<i class="fa-regular fa-user"> </i>`

chat_title.innerHTML = i + ' ' + receiver.textContent

receiverId = receiver.dataset.id
chat_area.innerHTML = ''
userId = decodedToken.id
message_section.style.display = 'block'

socket.emit("past private messages between two users", {userId, receiverId})

})
})
);


sendMessageBtn.addEventListener("click",async (e)=>{
e.preventDefault()
const sender = decodedToken.name
const userId = decodedToken.id
const message = messageInput.value

socket.emit("private chat message", {sender, userId, receiverId, message})
messageInput.value = ""

})
socket.on("validation error", (error) =>{
console.log(error)
})

socket.on("private message sent", (message) =>{
let isSender = message.sender === decodedToken.name
addMessageToUi(isSender, message)
})

socket.on("past private user to user message sent", (message) =>{
let isSender = message.sender === decodedToken.name
addPastMessageToUi(isSender, message)
})


</script>
</body>
</html>
9 changes: 8 additions & 1 deletion src/config/socketCofing.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Server,Socket } from "socket.io";
import { sendMessages, getPastMessages } from "../controllers/chatsController";
import { createAPrivateMessageSocket, retrieveAUserToUserPrivateMessageSocket } from "../controllers/privateChatController";



Expand All @@ -9,7 +10,7 @@ import { sendMessages, getPastMessages } from "../controllers/chatsController";
connectedClients.add(socket.id);
io.emit('connected client', connectedClients.size);

console.log("connected client")
console.log(`connected client`)
await getPastMessages(socket);


Expand All @@ -21,6 +22,12 @@ import { sendMessages, getPastMessages } from "../controllers/chatsController";
socket.on('chat message', async(data: any) => {
await sendMessages(io, data);
});
socket.on('private chat message', async(data: any) =>{
await createAPrivateMessageSocket(io, data);
} )
socket.on('past private messages between two users', async(data:any) =>{
await retrieveAUserToUserPrivateMessageSocket(io, data)
})
});
}

Expand Down
5 changes: 2 additions & 3 deletions src/controllers/chatsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const sendMessages = async(io:Server,data:any) =>{
const newMessage = {
sender,
userId,
message
message,
}
const validated:any = chatMessageSchema.validate(newMessage);
if(validated.error){
Expand All @@ -30,5 +30,4 @@ export const getPastMessages = async(socket:Socket) =>{
}
export const joiRoom = async(req:Request,res:Response) => {
res.sendFile(path.resolve('public/index.html'))
}

}
Loading

0 comments on commit e4d2af2

Please sign in to comment.