add part of site to docker and login works using sessions

This commit is contained in:
2024-08-24 18:28:32 +02:00
parent 1291a6add8
commit 57ef3a5d2d
49 changed files with 2544 additions and 108 deletions

View File

@ -0,0 +1,143 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* Screen.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marvin <marvin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/22 23:13:53 by edbernar #+# #+# */
/* Updated: 2024/08/24 11:39:09 by marvin ### ########.fr */
/* */
/* ************************************************************************** */
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import * as THREE from 'three'
const loader = new GLTFLoader();
class Screen
{
screen = null;
tv = null;
pointLightIntensity = 1;
screenMaterial = null;
constructor(scene)
{
this.screen = this.#createScreen(scene);
loader.load( './modeles/tv.glb', (gltf) => {
const tv = gltf.scene.children[0];
const boundingBox = new THREE.Box3().setFromObject(tv);
const center = boundingBox.getCenter(new THREE.Vector3());
tv.geometry.center();
this.tv = tv;
tv.position.set(0, 0.99, 2);
tv.material = new THREE.MeshPhysicalMaterial({color: 0xaaaaaa});
tv.material.roughness = 10;
tv.material.metalness = 1;
tv.scale.set(0.05, 0.05, 0.05);
tv.castShadow = true;
tv.receiveShadow = true;
scene.add(tv);
}, undefined, function ( error ) {
console.error( error );
throw Error("Can't open file 'tv.glb'");
} );
this.#showVideo('/modeles/pong.mp4')
}
#createScreen(scene)
{
const geometry = new THREE.PlaneGeometry(4.1, 3, 50, 50);
const positionAttribute = geometry.attributes.position;
const vertices = positionAttribute.array;
const material = new THREE.MeshStandardMaterial({color: 0xbbbbbb});
const mesh = new THREE.Mesh(geometry, material);
const pointLight = new THREE.PointLight( 0xffffff, 10 * this.pointLightIntensity, 0, 2);
for (let i = 0; i < vertices.length; i += 3)
{
const x = vertices[i];
const y = vertices[i + 1];
const distance = (Math.sqrt(x * x + y * y));
const height = Math.pow(distance, 2) * -0.02;
vertices[i + 2] = height;
}
positionAttribute.needsUpdate = true;
mesh.scale.set(0.41, 0.42);
mesh.position.set(-0.155, 1.2, 1.15);
mesh.rotation.x = Math.PI + 0.05;
mesh.rotation.z = Math.PI;
scene.add(mesh);
pointLight.position.set(-0.05, 1.2, 0.95);
pointLight.castShadow = true;
pointLight.shadow.mapSize.width = 2048;
pointLight.shadow.mapSize.height = 2048;
console.log(pointLight.shadow)
scene.add(pointLight);
setInterval(() => {
const intensity = Math.random() * 2 + 10;
pointLight.intensity = intensity * this.pointLightIntensity > 13 * this.pointLightIntensity ? 13 * this.pointLightIntensity : intensity * this.pointLightIntensity;
}, 100);
return (mesh);
}
#showVideo(path)
{
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d', { willReadFrequently: true });
const video = document.createElement('video');
const texture = new THREE.CanvasTexture(canvas);
const material = new THREE.MeshBasicMaterial({ map: texture,color: 0xffffff, transparent: true, opacity: 1 });
canvas.width = 534;
canvas.height = 360;
video.src = path + '?t=' + new Date().getTime();
video.loop = true;
video.muted = true;
video.crossOrigin = 'anonymous';
video.addEventListener('loadedmetadata', () => {
const texture = this.screen.material.map;
texture.needsUpdate = true;
video.play().then(() => {
updateCanvas();
}).catch(err => console.error("Error playing video: ", err));
});
function addNoiseOnImage(context)
{
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
for (let i = 0; i < data.length; i += 4)
{
const r = data[i];
const g = data[i + 1];
const b = data[i + 2];
const brightness = (3 * r + 4 * g + b) >>> 3;
const noise = Math.random() * 128 - 32;
data[i] = data[i + 1] = data[i + 2] = brightness + noise;
}
context.putImageData(imageData, 0, 0);
}
function updateCanvas()
{
if (!video.paused && !video.ended)
{
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(video, 0, 0, canvas.width, canvas.height);
addNoiseOnImage(context);
texture.needsUpdate = true;
}
requestAnimationFrame(updateCanvas);
}
texture.offset.set(0.02, 0);
this.screen.material = material;
video.load();
}
};
export { Screen };

View File

