Merge pull request 'update malouze cooking' (#6) from main into malouze-cooking
Reviewed-on: https://codeberg.org/adrien-lsh/ft_transcendence/pulls/6
This commit is contained in:
@ -19,6 +19,10 @@ export default class extends AbstractView {
|
||||
document.getElementById('stopGameButton').onclick = this.stopGame.bind(this);
|
||||
}
|
||||
|
||||
async leavePage() {
|
||||
this.game?.cleanup();
|
||||
}
|
||||
|
||||
startGame() {
|
||||
if (this.game == null) {
|
||||
document.getElementById('startGameButton').innerHTML = 'Reset Game';
|
||||
@ -26,6 +30,7 @@ export default class extends AbstractView {
|
||||
}
|
||||
else {
|
||||
document.getElementById('app').removeChild(this.game.canvas);
|
||||
document.getElementById('app').removeChild(this.game.scoresDisplay);
|
||||
this.game.cleanup();
|
||||
this.game = new Game;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ export default class extends AbstractView
|
||||
this.my_player = undefined;
|
||||
}
|
||||
|
||||
keyStretchHandler(event)
|
||||
keyReleaseHandler(event)
|
||||
{
|
||||
const idx = this.keys_pressed.indexOf(event.key);
|
||||
if (idx != -1)
|
||||
@ -26,7 +26,7 @@ export default class extends AbstractView
|
||||
this.keys_pressed.push(event.key);
|
||||
}
|
||||
|
||||
draw()
|
||||
render_game()
|
||||
{
|
||||
const canva = document.getElementById('canva');
|
||||
|
||||
@ -40,36 +40,39 @@ export default class extends AbstractView
|
||||
|
||||
ctx.beginPath();
|
||||
|
||||
this.game.draw(ctx);
|
||||
this.game.render(ctx);
|
||||
|
||||
ctx.strokeStyle = "#000000";
|
||||
ctx.lineWidth = 10;
|
||||
ctx.lineWidth = 1;
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
render_game()
|
||||
render()
|
||||
{
|
||||
let loop_id = setInterval(() => {
|
||||
if (this.game === undefined)
|
||||
clearInterval(loop_id);
|
||||
if (this.my_player)
|
||||
this.my_player.update_paddle(this.keys_pressed);
|
||||
this.draw();
|
||||
this.render_game();
|
||||
this.game?.time.new_frame();
|
||||
//clearInterval(loop_id);
|
||||
// 1 sec fps
|
||||
}, 1000 / 60);
|
||||
}
|
||||
|
||||
register_key()
|
||||
{
|
||||
document.addEventListener('keydown', this.keyPressHandler.bind(this));
|
||||
document.addEventListener('keyup', this.keyStretchHandler.bind(this));
|
||||
this.keyPressHandler = this.keyPressHandler.bind(this);
|
||||
this.keyReleaseHandler = this.keyReleaseHandler.bind(this);
|
||||
document.addEventListener('keydown', this.keyPressHandler);
|
||||
document.addEventListener('keyup', this.keyReleaseHandler);
|
||||
}
|
||||
|
||||
unregister_key()
|
||||
{
|
||||
document.removeEventListener('keydown', this.keyPressHandler);
|
||||
document.removeEventListener('keyup', this.keyStretchHandler);
|
||||
document.removeEventListener('keyup', this.keyReleaseHandler);
|
||||
}
|
||||
|
||||
async join_game()
|
||||
@ -99,7 +102,7 @@ export default class extends AbstractView
|
||||
|
||||
this.register_key()
|
||||
|
||||
this.render_game();
|
||||
this.render();
|
||||
}
|
||||
|
||||
async update_game_state()
|
||||
|
@ -1,18 +1,19 @@
|
||||
import AbstractAuthentificateView from "./abstracts/AbstractAuthentifiedView.js";
|
||||
import { lang } from "../index.js";
|
||||
import AbstractAuthenticatedView from "./abstracts/AbstractAuthenticatedView.js";
|
||||
|
||||
export default class extends AbstractAuthentificateView {
|
||||
export default class extends AbstractAuthenticatedView {
|
||||
constructor(params) {
|
||||
super(params, "Home");
|
||||
super(params, 'homeWindowTitle');
|
||||
this.redirect_url = "/login"
|
||||
}
|
||||
|
||||
async getHtml() {
|
||||
return /* HTML */ `
|
||||
<h1>HOME</h1>
|
||||
<a href="/matchmaking" class="nav__link" data-link>Play a game</a>
|
||||
<a href="/games/offline" class="nav__link" data-link>Play offline</a>
|
||||
<a href="/me" class="nav__link" data-link>Me</a>
|
||||
<a href="/logout" class="nav__link" data-link>Logout</a>
|
||||
<h1>${lang.get('homeTitle', 'Home')}</h1>
|
||||
<a href="/matchmaking" data-link>${lang.get('homeOnline', 'Play online')}</a>
|
||||
<a href="/games/offline" data-link>${lang.get('homeOffline', 'Play offline')}</a>
|
||||
<a href="/settings" data-link>${lang.get('homeSettings', 'Settings')}</a>
|
||||
<a href="/logout" data-link>${lang.get('homeLogout', 'Logout')}</a>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { client, navigateTo } from "../index.js";
|
||||
import { clear, fill_errors } from "../utils/formUtils.js";
|
||||
import AbstractAuthentifiedView from "./abstracts/AbstractAuthentifiedView.js";
|
||||
import AbstractAuthenticatedView from "./abstracts/AbstractAuthenticatedView.js";
|
||||
|
||||
export default class extends AbstractAuthentifiedView {
|
||||
export default class extends AbstractAuthenticatedView {
|
||||
constructor(params)
|
||||
{
|
||||
super(params, "Matchmaking");
|
||||
|
@ -1,13 +1,15 @@
|
||||
import AbstractView from "./abstracts/AbstractView.js";
|
||||
import { lang } from '../index.js'
|
||||
|
||||
export default class extends AbstractView {
|
||||
constructor(params) {
|
||||
super(params, "Dashboard");
|
||||
super(params, '404WindowTitle');
|
||||
}
|
||||
|
||||
async getHtml() {
|
||||
return `
|
||||
<h1>404 Bozo</h1>
|
||||
<img src="https://media.giphy.com/media/pm0BKtuBFpdM4/giphy.gif">
|
||||
<p>Git gud</p>
|
||||
`;
|
||||
}
|
||||
|
@ -1,25 +1,26 @@
|
||||
import AbstractView from "./abstracts/AbstractView.js";
|
||||
import { client } from "../index.js"
|
||||
import { client, lang } from "../index.js"
|
||||
|
||||
export default class extends AbstractView {
|
||||
constructor(params) {
|
||||
super(params, params.username);
|
||||
this.username = params.username;
|
||||
super(params, decodeURI(params.username));
|
||||
this.username = decodeURI(params.username);
|
||||
}
|
||||
|
||||
async postInit()
|
||||
{
|
||||
this.profile = await client.profiles.getProfile(this.username);
|
||||
|
||||
if (this.profile === null)
|
||||
return 404;
|
||||
this.userId = this.profile.id;
|
||||
this.user_id = this.profile.id;
|
||||
|
||||
this.info = document.getElementById("info");
|
||||
|
||||
// Username
|
||||
let username = document.createElement("a");
|
||||
username.id = "username";
|
||||
username.appendChild(document.createTextNode(this.profile.username));
|
||||
username.appendChild(document.createTextNode(this.username));
|
||||
this.info.appendChild(username);
|
||||
|
||||
this.info.appendChild(document.createElement("br"));
|
||||
@ -31,30 +32,97 @@ export default class extends AbstractView {
|
||||
this.info.appendChild(avatar);
|
||||
|
||||
await this.blockButton();
|
||||
|
||||
await this.friendButton();
|
||||
|
||||
client.notice.rewrite_profile = async () => {
|
||||
let result = await this.profile.getFriend();
|
||||
await this.profile.getBlock()
|
||||
await this.friendButton();
|
||||
}
|
||||
}
|
||||
|
||||
async blockButton() {
|
||||
// Block option
|
||||
if (await client.isAuthentificate() === false)
|
||||
if (await client.isAuthenticated() === false)
|
||||
return;
|
||||
|
||||
if (client.me.id != this.userId) {
|
||||
let block = document.getElementById("block") || document.createElement("a");
|
||||
if (client.me.id != this.user_id) {
|
||||
let block = document.getElementById("block");
|
||||
if (block == undefined) {
|
||||
block = document.createElement("p");
|
||||
this.info.appendChild(block);
|
||||
}
|
||||
|
||||
block.id = "block";
|
||||
block.innerText = "";
|
||||
block.onclick = async () => {
|
||||
if (!this.profile.isBlocked)
|
||||
await client.profiles.block(this.userId);
|
||||
await client.profiles.block(this.user_id);
|
||||
else
|
||||
await client.profiles.deblock(this.userId);
|
||||
await client.profiles.deblock(this.user_id);
|
||||
this.profile = await client.profiles.getProfile(this.username);
|
||||
|
||||
this.blockButton();
|
||||
};
|
||||
if (this.profile.isBlocked)
|
||||
block.appendChild(document.createTextNode("Deblock"));
|
||||
block.textContent = lang.get('profileUnblock', 'Unblock');
|
||||
else
|
||||
block.appendChild(document.createTextNode("Block"));
|
||||
this.info.appendChild(block);
|
||||
block.textContent = lang.get('profileBlock', 'Block');
|
||||
}
|
||||
}
|
||||
|
||||
async friendButton() {
|
||||
if (await client.isAuthenticated() === false)
|
||||
return;
|
||||
|
||||
if (client.me.id != this.user_id) {
|
||||
let yes = document.getElementById("yes") || document.createElement("p");
|
||||
let no = document.getElementById("no") || document.createElement("p");
|
||||
let friend = document.getElementById("friend") || document.createElement("p");
|
||||
|
||||
if (client.notice.data["asker"].includes(this.user_id)) {
|
||||
|
||||
if (friend)
|
||||
friend.remove();
|
||||
|
||||
yes.id = "yes";
|
||||
yes.textContent = lang.get('profileAcceptRequest', 'Accept Friend');
|
||||
yes.onclick = async () => {
|
||||
client.notice.accept_friend(this.user_id);
|
||||
}
|
||||
|
||||
no.id = "no";
|
||||
no.textContent = lang.get('profileDenyRequest', 'Decline Friend');
|
||||
no.onclick = async () => {
|
||||
client.notice.refuse_friend(this.user_id);
|
||||
}
|
||||
|
||||
this.info.appendChild(yes);
|
||||
this.info.appendChild(document.createTextNode(" "));
|
||||
this.info.appendChild(no);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
if (yes && no)
|
||||
yes.remove(); no.remove();
|
||||
|
||||
friend.id = "friend"
|
||||
friend.onclick = async () => {
|
||||
if (this.profile.isFriend)
|
||||
await client.notice.remove_friend(this.user_id);
|
||||
else
|
||||
await client.notice.ask_friend(this.user_id);
|
||||
await client.profiles.getProfile(this.username);
|
||||
this.friendButton();
|
||||
};
|
||||
if (this.profile.isFriend)
|
||||
friend.textContent = lang.get('profileRemoveFriend', 'Remove Friend');
|
||||
else {
|
||||
friend.textContent = lang.get('profileAddFriend', 'Ask Friend');
|
||||
}
|
||||
this.info.appendChild(friend);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,27 +1,27 @@
|
||||
import AbstractView from "./abstracts/AbstractView.js";
|
||||
import {client} from "../index.js";
|
||||
import { client, lang } from "../index.js";
|
||||
import {Message} from "../api/chat/message.js"
|
||||
|
||||
export default class extends AbstractView {
|
||||
constructor(params) {
|
||||
super(params, "Search");
|
||||
super(params, 'SearchWindowTitle');
|
||||
}
|
||||
|
||||
async wait_get_online_users() {
|
||||
return new Promise((resolve) => {
|
||||
const checkInterval = setInterval(() => {
|
||||
//console.log(client.notice.data["online"].length);
|
||||
if (client.notice.data["online"].length > 0) {
|
||||
console.log(client.notice.data["online"]);
|
||||
if (Object.keys(client.notice.data["online"]).length > 0) {
|
||||
clearInterval(checkInterval);
|
||||
resolve();
|
||||
}
|
||||
}, 100);
|
||||
}, 1);
|
||||
});
|
||||
}
|
||||
|
||||
async postInit() {
|
||||
|
||||
let logged = await client.isAuthentificate();
|
||||
let logged = await client.isAuthenticated();
|
||||
let profiles = await client.profiles.all();
|
||||
|
||||
//console.log(client.notice.data);
|
||||
@ -29,11 +29,13 @@ export default class extends AbstractView {
|
||||
return console.log("Error");
|
||||
|
||||
//await client.notice.getOnlineUser();
|
||||
await this.wait_get_online_users();
|
||||
//await this.wait_get_online_users();
|
||||
client.notice.rewrite_usernames = this.rewrite_usernames;
|
||||
client.notice.rewrite_invite = this.display_invite;
|
||||
|
||||
let search = document.getElementById("input_user");
|
||||
search.oninput = () => this.display_users(logged, profiles);
|
||||
if (search != undefined)
|
||||
search.oninput = () => this.display_users(logged, profiles);
|
||||
|
||||
let chat_input = document.getElementById("input_chat");
|
||||
//chat_input.addEventListener("keydown", this.display_chat_manager)
|
||||
@ -66,7 +68,12 @@ export default class extends AbstractView {
|
||||
username.setAttribute('data-link', '');
|
||||
username.id = `username${user.id}`
|
||||
username.href = `/profiles/${user.username}`;
|
||||
username.style.color = client.notice.data["online"].includes(user.id.toString()) ? "green" : "red";
|
||||
if (logged && user.id == client.me.id)
|
||||
username.style.color = "green";
|
||||
else {
|
||||
let online = client.notice.data["online"][user.id];
|
||||
username.style.color = online !== undefined ? online : "gray";
|
||||
}
|
||||
username.appendChild(document.createTextNode(user.username));
|
||||
new_user.appendChild(username);
|
||||
|
||||
@ -135,8 +142,14 @@ export default class extends AbstractView {
|
||||
|
||||
profiles.filter(user => user.username.toLowerCase().startsWith(search) == true).forEach((user) => {
|
||||
let username = document.getElementById(`username${user.id}`);
|
||||
if (username !== null)
|
||||
username.style.color = client.notice.data["online"].includes(user.id.toString()) ? "green" : "red";
|
||||
if (username !== null) {
|
||||
if (user.id == client.me.id)
|
||||
username.style.color = "green";
|
||||
else {
|
||||
let online = client.notice.data["online"][user.id];
|
||||
username.style.color = online !== undefined ? online : "gray";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
@ -175,13 +188,15 @@ export default class extends AbstractView {
|
||||
chat_input.maxLength=255;
|
||||
chat.appendChild(chat_input);
|
||||
|
||||
let members_id = client.channels.channel.members_id;
|
||||
|
||||
chat_input.onkeydown = async () => {
|
||||
if (event.keyCode == 13 && client.channels.channel != undefined) {
|
||||
//let chat_input = document.getElementById("input_chat");
|
||||
let chat_text = chat_input.value;
|
||||
|
||||
let receivers_id = [];
|
||||
client.channels.channel.members_id.forEach((member_id) => {
|
||||
members_id.forEach((member_id) => {
|
||||
if (member_id != client.me.id)
|
||||
receivers_id.push(profiles.filter(user => user.id == member_id)[0].id);
|
||||
});
|
||||
@ -196,7 +211,7 @@ export default class extends AbstractView {
|
||||
// Scroll to the bottom of messages
|
||||
messages.scrollTop = messages.scrollHeight;
|
||||
|
||||
this.display_invite(chat);
|
||||
this.display_invite();
|
||||
|
||||
}
|
||||
|
||||
@ -242,33 +257,86 @@ export default class extends AbstractView {
|
||||
}
|
||||
|
||||
async display_members(chat, profiles) {
|
||||
|
||||
let members_id = client.channels.channel.members_id;
|
||||
|
||||
let members = document.createElement("h2");
|
||||
members.id = "members";
|
||||
let usernames = "";
|
||||
client.channels.channel.members_id.forEach((member_id) => {
|
||||
members_id.forEach((member_id) => {
|
||||
if (member_id != client.me.id) {
|
||||
if (usernames.length > 0)
|
||||
usernames += ", ";
|
||||
usernames += (profiles.filter(user => user.id == member_id)[0].username);
|
||||
}
|
||||
});
|
||||
members.appendChild(document.createTextNode(usernames));
|
||||
members.textContent = usernames;
|
||||
chat.appendChild(members);
|
||||
|
||||
|
||||
return members
|
||||
}
|
||||
|
||||
async display_invite(chat, profiles) {
|
||||
async display_invite() {
|
||||
|
||||
let chat = document.getElementById("chat");
|
||||
|
||||
if (chat == undefined)
|
||||
return ;
|
||||
|
||||
let members_id = client.channels.channel.members_id;
|
||||
let others = members_id.filter(id => id !== client.me.id);
|
||||
|
||||
// Button to send invite to play
|
||||
let invite = document.getElementById("invite") || document.createElement("button");
|
||||
invite.id = "invite";
|
||||
invite.innerText = "invite";
|
||||
invite.onclick = async () => {
|
||||
await client.notice.sendInvite(client.me.id,
|
||||
client.channels.channel.members_id.filter(id => id !== client.me.id));
|
||||
};
|
||||
chat.appendChild(invite);
|
||||
let yes = document.getElementById("yes") || document.createElement("button");
|
||||
let no = document.getElementById("no") || document.createElement("button");
|
||||
|
||||
let invitedBy = undefined;
|
||||
for (let x in others) {
|
||||
if (client.notice.data["invited"].includes(others[x])) {
|
||||
invitedBy = others[x];
|
||||
}
|
||||
}
|
||||
|
||||
if (invitedBy == undefined) {
|
||||
|
||||
if (yes && no) {
|
||||
yes.remove();
|
||||
no.remove();
|
||||
}
|
||||
|
||||
// Button to send invite to play
|
||||
invite.id = "invite";
|
||||
invite.style.background = "orange";
|
||||
invite.innerText = "invite";
|
||||
invite.title = "Invite to play a game"
|
||||
invite.onclick = async () => {
|
||||
await client.notice.send_invite(others);
|
||||
};
|
||||
chat.appendChild(invite);
|
||||
}
|
||||
else {
|
||||
|
||||
if (invite)
|
||||
invite.remove()
|
||||
|
||||
yes.id = "yes";
|
||||
yes.style.background = "green";
|
||||
yes.title = "Accept to play a game"
|
||||
yes.onclick = async () => {
|
||||
await client.notice.accept_invite(invitedBy);
|
||||
};
|
||||
|
||||
no.id = "no";
|
||||
no.style.background = "red";
|
||||
no.title = "Refuse to play a game"
|
||||
no.onclick = async () => {
|
||||
await client.notice.refuse_invite(invitedBy);
|
||||
};
|
||||
|
||||
chat.appendChild(yes);
|
||||
chat.appendChild(no);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
import { client, navigateTo } from "../index.js";
|
||||
import { clear, fill_errors } from "../utils/formUtils.js";
|
||||
import AbstractAuthentificateView from "./abstracts/AbstractAuthentifiedView.js";
|
||||
import AbstractAuthenticatedView from "./abstracts/AbstractAuthenticatedView.js";
|
||||
|
||||
export default class extends AbstractAuthentificateView
|
||||
export default class extends AbstractAuthenticatedView
|
||||
{
|
||||
constructor(params)
|
||||
{
|
||||
super(params, "Me");
|
||||
super(params, "Settings");
|
||||
this.PROFILE_PICTURE_MAX_SIZE = 2 * 1024 * 1024; // 2MB
|
||||
}
|
||||
|
||||
async postInit()
|
||||
@ -24,7 +25,7 @@ export default class extends AbstractAuthentificateView
|
||||
document.getElementById("avatar").remove();
|
||||
let avatar = document.createElement("img");
|
||||
avatar.id = "avatar";
|
||||
avatar.src = profile.avatar_url;
|
||||
avatar.src = profile.avatar_url + '?t=' +new Date().getTime();
|
||||
document.getElementsByClassName("avatar")[0].appendChild(avatar);
|
||||
}
|
||||
}
|
||||
@ -35,7 +36,7 @@ export default class extends AbstractAuthentificateView
|
||||
|
||||
let response_data = await client.account.delete(current_password);
|
||||
|
||||
console.log(await client.isAuthentificate())
|
||||
console.log(await client.isAuthenticated())
|
||||
if (response_data === null || response_data === "user deleted")
|
||||
{
|
||||
navigateTo("/login");
|
||||
@ -78,18 +79,24 @@ export default class extends AbstractAuthentificateView
|
||||
|
||||
if (avatar.files[0] !== undefined)
|
||||
{
|
||||
if (avatar.files[0].size > this.PROFILE_PICTURE_MAX_SIZE) {
|
||||
document.getElementById("save-profile").classList.add('text-danger');
|
||||
document.getElementById("save-profile").innerHTML = "Image too large :/";
|
||||
return;
|
||||
}
|
||||
let form_data = new FormData();
|
||||
form_data.append("file", avatar.files[0]);
|
||||
form_data.append("avatar", avatar.files[0]);
|
||||
await client.me.change_avatar(form_data);
|
||||
this.display_avatar();
|
||||
}
|
||||
document.getElementById("save-profile").classList.remove('text-danger');
|
||||
document.getElementById("save-profile").innerHTML = "Saved";
|
||||
}
|
||||
|
||||
async getHtml()
|
||||
{
|
||||
return /* HTML */ `
|
||||
<link rel="stylesheet" href="/static/css/me.css">
|
||||
<link rel="stylesheet" href="/static/css/settings.css">
|
||||
<h1>ME</h1>
|
||||
<div id="main">
|
||||
<div class="avatar">
|
@ -2,13 +2,13 @@ import { client, navigateTo } from "../../index.js";
|
||||
import AbstractRedirectView from "./AbstractRedirectView.js";
|
||||
|
||||
export default class extends AbstractRedirectView{
|
||||
constructor(params, title) {
|
||||
super(params, title, "/login");
|
||||
constructor(params, titleKey, uri = "/login") {
|
||||
super(params, titleKey, uri);
|
||||
}
|
||||
|
||||
async redirect()
|
||||
{
|
||||
if (await client.isAuthentificate() === false)
|
||||
if (await client.isAuthenticated() === false)
|
||||
{
|
||||
navigateTo(this.redirect_url);
|
||||
return 1;
|
@ -2,13 +2,13 @@ import { client, navigateTo } from "../../index.js";
|
||||
import AbstractRedirectView from "./AbstractRedirectView.js";
|
||||
|
||||
export default class extends AbstractRedirectView{
|
||||
constructor(params, title, url) {
|
||||
super(params, title, url);
|
||||
constructor(params, titleKey, uri = "/home") {
|
||||
super(params, titleKey, uri);
|
||||
}
|
||||
|
||||
async redirect()
|
||||
{
|
||||
if (await client.isAuthentificate() === false)
|
||||
if (await client.isAuthenticated() === false)
|
||||
return 0;
|
||||
navigateTo(this.redirect_url);
|
||||
return 1;
|
@ -2,14 +2,14 @@ import { navigateTo } from "../../index.js";
|
||||
import AbstractView from "./AbstractView.js";
|
||||
|
||||
export default class extends AbstractView{
|
||||
constructor(params, title, url)
|
||||
constructor(params, titleKey, uri)
|
||||
{
|
||||
super(params, title);
|
||||
this.redirect_url = url;
|
||||
super(params, titleKey);
|
||||
this.redirect_url = uri;
|
||||
}
|
||||
|
||||
async redirect()
|
||||
{
|
||||
navigateTo(url);
|
||||
navigateTo(this.redirect_url);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
import {lang} from '../../index.js'
|
||||
|
||||
export default class {
|
||||
constructor(params, title) {
|
||||
constructor(params, titleKey) {
|
||||
this.params = params;
|
||||
this.title = title;
|
||||
this.titleKey = titleKey;
|
||||
}
|
||||
|
||||
async postInit() {
|
||||
@ -11,7 +13,7 @@ export default class {
|
||||
}
|
||||
|
||||
setTitle() {
|
||||
document.title = this.title;
|
||||
document.title = lang.get(this.titleKey, 'Bozo Pong');
|
||||
}
|
||||
|
||||
async getHtml() {
|
||||
|
177
frontend/static/js/views/accounts/AuthenticationView.js
Normal file
177
frontend/static/js/views/accounts/AuthenticationView.js
Normal file
@ -0,0 +1,177 @@
|
||||
import { client, lang, navigateTo } from "../../index.js";
|
||||
import { clear, fill_errors } from "../../utils/formUtils.js";
|
||||
import AbstractNonAuthenticatedView from "../abstracts/AbstractNonAuthenticatedView.js";
|
||||
|
||||
export default class extends AbstractNonAuthenticatedView
|
||||
{
|
||||
constructor(params, lastUrlBeforeLogin = '/home')
|
||||
{
|
||||
super(params, 'loginWindowTitle', lastUrlBeforeLogin);
|
||||
this.redirect_url = lastUrlBeforeLogin;
|
||||
this.current_mode = undefined
|
||||
}
|
||||
|
||||
async leavePage()
|
||||
{
|
||||
this.current_mode = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async postInit()
|
||||
{
|
||||
let element = document.getElementById("toggle-register-login");
|
||||
|
||||
element.onclick = this.toggle_register_login.bind(this);
|
||||
|
||||
let new_mode = location.pathname.slice(1);
|
||||
this.update_mode(new_mode);
|
||||
|
||||
document.getElementById("button").onclick = this.authentication.bind(this);
|
||||
|
||||
let username_input = document.getElementById('username-input'),
|
||||
password_input = document.getElementById('password-input');
|
||||
|
||||
[username_input, password_input].forEach(input => {
|
||||
input.addEventListener('keydown', async ev => {
|
||||
if (ev.key === 'Enter')
|
||||
await this.authentication.bind(this)()
|
||||
});
|
||||
});
|
||||
username_input.focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if field is normal
|
||||
* @param username {String}
|
||||
* @param password {String}
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
basic_verif(username, password)
|
||||
{
|
||||
if (username === '')
|
||||
document.getElementById('username').innerHTML = lang.get('errorEmptyField', 'This field may not be blank.');
|
||||
|
||||
if (password === '')
|
||||
document.getElementById('password').innerHTML = lang.get('errorEmptyField', 'This field may not be blank.');
|
||||
|
||||
if (username === '' || password === '')
|
||||
return false;
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns { undefined }
|
||||
*/
|
||||
toggle_register_login(event)
|
||||
{
|
||||
event.preventDefault();
|
||||
|
||||
let new_mode = this.current_mode === "register" ? "login" : "register";
|
||||
|
||||
this.update_mode(new_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} new_mode
|
||||
*/
|
||||
update_mode(new_mode)
|
||||
{
|
||||
if (new_mode === this.current_mode)
|
||||
return;
|
||||
|
||||
this.current_mode = new_mode;
|
||||
|
||||
let title = document.getElementById("title"),
|
||||
username_label = document.getElementById("username-label"),
|
||||
password_label = document.getElementById("password-label"),
|
||||
toggle_register_login = document.getElementById("toggle-register-login"),
|
||||
toggle_register_login_label = document.getElementById("toggle-register-login-label"),
|
||||
button = document.getElementById("button")
|
||||
;
|
||||
|
||||
let title_text = this.current_mode === "register" ? "registerFormTitle" : "loginFormTitle";
|
||||
title.innerText = lang.get(title_text, "ERROR LANG");
|
||||
|
||||
let username_label_text = this.current_mode === "register" ? "registerFormUsername" : "loginFormUsername";
|
||||
username_label.innerText = lang.get(username_label_text, "ERROR LANG");
|
||||
|
||||
let password_label_text = this.current_mode === "register" ? "registerFormPassword" : "loginFormPassword";
|
||||
password_label.innerText = lang.get(password_label_text, "ERROR LANG");
|
||||
|
||||
let toggle_register_login_label_text = this.current_mode === "register" ? "registerAlreadyAccount" : "loginNoAccount";
|
||||
toggle_register_login_label.innerText = lang.get(toggle_register_login_label_text, "ERROR LANG");;
|
||||
|
||||
let toggle_register_login_text = this.current_mode === "register" ? "registerLogin" : "loginRegister";
|
||||
toggle_register_login.innerText = lang.get(toggle_register_login_text, "ERROR LANG");
|
||||
|
||||
let button_text = this.current_mode === "register" ? "registerFormButton" : "loginFormButton";
|
||||
button.innerText = lang.get(button_text, "ERROR LANG");
|
||||
|
||||
this.titleKey = this.current_mode === 'register' ? 'registerWindowTitle' : 'loginWindowTitle';
|
||||
this.setTitle();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async authentication()
|
||||
{
|
||||
let username = document.getElementById("username-input").value,
|
||||
password = document.getElementById("password-input").value;
|
||||
|
||||
if (!this.basic_verif())
|
||||
return;
|
||||
|
||||
let response;
|
||||
|
||||
if (this.current_mode === "register")
|
||||
response = await client.account.create(username, password)
|
||||
else
|
||||
response = await client.login(username, password);
|
||||
|
||||
if (response.status === 200 || response.status === 201)
|
||||
{
|
||||
navigateTo(this.redirect_url);
|
||||
return;
|
||||
}
|
||||
|
||||
let response_data = await response.json()
|
||||
|
||||
console.log(response_data);
|
||||
|
||||
clear("innerHTML", ["username", "password", 'login']);
|
||||
fill_errors(response_data, "innerHTML");
|
||||
}
|
||||
|
||||
async getHtml()
|
||||
{
|
||||
return /* HTML */ `
|
||||
<div class='container-fluid'>
|
||||
<form class='border border-2 rounded bg-light-subtle mx-auto p-2 col-md-7 col-lg-4'>
|
||||
<h4 class='text-center fw-semibold mb-4' id="title">Loading...</h4>
|
||||
<div class='form-floating mb-2'>
|
||||
<input type='text' class='form-control' id='username-input' placeholder='Username'>
|
||||
<label for='usernameInput' id='username-label'>Loading...</label>
|
||||
<span class='text-danger' id='username'></span>
|
||||
</div>
|
||||
<div class='form-floating'>
|
||||
<input type='password' class='form-control' id='password-input' placeholder='Password'>
|
||||
<label for='password-input' id='password-label'>Loading...</label>
|
||||
<span class='text-danger' id='password'></span>
|
||||
</div>
|
||||
<div class='d-flex'>
|
||||
<button type='button' class='btn btn-primary mt-3 mb-2' id='button'>Loading...</button>
|
||||
<span class='text-danger my-auto mx-2' id='login'></span>
|
||||
<div class='ms-auto mt-auto flex-row d-flex gap-2' id="toggle">
|
||||
<p id='toggle-register-login-label'>Loading...</p>
|
||||
<a id="toggle-register-login" href='#'>Loading...</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
import { client, navigateTo } from "../../index.js";
|
||||
import { clear, fill_errors } from "../../utils/formUtils.js";
|
||||
import AbstractNonAuthentifiedView from "../abstracts/AbstractNonAuthentified.js";
|
||||
|
||||
async function login(redirectTo = '/home')
|
||||
{
|
||||
clear('innerHTML', ['username', 'password', 'login']);
|
||||
|
||||
let username = document.getElementById('usernameInput').value;
|
||||
let password = document.getElementById('passwordInput').value;
|
||||
|
||||
if (username === '') {
|
||||
document.getElementById('username').innerHTML = 'This field may not be blank.';
|
||||
}
|
||||
if (password === '') {
|
||||
document.getElementById('password').innerHTML = 'This field may not be blank.';
|
||||
}
|
||||
if (username === '' || password === '')
|
||||
return;
|
||||
|
||||
let response = await client.login(username, password);
|
||||
|
||||
if (response.status == 200) {
|
||||
await client.notice.disconnect();
|
||||
await client.notice.connect();
|
||||
navigateTo(redirectTo);
|
||||
} else {
|
||||
let error = await response.json();
|
||||
fill_errors(error, "innerHTML");
|
||||
}
|
||||
}
|
||||
|
||||
export default class extends AbstractNonAuthentifiedView {
|
||||
constructor(params, lastUrlBeforeLogin = '/home') {
|
||||
super(params, "Login", lastUrlBeforeLogin);
|
||||
this.redirectTo = lastUrlBeforeLogin;
|
||||
}
|
||||
|
||||
async postInit()
|
||||
{
|
||||
let usernameField = document.getElementById('usernameInput');
|
||||
usernameField.addEventListener('keydown', ev => {
|
||||
if (ev.key === 'Enter')
|
||||
login(this.redirectTo);
|
||||
});
|
||||
usernameField.focus();
|
||||
let passwordField = document.getElementById('passwordInput');
|
||||
passwordField.addEventListener('keydown', ev => {
|
||||
if (ev.key === 'Enter')
|
||||
login(this.redirectTo);
|
||||
});
|
||||
document.getElementById('loginButton').onclick = _ => login(this.redirectTo);
|
||||
}
|
||||
|
||||
async getHtml() {
|
||||
return `
|
||||
<div class='container-fluid'>
|
||||
<form class='border border-2 rounded bg-light-subtle mx-auto p-2 col-md-7 col-lg-4'>
|
||||
<h4 class='text-center fw-semibold mb-4'>Login</h4>
|
||||
<div class='form-floating mb-2'>
|
||||
<input type='text' class='form-control' id='usernameInput' placeholder='Username'>
|
||||
<label for='usernameInput'>Username</label>
|
||||
<span class='text-danger' id='username'></span>
|
||||
</div>
|
||||
<div class='form-floating'>
|
||||
<input type='password' class='form-control' id='passwordInput' placeholder='Password'>
|
||||
<label for='passwordInput'>Password</label>
|
||||
<span class='text-danger' id='password'></span>
|
||||
</div>
|
||||
<div class='d-flex'>
|
||||
<button type='button' class='btn btn-primary mt-3 mb-2' id='loginButton'>Login</button>
|
||||
<span class='text-danger my-auto mx-2' id='login'></span>
|
||||
<p class='ms-auto mt-auto'>No account yet? <a href='/register' data-link>Register</a></p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
import { client, navigateTo } from "../../index.js";
|
||||
import AbstractAuthentifiedView from "../abstracts/AbstractAuthentifiedView.js";
|
||||
import AbstractAuthenticatedView from "../abstracts/AbstractAuthenticatedView.js";
|
||||
|
||||
export default class extends AbstractAuthentifiedView
|
||||
export default class extends AbstractAuthenticatedView
|
||||
{
|
||||
constructor(params, lastPageUrl = '/login') {
|
||||
super(params, "Logout");
|
||||
super(params, 'logoutWindowTitle', lastPageUrl);
|
||||
this.lastPageUrl = lastPageUrl;
|
||||
}
|
||||
|
||||
|
@ -1,77 +0,0 @@
|
||||
import { client, navigateTo } from "../../index.js";
|
||||
import { clear, fill_errors } from "../../utils/formUtils.js";
|
||||
import AbstractNonAuthentifiedView from "../abstracts/AbstractNonAuthentified.js";
|
||||
|
||||
async function register(redirectTo = '/home')
|
||||
{
|
||||
let username = document.getElementById("usernameInput").value;
|
||||
let password = document.getElementById("passwordInput").value;
|
||||
|
||||
if (username === '' || password === '') {
|
||||
clear("innerHTML", ["username", "password"]);
|
||||
if (username === '')
|
||||
document.getElementById('username').innerHTML = 'This field may not be blank.';
|
||||
if (password === '')
|
||||
document.getElementById('password').innerHTML = 'This field may not be blank.';
|
||||
return;
|
||||
}
|
||||
|
||||
let response_data = await client.account.create(username, password);
|
||||
|
||||
if (response_data == null)
|
||||
{
|
||||
navigateTo(redirectTo);
|
||||
return;
|
||||
}
|
||||
|
||||
clear("innerHTML", ["username", "password", 'register']);
|
||||
fill_errors(response_data, "innerHTML");
|
||||
}
|
||||
|
||||
export default class extends AbstractNonAuthentifiedView {
|
||||
constructor(params, lastUrlBeforeLogin = '/home') {
|
||||
super(params, "Register", lastUrlBeforeLogin);
|
||||
this.redirectTo = lastUrlBeforeLogin;
|
||||
}
|
||||
|
||||
async postInit()
|
||||
{
|
||||
let usernameField = document.getElementById('usernameInput');
|
||||
usernameField.addEventListener('keydown', ev => {
|
||||
if (ev.key === 'Enter')
|
||||
register(this.redirectTo);
|
||||
});
|
||||
usernameField.focus();
|
||||
let passwordField = document.getElementById('passwordInput');
|
||||
passwordField.addEventListener('keydown', ev => {
|
||||
if (ev.key === 'Enter')
|
||||
register(this.redirectTo);
|
||||
});
|
||||
document.getElementById("registerButton").onclick = _ => register(this.redirectTo);
|
||||
}
|
||||
|
||||
async getHtml() {
|
||||
return `
|
||||
<div class='container-fluid'>
|
||||
<form class='border border-2 rounded bg-light-subtle mx-auto p-2 col-md-7 col-lg-4'>
|
||||
<h4 class='text-center fw-semibold mb-4'>Register</h4>
|
||||
<div class='form-floating mb-2'>
|
||||
<input type='text' class='form-control' id='usernameInput' placeholder='Username'>
|
||||
<label for='usernameInput'>Username</label>
|
||||
<span class='text-danger' id='username'></span>
|
||||
</div>
|
||||
<div class='form-floating'>
|
||||
<input type='password' class='form-control' id='passwordInput' placeholder='Password'>
|
||||
<label for='passwordInput'>Password</label>
|
||||
<span class='text-danger' id='password'></span>
|
||||
</div>
|
||||
<div class='d-flex'>
|
||||
<button type='button' class='btn btn-primary mt-3 mb-2' id='registerButton'>Register</button>
|
||||
<span class='text-danger my-auto mx-2' id='register'></span>
|
||||
<p class='ms-auto mt-auto'>Already have an account? <a href='/login' data-link>Login</a></p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
import {client, navigateTo} from "../../index.js";
|
||||
import { clear, fill_errors } from "../../utils/formUtils.js";
|
||||
import AbstractAuthentifiedView from "../abstracts/AbstractAuthentifiedView.js";
|
||||
import AbstractAuthenticatedView from "../abstracts/AbstractAuthenticatedView.js";
|
||||
|
||||
export default class extends AbstractAuthentifiedView
|
||||
export default class extends AbstractAuthenticatedView
|
||||
{
|
||||
constructor(params)
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {client, navigateTo} from "../../index.js";
|
||||
import AbstractAuthentifiedView from "../abstracts/AbstractAuthentifiedView.js";
|
||||
import AbstractAuthenticatedView from "../abstracts/AbstractAuthenticatedView.js";
|
||||
|
||||
export default class extends AbstractAuthentifiedView
|
||||
export default class extends AbstractAuthenticatedView
|
||||
{
|
||||
constructor(params)
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {client} from "../../index.js";
|
||||
import AbstractAuthentifiedView from "../abstracts/AbstractAuthentifiedView.js";
|
||||
import AbstractAuthenticatedView from "../abstracts/AbstractAuthenticatedView.js";
|
||||
|
||||
export default class extends AbstractAuthentifiedView
|
||||
export default class extends AbstractAuthenticatedView
|
||||
{
|
||||
constructor(params)
|
||||
{
|
||||
|
Reference in New Issue
Block a user