diff --git a/docker-compose/requirements/djangoserver/Dockerfile b/docker-compose/requirements/djangoserver/Dockerfile index 3e2c7d7..794eead 100644 --- a/docker-compose/requirements/djangoserver/Dockerfile +++ b/docker-compose/requirements/djangoserver/Dockerfile @@ -2,8 +2,16 @@ FROM debian:bullseye RUN apt update RUN apt upgrade -y +RUN apt install gnupg curl -y + +RUN echo "deb http://ppa.launchpad.net/deadsnakes/ppa/ubuntu focal main" | tee /etc/apt/sources.list.d/deadsnakes-ppa.list +RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 6A755776 +RUN apt update +RUN apt upgrade -y +RUN apt install -y python3.12 postgresql-client +RUN curl https://bootstrap.pypa.io/get-pip.py -o /root/get-pip.py +RUN python3.12 /root/get-pip.py -RUN apt install -y python3 python3-pip postgresql-client RUN pip3 install requests django psycopg "channels[daphne]" ARG DB_HOST=; @@ -18,19 +26,19 @@ ENV PYTHONUNBUFFERED=1 ENV UID_42=${UID_42} ENV SECRET_42=${SECRET_42} +COPY start.sh /root/start.sh + RUN mkdir -p /var/www/djangoserver/ -RUN mkdir -p /var/www/djangoserver/static/ -COPY file/server /var/www/djangoserver/server -RUN chmod 755 /var/www/djangoserver/ -RUN chown -R www-data:www-data /var/www/djangoserver/ - -RUN sed -i "s/VAR_DB_HOST/$DB_HOST/" /var/www/djangoserver/server/server/settings.py -RUN sed -i "s/VAR_DB_NAME/$DB_NAME/" /var/www/djangoserver/server/server/settings.py -RUN sed -i "s/VAR_DB_USERNAME/$DB_USERNAME/" /var/www/djangoserver/server/server/settings.py -RUN sed -i "s/VAR_DB_PASSWORD/$DB_PASSWORD/" /var/www/djangoserver/server/server/settings.py - WORKDIR /var/www/djangoserver STOPSIGNAL SIGKILL +RUN mkdir -p /var/www/djangoserver/static/ + +COPY file/server /var/www/djangoserver/server +RUN chmod 755 /var/www/djangoserver/ && chown -R www-data:www-data /var/www/djangoserver/ + +RUN sed -i "s/VAR_DB_HOST/$DB_HOST/" /var/www/djangoserver/server/server/settings.py && \ +sed -i "s/VAR_DB_NAME/$DB_NAME/" /var/www/djangoserver/server/server/settings.py && \ +sed -i "s/VAR_DB_USERNAME/$DB_USERNAME/" /var/www/djangoserver/server/server/settings.py && \ +sed -i "s/VAR_DB_PASSWORD/$DB_PASSWORD/" /var/www/djangoserver/server/server/settings.py -COPY start.sh /root/start.sh ENTRYPOINT ["sh", "/root/start.sh"] diff --git a/docker-compose/requirements/djangoserver/file/server/server/settings.py b/docker-compose/requirements/djangoserver/file/server/server/settings.py index 413abc0..8daaef5 100644 --- a/docker-compose/requirements/djangoserver/file/server/server/settings.py +++ b/docker-compose/requirements/djangoserver/file/server/server/settings.py @@ -123,6 +123,12 @@ USE_TZ = True STATIC_URL = 'static/' +STATIC_DIRS = [ + BASE_DIR/ "static" +] + +STATIC_ROOT = BASE_DIR / 'staticfiles' + # Default primary key field type # https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field diff --git a/docker-compose/requirements/djangoserver/file/server/server/templates/index.html b/docker-compose/requirements/djangoserver/file/server/server/templates/index.html new file mode 100644 index 0000000..a14605d --- /dev/null +++ b/docker-compose/requirements/djangoserver/file/server/server/templates/index.html @@ -0,0 +1,127 @@ + + + + + + Chat + + + + + + + + + + + +
+
+
+

PTME

+
+

HOME

+

PROJECT

+

NEWS

+
+
+

LOGIN

+
+
+ +
+

CHAT

+
+
+
+

Chat

+
+

X

+
+
+
+
+
+
+ + +
+