@ -0,0 +1,162 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* home3D.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marvin <marvin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/22 17:19:17 by edbernar #+# #+# */
/* Updated: 2024/08/24 11:41:18 by marvin ### ########.fr */
/* */
/* ************************************************************************** */
import * as THREE from 'three'
import { Screen } from './Screen.js'
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
import { BokehPass } from 'three/examples/jsm/postprocessing/BokehPass.js';
const scene = new THREE.Scene();
const renderer = new THREE.WebGLRenderer({antialias: true});
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight);
const ambiantLight = new THREE.AmbientLight(0xffffff, 35);
const screen = new Screen(scene);
const cube = createCube();
renderer.toneMapping = THREE.LinearToneMapping;
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.getElementsByClassName('homeSection')[0].appendChild(renderer.domElement);
scene.background = new THREE.Color(0x020202)
camera.position.set(6, 1, -5.5);
camera.rotation.set(Math.PI + 0.2, 0, Math.PI);
scene.add(ambiantLight);
let globalSpeed = 0.75;
const composer = new EffectComposer(renderer);
composer.addPass(new RenderPass(scene, camera));
const dofPass = new BokehPass(scene, camera, {
focus: 10.0,
aperture: 0.020,
maxblur: 0.01,
});
composer.addPass(dofPass);
setTimeout(() => {
let interval = setInterval(() => {
camera.position.x -= (0.01 * globalSpeed);
camera.lookAt(screen.tv.position);
if (camera.position.x < 3.3)
fadeInOut();
if (dofPass.materialBokeh.uniforms.aperture.value > 0)
dofPass.materialBokeh.uniforms.aperture.value -= 0.0001;
if (camera.position.x < 3)
{
clearInterval(interval);
camera.position.set(-2, 4, -6);
interval = setInterval(() => {
camera.lookAt(screen.tv.position);
camera.position.x += (0.01 * globalSpeed);
camera.position.y -= (0.005 * globalSpeed);
if (camera.position.x > 1.7)
fadeInOut();
if (camera.position.x > 2)
{
camera.position.set(0, 1.2, 0);
clearInterval(interval);
interval = setInterval(() => {
camera.lookAt(screen.tv.position);
camera.position.y += (0.005 * globalSpeed);
camera.position.z -= (0.01 * globalSpeed);
if (camera.position.x < -2.3)
fadeInOut();
if (camera.position.z < -2)
{
globalSpeed -= 0.001;
if (globalSpeed < 0)
clearInterval(interval);
}
}, 10);
}
}, 10);
}
}, 10);
}, 500)
document.addEventListener('resize', () => {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
});
let isInFade = false;
function fadeInOut()
{
if (isInFade)
return;
let interval = null;
isInFade = true;
interval = setInterval(() => {
screen.pointLightIntensity -= 0.2;
screen.screen.material.opacity -= 0.05;
if (screen.screen.material.opacity <= 0)
{
clearInterval(interval);
setTimeout(() => {
interval = setInterval(() => {
screen.pointLightIntensity += 0.2;
screen.screen.material.opacity += 0.05;
if (screen.screen.material.opacity >= 1)
{
clearInterval(interval);
isInFade = false;
}
}, 20);
}, 500);
}
}, 20);
}
function createCube()
{
const geometry = new THREE.BoxGeometry(5, 5, 0.1);
const material = new THREE.MeshStandardMaterial({color: 0x020202});
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(8, 1, -5);
scene.add(mesh);
}
function home3D()
{
createPlane();
renderer.setAnimationLoop(loop)
}
function createPlane()
{
const geometry = new THREE.PlaneGeometry(500, 500);
const material = new THREE.MeshPhysicalMaterial({side: THREE.DoubleSide, color: 0x020202});
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 0, 0);
mesh.rotateX(-(Math.PI / 2));
mesh.receiveShadow = true;
scene.add(mesh);
}
function loop()
{
composer.render();
// renderer.render(scene, camera);
}
export { home3D };

View File

@ -0,0 +1,81 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* main.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/04 19:19:10 by edbernar #+# #+# */
/* Updated: 2024/08/04 23:10:18 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import { infoPanel } from "../typeResponse/typePrivateListMessage.js";
import { showActualGameMessage } from "./showActualGameMessage.js";
import { showListUser } from "./showUserList.js";
/*
Todo (Eddy) :
- add a function to "New conversation +"
- game message when game will be implemented
*/
function addDefaultButton()
{
const newDiv = document.createElement("div");
const newPrivateButton = document.createElement("h2");
const newGameButton = document.createElement("h2");
const divMessageListChatHome = document.createElement("div");
newDiv.setAttribute("id", "buttonTypeChatHome");
newPrivateButton.textContent = "Private";
newGameButton.textContent = "Game";
newPrivateButton.setAttribute("id", "selected");
newDiv.appendChild(newPrivateButton);
newDiv.appendChild(newGameButton);
document.getElementById("chatDiv").appendChild(newDiv);
divMessageListChatHome.setAttribute("id", "messageListChatHome");
document.getElementById("chatDiv").appendChild(divMessageListChatHome);
newPrivateButton.addEventListener("click", async () => {
newGameButton.removeAttribute("id");
newPrivateButton.setAttribute("id", "selected");
await showListUser();
});
newGameButton.addEventListener("click", () => {
newPrivateButton.removeAttribute("id");
newGameButton.setAttribute("id", "selected");
showActualGameMessage();
});
}
function removeButtonIfExist()
{
const divButtonTypeChatHome = document.getElementById("buttonTypeChatHome");
if (divButtonTypeChatHome)
{
divButtonTypeChatHome.remove();
document.getElementById("messageListChatHome").remove();
}
}
function liveChat()
{
const chatButton = document.getElementById("chatButton");
const chatDiv = document.getElementById("chatDiv");
const topChatHomeCross = document.getElementById("topChatCross");
chatButton.addEventListener("click", async () => {
chatDiv.style.display = "flex";
removeButtonIfExist();
addDefaultButton();
await showListUser();
});
topChatHomeCross.addEventListener("click", () => {
chatDiv.style.display = "none";
infoPanel.isOpen = false;
});
}
export { liveChat };

