- Reorganize folder
    - Reorganize function
    - Add "todo" in mains
This commit is contained in:
Kum1ta
2024-08-04 22:18:05 +02:00
parent d7e1b551d7
commit cbdce2f62a
19 changed files with 1287 additions and 0 deletions

View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Chat</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' type='text/css' href='style/style.css'>
<script type="module" src='main.js'></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
</head>
<body>
<div id="chatButton">
<p>CHAT</p>
</div>
<div id="chatDiv">
<div id="topChatHome">
<h1>Chat</h1>
<div id="topChatCross">
<h2>X</h2>
</div>
</div>
<div id="buttonTypeChatHome">
<h2 id="selected">Private</h2>
<h2>Game</h2>
</div>
<div id="messageListChatHome">
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,125 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* launchPrivateChat.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/04 19:17:54 by edbernar #+# #+# */
/* Updated: 2024/08/04 19:42:49 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import { messageList, infoPanel, waitForMessageList } from "../typeResponse/typePrivateListMessage.js";
import { userMeInfo } from "../typeResponse/typeLogin.js";
import { showListUser } from "./showUserList.js";
import { sendRequest } from "../websocket.js";
async function launchPrivateChat(user)
{
const divMessageListChatHome = document.getElementById("messageListChatHome");
sendRequest("get_private_list_message", {id: user.id});
await waitForMessageList();
infoPanel.id = user.id;
infoPanel.isOpen = true;
infoPanel.divMessage = divMessageListChatHome;
await changeButton(user);
await displayAllMessage(divMessageListChatHome);
await displayInputBar(divMessageListChatHome, user);
}
async function changeButton(user)
{
const divButtonTypeChatHome = document.getElementById("buttonTypeChatHome");
let returnButton;
let h2Button;
let lenh2Button;
h2Button = divButtonTypeChatHome.getElementsByTagName("h2");
lenh2Button = h2Button.length;
for (let i = 0; i < lenh2Button; i++) {
h2Button[i - i].remove();
}
divButtonTypeChatHome.innerHTML += `
<h2>${user.name}</h2>
<p id="returnButton" style="margin: 8px 10px 0 0; text-align: right;">Return</p>
`;
h2Button[0].style.cursor = "default";
returnButton = document.getElementById("returnButton");
returnButton.style.cursor = "pointer";
returnButton.addEventListener("click", () => {
divButtonTypeChatHome.innerHTML = `
<h2 id="selected">Private</h2>
<h2>Game</h2>
`;
infoPanel.isOpen = false;
showListUser();
});
}
async function displayAllMessage(divMessageListChatHome)
{
divMessageListChatHome.style.height = "230px";
divMessageListChatHome.style.paddingBottom = "20px";
divMessageListChatHome.innerHTML = '';
messageList.forEach(element => {
divMessageListChatHome.innerHTML += `
<div class="${element.from === userMeInfo.id ? "meMessage" : "opponentMessage"}">
<p class="content">${element.content}</p>
<p class="time">${element.date}</p>
</div>
`;
});
divMessageListChatHome.scrollTop = divMessageListChatHome.scrollHeight;
}
async function displayInputBar(divMessageListChatHome, user)
{
let sendButton;
let inputMessage;
divMessageListChatHome.innerHTML += `
<div id="inputMessageDiv">
<textarea type="text" id="inputMessage" placeholder="Enter your message here"></textarea>
<p id="sendButton"">\></p>
</div>
`;
sendButton = document.getElementById("sendButton");
sendButton.style.cursor = "pointer";
sendButton.addEventListener("click", () => {
sendMessage(user);
inputMessage.value = "";
inputMessage.focus();
});
inputMessage = document.getElementById("inputMessage");
inputMessage.addEventListener("keyup", (event) => {
if (event.key === "Enter" && !event.shiftKey && inputMessage.value.trim() !== "")
{
event.preventDefault();
sendMessage(user);
inputMessage.value = "";
inputMessage.focus();
}
});
inputMessage.addEventListener("keydown", (event) => {
if (event.key === "Enter")
event.preventDefault();
});
inputMessage.focus();
}
function sendMessage(user) {
const inputMessage = document.getElementById("inputMessage");
let message;
message = {
from: userMeInfo.id,
to: user.id,
content: inputMessage.value,
time: new Date()
};
sendRequest("send_private_message", message);
}
export { launchPrivateChat };

View File

@ -0,0 +1,53 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* main.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/04 19:19:10 by edbernar #+# #+# */
/* Updated: 2024/08/04 19:49:19 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import { infoPanel } from "../typeResponse/typePrivateListMessage.js";
import { showListUser } from "./showUserList.js";
/*
Todo (Eddy) :
- add a function to "New conversation +"
- game message when game will be implemented
- fix the bug on button "private" and "game"
*/
function liveChat()
{
const chatButton = document.getElementById("chatButton");
const chatDiv = document.getElementById("chatDiv");
const topChatHomeCross = document.getElementById("topChatCross");
const privateButtonChatHome = document.getElementById("buttonTypeChatHome").getElementsByTagName("h2")[0];
const gameButtonChatHome= document.getElementById("buttonTypeChatHome").getElementsByTagName("h2")[1];
chatButton.addEventListener("click", async () => {
chatDiv.style.display = "flex";
gameButtonChatHome.removeAttribute("id");
privateButtonChatHome.setAttribute("id", "selected");
await showListUser();
});
topChatHomeCross.addEventListener("click", () => {
chatDiv.style.display = "none";
infoPanel.isOpen = false;
});
privateButtonChatHome.addEventListener("click", async () => {
gameButtonChatHome.removeAttribute("id");
privateButtonChatHome.setAttribute("id", "selected");
await showListUser();
});
gameButtonChatHome.addEventListener("click", () => {
privateButtonChatHome.removeAttribute("id");
gameButtonChatHome.setAttribute("id", "selected");
showActualGameMessage();
});
}
export { liveChat };