Lorem ipsum dolor sit amet consectetur adipisicing elit. Officia totam cupiditate magni unde expedita molestiae eum aliquam fugit voluptatibus omnis! Dolores, ipsa inventore necessitatibus numquam aspernatur in perferendis id voluptas?

+

Lorem ipsum dolor sit amet consectetur adipisicing elit. Officia totam cupiditate magni unde expedita molestiae eum aliquam fugit voluptatibus omnis! Dolores, ipsa inventore necessitatibus numquam aspernatur in perferendis id voluptas?

+
+
+
+
+
+ Tom +

Tom, tomoron

+

Partie Backend

+
+

Tom est spécialisé en développement backend et travaille principalement avec Node.js et MongoDB.

+
+
+
+ Mathis +

Mathis, madegryc

+

Partie Frontend / Design

+
+

Tom est spécialisé en développement backend et travaille principalement avec Node.js et MongoDB.

+
+
+
+ Eddy +

Eddy, edbernar

+

Partie Midend

+
+

Tom est spécialisé en développement backend et travaille principalement avec Node.js et MongoDB.

+
+
+
+ Hugo +

Hugo, hubourge

+

Partie jeu

+
+

Tom est spécialisé en développement backend et travaille principalement avec Node.js et MongoDB.

+
+
+
+
+ + + diff --git a/docker-compose/requirements/djangoserver/file/server/server/typeRequets/createAccount.py b/docker-compose/requirements/djangoserver/file/server/server/typeRequets/createAccount.py index 741b34a..d12bf8f 100644 --- a/docker-compose/requirements/djangoserver/file/server/server/typeRequets/createAccount.py +++ b/docker-compose/requirements/djangoserver/file/server/server/typeRequets/createAccount.py @@ -6,7 +6,7 @@ # By: edbernar 20): - await socket.sendError("Username must be at most 20 characters long", 9009) + socket.sendError("Username must be at most 20 characters long", 9009) return if (content["username"].find(' ') != -1): - await socket.sendError("Username must not contain spaces", 9011) + socket.sendError("Username must not contain spaces", 9011) return if (content["username"].isalnum() == False): - await socket.sendError("Username must contain only letters and numbers", 9012) + socket.sendError("Username must contain only letters and numbers", 9012) return if (len(content["password"]) < 8): - await socket.sendError("Password must be at least 8 characters long", 9013) + socket.sendError("Password must be at least 8 characters long", 9013) return if (bool(re.match(pattern, content["password"]))): - await socket.sendError("Password must contain at least one lowercase letter, one uppercase letter and one special character", 9014) + socket.sendError("Password must contain at least one lowercase letter, one uppercase letter and one special character", 9014) return if (content["password"].find(content["username"]) != -1): - await socket.sendError("Password must not contain the username", 9015) + socket.sendError("Password must not contain the username", 9015) return # |Tom| Au lieu d'utiliser userList, faire une requête à la base de donnée pour savoir si on a un utilisateur avec cet email ou cet username if (content["mail"] in userList): - await socket.sendError("Mail already used", 9016) + socket.sendError("Mail already used", 9016) return if (content["username"] in userList): - await socket.sendError("Username already used", 9017) + socket.sendError("Username already used", 9017) return content["token"] = generateToken() while (True): @@ -62,9 +62,12 @@ async def createAccount(socket, content): if (content["id"] not in userList): break userList.append(content) - await socket.send({"type": "create_account", "content": "Account created"}) + socket.send(text_data=json.dumps({"type": "create_account", "content": "Account created"})) + socket.scope["session"]["logged_in"] = True + socket.scope["session"]["username"] = content["username"] + socket.scope["session"].save() except Exception as e: - await socket.sendError("Error create account", 9005, e) + socket.sendError("Error create account", 9005, e) def generateToken(): list = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" diff --git a/docker-compose/requirements/djangoserver/file/server/server/typeRequets/getPrivateListMessage.py b/docker-compose/requirements/djangoserver/file/server/server/typeRequets/getPrivateListMessage.py index b0adbdf..6f0901c 100644 --- a/docker-compose/requirements/djangoserver/file/server/server/typeRequets/getPrivateListMessage.py +++ b/docker-compose/requirements/djangoserver/file/server/server/typeRequets/getPrivateListMessage.py @@ -6,7 +6,7 @@ # By: edbernar +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2024/08/03 15:10:23 by edbernar #+# #+# # -# Updated: 2024/08/22 19:13:09 by tomoron ### ########.fr # +# Updated: 2024/08/23 23:55:50 by tomoron ### ########.fr # # # # **************************************************************************** # @@ -52,9 +52,9 @@ data = [ } ] -async def getPrivateListUser(socket, content=None): +def getPrivateListUser(socket, content=None): # |TOM| Faire une requête à la base de données pour récupérer la liste des # utilisateurs qui doivent apparaitre dans la liste du chat privé # (ceux qui ont eu conversation avec l'utilisateur) - # Si user existe pas, faire ça : await socket.sendError("User not found", 9008) - await socket.send({"type": "private_list_user", "content": data}) + # Si user existe pas, faire ça : socket.sendError("User not found", 9008) + socket.send(text_data=json.dumps({"type": "private_list_user", "content": data})) diff --git a/docker-compose/requirements/djangoserver/file/server/server/typeRequets/login.py b/docker-compose/requirements/djangoserver/file/server/server/typeRequets/login.py index 54af3d8..5668caf 100644 --- a/docker-compose/requirements/djangoserver/file/server/server/typeRequets/login.py +++ b/docker-compose/requirements/djangoserver/file/server/server/typeRequets/login.py @@ -6,7 +6,7 @@ # By: edbernar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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 }; \ No newline at end of file diff --git a/docker-compose/requirements/nginx/static/home3D/home3D.js b/docker-compose/requirements/nginx/static/home3D/home3D.js new file mode 100644 index 0000000..d482ec4 --- /dev/null +++ b/docker-compose/requirements/nginx/static/home3D/home3D.js @@ -0,0 +1,162 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* home3D.js :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: marvin +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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 }; \ No newline at end of file diff --git a/docker-compose/requirements/nginx/static/liveChat/main.js b/docker-compose/requirements/nginx/static/liveChat/main.js new file mode 100644 index 0000000..cfb352f --- /dev/null +++ b/docker-compose/requirements/nginx/static/liveChat/main.js @@ -0,0 +1,81 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main.js :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: edbernar { + 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 }; \ No newline at end of file diff --git a/docker-compose/requirements/nginx/static/liveChat/showActualGameMessage.js b/docker-compose/requirements/nginx/static/liveChat/showActualGameMessage.js new file mode 100644 index 0000000..be4c6d3 --- /dev/null +++ b/docker-compose/requirements/nginx/static/liveChat/showActualGameMessage.js @@ -0,0 +1,96 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* showActualGameMessage.js :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: edbernar { + 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 += ` +
+ +