View File

@ -0,0 +1,96 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* showActualGameMessage.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/04 19:21:55 by edbernar #+# #+# */
/* Updated: 2024/08/06 23:19:51 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import { sendRequest } from "../websocket.js";
function showActualGameMessage()
{
const divMessageListChatHome = document.getElementById("messageListChatHome");
let newDiv = null;
let contentNode = null;
let dateNode = null;
let tmp = null;
let me = "Kumita";
let request = {
isInGame: true,
opponent: {
name: "Astropower",
id: "301547"
},
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 => {
newDiv = document.createElement("div");
contentNode = document.createTextNode(element.content);
dateNode = document.createTextNode(element.date);
newDiv.classList.add(element.from == me ? "meMessage" : "opponentMessage");
tmp = document.createElement("p");
tmp.classList.add("content");
tmp.appendChild(contentNode);
newDiv.appendChild(tmp);
tmp = document.createElement("p");
tmp.classList.add("time");
tmp.appendChild(dateNode);
newDiv.appendChild(tmp);
divMessageListChatHome.appendChild(newDiv);
});
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,153 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* showPrivateChat.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/04 19:17:54 by edbernar #+# #+# */
/* Updated: 2024/08/06 23:32:35 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";
let savedButtons = [];
async function showPrivateChat(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 restoreButton()
{
const divButtonTypeChatHome = document.getElementById("buttonTypeChatHome");
divButtonTypeChatHome.innerHTML = '';
savedButtons.forEach(element => {
divButtonTypeChatHome.appendChild(element);
});
}
async function changeButton(user)
{
const divButtonTypeChatHome = document.getElementById("buttonTypeChatHome");
const h2Username = document.createElement("h2");
const h2UsernameNode = document.createTextNode(user.name);
let returnButton = null;
let h2Button = null;
let lenh2Button = 0;
h2Button = divButtonTypeChatHome.getElementsByTagName("h2");
lenh2Button = h2Button.length;
savedButtons.splice(0, savedButtons.length);
for (let i = 0; i < lenh2Button; i++) {
savedButtons.push(h2Button[0]);
h2Button[0].remove();
}
h2Username.appendChild(h2UsernameNode);
divButtonTypeChatHome.appendChild(h2Username);
divButtonTypeChatHome .innerHTML += `
<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", () => {
restoreButton();
infoPanel.isOpen = false;
showListUser();
});
}
async function displayAllMessage(divMessageListChatHome)
{
let newDiv = null;
let contentNode = null;
let dateNode = null;
let tmp = null;
divMessageListChatHome.style.height = "230px";
divMessageListChatHome.style.paddingBottom = "20px";
divMessageListChatHome.innerHTML = '';
messageList.forEach(element => {
newDiv = document.createElement("div");
contentNode = document.createTextNode(element.content);
dateNode = document.createTextNode(element.date);
console.log(element.from, userMeInfo.id);
newDiv.classList.add(element.from === userMeInfo.id ? "meMessage" : "opponentMessage");
tmp = document.createElement("p");
tmp.classList.add("content");
tmp.appendChild(contentNode);
newDiv.appendChild(tmp);
tmp = document.createElement("p");
tmp.classList.add("time");
tmp.appendChild(dateNode);
newDiv.appendChild(tmp);
divMessageListChatHome.appendChild(newDiv);
});
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 { showPrivateChat };

View File

@ -0,0 +1,53 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* showUserList.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/04 19:21:10 by edbernar #+# #+# */
/* Updated: 2024/08/05 14:28:31 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import { waitForUserList } from "../typeResponse/typePrivateListUser.js";
import { userList } from "../typeResponse/typePrivateListUser.js";
import { showPrivateChat } from "./showPrivateChat.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 => {
let user = document.createElement("div");
user.classList.add("user");
user.innerHTML = `
<div class="status ${element.status}">
<img>
</div>
<h3></h3>
`
user.querySelector("img").src = element.pfp;
user.querySelector("h3").innerText = element.name;
divMessageListChatHome.appendChild(user);
});
}
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 showPrivateChat(userList[i]);
});
}
}
export { showListUser };

View File

@ -0,0 +1,28 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* connectedWith42.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/09 09:15:24 by edbernar #+# #+# */
/* Updated: 2024/08/10 15:02:33 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import { typeLogin } from "../typeResponse/typeLogin.js";
import { sendRequest } from "../websocket.js";
function connectedWith42Func()
{
const token42 = window.location.search.split('code=')[1];
if (!token42)
{
typeLogin(null);
return ;
}
sendRequest("login", {type: "by42", token: token42});
}
export { connectedWith42Func };

View File

@ -0,0 +1,87 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* main.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: madegryc <madegryc@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/07 17:40:15 by edbernar #+# #+# */
/* Updated: 2024/08/23 18:35:44 by madegryc ### ########.fr */
/* */
/* ************************************************************************** */
import { createNotification as CN } from "../notification/main.js";
import { userMeInfo, waitForLogin } from "../typeResponse/typeLogin.js";
function login()
{
const loginButton = document.getElementById('loginButton');
const pLoginButton = loginButton.getElementsByTagName('p')[0];
let nodeText = null;
// waitForLogin().then((token) => {
// nodeText = document.createTextNode(userMeInfo.username);
// if (userMeInfo.id !== -1)
// {
// loginButton.replaceChild(nodeText, pLoginButton);
// loginButton.addEventListener('click', showMenu);
// }
// else
loginButton.addEventListener('click', showLoginDiv);
// });
}
function showLoginDiv()
{
const popout = document.getElementById('loginPopup');
if (popout.style.display === 'flex')
popout.style.display = 'none';
else
popout.style.display = 'flex';
}
function showMenu()
{
const loginButton = document.getElementById('loginButton');
const divMenu = document.createElement("div");
const ul = document.createElement("ul");
const li1 = document.createElement("li");
const li2 = document.createElement("li");
let already_activated = false;
divMenu.setAttribute("id", "menuDiv");
li1.innerHTML = "Profile";
li2.innerHTML = "Logout";
li1.addEventListener('click', (e) => {
console.log("profile");
});
li2.addEventListener('click', (e) => {
document.cookie = "token=; path=/; Secure; SameSite=Strict; max-age=0";
window.location.href = "/";
location.reload();
});
ul.appendChild(li1);
ul.appendChild(li2);
divMenu.appendChild(ul);
divMenu.style.position = "absolute";
divMenu.style.width = loginButton.offsetWidth + "px";
divMenu.style.top = loginButton.offsetTop + loginButton.offsetHeight + "px";
divMenu.style.left = loginButton.offsetLeft + "px";
document.body.appendChild(divMenu);
loginButton.removeEventListener('click', showMenu);
loginButton.addEventListener('click', () => {
if (!already_activated)
{
setTimeout(() => {
document.getElementById("menuDiv").remove();
loginButton.addEventListener('click', showMenu);
already_activated = true;
}, 199);
document.getElementById("menuDiv").style.animation = "animHideMenuDiv 0.21s";
}
});
}
export { login, showLoginDiv, showMenu };

