- change proba for easter egg
    - add invit on profil page
    - add pie stat on profil page
    - settings are ready, just wait for popup to confirm delete account
    - add spotlight on home apge
    - fix bug camera mouvement when it move into screen
    - add settings button on all top bar
Django
    - update function changePrivateInfo
This commit is contained in:
Kum1ta
2024-09-27 01:22:26 +02:00
parent 7d6eec100b
commit 3f68bad744
14 changed files with 248 additions and 39 deletions

View File

@ -18,6 +18,7 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>

View File

@ -13,6 +13,7 @@
<img id="github" src="/static/img/profilPage/github.png">
<img id="discord" src="/static/img/profilPage/discord.webp">
<img id="newConv" src="/static/img/profilPage/addConv.png">
<img id="invite" src="/static/img/profilPage/invite.png">
</div>
</div>
@ -20,6 +21,11 @@
<div class="content">
<div class="dashboard">
<h3>Dashboard</h3>
<div class="contentStats">
<canvas id="stats">
</canvas>
</div>
</div>
<div class="history">
<h3>History</h3>

View File

@ -1,3 +1,14 @@
<div id="topBar">
<h1 id="homeButton">METH</h1>
<div id="loginButton">
<p>LOGIN</p>
</div>
<div id="popMenuLoginButton">
<p>Profil</p>
<p>Settings</p>
<p>Logout</p>
</div>
</div>
<div id="settingsBody">
<div class="container-settings">
<div class="left-section">
@ -45,11 +56,13 @@
<input type="password" id="confirm-password" placeholder="Confirm password">
<div class="form-footer">
<small>We advise you to change your password regularly to reduce the risk of unauthorized access.</small>
<button class="save-btn-settings">SAVE</button>
<button class="save-btn-settings" id="passwordButtonSave">SAVE</button>
</div>
</div>
<button class="delete-btn">Delete the account</button>
<button class="delete-btn" id="deleteButton">Delete the account</button>
</div>
</div>
</div>
<div id="divNotification">
</div>

View File