\>

+
+ `; +} + +export { showActualGameMessage }; \ No newline at end of file diff --git a/docker-compose/requirements/nginx/static/liveChat/showPrivateChat.js b/docker-compose/requirements/nginx/static/liveChat/showPrivateChat.js new file mode 100644 index 0000000..d174e8f --- /dev/null +++ b/docker-compose/requirements/nginx/static/liveChat/showPrivateChat.js @@ -0,0 +1,153 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* showPrivateChat.js :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: edbernar { + 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 += ` +

Return

+ `; + 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 += ` +
+ +

\>

+
+ `; + 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 }; \ No newline at end of file diff --git a/docker-compose/requirements/nginx/static/liveChat/showUserList.js b/docker-compose/requirements/nginx/static/liveChat/showUserList.js new file mode 100644 index 0000000..6fbc44a --- /dev/null +++ b/docker-compose/requirements/nginx/static/liveChat/showUserList.js @@ -0,0 +1,53 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* showUserList.js :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: edbernar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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 = ` +
+ +
+

+ ` + user.querySelector("img").src = element.pfp; + user.querySelector("h3").innerText = element.name; + divMessageListChatHome.appendChild(user); + }); + } + divMessageListChatHome.innerHTML += "

New conversation +

"; + divUser = document.getElementsByClassName("user"); + for (let i = 0; i < divUser.length; i++) { + divUser[i].addEventListener("click", async () => { + await showPrivateChat(userList[i]); + }); + } +} + +export { showListUser }; \ No newline at end of file diff --git a/docker-compose/requirements/nginx/static/login/connectedWith42.js b/docker-compose/requirements/nginx/static/login/connectedWith42.js new file mode 100644 index 0000000..b573991 --- /dev/null +++ b/docker-compose/requirements/nginx/static/login/connectedWith42.js @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* connectedWith42.js :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: edbernar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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 }; \ No newline at end of file diff --git a/docker-compose/requirements/nginx/static/main.js b/docker-compose/requirements/nginx/static/main.js new file mode 100644 index 0000000..0538bab --- /dev/null +++ b/docker-compose/requirements/nginx/static/main.js @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main.js :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: marvin +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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(); +}); diff --git a/docker-compose/requirements/nginx/static/modeles/pong.mp4 b/docker-compose/requirements/nginx/static/modeles/pong.mp4 new file mode 100644 index 0000000..ef6dd1a Binary files /dev/null and b/docker-compose/requirements/nginx/static/modeles/pong.mp4 differ diff --git a/docker-compose/requirements/nginx/static/modeles/tv.glb b/docker-compose/requirements/nginx/static/modeles/tv.glb new file mode 100644 index 0000000..0bf343a Binary files /dev/null and b/docker-compose/requirements/nginx/static/modeles/tv.glb differ diff --git a/docker-compose/requirements/nginx/static/notification/ico/error.png b/docker-compose/requirements/nginx/static/notification/ico/error.png new file mode 100644 index 0000000..b4dc6b8 Binary files /dev/null and b/docker-compose/requirements/nginx/static/notification/ico/error.png differ diff --git a/docker-compose/requirements/nginx/static/notification/ico/info.png b/docker-compose/requirements/nginx/static/notification/ico/info.png new file mode 100644 index 0000000..5b9754d Binary files /dev/null and b/docker-compose/requirements/nginx/static/notification/ico/info.png differ diff --git a/docker-compose/requirements/nginx/static/notification/ico/success.png b/docker-compose/requirements/nginx/static/notification/ico/success.png new file mode 100644 index 0000000..d31d26b Binary files /dev/null and b/docker-compose/requirements/nginx/static/notification/ico/success.png differ diff --git a/docker-compose/requirements/nginx/static/notification/ico/warning.png b/docker-compose/requirements/nginx/static/notification/ico/warning.png new file mode 100644 index 0000000..e34ef61 Binary files /dev/null and b/docker-compose/requirements/nginx/static/notification/ico/warning.png differ diff --git a/docker-compose/requirements/nginx/static/notification/main.js b/docker-compose/requirements/nginx/static/notification/main.js new file mode 100644 index 0000000..97eef0f --- /dev/null +++ b/docker-compose/requirements/nginx/static/notification/main.js @@ -0,0 +1,170 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main.js :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: edbernar { + 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 }; \ No newline at end of file diff --git a/docker-compose/requirements/nginx/static/style/ball3D.png b/docker-compose/requirements/nginx/static/style/ball3D.png new file mode 100644 index 0000000..7a6f26f Binary files /dev/null and b/docker-compose/requirements/nginx/static/style/ball3D.png differ diff --git a/docker-compose/requirements/nginx/static/style/ball3D2.png b/docker-compose/requirements/nginx/static/style/ball3D2.png new file mode 100644 index 0000000..6ec3445 Binary files /dev/null and b/docker-compose/requirements/nginx/static/style/ball3D2.png differ diff --git a/docker-compose/requirements/nginx/static/style/ball3D3.png b/docker-compose/requirements/nginx/static/style/ball3D3.png new file mode 100644 index 0000000..f36b571 Binary files /dev/null and b/docker-compose/requirements/nginx/static/style/ball3D3.png differ diff --git a/docker-compose/requirements/nginx/static/style/edbernard.png b/docker-compose/requirements/nginx/static/style/edbernard.png new file mode 100644 index 0000000..8fda234 Binary files /dev/null and b/docker-compose/requirements/nginx/static/style/edbernard.png differ diff --git a/docker-compose/requirements/nginx/static/style/home.css b/docker-compose/requirements/nginx/static/style/home.css new file mode 100644 index 0000000..faf27bb --- /dev/null +++ b/docker-compose/requirements/nginx/static/style/home.css @@ -0,0 +1,409 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* home.css :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: marvin +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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; +} diff --git a/docker-compose/requirements/nginx/static/style/hubourge.png b/docker-compose/requirements/nginx/static/style/hubourge.png new file mode 100644 index 0000000..124ce88 Binary files /dev/null and b/docker-compose/requirements/nginx/static/style/hubourge.png differ diff --git a/docker-compose/requirements/nginx/static/style/liveChat.css b/docker-compose/requirements/nginx/static/style/liveChat.css new file mode 100644 index 0000000..71b0fce --- /dev/null +++ b/docker-compose/requirements/nginx/static/style/liveChat.css @@ -0,0 +1,235 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* liveChat.css :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: marvin +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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); + } +} + diff --git a/docker-compose/requirements/nginx/static/style/loginPage.css b/docker-compose/requirements/nginx/static/style/loginPage.css new file mode 100644 index 0000000..7faf6d0 --- /dev/null +++ b/docker-compose/requirements/nginx/static/style/loginPage.css @@ -0,0 +1,199 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* loginPage.css :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: marvin +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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; +} \ No newline at end of file diff --git a/docker-compose/requirements/nginx/static/style/madegryc.png b/docker-compose/requirements/nginx/static/style/madegryc.png new file mode 100644 index 0000000..2bed972 Binary files /dev/null and b/docker-compose/requirements/nginx/static/style/madegryc.png differ diff --git a/docker-compose/requirements/nginx/static/style/notification.css b/docker-compose/requirements/nginx/static/style/notification.css new file mode 100644 index 0000000..3b22955 --- /dev/null +++ b/docker-compose/requirements/nginx/static/style/notification.css @@ -0,0 +1,104 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* notification.css :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: edbernar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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; +} \ No newline at end of file diff --git a/docker-compose/requirements/nginx/static/style/tomoron.png b/docker-compose/requirements/nginx/static/style/tomoron.png new file mode 100644 index 0000000..36eb6f7 Binary files /dev/null and b/docker-compose/requirements/nginx/static/style/tomoron.png differ diff --git a/docker-compose/requirements/nginx/static/typeErrorResponse/typeErrorInvalidPassword.js b/docker-compose/requirements/nginx/static/typeErrorResponse/typeErrorInvalidPassword.js new file mode 100644 index 0000000..22b7e54 --- /dev/null +++ b/docker-compose/requirements/nginx/static/typeErrorResponse/typeErrorInvalidPassword.js @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* typeErrorInvalidPassword.js :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: edbernar { + + 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 }; \ No newline at end of file diff --git a/docker-compose/requirements/nginx/static/typeResponse/typeNewPrivateMessage.js b/docker-compose/requirements/nginx/static/typeResponse/typeNewPrivateMessage.js new file mode 100644 index 0000000..112abf9 --- /dev/null +++ b/docker-compose/requirements/nginx/static/typeResponse/typeNewPrivateMessage.js @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* typeNewPrivateMessage.js :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: edbernar +

${content.content}

+

${content.date}

+ + `); + infoPanel.divMessage.scrollTop = infoPanel.divMessage.scrollHeight; + } +} + +export { typeNewPrivateMessage }; \ No newline at end of file diff --git a/docker-compose/requirements/nginx/static/typeResponse/typePrivateListMessage.js b/docker-compose/requirements/nginx/static/typeResponse/typePrivateListMessage.js new file mode 100644 index 0000000..eb75aa1 --- /dev/null +++ b/docker-compose/requirements/nginx/static/typeResponse/typePrivateListMessage.js @@ -0,0 +1,43 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* typePrivateListMessage.js :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: edbernar { + + 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 }; \ No newline at end of file diff --git a/docker-compose/requirements/nginx/static/typeResponse/typePrivateListUser.js b/docker-compose/requirements/nginx/static/typeResponse/typePrivateListUser.js new file mode 100644 index 0000000..e8e4df1 --- /dev/null +++ b/docker-compose/requirements/nginx/static/typeResponse/typePrivateListUser.js @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* typePrivateListUser.js :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: edbernar { + if (userListAvailable) + resolve(); + else + userListResolve = resolve; + }); +} + +function typePrivateListUser(list) { + userList = list; + userListAvailable = true; + if (userListResolve) + { + userListResolve(); + userListResolve = null; + } +} + +export { userList, typePrivateListUser, waitForUserList }; \ No newline at end of file diff --git a/docker-compose/requirements/nginx/static/websocket.js b/docker-compose/requirements/nginx/static/websocket.js new file mode 100644 index 0000000..2e6f6fb --- /dev/null +++ b/docker-compose/requirements/nginx/static/websocket.js @@ -0,0 +1,124 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* websocket.js :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: edbernar { + 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 }; \ No newline at end of file