View File

@ -0,0 +1,85 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* showActualGameMessage.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/04 19:21:55 by edbernar #+# #+# */
/* Updated: 2024/08/04 19:49:35 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import { sendRequest } from "../websocket";
function showActualGameMessage()
{
const divMessageListChatHome = document.getElementById("messageListChatHome");
let me = "Kumita";
let request = {
isInGame: false,
opponent: {
name: "Astropower",
pfp: "https://ashisheditz.com/wp-content/uploads/2024/03/cool-anime-pfp-demon-slayer-HD.jpg"
},
listMessage: [
{
from: "Astropower",
content: "Hello !",
date: "19:21 30/07/2024"
},
{
from: "Kumita",
content: "Hey",
date: "19:21 30/07/2024"
},
{
from: "Astropower",
content: "Do you want play ?",
date: "19:22 30/07/2024"
},
{
from: "Kumita",
content: "Yes, i'm ready !",
date: "19:22 30/07/2024"
},
{
from: "Kumita",
content: "The game was too hard but well played",
date: "19:27 30/07/2024"
},
{
from: "Astropower",
content: "Yeah but you still won. See you soon",
date: "19:27 30/07/2024"
},
]
}; //Remplace temporairement la requete qui devra être de la meme forme
divMessageListChatHome.style.height = "230px";
divMessageListChatHome.style.paddingBottom = "20px";
divMessageListChatHome.innerHTML = '';
if (request.isInGame === false)
{
divMessageListChatHome.innerHTML = "<p style='text-align: center; margin-top: 20px;'>You are currently not in a game.</p>";
return ;
}
request.listMessage.forEach(element => {
divMessageListChatHome.innerHTML += `
<div class="${element.from === me ? "meMessage" : "opponentMessage"}">
<p class="content">${element.content}</p>
<p class="time">${element.date}</p>
</div>
`;
});
divMessageListChatHome.scrollTop = divMessageListChatHome.scrollHeight;
divMessageListChatHome.innerHTML += `
<div id="inputMessageDiv">
<textarea type="text" id="inputMessage" placeholder="Enter your message here"></textarea>
<p id="sendButton">\></p>
</div>
`;
}
export { showActualGameMessage };

View File

@ -0,0 +1,50 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* showUserList.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/04 19:21:10 by edbernar #+# #+# */
/* Updated: 2024/08/04 19:29:20 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import { waitForUserList } from "../typeResponse/typePrivateListUser.js";
import { userList } from "../typeResponse/typePrivateListUser.js";
import { launchPrivateChat } from "./launchPrivateChat.js";
import { sendRequest } from "../websocket.js";
async function showListUser() {
const divMessageListChatHome = document.getElementById("messageListChatHome");
let divUser;
sendRequest("get_private_list_user", {});
await waitForUserList();
divMessageListChatHome.style.height = "100%";
divMessageListChatHome.style.paddingBottom = "10px";
divMessageListChatHome.innerHTML = '';
divMessageListChatHome.scrollTop = 0;
if (JSON.stringify(userList) !== "{}")
{
userList.forEach(element => {
divMessageListChatHome.innerHTML += `
<div class="user">
<div class="status ${element.status}">
<img src="${element.pfp}">
</div>
<h3>${element.name}</h3>
</div>
`;
});
}
divMessageListChatHome.innerHTML += "<p style='text-align: center; margin-top: 20px;'>New conversation +</p>";
divUser = document.getElementsByClassName("user");
for (let i = 0; i < divUser.length; i++) {
divUser[i].addEventListener("click", async () => {
await launchPrivateChat(userList[i]);
});
}
}
export { showListUser };

View File

@ -0,0 +1,17 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* main.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/30 13:50:35 by edbernar #+# #+# */
/* Updated: 2024/08/04 19:20:02 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import { liveChat } from "./liveChat/main.js";
document.addEventListener('DOMContentLoaded', () => {
liveChat();
});

View File

@ -0,0 +1,243 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* style.css :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/30 13:53:39 by edbernar #+# #+# */
/* Updated: 2024/08/01 23:25:38 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
body {
border: 0;
padding: 0;
width: 100%;
height: 100%;
background-color: #616161;
user-select: none;
}
#chatButton {
position: absolute;
bottom: 10px;
left: 30px;
background-color: white;
width: 100px;
height: 40px;
text-align: center;
cursor : pointer;
z-index: 998;
}
#chatButton p {
margin: 0;
margin-top: 10px;
}
#chatButton:hover {
background-color: rgb(204, 204, 204);
}
#chatDiv {
width: 350px;
height: 400px;
background-color: #131313;
position: absolute;
left: 20px;
bottom: 0px;
z-index: 999;
display: none;
flex-direction: column;
color: white;
font-family: 'Poppins';
padding: 20px;
padding-bottom: 0;
}
#chatDiv h1 {
margin: 0;
font-size: 25px;
}
/* Delete this, is just for cross style */
#chatDiv h2 {
cursor : pointer;
margin: 0;
font-size: 25px;
}
#chatDiv #topChatHome {
display: flex;
flex-direction: row;
justify-content: space-between;
padding-bottom: 10px;
}
#buttonTypeChatHome {
display: grid;
grid-template-columns: 50% 50%;
width: 100%;
}
#buttonTypeChatHome h2 {
text-align: center;
font-size: 20px;
color: #dfdfdf;
padding-top: 5px;
padding-bottom: 5px;
}
#selected {
background-color: black;
}
#messageListChatHome {
display: flex;
flex-direction: column;
overflow: auto;
height: 230px;
padding-bottom: 20px;
padding-top: 5px;
}
#messageListChatHome .user {
display: flex;
flex-direction: row;
height: 75px;
margin: 0;
padding: 10px 0 5px 5px;
}
#messageListChatHome .user:hover {
background-color: #484848;
cursor : pointer;
}
#messageListChatHome .user .status {
border-radius: 1000px;
width: 60px;
height: 60px;
margin-right: 10px;
}
#messageListChatHome .online {
background-color: rgb(17, 165, 29);
}
#messageListChatHome .offline {
background-color: rgb(148, 39, 39);
}
#messageListChatHome .user img {
height: 52px;
width: 52px;
margin-left: 4px;
margin-top: 4px;
border-radius: 100%;
}
#messageListChatHome .opponentMessage {
max-width: 80%;
padding: 10px;
margin-top: 20px;
background-color: #484848;
margin-right: auto;
}
#messageListChatHome .meMessage {
max-width: 80%;
padding: 10px;
margin-top: 20px;
background-color: #222222;
margin-right: 0;
margin-left: auto;
}
#messageListChatHome .meMessage p {
text-align: right;
}
#messageListChatHome .content {
user-select: text;
}
#messageListChatHome .time {
margin-top: 10px;
font-size: 12px;
}
#messageListChatHome p {
margin: 0;
word-break: break-word;
}
#inputMessageDiv {
position: absolute;
width: 348px;
height: 50px;
background-color: #0B0B0B;
bottom: 10px;
color: white;
display: flex;
flex-direction: row;
border: 1px solid #000000;
}
#inputMessageDiv p {
margin: 0;
margin-left: 10px;
margin-right: 10px;
font-family: "Poppins";
font-weight: bolder;
font-size: 35px;
margin-top: -2px;
}
#inputMessage{
user-select: text;
background-color: #0f0f0f;
width: 100%;
overflow: hidden;
resize: none;
border: 0;
color: white;
padding: 15px 5% 15px 5%;
}
#inputMessage:focus {
outline: none;
border: 0;
}
#messageListChatHome {
--sb-thumb-color: #080808;
--sb-size: 5px;
}
#messageListChatHome::-webkit-scrollbar {
width: var(--sb-size)
}
#messageListChatHome::-webkit-scrollbar-track {
border-radius: 1px;
}
#messageListChatHome::-webkit-scrollbar-thumb {
background: var(--sb-thumb-color);
border-radius: 1px;
}
@supports not selector(::-webkit-scrollbar) {
#messageListChatHome {
scrollbar-color: var(--sb-thumb-color)
var(--sb-track-color);
}
}

