Merge branch 'master' into hugo
4
Makefile
@@ -1,5 +1,7 @@
|
|||||||
DOCKERCOMPOSEPATH=./srcs/docker-compose.yml
|
DOCKERCOMPOSEPATH=./srcs/docker-compose.yml
|
||||||
|
|
||||||
|
all : up
|
||||||
|
|
||||||
#dev allow hot reload.
|
#dev allow hot reload.
|
||||||
up:
|
up:
|
||||||
@bash ./make_env.sh
|
@bash ./make_env.sh
|
||||||
@@ -11,8 +13,6 @@ start:
|
|||||||
docker compose -f ${DOCKERCOMPOSEPATH} start
|
docker compose -f ${DOCKERCOMPOSEPATH} start
|
||||||
docker logs --follow nestjs
|
docker logs --follow nestjs
|
||||||
|
|
||||||
all : up
|
|
||||||
|
|
||||||
re: down up
|
re: down up
|
||||||
|
|
||||||
down:
|
down:
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./requirements/nestjs/api_back/src:/usr/app/src
|
- ./requirements/nestjs/api_back/src:/usr/app/src
|
||||||
- ./requirements/nestjs/api_back/test:/usr/app/test/
|
- ./requirements/nestjs/api_back/test:/usr/app/test/
|
||||||
- nestjs_photos_volume:/usr/app/src/uploads/avatars
|
- nestjs_photos_volume:/usr/app/uploads/avatars
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgresql
|
- postgresql
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import * as ev from "../../shared_js/class/Event.js"
|
|||||||
import * as en from "../../shared_js/enums.js"
|
import * as en from "../../shared_js/enums.js"
|
||||||
|
|
||||||
export class Client {
|
export class Client {
|
||||||
|
role: en.ClientRole;
|
||||||
socket: WebSocket;
|
socket: WebSocket;
|
||||||
id: string; // same as "socket.id"
|
id: string; // same as "socket.id"
|
||||||
isAlive: boolean = true;
|
isAlive: boolean = true;
|
||||||
@@ -23,9 +24,8 @@ export class ClientPlayer extends Client {
|
|||||||
inputBuffer: ev.EventInput = new ev.EventInput();
|
inputBuffer: ev.EventInput = new ev.EventInput();
|
||||||
lastInputId: number = 0;
|
lastInputId: number = 0;
|
||||||
racket: Racket;
|
racket: Racket;
|
||||||
constructor(socket: WebSocket, id: string, racket: Racket) {
|
constructor(socket: WebSocket, id: string) {
|
||||||
super(socket, id);
|
super(socket, id);
|
||||||
this.racket = racket;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ async function clientAnnounceListener(this: WebSocket, data: string)
|
|||||||
if (msg.role === en.ClientRole.player)
|
if (msg.role === en.ClientRole.player)
|
||||||
{
|
{
|
||||||
const announce: ev.ClientAnnouncePlayer = <ev.ClientAnnouncePlayer>msg;
|
const announce: ev.ClientAnnouncePlayer = <ev.ClientAnnouncePlayer>msg;
|
||||||
|
const player = clientsMap.get(this.id) as ClientPlayer;
|
||||||
|
player.role = msg.role;
|
||||||
|
|
||||||
const body = {
|
const body = {
|
||||||
playerOneUsername: announce.username,
|
playerOneUsername: announce.username,
|
||||||
@@ -106,8 +108,6 @@ async function clientAnnounceListener(this: WebSocket, data: string)
|
|||||||
clientTerminate(clientsMap.get(this.id));
|
clientTerminate(clientsMap.get(this.id));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const player = clientsMap.get(this.id) as ClientPlayer;
|
|
||||||
player.matchOptions = announce.matchOptions;
|
player.matchOptions = announce.matchOptions;
|
||||||
player.token = announce.token;
|
player.token = announce.token;
|
||||||
player.username = announce.username;
|
player.username = announce.username;
|
||||||
@@ -126,13 +126,15 @@ async function clientAnnounceListener(this: WebSocket, data: string)
|
|||||||
else if (msg.role === en.ClientRole.spectator)
|
else if (msg.role === en.ClientRole.spectator)
|
||||||
{
|
{
|
||||||
const announce: ev.ClientAnnounceSpectator = <ev.ClientAnnounceSpectator>msg;
|
const announce: ev.ClientAnnounceSpectator = <ev.ClientAnnounceSpectator>msg;
|
||||||
|
const spectator = clientsMap.get(this.id) as ClientSpectator;
|
||||||
|
spectator.role = msg.role;
|
||||||
|
|
||||||
const gameSession = gameSessionsMap.get(announce.gameSessionId);
|
const gameSession = gameSessionsMap.get(announce.gameSessionId);
|
||||||
if (!gameSession) {
|
if (!gameSession) {
|
||||||
this.send(JSON.stringify( new ev.EventError("invalid gameSessionId") ));
|
this.send(JSON.stringify( new ev.EventError("invalid gameSessionId") ));
|
||||||
clientTerminate(clientsMap.get(this.id));
|
clientTerminate(clientsMap.get(this.id));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const spectator = clientsMap.get(this.id) as ClientSpectator;
|
|
||||||
spectator.gameSession = gameSession;
|
spectator.gameSession = gameSession;
|
||||||
gameSession.spectatorsMap.set(spectator.id, spectator);
|
gameSession.spectatorsMap.set(spectator.id, spectator);
|
||||||
spectator.socket.once("message", spectatorReadyConfirmationListener);
|
spectator.socket.once("message", spectatorReadyConfirmationListener);
|
||||||
@@ -419,7 +421,7 @@ const pingInterval = setInterval( () => {
|
|||||||
}, 4200);
|
}, 4200);
|
||||||
|
|
||||||
|
|
||||||
export function clientTerminate(client: Client)
|
export async function clientTerminate(client: Client)
|
||||||
{
|
{
|
||||||
client.socket.terminate();
|
client.socket.terminate();
|
||||||
if (client.gameSession)
|
if (client.gameSession)
|
||||||
@@ -439,6 +441,23 @@ export function clientTerminate(client: Client)
|
|||||||
else if (privateMatchmakingMap.has(client.id)) {
|
else if (privateMatchmakingMap.has(client.id)) {
|
||||||
privateMatchmakingMap.delete(client.id);
|
privateMatchmakingMap.delete(client.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (client.role === en.ClientRole.player)
|
||||||
|
{
|
||||||
|
const player = client as ClientPlayer;
|
||||||
|
console.log("/resetuserstatus " + player.username);
|
||||||
|
const response = await fetch(c.addressBackEnd + "/game/gameserver/resetuserstatus",
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({username: player.username})
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
console.log("/resetuserstatus " + player.username + " failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { Response } from 'express';
|
|||||||
import { TwoFaDto } from './dto/2fa.dto';
|
import { TwoFaDto } from './dto/2fa.dto';
|
||||||
import { UsersService } from 'src/users/users.service';
|
import { UsersService } from 'src/users/users.service';
|
||||||
import { User } from 'src/users/entities/user.entity';
|
import { User } from 'src/users/entities/user.entity';
|
||||||
|
import { STATUS } from 'src/common/constants/constants';
|
||||||
|
|
||||||
@Controller('auth')
|
@Controller('auth')
|
||||||
export class AuthenticationController {
|
export class AuthenticationController {
|
||||||
@@ -36,6 +37,7 @@ export class AuthenticationController {
|
|||||||
console.log('On redirige');
|
console.log('On redirige');
|
||||||
const user : User = request.user
|
const user : User = request.user
|
||||||
if (user.isEnabledTwoFactorAuth === false || user.isTwoFactorAuthenticated === true){
|
if (user.isEnabledTwoFactorAuth === false || user.isTwoFactorAuthenticated === true){
|
||||||
|
this.userService.updateStatus(user.id, STATUS.CONNECTED)
|
||||||
console.log('ON VA VERS PROFILE');
|
console.log('ON VA VERS PROFILE');
|
||||||
return response.status(200).redirect('http://' + process.env.WEBSITE_HOST + ':' + process.env.WEBSITE_PORT + '/#/profile');
|
return response.status(200).redirect('http://' + process.env.WEBSITE_HOST + ':' + process.env.WEBSITE_PORT + '/#/profile');
|
||||||
}
|
}
|
||||||
@@ -51,7 +53,7 @@ export class AuthenticationController {
|
|||||||
@UseGuards(AuthenticateGuard)
|
@UseGuards(AuthenticateGuard)
|
||||||
logout(@Req() request, @Res() response, @Next() next) {
|
logout(@Req() request, @Res() response, @Next() next) {
|
||||||
this.userService.setIsTwoFactorAuthenticatedWhenLogout(request.user.id);
|
this.userService.setIsTwoFactorAuthenticatedWhenLogout(request.user.id);
|
||||||
this.userService.updateStatus(request.user.id, 'disconnected');
|
this.userService.updateStatus(request.user.id, STATUS.DISCONNECTED);
|
||||||
request.logout(function(err) {
|
request.logout(function(err) {
|
||||||
if (err) { return next(err); }
|
if (err) { return next(err); }
|
||||||
response.redirect('/');
|
response.redirect('/');
|
||||||
@@ -83,6 +85,7 @@ export class AuthenticationController {
|
|||||||
throw new UnauthorizedException('Wrong Code.');
|
throw new UnauthorizedException('Wrong Code.');
|
||||||
await this.userService.authenticateUserWith2FA(request.user.id);
|
await this.userService.authenticateUserWith2FA(request.user.id);
|
||||||
console.log('ON REDIRIGE');
|
console.log('ON REDIRIGE');
|
||||||
|
this.userService.updateStatus(user.id, STATUS.CONNECTED)
|
||||||
return response.status(200).redirect('http://' + process.env.WEBSITE_HOST + ':' + process.env.WEBSITE_PORT + '/#/profile');
|
return response.status(200).redirect('http://' + process.env.WEBSITE_HOST + ':' + process.env.WEBSITE_PORT + '/#/profile');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,4 +101,9 @@ export class GameController {
|
|||||||
{
|
{
|
||||||
return this.gameService.destroySession(token);
|
return this.gameService.destroySession(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Post('gameserver/resetuserstatus')
|
||||||
|
async resetUserStatus(@Body('username') username){
|
||||||
|
this.gameService.resetStatus(username);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,12 +92,17 @@ export class GameService {
|
|||||||
}
|
}
|
||||||
this.userRepository.save(user);
|
this.userRepository.save(user);
|
||||||
}
|
}
|
||||||
// if (grantTicketDto.isGameIsWithInvitation === true && user.status !== STATUS.IN_GAME) // WIP: need to fix STATUS.IN_GAME
|
|
||||||
if (grantTicketDto.isGameIsWithInvitation === true)
|
if (grantTicketDto.isGameIsWithInvitation === true)
|
||||||
{
|
{
|
||||||
const secondUser : Partial<User> = await this.userService.findOne(grantTicketDto.playerTwoUsername)
|
if (grantTicketDto.playerTwoUsername === user.username) {
|
||||||
if (!secondUser || secondUser.username === user.username)
|
return res.status(HttpStatus.BAD_REQUEST).json({message : "You cant play against yourself."});
|
||||||
return res.status(HttpStatus.NOT_FOUND).json({message : "User not found OR you want to play with yourself."});
|
}
|
||||||
|
const secondUser : User = await this.userRepository.createQueryBuilder('user')
|
||||||
|
.where("user.username = :username", {username : grantTicketDto.playerTwoUsername})
|
||||||
|
.getOne();
|
||||||
|
if (!secondUser) {
|
||||||
|
return res.status(HttpStatus.NOT_FOUND).json({message : "Invited user not found"});
|
||||||
|
}
|
||||||
const encryptedTextToReturn = await this.encryptToken(user.username + '_' + secondUser.username + '_'
|
const encryptedTextToReturn = await this.encryptToken(user.username + '_' + secondUser.username + '_'
|
||||||
+ grantTicketDto.gameOptions + '_' + grantTicketDto.isGameIsWithInvitation + '_' + new Date())
|
+ grantTicketDto.gameOptions + '_' + grantTicketDto.isGameIsWithInvitation + '_' + new Date())
|
||||||
const tok = this.tokenGameRepository.create(grantTicketDto);
|
const tok = this.tokenGameRepository.create(grantTicketDto);
|
||||||
@@ -106,9 +111,9 @@ export class GameService {
|
|||||||
tok.token = encryptedTextToReturn;
|
tok.token = encryptedTextToReturn;
|
||||||
this.tokenGameRepository.save(tok);
|
this.tokenGameRepository.save(tok);
|
||||||
this.userService.updateStatus(user.id, STATUS.IN_POOL)
|
this.userService.updateStatus(user.id, STATUS.IN_POOL)
|
||||||
|
this.userService.updateStatus(secondUser.id, STATUS.IN_POOL)
|
||||||
return res.status(HttpStatus.OK).json({ token : encryptedTextToReturn });
|
return res.status(HttpStatus.OK).json({ token : encryptedTextToReturn });
|
||||||
}
|
}
|
||||||
// else if (grantTicketDto.isGameIsWithInvitation === false && user.status !== STATUS.IN_GAME) { // WIP: need to fix STATUS.IN_GAME
|
|
||||||
else if (grantTicketDto.isGameIsWithInvitation === false) {
|
else if (grantTicketDto.isGameIsWithInvitation === false) {
|
||||||
const encryptedTextToReturn = await this.encryptToken(user.username + '_'
|
const encryptedTextToReturn = await this.encryptToken(user.username + '_'
|
||||||
+ grantTicketDto.gameOptions + '_' + grantTicketDto.isGameIsWithInvitation + '_' + new Date())
|
+ grantTicketDto.gameOptions + '_' + grantTicketDto.isGameIsWithInvitation + '_' + new Date())
|
||||||
@@ -142,13 +147,11 @@ export class GameService {
|
|||||||
const userOne : User = await this.userRepository.createQueryBuilder('user')
|
const userOne : User = await this.userRepository.createQueryBuilder('user')
|
||||||
.where("user.username = :username", {username : tokenGame.playerOneUsername})
|
.where("user.username = :username", {username : tokenGame.playerOneUsername})
|
||||||
.getOne();
|
.getOne();
|
||||||
this.userService.updateStatus(userOne.id, STATUS.IN_GAME)
|
|
||||||
const userTwo : User = await this.userRepository.createQueryBuilder('user')
|
const userTwo : User = await this.userRepository.createQueryBuilder('user')
|
||||||
.where("user.username = :username", {username : tokenGame.playerTwoUsername})
|
.where("user.username = :username", {username : tokenGame.playerTwoUsername})
|
||||||
.getOne();
|
.getOne();
|
||||||
this.deleteToken(userOne)
|
this.deleteToken(userOne)
|
||||||
this.deleteToken(userTwo)
|
this.deleteToken(userTwo)
|
||||||
this.userService.updateStatus(userTwo.id, STATUS.IN_GAME)
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -168,7 +171,6 @@ export class GameService {
|
|||||||
const user : User = await this.userRepository.createQueryBuilder('user')
|
const user : User = await this.userRepository.createQueryBuilder('user')
|
||||||
.where("user.username = :username", {username : tokenGame.playerOneUsername})
|
.where("user.username = :username", {username : tokenGame.playerOneUsername})
|
||||||
.getOne();
|
.getOne();
|
||||||
this.userService.updateStatus(user.id, STATUS.IN_GAME)
|
|
||||||
this.deleteToken(user)
|
this.deleteToken(user)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -259,6 +261,14 @@ export class GameService {
|
|||||||
this.gameRepository.save(game);
|
this.gameRepository.save(game);
|
||||||
if (!game)
|
if (!game)
|
||||||
return HttpStatus.INTERNAL_SERVER_ERROR
|
return HttpStatus.INTERNAL_SERVER_ERROR
|
||||||
|
const playerOne : User = await this.userRepository.createQueryBuilder('user')
|
||||||
|
.where("user.username = :username", {username : creategameDto.playerOneUsername})
|
||||||
|
.getOne();
|
||||||
|
const playerTwo : User = await this.userRepository.createQueryBuilder('user')
|
||||||
|
.where("user.username = :username", {username : creategameDto.playerTwoUsername})
|
||||||
|
.getOne();
|
||||||
|
this.userService.updateStatus(playerOne.id, STATUS.IN_GAME)
|
||||||
|
this.userService.updateStatus(playerTwo.id, STATUS.IN_GAME)
|
||||||
console.log("200 retourné pour la création de partie")
|
console.log("200 retourné pour la création de partie")
|
||||||
return HttpStatus.OK
|
return HttpStatus.OK
|
||||||
}
|
}
|
||||||
@@ -280,6 +290,8 @@ export class GameService {
|
|||||||
const playerTwo = await this.userRepository.findOneBy({username : game.playerTwoUsername})
|
const playerTwo = await this.userRepository.findOneBy({username : game.playerTwoUsername})
|
||||||
if (!playerOne || !playerTwo)
|
if (!playerOne || !playerTwo)
|
||||||
return new HttpException("Internal Server Error. Impossible to update the database", HttpStatus.INTERNAL_SERVER_ERROR);
|
return new HttpException("Internal Server Error. Impossible to update the database", HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
|
this.userService.updateStatus(playerOne.id, STATUS.CONNECTED);
|
||||||
|
this.userService.updateStatus(playerTwo.id, STATUS.CONNECTED);
|
||||||
if (game.playerOneUsernameResult === game.playerTwoUsernameResult)
|
if (game.playerOneUsernameResult === game.playerTwoUsernameResult)
|
||||||
{
|
{
|
||||||
this.userService.incrementDraws(playerOne.id)
|
this.userService.incrementDraws(playerOne.id)
|
||||||
@@ -296,9 +308,14 @@ export class GameService {
|
|||||||
this.userService.incrementVictories(playerOne.id)
|
this.userService.incrementVictories(playerOne.id)
|
||||||
this.userService.incrementDefeats(playerTwo.id)
|
this.userService.incrementDefeats(playerTwo.id)
|
||||||
}
|
}
|
||||||
this.userService.updateStatus(playerOne.id, STATUS.CONNECTED)
|
|
||||||
this.userService.updateStatus(playerTwo.id, STATUS.CONNECTED)
|
|
||||||
return HttpStatus.OK
|
return HttpStatus.OK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async resetStatus(username : string){
|
||||||
|
const user : User = await this.userRepository.findOneBy({username : username})
|
||||||
|
if (!user)
|
||||||
|
return HttpStatus.NOT_FOUND;
|
||||||
|
this.userService.updateStatus(user.id, STATUS.CONNECTED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,11 +13,6 @@ body {
|
|||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
||||||
/* tmp? */
|
/* tmp? */
|
||||||
background: bisque;
|
background: bisque;
|
||||||
|
|
||||||
/* overflow-x: hidden; */
|
|
||||||
/* This seems to have fixed my pages that are too long */
|
|
||||||
/* but now i can't scroll anywhere ... */
|
|
||||||
/* overflow-y: hidden; */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
|||||||
BIN
srcs/requirements/svelte/api_front/public/img/BACKGROUND.png
Normal file
|
After Width: | Height: | Size: 169 KiB |
|
After Width: | Height: | Size: 407 KiB |
|
Before Width: | Height: | Size: 675 KiB |
|
Before Width: | Height: | Size: 20 KiB |
BIN
srcs/requirements/svelte/api_front/public/img/logo_potato.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
srcs/requirements/svelte/api_front/public/img/potato_only.png
Normal file
|
After Width: | Height: | Size: 181 KiB |
|
Before Width: | Height: | Size: 430 KiB |
@@ -1 +0,0 @@
|
|||||||
<svg id="visual" viewBox="0 0 900 150" width="900" height="150" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"><path d="M0 36L21.5 33.7C43 31.3 86 26.7 128.8 32.5C171.7 38.3 214.3 54.7 257.2 63.5C300 72.3 343 73.7 385.8 65.7C428.7 57.7 471.3 40.3 514.2 30.5C557 20.7 600 18.3 642.8 25.8C685.7 33.3 728.3 50.7 771.2 59.5C814 68.3 857 68.7 878.5 68.8L900 69L900 0L878.5 0C857 0 814 0 771.2 0C728.3 0 685.7 0 642.8 0C600 0 557 0 514.2 0C471.3 0 428.7 0 385.8 0C343 0 300 0 257.2 0C214.3 0 171.7 0 128.8 0C86 0 43 0 21.5 0L0 0Z" fill="#618174" stroke-linecap="round" stroke-linejoin="miter"></path></svg>
|
|
||||||
|
Before Width: | Height: | Size: 645 B |
@@ -9,22 +9,8 @@
|
|||||||
user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`)
|
user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`)
|
||||||
.then((resp) => resp.json())
|
.then((resp) => resp.json())
|
||||||
|
|
||||||
// i mean i could do a failed to load user or some shit, maybe with a .catch or something? but atm why bother
|
|
||||||
|
|
||||||
console.log('User var');
|
|
||||||
console.log(user);
|
|
||||||
// if (user && user.statusCode && user.statusCode === 403) {
|
|
||||||
// console.log('user not logged in')
|
|
||||||
// }
|
|
||||||
// if (user && user.username) {
|
|
||||||
// console.log('we have a user');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// user === undefined doesn't work cuz we declared user in the scope of onMount
|
|
||||||
// if (user === undefined) {
|
|
||||||
if (user && user.statusCode && user.statusCode === 403) {
|
if (user && user.statusCode && user.statusCode === 403) {
|
||||||
console.log('on mount no user, returned status code 403 so logging out of userStore')
|
console.log('on mount no user, returned status code 403 so logging out of userStore')
|
||||||
// userLogout(); // which i think should delete any previous local storage
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -34,8 +20,6 @@
|
|||||||
console.log('you are now logged in');
|
console.log('you are now logged in');
|
||||||
}
|
}
|
||||||
|
|
||||||
// i could prolly put this in it's own compoent, i seem to use it in several places... or maybe just some JS? like no need for html
|
|
||||||
// we could .then( () => replace('/') ) need the func so TS compatible...
|
|
||||||
const logout = async() => {
|
const logout = async() => {
|
||||||
await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/auth/logout`, {
|
await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/auth/logout`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -46,108 +30,71 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<header class="grid-container">
|
<div class="container">
|
||||||
<h1>Potato Pong</h1>
|
<div class="splash-page">
|
||||||
<nav>
|
{#if user && user.username}
|
||||||
<!-- {#if user !== undefined} -->
|
<button class="button-in" on:click={ () => (push('/profile')) }>Profile</button>
|
||||||
{#if user && user.username}
|
<button class="button-out" on:click={logout}>Logout</button>
|
||||||
<div on:click={ () => (push('/profile')) }>Profile</div>
|
{:else}
|
||||||
<div on:click={logout}>Logout</div>
|
<button class="button-in" on:click={login}>Login</button>
|
||||||
{:else}
|
{/if}
|
||||||
<div on:click={login}>Login</div>
|
</div>
|
||||||
{/if}
|
</div>
|
||||||
</nav>
|
|
||||||
<h2>
|
|
||||||
<div>Welcome to</div>
|
|
||||||
<div>Potato Pong</div>
|
|
||||||
</h2>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<Canvas/>
|
|
||||||
|
|
||||||
<!-- doesn't work :( -->
|
|
||||||
<!-- <svelte:body style="overflow-y: hidden"/> -->
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@font-face {
|
||||||
|
font-family: "Bit5x3";
|
||||||
|
src:
|
||||||
|
url("/fonts/Bit5x3.woff2") format("woff2"),
|
||||||
|
local("Bit5x3"),
|
||||||
|
url("/fonts/Bit5x3.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
/* :global(body) {
|
.container {
|
||||||
overflow-y: hidden;
|
height: 100%;
|
||||||
} */
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
header {
|
background-image: url('/img/SPLASH_PAGE_BACKGROUND.png');
|
||||||
/* didn't work... */
|
background-position: center center;
|
||||||
overflow-y: hidden;
|
background-repeat: no-repeat;
|
||||||
}
|
background-attachment: fixed;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The actually important stuff */
|
.splash-page {
|
||||||
|
margin: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 80%;
|
||||||
|
-ms-transform: translateY(-80%);
|
||||||
|
transform: translateY(-80%);
|
||||||
|
left: 50%;
|
||||||
|
-ms-transform: translateX(-50%);
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
.grid-container{
|
.button-in {
|
||||||
position: absolute;
|
background-color: #8c0000;
|
||||||
left: 0;
|
border-color: black;
|
||||||
top: 0;
|
border-width: 4px;
|
||||||
|
color: white;
|
||||||
|
font-family: "Bit5x3";
|
||||||
|
font-size: x-large;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
box-sizing: border-box;
|
.button-out {
|
||||||
width: 100%;
|
background-color: #008c8c;
|
||||||
height: 100%;
|
border-color: black;
|
||||||
/* max-height: 100%; */
|
border-width: 4px;
|
||||||
white-space: nowrap;
|
color: white;
|
||||||
/* padding-bottom: 0; */
|
font-family: "Bit5x3";
|
||||||
margin-bottom: 0px;
|
font-size: x-large;
|
||||||
overflow: hidden;
|
padding: 10px;
|
||||||
padding: 20px 40px;
|
}
|
||||||
margin: 0px;
|
|
||||||
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(12, 1fr);
|
|
||||||
grid-template-rows: 1fr 1fr 1fr 1fr 1fr;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
header h1{
|
|
||||||
grid-column: 1 / 7;
|
|
||||||
grid-row: 1;
|
|
||||||
/* grid-column: span 6; */
|
|
||||||
/* tmp? */
|
|
||||||
padding: 20px;
|
|
||||||
border: 1px solid bisque;
|
|
||||||
}
|
|
||||||
header nav{
|
|
||||||
/* make it a flexbox? */
|
|
||||||
grid-column: 7 / 13;
|
|
||||||
grid-row: 1;
|
|
||||||
justify-self: end;
|
|
||||||
/* tmp? */
|
|
||||||
padding: 20px;
|
|
||||||
border: 1px solid bisque;
|
|
||||||
}
|
|
||||||
|
|
||||||
header h2{
|
|
||||||
grid-row: 3;
|
|
||||||
grid-column: 5 / span 4;
|
|
||||||
justify-self: center;
|
|
||||||
/* tmp */
|
|
||||||
border: 1px solid black;
|
|
||||||
z-index: 3;
|
|
||||||
}
|
|
||||||
header h2 div{
|
|
||||||
font-size: 2em;
|
|
||||||
/* color: red; */
|
|
||||||
}
|
|
||||||
|
|
||||||
nav div {
|
|
||||||
display: inline;
|
|
||||||
color: bisque;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
nav > div {
|
|
||||||
padding-left: 1em;
|
|
||||||
/* didn't quite work, applies to both for some reason */
|
|
||||||
/* nav:first-child doesn't work either*/
|
|
||||||
}
|
|
||||||
nav div:hover{
|
|
||||||
text-decoration: underline;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -268,25 +268,34 @@
|
|||||||
<button class="pong_button" on:click={fetchInvitations}>Show invitations</button>
|
<button class="pong_button" on:click={fetchInvitations}>Show invitations</button>
|
||||||
<fieldset in:fly="{{ y: 10, duration: 1000 }}">
|
<fieldset in:fly="{{ y: 10, duration: 1000 }}">
|
||||||
<legend>game options</legend>
|
<legend>game options</legend>
|
||||||
<div>
|
|
||||||
|
<label for="multi_balls">
|
||||||
<input type="checkbox" id="multi_balls" name="multi_balls" bind:checked={options.multi_balls}>
|
<input type="checkbox" id="multi_balls" name="multi_balls" bind:checked={options.multi_balls}>
|
||||||
<label for="multi_balls">Multiples balls</label>
|
Multiples balls
|
||||||
</div>
|
</label>
|
||||||
<div>
|
|
||||||
|
<label for="moving_walls">
|
||||||
<input type="checkbox" id="moving_walls" name="moving_walls" bind:checked={options.moving_walls}>
|
<input type="checkbox" id="moving_walls" name="moving_walls" bind:checked={options.moving_walls}>
|
||||||
<label for="moving_walls">Moving walls</label>
|
Moving walls
|
||||||
</div>
|
</label>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p>sound :</p>
|
sound :
|
||||||
<input type="radio" id="sound_on" name="sound_selector" bind:group={options.sound} value="on">
|
<label for="sound_on">
|
||||||
<label for="sound_on">on</label>
|
<input type="radio" id="sound_on" name="sound_selector" bind:group={options.sound} value="on">
|
||||||
<input type="radio" id="sound_off" name="sound_selector" bind:group={options.sound} value="off">
|
on
|
||||||
<label for="sound_off">off</label>
|
</label>
|
||||||
</div>
|
<label for="sound_off">
|
||||||
<div>
|
<input type="radio" id="sound_off" name="sound_selector" bind:group={options.sound} value="off">
|
||||||
<input type="checkbox" id="isSomeoneIsInvited" bind:checked={options.isSomeoneIsInvited}>
|
off
|
||||||
<label for="moving_walls">Invite a friend</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<label for="invitation_checkbox">
|
||||||
|
<input type="checkbox" id="invitation_checkbox" bind:checked={options.isSomeoneIsInvited}>
|
||||||
|
Invite a friend
|
||||||
|
</label>
|
||||||
|
|
||||||
{#if options.isSomeoneIsInvited}
|
{#if options.isSomeoneIsInvited}
|
||||||
<select bind:value={options.playerTwoUsername}>
|
<select bind:value={options.playerTwoUsername}>
|
||||||
{#each allUsers as user }
|
{#each allUsers as user }
|
||||||
|
|||||||
@@ -131,13 +131,19 @@
|
|||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>options</legend>
|
<legend>options</legend>
|
||||||
<button class="pong_button" on:click={fetchMatchList}>Reload</button>
|
<button class="pong_button" on:click={fetchMatchList}>Reload</button>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p>sound :</p>
|
sound :
|
||||||
<input type="radio" id="sound_on" name="sound_selector" bind:group={sound} value="on">
|
<label for="sound_on">
|
||||||
<label for="sound_on">on</label>
|
<input type="radio" id="sound_on" name="sound_selector" bind:group={sound} value="on">
|
||||||
<input type="radio" id="sound_off" name="sound_selector" bind:group={sound} value="off">
|
on
|
||||||
<label for="sound_off">off</label>
|
</label>
|
||||||
|
<label for="sound_off">
|
||||||
|
<input type="radio" id="sound_off" name="sound_selector" bind:group={sound} value="off">
|
||||||
|
off
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
{#if matchList.length !== 0}
|
{#if matchList.length !== 0}
|
||||||
<menu id="match_list">
|
<menu id="match_list">
|
||||||
|
|||||||