View File

@ -0,0 +1,36 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* main.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marvin <marvin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/30 13:50:35 by edbernar #+# #+# */
/* Updated: 2024/08/24 11:57:47 by marvin ### ########.fr */
/* */
/* ************************************************************************** */
import { liveChat } from "./liveChat/main.js";
import { login } from "./login/main.js";
import { home3D } from "./home3D/home3D.js"
window.addEventListener('scroll', () => {
const scrollPosition = window.scrollY;
const rotationAngle = scrollPosition * 0.1;
const parallaxElement = document.querySelector('#firstBall');
const parallaxElement2 = document.querySelector('#secondBall');
const parallaxSpeed = scrollPosition * -0.17;
parallaxElement.style.transform = `translateX(-50%) translateY(${-parallaxSpeed}px) rotate(${rotationAngle}deg)`;
parallaxElement2.style.transform = `translateX(50%) translateY(${-parallaxSpeed}px) rotate(${rotationAngle}deg)`;
});
// document.getElementById('closePopupBtn').addEventListener('click', function() {
// document.getElementById('loginPopup').style.display = 'none';
// });
document.addEventListener('DOMContentLoaded', () => {
liveChat();
login();
home3D();
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,170 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* main.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/04 23:32:52 by edbernar #+# #+# */
/* Updated: 2024/08/06 23:34:39 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
function createHeader(title, img)
{
const divHeader = document.createElement("div");
const icon = document.createElement("img");
const h1Title = document.createElement("h1");
const cross = document.createElement("p");
const titleTextNode = document.createTextNode(title);
divHeader.classList.add("header");
if (img)
{
icon.style.width = "20px";
icon.style.height = "20px";
icon.style.position = 'absolute';
icon.src = img;
}
h1Title.appendChild(titleTextNode);
h1Title.style.textAlign = "center";
h1Title.style.width = "100%";
h1Title.style.marginTop = "5px";
cross.innerHTML = "X";
cross.style.position = 'absolute';
cross.style.cursor = 'pointer';
cross.style.margin = '0';
cross.style.right = '10px';
cross.style.marginTop = '5px';
cross.style.fontSize = '20px';
cross.style.fontWeight = 'bold';
cross.addEventListener("click", () => {
divHeader.parentNode.style.animation = "slideOut 0.21s";
setTimeout(() => {
divHeader.parentNode.remove();
}, 199);
});
if (img)
divHeader.appendChild(icon);
divHeader.appendChild(h1Title);
divHeader.appendChild(cross);
return (divHeader);
}
function createContent(message)
{
const divContent = document.createElement("div");
const pMessage = document.createElement("p");
const pMessageNode = document.createTextNode(message);
const limit = 100;
divContent.classList.add("content");
pMessage.style.textAlign = "center";
if (message.length > limit)
message = message.substring(0, limit) + "...";
pMessage.appendChild(pMessageNode);
divContent.appendChild(pMessage);
return (divContent);
}
function createLoadBar(newNotification, timer)
{
const divLoadBar = document.createElement("div");
const progress = document.createElement("div");
let interval = null;
const intervalTimer = timer / 100;
let i = 1;
progress.classList.add("progress");
divLoadBar.classList.add("loadBar");
divLoadBar.appendChild(progress);
progress.style.height = '5px';
progress.style.width = '0px';
progress.style.backgroundColor = 'black';
newNotification.addEventListener("mouseover", () => {
clearInterval(interval);
progress.style.width = "100%";
});
interval = setInterval(() => {
progress.style.width = (intervalTimer * i) * 100 / timer + "%";
i++;
}, intervalTimer);
setTimeout(() => {
clearInterval(interval);
}, timer);
newNotification.appendChild(divLoadBar);
return (interval);
}
function createFooter(action, actionText)
{
const newButton = document.createElement("div");
const textNode = document.createTextNode(actionText);
if (action == null)
return (null);
newButton.style.cursor = "pointer";
if (actionText.length > 20)
actionText = actionText.substring(0, 20) + "...";
newButton.appendChild(textNode);
newButton.setAttribute("onclick", action);
newButton.classList.add("footer");
if (typeof(action) !== "function")
throw new Error("Action must be a function");
newButton.addEventListener("click", action);
return (newButton);
}
function newNotification(title, message, img, action, timer, actionText)
{
const divNotification = document.getElementById("divNotification");
const newNotification = document.createElement("div");
const header = createHeader(title, img);
const content = createContent(message);
const footer = createFooter(action, actionText);
let intervalLoadBar = null;
let timeoutInTimout = null;
console.log("New notification: " + message);
newNotification.classList.add("notification");
newNotification.style.width = "100%";
newNotification.appendChild(header);
divNotification.appendChild(newNotification);
newNotification.appendChild(content);
if (footer)
newNotification.appendChild(footer);
intervalLoadBar = createLoadBar(newNotification, timer);
const timeout = setTimeout(() => {
timeoutInTimout = setTimeout(() => {
divNotification.removeChild(newNotification);
}, 199);
newNotification.style.animation = "slideOut 0.21s";
}, timer);
newNotification.addEventListener("mouseover", () => {
clearTimeout(timeout);
clearTimeout(timeoutInTimout);
clearInterval(intervalLoadBar);
});
}
class notification
{
timer = 5000;
defaultIcon = {
"warning": "/site/notification/ico/warning.png",
"error": "/site/notification/ico/error.png",
"success": "/site/notification/ico/success.png",
"info": "/site/notification/ico/info.png"
};
constructor() {}
new(title, message, img=null, action=null, actionText="Confirm")
{
newNotification(title, message, img, action, this.timer, actionText);
}
}
const createNotification = new notification();
export { createNotification };

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 MiB

View File

@ -0,0 +1,409 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* home.css :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marvin <marvin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/07 12:00:55 by edbernar #+# #+# */
/* Updated: 2024/08/24 11:26:27 by marvin ### ########.fr */
/* */
/* ************************************************************************** */
@keyframes animShowMenuDiv {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes animHideMenuDiv {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
::-webkit-scrollbar {
width: 10px;
}
::-webkit-scrollbar-thumb {
background: white;
}
* {
margin: 0;
padding: 0;
}
body {
border: 0;
padding: 0;
width: 100%;
height: 100%;
background-color: #020202;
user-select: none;
font-family: "Poppins", sans-serif;
font-weight: 500;
font-style: normal;
}
#topBar {
margin-block: 25px;
padding: 0;
padding-inline: 50px;
display: flex;
gap: 2rem;
align-items: center;
position: absolute;
inset-inline: 0;
top: 0;
z-index: 999;
}
#topButton{
padding: 0;
color: white;
display: flex;
font-size: 25px;
padding-left: 60px;
gap: 6rem;
}
#topButton p {
position: relative;
}
#topButton p:after {
content: "";
position: absolute;
background-color: white;
height: 3px;
width: 0%;
left: 0;
bottom: 1px;
transition: 0.3s;
}
#topButton p:hover:after {
/* color: blue; */
width: 100%;
}
#topBar h1 {
padding: 0;
padding-top: 4px;
font-size: 35px;
color: white;
font-family: 'Poppins';
font-style: italic;
font-weight: bold;
}
#topBar #loginButton {
font-size: 20px;
background-color: white;
height: 40px;
width: 130px;
color: black;
text-align: center;
line-height: 40px;
margin-left: auto;
transition: background-color 0.3s ease;
}
#topBar #loginButton:hover {
background-color: #020202;
color: white;
cursor: pointer;
}
.popup {
display: none; /* La popup est masquée par défaut */
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(5px);
justify-content: center;
align-items: center;
z-index: 1000;
}
.container {
display: flex;
width: 70%;
height: 80%;
background-color: #020202;
}
.left-side {
background-color: #D3D3D3;
flex: 1;
}
.right-side {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
padding: 0;
padding-inline: 180px;
color: white;
}
.right-side h1 {
font-size: 2rem;
margin-bottom: 30px;
align-items: center;
justify-content: center;
}
form {
display: flex;
flex-direction: column;
}
label {
margin-bottom: 5px;
font-size: 1rem;
}
input {
border: none;
padding: 20px;
margin-bottom: 20px;
font-size: 1rem;
font-family: "Poppins", sans-serif;
font-weight: 500;
font-style: normal;
}
button {
padding: 15px;
font-size: 1rem;
cursor: pointer;
border: none;
font-family: "Poppins", sans-serif;
font-weight: 500;
font-style: normal;
}
.login-btn {
background-color: #fff;
margin-bottom: 20px;
transition: background-color 0.3s ease;
}
.login-btn:hover {
background-color: #f0f0f0e1;
}
.new-player {
text-align: center;
margin-bottom: 20px;
}
.new-player a {
color: white;
text-decoration: underline;
transition: color 0.3s ease;
}
.new-player a:hover {
color: #f0f0f0e1;
}
.divider {
display: flex;
align-items: center;
text-align: center;
margin-bottom: 20px;
}
.divider span {
flex: 1;
height: 1px;
background-color: #fff;
}
.divider p {
margin: 0 10px;
font-size: 1rem;
}
.login-42-btn {
background-color: #fff;
display: flex;
justify-content: center;
align-items: center;
transition: background-color 0.3s ease;
}
.login-42-btn span {
font-size: 1.5rem;
font-weight: bold;
}
.login-42-btn:hover {
background-color: #f0f0f0e1;
}
.close {
position: absolute;
top: 10px;
right: 10px;
font-size: 20px;
cursor: pointer;
}
.homeSection{
min-height: 100svh;
overflow: hidden;
}
.homeSection p{
color: white;
}
#firstText{
font-size: 45px;
padding-inline: 50px;
padding-top: 70px;
}
#secondText{
font-size: 45px;
padding-inline: 50px;
padding-top: 140px;
text-align: right;
}
#firstBall{
position: absolute;
width: 340px;
transform-origin: center;
transform: translateX(-50%);
left: 0;
}
#secondBall{
position: absolute;
width: 340px;
transform-origin: center;
transform: translateX(50%);
top: 250px;
right: 0;
}
.relative{
position: relative;
}
#menuDiv {
display: flex;
flex-direction: column;
align-items: right;
font-family: "Poppins", sans-serif;
background-color: #ffffff;
animation: animShowMenuDiv 0.5s;
}
#menuDiv li {
list-style-type: none;
text-align: center;
font-size: 16px;
padding: 10px;
cursor: pointer;
}
#menuDiv li:hover {
background-color: #f0f0f0;
}
.team {
display: flex;
gap: 40px;
padding-inline: 200px;
padding-block: 200px;
justify-content: center;
}
.team h2 {
color: white;
font-size: 30px;
}
.team-member {
max-width: 350px;
transition: transform 0.3s ease;
}
.team-member:hover {
transform: scale(1.2);
}
.team-member:not(:hover) {
transform: scale(0.8);
}
.team-photo {
width: 100%;
height: auto;
}
.info {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%) translateY(10px);
background-color: #020202;
padding: 10px;
width: 100%;
opacity: 0;
transition: transform 0.3s ease, opacity 0.3s ease;
}
.team-member:hover .info {
transform: translateX(-50%) translateY(25%);
opacity: 1;
}
footer {
padding: 25px;
overflow: hidden;
height: 150px;
background-color: white;
color: #020202;
}
.footer-content {
display: flex;
justify-content: space-between;
align-items: center;
}
.footer-left h1 {
font-size: 1.5em;
font-style: italic;
font-weight: bold;
margin: 0;
}
.footer-left p {
color: #afafaf;
}
.footer-right p {
font-weight: bold;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 MiB

View File

@ -0,0 +1,235 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* liveChat.css :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marvin <marvin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/30 13:53:39 by edbernar #+# #+# */
/* Updated: 2024/08/10 16:47:10 by marvin ### ########.fr */
/* */
/* ************************************************************************** */
#chatButton {
position: absolute;
bottom: 10px;
left: 30px;
background-color: white;
width: 100px;
height: 40px;
text-align: center;
cursor : pointer;
z-index: 10;
}
#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;
}
#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,199 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* loginPage.css :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marvin <marvin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/07 17:15:28 by edbernar #+# #+# */
/* Updated: 2024/08/13 13:30:43 by marvin ### ########.fr */
/* */
/* ************************************************************************** */
@keyframes anim1 {
0% {
transform: translate(0, -150%);
}
100% {
transform: translateY(0, 0);
}
}
@keyframes anim2 {
0% {
backdrop-filter: blur(0px);
background-color: rgba(0, 0, 0, 0);
}
100% {
backdrop-filter: blur(5px);
background-color: rgba(0, 0, 0, 0.8);
}
}
#mainText{
color: white;
font-size: 50px;
font-family: "Poppins", sans-serif;
font-weight: 500;
font-style: normal;
margin-top: 125px;
margin-bottom: 50px;
align-content: center;
text-align: center;
}
#inputLogin{
margin-top: 2px;
margin-bottom: 15px;
padding-left: 3%;
padding-right: 3%;
font-family: "Poppins", sans-serif;
font-weight: 500;
font-style: normal;
border: none;
text-decoration: none;
height: 45px;
width: 94%;
}
#inputPassword{
margin-top: 2px;
margin-bottom: 25px;
padding-left: 3%;
padding-right: 3%;
font-family: "Poppins", sans-serif;
font-weight: 500;
font-style: normal;
border: none;
text-decoration: none;
height: 45px;
width: 94%;
}
#styleButton{
font-family: "Poppins", sans-serif;
font-weight: 600;
font-style: normal;
height: 45px;
width: 100%;
border: none;
text-decoration: none;
transition: background-color 0.3s ease;
}
#styleButton:hover{
background-color: #b4b4b4;
}
#styleButton42{
font-family: "Poppins", sans-serif;
font-weight: 600;
font-style: normal;
height: 45px;
width: 100%;
border: none;
text-decoration: none;
transition: background-color 0.3s ease;
}
#styleButton42:hover{
background-color: #b4b4b4;
}
#createAccText{
margin-left: 10px;
cursor: pointer;
border-bottom: white 1px solid;
transition: color 0.3s ease;
}
#createAccText:hover{
color: rgb(165, 165, 165);
}
#orText{
align-content: center;
text-align: center;
margin-top: 15px;
margin-bottom: 15px;
}
#newAccDiv{
display: flex;
flex-direction: row;
margin-top: 15px;
margin-bottom: 15px;
justify-content: center;
}
#loginDiv {
inset: 0;
padding-block: 7rem;
display: flex;
position: absolute;
z-index: 500;
animation: anim1 0.4s;
font-family: "Poppins", sans-serif;
font-weight: 500;
font-style: normal;
justify-content: center;
}
#globalBg {
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
position: absolute;
z-index: 499;
top: 0;
left: 0;
backdrop-filter: blur(5px);
animation: anim2 0.5s;
}
#threeDiv {
width: 20%;
height: 100%;
background-color: white;
}
#connectDiv {
width: 45%;
height: 100%;
background-color: #020202;
display: flex;
flex-direction: column;
}
#connectDiv #divCenter {
width: 45%;
height: 50%;
margin-left: 27.5%;
}
#connectDiv form {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
#connectDiv form p{
color: white;
}
#connectDiv #button {
width: 20%;
height: 20px;
margin: 10px;
cursor: pointer;
background-color: white;
text-align: center;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 MiB