View File

@ -0,0 +1,25 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* typeLogin.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/02 00:39:53 by edbernar #+# #+# */
/* Updated: 2024/08/03 23:37:33 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
let userMeInfo = {
username: "",
id: 42
};
function typeLogin(content)
{
console.log("Welcome " + content.username + "\nYou're id is " + content.id);
userMeInfo.username = content.username;
userMeInfo.id = content.id;
}
export { userMeInfo, typeLogin };

View File

@ -0,0 +1,32 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* typeNewPrivateMessage.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/04 15:15:49 by edbernar #+# #+# */
/* Updated: 2024/08/04 18:26:40 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import { sendRequest } from "../websocket.js";
import { messageList, infoPanel } from "./typePrivateListMessage.js";
import { userMeInfo } from "./typeLogin.js";
function typeNewPrivateMessage(content)
{
messageList.push(content);
if (infoPanel.isOpen && infoPanel.id === content.channel)
{
infoPanel.divMessage.insertAdjacentHTML('beforeend', `
<div class="${content.from === userMeInfo.id ? "meMessage" : "opponentMessage"}">
<p class="content">${content.content}</p>
<p class="time">${content.date}</p>
</div>
`);
infoPanel.divMessage.scrollTop = infoPanel.divMessage.scrollHeight;
}
}
export { typeNewPrivateMessage };

View File

@ -0,0 +1,43 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* typePrivateListMessage.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/03 22:20:35 by edbernar #+# #+# */
/* Updated: 2024/08/04 18:58:45 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
let infoPanel = {
isOpen: false,
id: -1,
divMessage: null
}
let messageList = [];
let messageListAvailable = false;
let messageListResolve = null;
function waitForMessageList() {
return new Promise((resolve) => {
if (messageListAvailable)
resolve();
else
messageListResolve = resolve;
});
}
function typePrivateListMessage(list) {
messageList = list;
messageListAvailable = true;
if (messageListResolve)
{
messageListResolve();
messageListResolve = null;
messageListAvailable = false;
}
}
export { messageList, infoPanel, typePrivateListMessage, waitForMessageList };

View File

@ -0,0 +1,36 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* typePrivateListUser.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/02 01:56:15 by edbernar #+# #+# */
/* Updated: 2024/08/03 14:36:20 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
let userList = [];
let userListAvailable = false;
let userListResolve = null;
function waitForUserList() {
return new Promise((resolve) => {
if (userListAvailable)
resolve();
else
userListResolve = resolve;
});
}
function typePrivateListUser(list) {
userList = list;
userListAvailable = true;
if (userListResolve)
{
userListResolve();
userListResolve = null;
}
}
export { userList, typePrivateListUser, waitForUserList };

View File

@ -0,0 +1,77 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* websocket.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/31 22:17:24 by edbernar #+# #+# */
/* Updated: 2024/08/04 19:51:29 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import { typeLogin } from "./typeResponse/typeLogin.js";
import { typePrivateListUser } from "./typeResponse/typePrivateListUser.js";
import { typePrivateListMessage } from "./typeResponse/typePrivateListMessage.js";
import { typeNewPrivateMessage } from "./typeResponse/typeNewPrivateMessage.js";
/*
Todo (Eddy) :
- Request to connect by email and password. Waiting for the front to do it (already functional on the back side)
sendRequest("login", {type: "byPass", mail: "aa@aa.fr", password: "ABC123"});
- Information: the 'token' variable is only used until the connection is fully implemented
*/
const socket = new WebSocket('ws://localhost:8000/');
const token = "IDSNCSDAd465sd13215421";
const typeResponse = ["login", "private_list_user", "private_list_message", "new_private_message"];
const functionResponse = [typeLogin, typePrivateListUser, typePrivateListMessage, typeNewPrivateMessage];
socket.onopen = () => {
console.log('Connected');
if (token)
sendRequest("login", {"type": "byToken", "token": token});
};
socket.onmessage = (event) => {
let response;
try {
response = JSON.parse(event.data);
} catch {
return ;
}
if (response.code >= 9000 && response.code <= 9999)
console.warn(response);
else
{
try {
functionResponse[typeResponse.indexOf(response.type)](response.content);
}
catch {
console.warn(response);
}
}
};
socket.onclose = () => {
console.log('Disconnected');
};
function sendRequest(type, content) {
let coc = null;
if (content instanceof Object)
coc = JSON.stringify(content);
else
coc = content;
socket.send(JSON.stringify({
type: type,
token: token,
content: content
}));
}
export { socket, token, sendRequest };