@ -6,7 +6,7 @@
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/09/25 23:28:49 by edbernar #+# #+# #
# Updated: 2024/09/26 00:41:16 by edbernar ### ########.fr #
# Updated: 2024/09/26 14:56:22 by edbernar ### ########.fr #
# #
# **************************************************************************** #
@ -26,13 +26,22 @@ def changePrivateInfo(socket, content):
data = []
if (content.get("username")):
data.append("username")
if (content.get("password")):
data.append("password")
if (content.get("new_password")):
data.append("new_password")
if (content.get("discord")):
data.append("discord")
if (content.get("delete")):
data.append("delete")
if (len(data) != 1):
socket.sendError("You must provide exactly one field to update", 9028)
return
if (content.get("delete")):
user = User.objects.get(id=socket.id)
user.delete()
socket.scope["session"].delete()
socket.sync_send(json.dumps({"type": "change_private_info", "content": "Successfully deleted."}))
socket.close()
return
if (content.get("username")):
if (content["username"].find(' ') != -1):
socket.sendError("Username must not contain spaces", 9015)
@ -49,15 +58,18 @@ def changePrivateInfo(socket, content):
if (User.objects.filter(username=content["username"]).exists()):
socket.sendError("Username already used", 9023)
return
if (content.get("password")):
if (len(content["password"]) < 8):
if (content.get("new_password")):
if (not content.get("old_password")):
raise Exception("Old password is required")
if (len(content["new_password"]) < 8):
socket.sendError("Password must be at least 8 characters long", 9019)
return
if (content["password"].find(content["username"]) != -1):
if (content["new_password"].find(str(content.get("username"))) != -1):
socket.sendError("Password must not contain the username", 9021)
return
if (not bool(re.match(password_pattern, content["password"]))):
socket.sendError("Password must contain at least one lowercase letter, one uppercase letter and one special character", 9020)
if (not bool(re.match(password_pattern, content["new_password"]))):
return
if (content.get("discord")):
if (len(content["discord"]) > 32):
@ -72,8 +84,11 @@ def changePrivateInfo(socket, content):
user.username = content["username"]
socket.username = content["username"]
socket.scope["session"]['username'] = content["username"]
if (content.get("password")):
user.password = hashlib.sha256(user['mail' + content["password"]].encode()).hexdigest()
if (content.get("new_password")):
if (hashlib.md5((user.mail + content["old_password"]).encode()).hexdigest() != user.password):
socket.sendError("Invalid password", 9029)
return
user.password = hashlib.md5((user.mail + content["new_password"]).encode()).hexdigest()
if (content.get("discord")):
if (content["discord"] != ""):
user.discord_username = content["discord"]

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@ -6,7 +6,7 @@
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/25 00:00:21 by edbernar #+# #+# */
/* Updated: 2024/09/25 17:01:12 by edbernar ### ########.fr */
/* Updated: 2024/09/26 16:37:29 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
@ -96,12 +96,10 @@ class Page
this.actualPage.create(arg);
else
this.actualPage.create();
console.log("Page created.");
})
})
.catch(error => {
window.location.href = '/';
// throw Error(error);
});
return ;

View File

@ -6,7 +6,7 @@
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/22 17:19:17 by edbernar #+# #+# */
/* Updated: 2024/09/23 13:39:20 by edbernar ### ########.fr */
/* Updated: 2024/09/27 01:16:28 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
@ -34,6 +34,7 @@ let mouse = null;
let renderPass = null;
let dofPass = null;
let playButtonMouseOver = false;
let spotLight = null;
class Home3D
{
@ -89,6 +90,7 @@ class Home3D
scene = null;
camera = null;
mouse = null;
spotLight = null;
}
}
}
@ -112,8 +114,14 @@ function home3D()
interval = null;
mouse = new THREE.Vector2();
isInFade = false;
spotLight = new THREE.SpotLight(0xffffff, 500);
if (Math.random() % 100 > 0.97)
spotLight.position.set(0, 10, 0);
spotLight.castShadow = true;
spotLight.rotateX(Math.PI / 2);
scene.add(spotLight);
if (Math.random() % 100 > 0.99)
video.pong = '/static/video/homePage/easteregg.webm'
newBgWall();
putObject('/static/models3D/homePage/lamp.glb', -2.5, 0, 2.5, 3, 0, Math.PI + Math.PI / 8, 0);
@ -405,11 +413,6 @@ function redirection()
interval = null;
}
moveCamera();
setTimeout(() => {
setTimeout(() => {
pageRenderer.changePage('lobbyPage');
}, 700);
}, 1000);
}
function moveCamera()
@ -425,6 +428,11 @@ function moveCamera()
const position = initialPosition.clone().lerp(targetPosition, t * t);
camera.position.copy(position);
if (position.equals(targetPosition))
{
pageRenderer.changePage('lobbyPage');
return ;
}
if (t < 1)
requestAnimationFrame(updateCameraPosition);
}

View File

@ -6,7 +6,7 @@
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/22 17:08:46 by madegryc #+# #+# */
/* Updated: 2024/09/25 15:37:29 by edbernar ### ########.fr */
/* Updated: 2024/09/26 16:41:52 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
@ -287,6 +287,9 @@ function initButtonPopMenuLogin()
buttons[0].addEventListener('click', () => {
pageRenderer.changePage('profilPage', false, userMeInfo.id);
});
buttons[1].addEventListener('click', () => {
pageRenderer.changePage('settingsPage', false);
});
buttons[2].addEventListener('click', () => {
window.location.replace('/logout');
});

View File

@ -6,7 +6,7 @@
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/07 17:40:15 by edbernar #+# #+# */
/* Updated: 2024/09/22 23:44:49 by edbernar ### ########.fr */
/* Updated: 2024/09/26 16:41:32 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
@ -125,6 +125,9 @@ function initButtonPopMenuLogin()
buttons[0].addEventListener('click', () => {
pageRenderer.changePage('profilPage', false, userMeInfo.id);
});
buttons[1].addEventListener('click', () => {
pageRenderer.changePage('settingsPage', false);
});
buttons[2].addEventListener('click', () => {
window.location.replace('/logout');
})

View File

@ -6,7 +6,7 @@
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/19 23:08:31 by edbernar #+# #+# */
/* Updated: 2024/09/24 17:32:22 by edbernar ### ########.fr */
/* Updated: 2024/09/27 00:54:02 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
@ -27,7 +27,9 @@ class ProfilPage
const pfp = document.getElementsByClassName('profile-image')[0];
const banner = document.getElementsByClassName('background-card')[0];
const convButton = document.getElementById('newConv');
const inviteButton = document.getElementById('invite');
const crossProfil = document.getElementById('cross-profil');
let ctx = document.getElementById('stats').getContext('2d');
let editPenPfpBg = null;
let inputPfp = null;
let editPenBanner = null;
@ -55,7 +57,6 @@ class ProfilPage
pageRenderer.changePage('lobbyPage');
});
waitForUserInfo().then((userInfo) => {
console.log(userInfo);
if (userInfo == null)
{
pageRenderer.changePage('homePage');
@ -72,9 +73,12 @@ class ProfilPage
banner.style.backgroundImage = `url("${userInfo.banner}")`
banner.style.backgroundSize = "cover";
banner.style.backgroundRepeat = "no-repeat";
externButtons(userInfo)
externButtons(userInfo);
createGraph(ctx, {win: 10, lose: 1});
console.warn("Graph values are settled in code, please change it with data request")
if (userInfo.id == userMeInfo.id)
{
inviteButton.remove();
pfp.innerHTML = `<div id='editPenPfpBg'><input style='display: none' id='inputPfp' type="file"><img class='editPenPfp' src='/static/img/profilPage/editPen.png'/></div>`
banner.innerHTML = `<img class='editPen' src='/static/img/profilPage/editPen.png'/><input style='display: none' id='inputBanner' type="file">`
editPenPfpBg = document.getElementById('editPenPfpBg');
@ -101,6 +105,14 @@ class ProfilPage
showChatMenu();
showPrivateChat({id: userInfo.id, name: userInfo.username});
});
inviteButton.addEventListener('click', () => {
if (!userInfo.online)
CN.new("Invitation", `Can't invite ${userInfo.username} (offline)`)
else
{
pageRenderer.changePage("waitingGamePage", false, {username: userInfo.username, id: userInfo.id});
}
});
}
else
convButton.remove();
@ -164,5 +176,32 @@ function inputChange(isPfp)
}
}
function createGraph(ctx, data)
{
new Chart(ctx, {
type: 'pie',
data: {
labels: ['Win', 'Lose'],
datasets: [{
label: 'Couleurs',
data: [data.win, data.lose],
backgroundColor: ['#11ad11', '#E74040'],
hoverOffset: 4
}]
},
options: {
responsive: true,
plugins: {
legend: {
position: 'bottom',
},
tooltip: {
enabled: true
}
}
}
});
}
export { ProfilPage };

View File

@ -6,12 +6,15 @@
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/25 17:00:35 by edbernar #+# #+# */
/* Updated: 2024/09/26 01:02:31 by edbernar ### ########.fr */
/* Updated: 2024/09/26 22:48:29 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import { waitForPrivateInfo } from "/static/javascript/typeResponse/typePrivateInfo.js"
import { createNotification as CN } from "/static/javascript/notification/main.js";
import { userMeInfo } from "/static/javascript/typeResponse/typeLogin.js";
import { sendRequest, status } from "/static/javascript/websocket.js";
import { pageRenderer } from '/static/javascript/main.js'
class settingsPage
{
@ -22,10 +25,15 @@ class settingsPage
const usernameInput = document.getElementById('username');
const passwordInput = document.getElementById('password');
const newPasswordInput = document.getElementById('new-password');
const confirmOasswordInput = document.getElementById('confirm-password');
const confirmPasswordInput = document.getElementById('confirm-password');
const usernameSaveButton = document.getElementById('usernameButtonSave');
const discordSaveButton = document.getElementById('discordButtonSave');
const passwordSaveButton = document.getElementById('passwordButtonSave');
const deleteButton = document.getElementById('deleteButton');
const loginButton = document.getElementById('loginButton').getElementsByTagName('p')[0];
const methButton = document.getElementById("homeButton");
let interval = null;
@ -36,16 +44,23 @@ class settingsPage
{
sendRequest("get_private_info", {});
clearInterval(interval);
interval = setInterval(() => {
if (userMeInfo.username != "")
{
loginButton.innerText = userMeInfo.username;
clearInterval(interval);
}
}, 200);
}
}, 200);
waitForPrivateInfo().then(data => {
console.log(data);
emailInput.value = data.mail ? data.mail : "Disabled because you have a 42 account."
passwordInput.value = newPasswordInput.value = confirmOasswordInput.value = data.is42Account ? "Disabled because you have a 42 account." : null;
passwordInput.value = newPasswordInput.value = confirmPasswordInput.value = data.is42Account ? "Disabled because you have a 42 account." : null;
if (data.is42Account)
{
passwordInput.style.backgroundColor = newPasswordInput.style.backgroundColor = confirmOasswordInput.style.backgroundColor = "#bbbbbb";
passwordInput.type = newPasswordInput.type = confirmOasswordInput.type = 'text';
passwordInput.style.backgroundColor = newPasswordInput.style.backgroundColor = confirmPasswordInput.style.backgroundColor = passwordSaveButton.style.backgroundColor = "#bbbbbb";
passwordInput.type = newPasswordInput.type = confirmPasswordInput.type = 'text';
passwordSaveButton.disabled = true;
}
discordInput.value = data.discord_username;
usernameInput.value = data.username;
@ -56,14 +71,99 @@ class settingsPage
discordSaveButton.addEventListener('click', () => {
sendRequest("change_private_info", {discord: discordInput.value});
});
deleteButton.addEventListener('click', () => {
sendRequest("change_private_info", {delete: true});
userMeInfo.id = -1;
setTimeout(() => {
CN.new("Information", "Your account is delete.")
}, 1000);
pageRenderer.changePage('homePage', false);
});
if (!data.is42Account)
{
passwordSaveButton.addEventListener('click', () => {
if (newPasswordInput.value != confirmPasswordInput.value)
{
CN.new("Error", "Passwords do not match", CN.defaultIcon.error);
return ;
}
sendRequest("change_private_info", {old_password: passwordInput.value, new_password: newPasswordInput.value});
});
}
});
loginButton.addEventListener('click', showMenu);
window.addEventListener('resize', movePopMenuLoginButton);
movePopMenuLoginButton();
initButtonPopMenuLogin();
methButton.addEventListener('click', goBackHome);
}
static dispose()
{
const loginButton = document.getElementById('loginButton').getElementsByTagName('p')[0];
const methButton = document.getElementById("homeButton");
window.removeEventListener('resize', movePopMenuLoginButton);
document.removeEventListener('click', hideMenu);
loginButton.addEventListener('click', showMenu);
methButton.addEventListener('click', goBackHome);
}
}
function initButtonPopMenuLogin()
{
const buttons = document.getElementById('popMenuLoginButton').getElementsByTagName('p');
buttons[0].addEventListener('click', () => {
pageRenderer.changePage('profilPage', false, userMeInfo.id);
});
buttons[1].addEventListener('click', () => {
pageRenderer.changePage('settingsPage', false);
});
buttons[2].addEventListener('click', () => {
window.location.replace('/logout');
});
}
function movePopMenuLoginButton()
{
const loginButton = document.getElementById('loginButton');
const pos = loginButton.getBoundingClientRect();
const popMenuLoginButton = document.getElementById('popMenuLoginButton');
popMenuLoginButton.style.left = pos.left + "px";
popMenuLoginButton.style.top = pos.top + pos.height + "px";
}
function showMenu()
{
const popMenuLoginButton = document.getElementById('popMenuLoginButton');
const loginButton = document.getElementById('loginButton');
popMenuLoginButton.style.display = 'flex';
setTimeout(() => {
document.addEventListener('click', hideMenu);
loginButton.removeEventListener('click', showMenu);
loginButton.addEventListener('click', hideMenu);
}, 50);
}
function hideMenu()
{
const loginButton = document.getElementById('loginButton');
const popMenuLoginButton = document.getElementById('popMenuLoginButton');
popMenuLoginButton.style.display = 'none';
setTimeout(() => {
document.removeEventListener('click', hideMenu);
loginButton.removeEventListener('click', hideMenu);
loginButton.addEventListener('click', showMenu);
}, 50);
}
function goBackHome()
{
pageRenderer.changePage('homePage', false);
}
export { settingsPage };

View File

@ -6,7 +6,7 @@
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/14 21:20:45 by edbernar #+# #+# */
/* Updated: 2024/09/25 09:06:34 by edbernar ### ########.fr */
/* Updated: 2024/09/27 00:26:12 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
@ -19,11 +19,11 @@ let timeout = null;
class WaitingGamePage
{
static create()
static create(opponentInfo)
{
const returnButton = document.getElementById('returnToLobbyButton');
const sentence = document.getElementById('sentence');
const text = sentence.innerText;
let text = sentence.innerText;
let points = "";
document.body.style.opacity = 1;
@ -31,6 +31,10 @@ class WaitingGamePage
{
document.body.children[i].style.animation = 'animShowMenuDiv 0.5s';
}
if (!opponentInfo)
opponentInfo = {id: -1}
else
text = text.replace("other players", opponentInfo.username);
intervalPoints = setInterval(() => {
if (points.length < 3)
points += '.';
@ -38,9 +42,11 @@ class WaitingGamePage
points = '';
sentence.innerText = text + points;
}, 500);
console.log(lastSelected)
timeout = setTimeout(() => {
sendRequest("game", {action: 0, skinId: lastSelected.id});
if (!lastSelected)
sendRequest("game", {action: 0, skinId: 0, opponent: opponentInfo.id});
else
sendRequest("game", {action: 0, skinId: lastSelected.id, opponent: opponentInfo.id});
timeout = null;
}, 1500);
returnButton.addEventListener('click', returnToLobby);

View File

@ -433,3 +433,19 @@ body {
.menuSelected {
display: none;
}
#stats {
display: flex;
justify-content: center;
max-width: 80%;
max-height: 80%;
}
.dashboard .contentStats {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}

View File

@ -29,7 +29,8 @@
- 9025 : Account not verified, please verify your account before logging in
- 9026 : An error occured while sending the email, glhf
- 9027 : An unknown error occured
- 9028 : You must provide exactly one field to update"
- 9028 : You must provide exactly one field to update
- 9029 : Invalid password
- 9100 : Action out of range
- 9101 : No game started