View File

@ -0,0 +1,104 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* notification.css :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/04 23:44:17 by edbernar #+# #+# */
/* Updated: 2024/08/07 18:04:17 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
@keyframes slideIn {
0% {
transform: translateX(100%);
opacity: 0;
}
100% {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slideOut {
0% {
transform: translateX(0);
opacity: 1;
}
100% {
transform: translateX(100%);
opacity: 0;
}
}
#divNotification {
position: fixed;
overflow: hidden;
font-family: 'Poppins';
top: 0px;
right: 10px;
display: flex;
flex-direction: column;
z-index: 1000;
}
#divNotification .notification {
background-color: #222222;
display: flex;
flex-direction: column;
color: white;
margin-top: 10px;
min-height: 100px;
min-width: 350px;
max-width: 350px;
animation: slideIn 0.1s;
}
#divNotification .header {
display: flex;
flex-direction: row;
}
#divNotification .header h1 {
font-size: 1.2em;
margin: 0;
}
#divNotification .header img {
color: white;
border: none;
margin-left: 9px;
margin-top: 9px;
object-fit: cover;
object-position: 50% 0;
}
#divNotification .content {
margin: 0;
width: 95%;
padding: 2.5%;
padding-bottom: 0;
}
#divNotification .content p {
word-wrap: break-word;
}
#divNotification .footer {
text-align: center;
background-color: #333333;
margin: 10px;
}
#divNotification .loadBar {
margin-top: auto;
margin-bottom: 0;
padding: 0;
/* position: fixed; */
}
.progress {
transition: width 0.1s;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 MiB

View File

@ -0,0 +1,20 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* typeErrorInvalidPassword.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/07 21:16:09 by edbernar #+# #+# */
/* Updated: 2024/08/07 21:18:22 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import { createNotification as NC } from "../notification/main.js";
function typeErrorInvalidPassword()
{
NC.new("Connection error", "Invalid mail or password", NC.defaultIcon.error);
}
export { typeErrorInvalidPassword };

View File

@ -0,0 +1,23 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* typeErrorInvalidToken42.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/10 14:29:34 by edbernar #+# #+# */
/* Updated: 2024/08/10 14:40:10 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import { createNotification as NC } from "../notification/main.js";
function typeErrorInvalidToken42()
{
// |Eddy| Changer le path pour mettre le bon path quand il y aura un vrai serveur
window.history.replaceState({}, document.title, "/site/");
NC.new("Error 42", "Invalid token", NC.defaultIcon.error);
}
export { typeErrorInvalidToken42 };

View File

@ -0,0 +1,23 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* typeErrorUnknown42Account.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/10 16:01:51 by edbernar #+# #+# */
/* Updated: 2024/08/10 18:01:08 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import { createNotification as CN } from "../notification/main.js";
import { typeLogin } from "../typeResponse/typeLogin.js";
function typeErrorUnknown42Account()
{
window.history.replaceState({}, document.title, "/site/");
CN.new("Unknown 42 account", "Your 42 account is not linked to any account.");
typeLogin(null);
}
export { typeErrorUnknown42Account };

View File

@ -0,0 +1,51 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* typeLogin.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/02 00:39:53 by edbernar #+# #+# */
/* Updated: 2024/08/07 22:14:49 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
let userMeInfo = {
username: "",
id: -1
};
let loginAvailable = false;
let loginResolve = null;
function waitForLogin() {
return new Promise((resolve) => {
if (loginAvailable)
resolve();
else
loginResolve = resolve;
});
}
function typeLogin(content)
{
if (content != null)
{
console.log("Welcome " + content.username + "\nYou're id is " + content.id);
userMeInfo.username = content.username;
userMeInfo.id = content.id;
}
loginAvailable = true;
if (loginResolve)
{
if (content != null)
loginResolve(content.token);
else
loginResolve();
loginResolve = null;
loginAvailable = false;
}
}
export { userMeInfo, typeLogin, waitForLogin };

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,124 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* websocket.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/31 22:17:24 by edbernar #+# #+# */
/* Updated: 2024/08/13 00:12:26 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import { typeErrorUnknown42Account } from "./typeErrorResponse/typeErrorUnknown42Account.js";
import { typeErrorInvalidPassword } from "./typeErrorResponse/typeErrorInvalidPassword.js";
import { typeErrorInvalidToken42 } from "./typeErrorResponse/typeErrorInvalidToken42.js";
import { typePrivateListMessage } from "./typeResponse/typePrivateListMessage.js";
import { typeNewPrivateMessage } from "./typeResponse/typeNewPrivateMessage.js";
import { typePrivateListUser } from "./typeResponse/typePrivateListUser.js";
import { connectedWith42Func } from "./login/connectedWith42.js";
import { typeLogin } from "./typeResponse/typeLogin.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 typeResponse = ["login", "private_list_user", "private_list_message", "new_private_message"];
const functionResponse = [typeLogin, typePrivateListUser, typePrivateListMessage, typeNewPrivateMessage];
const errorCode = [9007, 9010, 9011];
const errorFunction = [typeErrorInvalidPassword, typeErrorInvalidToken42, typeErrorUnknown42Account];
let status = 0;
function getCookie(name)
{
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
let token = null;
if (parts.length === 2)
{
token = parts.pop().split(';').shift();
token = token.substring(1, token.length - 1);
}
return (token);
}
socket.onopen = () => {
let token = getCookie("token");
status = 1;
console.log('Connected');
if (token)
sendRequest("login", {type: "byToken", token: token});
else
connectedWith42Func();
};
socket.onmessage = (event) => {
let response;
try {
response = JSON.parse(event.data);
} catch {
return ;
}
if (response.code >= 9000 && response.code <= 9999)
{
try {
errorFunction[errorCode.indexOf(response.code)]();
} catch {
console.warn(response);
}
}
else
{
try {
functionResponse[typeResponse.indexOf(response.type)](response.content);
} catch {
console.warn(response);
}
}
};
socket.onclose = () => {
status = 0;
console.log('Disconnected');
};
function sendRequest(type, content) {
let coc = null;
if (status === 0)
{
console.warn('Not connected');
return ;
}
if (content instanceof Object)
coc = JSON.stringify(content);
else
coc = content;
if (getCookie("token"))
{
socket.send(JSON.stringify({
type: type,
token: getCookie("token"),
content: content
}));
}
else
{
socket.send(JSON.stringify({
type: type,
content: content
}));
}
}
export { socket, sendRequest };