Merge branch 'master' into hugo

This commit is contained in:
simplonco
2023-01-17 11:53:01 +01:00
24 changed files with 637 additions and 701 deletions

View File

@@ -12,17 +12,8 @@ import { SessionSerializer } from './utils/serializer';
@Module({ @Module({
imports: [TypeOrmModule.forFeature([User, Friendship]), UsersModule, imports: [TypeOrmModule.forFeature([User, Friendship]), UsersModule,
// JwtModule.registerAsync({
// useFactory: async (configService: ConfigService) => {
// return {
// signOptions: { expiresIn: '1h' },
// secret: process.env.JWT_SECRET,
// };
// }
// })
], ],
providers: [AuthenticationService, FortyTwoStrategy, UsersService, SessionSerializer, FriendshipService providers: [AuthenticationService, FortyTwoStrategy, UsersService, SessionSerializer, FriendshipService
// JwtStrategy
], ],
exports: [AuthenticationService], exports: [AuthenticationService],
controllers: [AuthenticationController], controllers: [AuthenticationController],

View File

@@ -1,9 +1,10 @@
import { IsBoolean, IsEmail, IsNotEmpty, IsOptional, IsString } from 'class-validator'; import { IsBoolean, Matches, IsEmail, IsNotEmpty, IsOptional, IsString } from 'class-validator';
import { isSet } from 'util/types'; import { isSet } from 'util/types';
export class CreateUsersDto { export class CreateUsersDto {
@IsString() @IsString()
@IsNotEmpty() @IsNotEmpty()
@Matches(/^[a-zA-Z0-9'-_]+$/)
readonly username: string; readonly username: string;
readonly fortyTwoId: string; readonly fortyTwoId: string;
@IsEmail() @IsEmail()

View File

@@ -15,7 +15,7 @@ export class User {
@Column({unique: true}) @Column({unique: true})
fortyTwoId: string; fortyTwoId: string;
@Column() @Column({unique: true})
username: string; username: string;
@Column() @Column()

View File

@@ -58,7 +58,7 @@ export class UsersController {
@Patch() @Patch()
async update(@Req() req, @Body(new ValidationPipe()) usersUpdateDto: UpdateUsersDto, @Res() response : Response) { async update(@Req() req, @Body(new ValidationPipe()) usersUpdateDto: UpdateUsersDto, @Res() response : Response) {
console.log('user.controller updating user info') console.log('user.controller updating user info')
const user = await this.usersService.update(req.user.id, usersUpdateDto); const user = await this.usersService.update(req.user.id, usersUpdateDto, req.user.username);
if (user.isEnabledTwoFactorAuth === false && user.isTwoFactorAuthenticated === true) if (user.isEnabledTwoFactorAuth === false && user.isTwoFactorAuthenticated === true)
this.usersService.setIsTwoFactorAuthenticatedWhenLogout(user.id); this.usersService.setIsTwoFactorAuthenticatedWhenLogout(user.id);
if (user.isEnabledTwoFactorAuth === true && user.isTwoFactorAuthenticated === false) if (user.isEnabledTwoFactorAuth === true && user.isTwoFactorAuthenticated === false)

View File

@@ -55,12 +55,9 @@ export class UsersService {
} }
async isUsernameExists(usernameToSearch: string): Promise<boolean> { async isUsernameExists(usernameToSearch: string): Promise<boolean> {
// console.log('searching for username: ' + usernameToSearch) const user = await this.userRepository.createQueryBuilder('user')
.where('LOWER(user.username) = LOWER(:username)', {username : usernameToSearch})
const user = await this.userRepository.findOneBy({username : usernameToSearch}); .getOne()
// console.log({...user})
if (!user) if (!user)
return false; return false;
return true; return true;
@@ -101,10 +98,9 @@ export class UsersService {
return this.userRepository.save(user); return this.userRepository.save(user);
} }
async update(id: number, updateUserDto: UpdateUsersDto) { async update(id: number, updateUserDto: UpdateUsersDto, username : string) {
// console.log(`Update user ${id} with ${updateUserDto.isEnabledTwoFactorAuth}`); console.log("Maj user username : " + username + " updateuser dto " + updateUserDto.username )
// console.log({...updateUserDto}) if (await this.isUsernameExists(updateUserDto.username) === true && updateUserDto.username !== username) {
if (await this.isUsernameExists(updateUserDto.username) === true) {
// console.log('updating username ' + updateUserDto.username + ' but it already is in use') // console.log('updating username ' + updateUserDto.username + ' but it already is in use')
throw new HttpException(`The username is already in use.`,HttpStatus.CONFLICT); throw new HttpException(`The username is already in use.`,HttpStatus.CONFLICT);
} }

View File

@@ -1,2 +0,0 @@
WEBSITE_HOST=localhost
WEBSITE_PORT=8080

View File

@@ -16,11 +16,11 @@ body {
} }
@font-face { @font-face {
font-family: "Bit5x3"; font-family: "PressStart2P";
src: src:
url("./fonts/Bit5x3.woff2") format("woff2"), url("./fonts/PressStart2P.woff2") format("woff2"),
local("Bit5x3"), local("PressStart2P"),
url("./fonts/Bit5x3.woff") format("woff"); url("./fonts/PressStart2P.woff") format("woff");
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
font-display: swap; font-display: swap;
@@ -42,8 +42,8 @@ a:visited {
.background-pages { .background-pages {
background-color: #333; background-color: #333;
font-family: "Bit5x3"; font-family: "PressStart2P";
font-size: 2vw; font-size: 1vw;
color: white; color: white;
} }

View File

@@ -1,18 +1,13 @@
<script lang="ts"> <script lang="ts">
import Canvas from "../pieces/Canvas.svelte";
import { push } from "svelte-spa-router"; import { push } from "svelte-spa-router";
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { fetchUser } from "../pieces/utils";
let user; let user;
onMount(async () => { onMount(async () => {
user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`) user = await fetchUser();
.then((resp) => resp.json())
if (user && user.statusCode && user.statusCode === 403) {
console.log('on mount no user, returned status code 403 so logging out of userStore')
}
}); });
const login = async() => { const login = async() => {
@@ -21,10 +16,21 @@
} }
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'
}
)
.then((response) => {
if (!response.ok) {
throw new Error("HTTP " + response.status);
}
})
.catch((error) => {
console.log("catch logout: ", error);
}); });
user = undefined;
user = null;
}; };
</script> </script>
@@ -71,8 +77,8 @@
border-color: #071013; border-color: #071013;
border-width: 2px; border-width: 2px;
color: white; color: white;
font-family: "Bit5x3"; font-family: "PressStart2P";
font-size: x-large; font-size: 1vw;
padding: 10px; padding: 10px;
} }
@@ -81,8 +87,8 @@
border-color: #071013; border-color: #071013;
border-width: 2px; border-width: 2px;
color: white; color: white;
font-family: "Bit5x3"; font-family: "PressStart2P";
font-size: x-large; font-size: 1vw;
padding: 10px; padding: 10px;
} }

View File

@@ -2,42 +2,57 @@
import { onMount } from "svelte"; import { onMount } from "svelte";
import { push } from "svelte-spa-router"; import { push } from "svelte-spa-router";
let qrCodeImg; let qrCodeImg;
let qrCode = ""; let qrCode = "";
let wrongCode = ""; let wrongCode = "";
const fetchQrCodeImg = (async () => { const fetchQrCodeImg = (async () => {
await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/auth/2fa/generate`, qrCodeImg = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/auth/2fa/generate`,
{ {
method: 'POST', method: "POST",
}
)
.then((response) => {
if (!response.ok) {
throw new Error("HTTP " + response.status);
}
return response.blob();
}) })
.then(response => {return response.blob()}) .then((blob) => {
.then(blob => { return URL.createObjectURL(blob);
const url = URL.createObjectURL(blob); })
qrCodeImg = url; .catch((error) => {
console.log("catch fetchQrCodeImg: ", error);
}); });
})()
})();
const submitCode = async () => { const submitCode = async () => {
const response = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/auth/2fa/check`, await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/auth/2fa/check`,
{ {
method : 'POST', method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
body: JSON.stringify({ body: JSON.stringify({
"twoFaCode" : qrCode, twoFaCode: qrCode,
}), }),
}); }
)
.then((response) => {
if (!response.ok) {
if (response.status === 401) { if (response.status === 401) {
qrCode = ""; qrCode = "";
wrongCode = `Wrong code`; wrongCode = `Wrong code`;
} }
if (response.status === 200) { throw new Error("HTTP " + response.status);
push('/profile');
console.log('valid Code for 2FA')
} }
push("/profile");
console.log("valid Code for 2FA");
})
.catch((error) => {
console.log("catch submitCode: ", error);
});
}; };
</script> </script>
@@ -88,7 +103,7 @@
.error { .error {
font-weight: bold; font-weight: bold;
font-size: 0.8em; font-size: 1vw;
color: red; color: red;
} }
</style> </style>

View File

@@ -14,8 +14,8 @@
let user; let user;
let allUsers; let allUsers;
let playerOneAvatar; let playerOneAvatar = "";
let playerTwoAvatar; let playerTwoAvatar = "";
//Game's stuff //Game's stuff
const options = new pong.InitOptions(); const options = new pong.InitOptions();
@@ -393,7 +393,16 @@
</div> <!-- div "game_page" --> </div> <!-- div "game_page" -->
<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;
}
.dim_background { .dim_background {
background-color: #222; background-color: #222;
} }
@@ -423,15 +432,16 @@ canvas {
/* background-color: #ff0000; */ /* background-color: #ff0000; */
background-color: #333; background-color: #333;
max-width: 75vw; max-width: 75vw;
font-family: "Bit5x3";
/* max-height: 100vh; */ /* max-height: 100vh; */
width: 80%; width: 80%;
} }
.div_game { .div_game {
text-align: center; text-align: center;
font-family: "Bit5x3"; font-family: "PressStart2P";
color: rgb(245, 245, 245); color: rgb(245, 245, 245);
font-size: x-large; font-size: 1vw;
} }
.div_game fieldset { .div_game fieldset {
max-width: 50vw; max-width: 50vw;
@@ -442,10 +452,10 @@ canvas {
padding: 10px; padding: 10px;
} }
.pong_button { .pong_button {
font-family: "Bit5x3"; font-family: "PressStart2P";
color: rgb(245, 245, 245); color: rgb(245, 245, 245);
background-color: #333333; background-color: #333333;
font-size: x-large; font-size: 1vw;
padding: 10px; padding: 10px;
} }
.avatar { .avatar {

View File

@@ -5,13 +5,13 @@
import MatchListElem from "../../pieces/MatchListElem.svelte"; import MatchListElem from "../../pieces/MatchListElem.svelte";
import type { Match } from "../../pieces/Match"; import type { Match } from "../../pieces/Match";
import { fetchUser, fetchAllUsers, fetchAvatar } from "../../pieces/utils"; import { fetchAvatar } from "../../pieces/utils";
import * as pongSpectator from "./client/pongSpectator"; import * as pongSpectator from "./client/pongSpectator";
import { gameState } from "./client/ws"; import { gameState } from "./client/ws";
let playerOneAvatar; let playerOneAvatar = "";
let playerTwoAvatar; let playerTwoAvatar = "";
//Game's stuff //Game's stuff
const gameAreaId = "game_area"; const gameAreaId = "game_area";
@@ -179,6 +179,16 @@
<!-- --> <!-- -->
<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;
}
.dim_background { .dim_background {
background-color: #222; background-color: #222;
@@ -203,15 +213,16 @@ canvas {
/* background-color: #ff0000; */ /* background-color: #ff0000; */
background-color: #333333; background-color: #333333;
max-width: 75vw; max-width: 75vw;
font-family: "Bit5x3";
/* max-height: 100vh; */ /* max-height: 100vh; */
width: 80%; width: 80%;
} }
.div_game { .div_game {
text-align: center; text-align: center;
font-family: "Bit5x3"; font-family: "PressStart2P";
color: rgb(245, 245, 245); color: rgb(245, 245, 245);
font-size: x-large; font-size: 1vw;
} }
.div_game fieldset { .div_game fieldset {
max-width: 50vw; max-width: 50vw;
@@ -222,15 +233,15 @@ canvas {
padding: 10px; padding: 10px;
} }
.pong_button { .pong_button {
font-family: "Bit5x3"; font-family: "PressStart2P";
color: rgb(245, 245, 245); color: rgb(245, 245, 245);
background-color: #333333; background-color: #333333;
font-size: x-large; font-size: 1vw;
padding: 10px; padding: 10px;
} }
#match_list { #match_list {
font-family: 'Courier New', Courier, monospace; font-family: 'Courier New', Courier, monospace;
font-size: large; font-size: 1vw;
} }
.avatar { .avatar {
min-height: 100px; min-height: 100px;

View File

@@ -1,28 +1,37 @@
<script lang="ts"> <script lang="ts">
import { onMount, onDestroy } from "svelte"; import { onMount, onDestroy } from "svelte";
import { fetchUser } from "../../pieces/utils";
let user;
let allUsersRanking = [];
let fetchScoresInterval;
//user's stuff
let currentUser;
let allUsers = [];
let idInterval;
onMount( async() => { onMount( async() => {
currentUser = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`) user = await fetchUser();
.then( x => x.json() ); allUsersRanking = await fetchScores();
allUsers = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/game/ranking`)
.then( x => x.json() ); fetchScoresInterval = setInterval(fetchScores, 10000);
idInterval = setInterval(fetchScores, 10000);
}) })
onDestroy( async() => { onDestroy( async() => {
clearInterval(idInterval); clearInterval(fetchScoresInterval);
}) })
function fetchScores() { async function fetchScores()
fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/game/ranking`) {
.then( x => x.json() ) return fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/game/ranking`)
.then( x => allUsers = x ); .then((response) => {
if (!response.ok) {
throw new Error("HTTP " + response.status);
}
return response.json();
})
.catch((error) => {
console.log("catch fetchScores: ", error);
return [];
});
} }
</script> </script>
@@ -41,18 +50,18 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{#each allUsers as user, i} {#each allUsersRanking as userRanking, i}
<tr> <tr>
<th>{i + 1}</th> <th>{i + 1}</th>
{#if user.username === currentUser.username} {#if userRanking.username === user.username}
<td><b>{user.username} [You]</b></td> <td><b>{userRanking.username} [You]</b></td>
{:else} {:else}
<td>{user.username}</td> <td>{userRanking.username}</td>
{/if} {/if}
<td>{user.stats.winGame}</td> <td>{userRanking.stats.winGame}</td>
<td>{user.stats.loseGame}</td> <td>{userRanking.stats.loseGame}</td>
<td>{user.stats.drawGame}</td> <td>{userRanking.stats.drawGame}</td>
<td>{user.stats.totalGame}</td> <td>{userRanking.stats.totalGame}</td>
</tr> </tr>
{/each} {/each}
</tbody> </tbody>
@@ -70,7 +79,7 @@
.stats-table { .stats-table {
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
font-size: 0.9em; font-size: 1vw;
min-width: 400px; min-width: 400px;
} }
@@ -82,6 +91,9 @@
.stats-table th, .stats-table th,
.stats-table td { .stats-table td {
padding: 12px 15px; padding: 12px 15px;
size: 10vw;
max-width: 10vw;
overflow-wrap: break-word;
} }
.stats-table tbody tr { .stats-table tbody tr {

View File

@@ -4,15 +4,15 @@
import GenerateUserDisplay from '../../pieces/GenerateUserDisplay.svelte'; import GenerateUserDisplay from '../../pieces/GenerateUserDisplay.svelte';
import { push } from 'svelte-spa-router'; import { push } from 'svelte-spa-router';
import Chat from '../../pieces/chat/Chat.svelte';
import { fetchUser } from "../../pieces/utils";
let user; let user;
onMount( async() => { onMount( async() => {
// console.log('mounting profile display') user = await fetchUser();
user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`)
.then( (x) => x.json() );
}) })
</script> </script>
<div class="background-pages"> <div class="background-pages">

View File

@@ -4,35 +4,22 @@
from a regular var. But yea it's functionally identical, seemed easier to just have a duplicate rather than figuring from a regular var. But yea it's functionally identical, seemed easier to just have a duplicate rather than figuring
out how to get a more complicated things to do 2 jobs.*/ out how to get a more complicated things to do 2 jobs.*/
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import GenerateUserDisplay from '../../pieces/GenerateUserDisplay.svelte'; import GenerateUserDisplay from '../../pieces/GenerateUserDisplay.svelte';
import { fetchUser } from "../../pieces/utils";
export let params; export let params;
let user; let oneUser;
onMount( async() => { onMount( async() => {
oneUser = await fetchUser(params.username);
// console.log('Display One User username: '+ params.username)
user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user?username=${params.username}`)
.then( (x) => x.json() );
console.log('in display ONE user')
console.log({...user})
}) })
export const updateUser = async() => {
user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user?username=${params.username}`)
.then( (x) => x.json() );
};
$: params.username, updateUser();
</script> </script>
<div class="background-pages"> <div class="background-pages">
{#if user !== undefined} {#if oneUser}
<GenerateUserDisplay user={user}/> <GenerateUserDisplay user={oneUser}/>
{:else} {:else}
<h2>Sorry</h2> <h2>Sorry</h2>
<div>Failed to load user {params.username}</div> <div>Failed to load user {params.username}</div>
@@ -41,4 +28,3 @@
<!-- This is where i might toss in an Invite to Game button ? --> <!-- This is where i might toss in an Invite to Game button ? -->
</div> </div>

View File

@@ -5,7 +5,7 @@
import { push } from 'svelte-spa-router'; import { push } from 'svelte-spa-router';
import Button from '../../pieces/Button.svelte'; import Button from '../../pieces/Button.svelte';
import { fetchAvatar } from "../../pieces/utils"; import { fetchUser, fetchAvatar } from "../../pieces/utils";
let user; let user;
let avatar, newAvatar; let avatar, newAvatar;
@@ -18,35 +18,26 @@
let success = {username: '', avatar: '' }; let success = {username: '', avatar: '' };
onMount( async() => { onMount( async() => {
user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`) user = await fetchUser();
.then( (x) => x.json() ); avatar = await fetchAvatar();
// do a .catch?
if (user === undefined) { if (!user) {
console.log('User did not load, something more official should prolly happen') console.log('User did not load, something more official should prolly happen')
} }
// i don't unerstand why this is necessary but it really doesn't like it otherwise // i don't unerstand why this is necessary but it really doesn't like it otherwise
nameTmp = user.username; nameTmp = user.username;
set.tfa = user.isEnabledTwoFactorAuth; set.tfa = user.isEnabledTwoFactorAuth;
avatar = await fetchAvatar(user.username);
}) })
const settingsHandler = async() => { const settingsHandler = async() =>
// I don't really care which i use at this point... {
// if (set.username === nameTmp) { if ((set.username.trim() === '')) {
if ((set.username.trim() === '') && set.tfa === user.isEnabledTwoFactorAuth) {
errors.username = 'Invalid new username';
return;
}
else if ((set.username.trim() === '') && set.tfa !== user.isEnabledTwoFactorAuth) {
set.username = user.username set.username = user.username
} }
else { errors.username = ''
errors.username = ''; await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`,
} {
await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`, {
method: 'PATCH', method: 'PATCH',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
@@ -55,27 +46,36 @@
"username": set.username, "username": set.username,
"isEnabledTwoFactorAuth": set.tfa "isEnabledTwoFactorAuth": set.tfa
}) })
})
.then((response) => {
if (response.status === 200)
success.username = "Your changes have been saved"
else if (response.status === 201)
push("/2fa");
else if (response.status === 409)
errors.username = `${set.username} is already in use, pick a different one.`;
else
errors.username = "Something went wrong";
} }
) )
.catch((err) => errors.username = err) .then((response) => {
if (!response.ok) {
success.username = ''
errors.username = "Use [a-zA-Z0-9] and - _ .";
if (response.status === 409) {
errors.username = `${set.username} is already in use, pick a different one.`;
}
throw new Error("HTTP " + response.status);
}
else {
if (response.status === 200) {
errors.username = ''
success.username = "Your changes have been saved";
}
else if (response.status === 201) {
push("/2fa");
}
}
// .then((result) => console.log(result)) })
// .then(() => console.log('successful sub of new settings')) .catch((error) => {
}; console.log("catch settingsHandler: ", error);
});
}
const uploadAvatar = async() => { const uploadAvatar = async() => {
errors.avatar = ''; errors.avatar = '';
if (newAvatar === undefined) { if (!newAvatar) {
errors.avatar = 'You need to pick a file.' errors.avatar = 'You need to pick a file.'
return; return;
} }
@@ -85,19 +85,23 @@
// tmp // tmp
console.log(data); console.log(data);
const responseWhenChangeAvatar = fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar`, await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar`,
{ {
method : 'POST', method : 'POST',
body : data, body : data,
}) }
const responseFromServer = await responseWhenChangeAvatar; )
if (responseFromServer.ok === true) { .then((response) => {
if (!response.ok) {
errors.avatar = response.statusText;
throw new Error("HTTP " + response.status);
}
uploadAvatarSuccess = true; uploadAvatarSuccess = true;
success.avatar = 'Your avatar has been updated'; success.avatar = 'Your avatar has been updated';
} })
else { .catch((error) => {
errors.avatar = responseFromServer.statusText; console.log("catch uploadAvatar: ", error);
} });
avatar = await fetchAvatar(user.username); avatar = await fetchAvatar(user.username);
} }
@@ -130,7 +134,7 @@
<Card> <Card>
<!-- ok so it can't actually show us the file we upload until we've uploaded it... --> <!-- ok so it can't actually show us the file we upload until we've uploaded it... -->
{#if avatar !== undefined} {#if avatar}
<img class="avatar" src={avatar} alt="your avatar"/> <img class="avatar" src={avatar} alt="your avatar"/>
{/if} {/if}
<form on:submit|preventDefault={uploadAvatar}> <form on:submit|preventDefault={uploadAvatar}>
@@ -141,7 +145,7 @@
<input type="file" bind:files={newAvatar}/> <input type="file" bind:files={newAvatar}/>
<div class="error">{errors.avatar}</div> <div class="error">{errors.avatar}</div>
</div> </div>
<Button type={newAvatar === undefined ? "primary" : "secondary"}>Upload Avatar</Button> <Button type={!newAvatar ? "primary" : "secondary"}>Upload Avatar</Button>
</form> </form>
</Card> </Card>
</div> </div>
@@ -198,13 +202,13 @@
.error{ .error{
font-size: 0.8em; font-size: 1vw;
font-weight: bold; font-weight: bold;
color: red; color: red;
} }
.success{ .success{
font-size: 0.8em; font-size: 1vw;
font-weight: bold; font-weight: bold;
color: green; color: green;
} }

View File

@@ -1,53 +1,52 @@
<script lang="ts"> <script lang="ts">
import { onMount } from "svelte"; import { onMount } from "svelte";
import Button from "../../pieces/Button.svelte"; import Button from "../../pieces/Button.svelte";
import DisplayAUser from "../../pieces/DisplayAUser.svelte"; import DisplayAUser from "../../pieces/DisplayAUser.svelte";
import Tabs from "../../pieces/Tabs.svelte"; import Tabs from "../../pieces/Tabs.svelte";
import { fetchUser, fetchAllUsers, fetchAvatar } from "../../pieces/utils";
let user; let user;
let allUsers; let allUsers = [];
let myFriendships; let myFriendships = [];
let requestsMade, requestsRecieved; let requestsMade, requestsRecieved;
let blockedUsers; let blockedUsers = [];
let usernameBeingViewed; let usernameBeingViewed;
let friendshipStatusFull; // date, reveiverUsername, status let friendshipStatusFull; // date, reveiverUsername, status
/**** Layout variables ****/ /**** Layout variables ****/
let tabItems: string[] = ['All Users', 'My Friends', 'Friend Requests', 'Blocked Users'] let tabItems: string[] = [
let activeTabItem: string = 'All Users'; "All Users",
"My Friends",
"Friend Requests",
"Blocked Users",
];
let activeTabItem: string = "All Users";
onMount(async () => { onMount(async () => {
user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`) user = await fetchUser();
.then( (x) => x.json() );
fetchAll(); fetchAll();
}); });
const fetchAll = async () => { const fetchAll = async () => {
// no need to await i think it can load in the background // no need to await i think it can load in the background
fetchAllUsers(); fetchAllUsers_Wrapper();
fetchMyFriendships(); fetchMyFriendships();
fetchRequestsMade(); fetchRequestsMade();
fetchRequestsReceived(); fetchRequestsReceived();
fetchBlockedUsers(); fetchBlockedUsers();
} };
/***** Fetch basic things *****/ /***** Fetch basic things *****/
const fetchAllUsers = async() => { const fetchAllUsers_Wrapper = async () => {
allUsers = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/all`) allUsers = await fetchAllUsers();
.then( x => x.json() ); if (usernameBeingViewed) {
console.log('got all users ') let found = allUsers.find(
console.log({...allUsers}) (e) => e.username === usernameBeingViewed
if (usernameBeingViewed !== undefined) { );
let found = allUsers.find(e => e.username === usernameBeingViewed); if (!found) {
// console.log("SEARCHING ALL USERS: ") usernameBeingViewed = null;
// console.log({...found}) friendshipStatusFull = null;
if (found === undefined) {
// console.log('none found')
usernameBeingViewed = undefined;
friendshipStatusFull = undefined;
} }
} }
}; };
@@ -56,150 +55,214 @@
// then i need to extract the users // then i need to extract the users
const fetchMyFriendships = async () => { const fetchMyFriendships = async () => {
myFriendships = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/myfriends`) myFriendships = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/myfriends`)
.then( x => x.json() ); .then((response) => {
if (!response.ok) {
console.log('got my friends ') throw new Error("HTTP " + response.status);
console.log({...myFriendships}) }
return response.json();
})
.catch((error) => {
console.log("catch fetchMyFriendships: ", error);
return [];
});
}; };
const fetchRequestsMade = async () => { const fetchRequestsMade = async () => {
requestsMade = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/pending`) requestsMade = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/pending`)
.then( x => x.json() ); .then((response) => {
if (!response.ok) {
console.log('got requests made ') throw new Error("HTTP " + response.status);
console.log({...requestsMade}) }
return response.json();
})
.catch((error) => {
console.log("catch fetchRequestsMade: ", error);
return [];
});
}; };
const fetchRequestsReceived = async () => { const fetchRequestsReceived = async () => {
requestsRecieved = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/received`) requestsRecieved = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/received`)
.then( x => x.json() ); .then((response) => {
if (!response.ok) {
console.log('got requests received ') throw new Error("HTTP " + response.status);
console.log({...requestsRecieved}) }
return response.json();
})
.catch((error) => {
console.log("catch fetchRequestsReceived: ", error);
return [];
});
}; };
const fetchBlockedUsers = async () => { const fetchBlockedUsers = async () => {
blockedUsers = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/blocked`) blockedUsers = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/blocked`)
.then( x => x.json() ); .then((response) => {
if (!response.ok) {
console.log('got blocked users, is it empty?') throw new Error("HTTP " + response.status);
console.log({...blockedUsers}) }
console.log(Object.keys(blockedUsers)) return response.json();
})
.catch((error) => {
console.log("catch fetchBlockedUsers: ", error);
return [];
});
}; };
/**** END OF MAIN FETCH ****/ /**** END OF MAIN FETCH ****/
// returns everything but BLOCKED // returns everything but BLOCKED
const fetchFriendshipFull = async (aUsername) => { const fetchFriendshipFull = async (aUsername) => {
console.log('fetch friendship from a username')
console.log(aUsername)
friendshipStatusFull = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/myfriends?username=${aUsername}`) friendshipStatusFull = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/myfriends?username=${aUsername}`)
.then( x => x.json()); .then((response) => {
if (!response.ok) {
console.log({...friendshipStatusFull}) throw new Error("HTTP " + response.status);
}
return response.json();
})
.catch((error) => {
console.log("catch fetchFriendshipFull: ", error);
return [];
});
}; };
const sendFriendRequest = async (aUsername) => { const sendFriendRequest = async (aUsername) => {
console.log('sending a friend request') await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations`,
console.log(aUsername) {
const resp = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations`, {
method: "POST", method: "POST",
headers: { 'Content-Type': 'application/json'}, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ body: JSON.stringify({
"receiverUsername": aUsername, receiverUsername: aUsername,
"status": "R" status: "R",
}),
}
)
.then((response) => {
if (!response.ok) {
throw new Error("HTTP " + response.status);
}
}) })
}) .catch((error) => {
.then( x => x.json()) console.log("catch sendFriendRequest: ", error);
// .catch( x => console.log({...x})) });
await fetchFriendshipFull(aUsername); await fetchFriendshipFull(aUsername);
await fetchAll(); await fetchAll();
}; };
const viewAUser = async (aUsername) => { const viewAUser = async (aUsername) => {
console.log('Profile Friend updating userBeingViewed')
usernameBeingViewed = aUsername; usernameBeingViewed = aUsername;
await fetchFriendshipFull(aUsername); await fetchFriendshipFull(aUsername);
console.log('Friendship Status Full')
console.log({...friendshipStatusFull})
}; };
const acceptFriendRequest = async (relationshipId) => { const acceptFriendRequest = async (relationshipId) => {
console.log('accept friend request') await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations/${relationshipId}/accept`,
{
method: "PATCH",
}
)
.then((response) => {
if (!response.ok) {
throw new Error("HTTP " + response.status);
}
})
.catch((error) => {
console.log("catch acceptFriendRequest: ", error);
});
const resp = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations/${relationshipId}/accept`, {
method: "PATCH"})
.then( x => x.json());
await fetchFriendshipFull(usernameBeingViewed); await fetchFriendshipFull(usernameBeingViewed);
await fetchAll(); await fetchAll();
activeTabItem = activeTabItem; activeTabItem = activeTabItem;
}; };
const declineFriendRequest = async (relationshipId) => { const declineFriendRequest = async (relationshipId) => {
console.log('decline friend request') await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations/${relationshipId}/decline`,
{
method: "PATCH",
}
)
.then((response) => {
if (!response.ok) {
throw new Error("HTTP " + response.status);
}
})
.catch((error) => {
console.log("catch declineFriendRequest: ", error);
});
const resp = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations/${relationshipId}/decline`, {
method: "PATCH"})
.then( x => x.json());
await fetchFriendshipFull(usernameBeingViewed); await fetchFriendshipFull(usernameBeingViewed);
await fetchAll(); await fetchAll();
activeTabItem = activeTabItem; activeTabItem = activeTabItem;
}; };
const unfriend = async (relationshipId) => { const unfriend = async (relationshipId) => {
console.log('Unfriend') await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations/${relationshipId}`,
{
const resp = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations/${relationshipId}`, { method: "DELETE",
method: "DELETE"}) }
.then( x => x.json()); )
.then((response) => {
if (!response.ok) {
throw new Error("HTTP " + response.status);
}
})
.catch((error) => {
console.log("catch unfriend: ", error);
});
await fetchFriendshipFull(usernameBeingViewed); await fetchFriendshipFull(usernameBeingViewed);
if (Object.keys(friendshipStatusFull).length === 0) if (Object.keys(friendshipStatusFull).length === 0) {
friendshipStatusFull = undefined; friendshipStatusFull = null;
}
await fetchAll(); await fetchAll();
activeTabItem = activeTabItem; activeTabItem = activeTabItem;
}; };
const blockANonFriendUser = async (aUsername) => { const blockANonFriendUser = async (aUsername) => {
console.log('Block a non friend user, their username') await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations`,
console.log(aUsername) {
let sentFriendRequest = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations`, {
method: "POST", method: "POST",
headers: { 'Content-Type': 'application/json'}, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ body: JSON.stringify({
"receiverUsername": aUsername, receiverUsername: aUsername,
"status": "B" status: "B",
}),
}
)
.then((response) => {
if (!response.ok) {
throw new Error("HTTP " + response.status);
}
}) })
}) .catch((error) => {
.then( x => x.json()) console.log("catch blockANonFriendUser: ", error);
// await fetchBlockedUsers(); });
// await fetchAllUsers();
await fetchAll(); await fetchAll();
usernameBeingViewed = undefined; usernameBeingViewed = null;
friendshipStatusFull = undefined; friendshipStatusFull = null;
activeTabItem = activeTabItem; activeTabItem = activeTabItem;
}; };
const blockAFriend = async (relationshipId) => { const blockAFriend = async (relationshipId) => {
console.log('blocking a friend, the relationshipID') await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations/${relationshipId}/block`,
console.log(relationshipId) {
method: "PATCH"
}
)
.then((response) => {
if (!response.ok) {
throw new Error("HTTP " + response.status);
}
})
.catch((error) => {
console.log("catch blockAFriend: ", error);
});
const resp = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations/${relationshipId}/block`, {method: "PATCH"})
.then( x => x.json() );
console.log('blocked a user response')
console.log({...resp})
// await fetchBlockedUsers();
// await fetchAllUsers();
await fetchAll(); await fetchAll();
usernameBeingViewed = undefined; usernameBeingViewed = null;
friendshipStatusFull = undefined; friendshipStatusFull = null;
// reloads active tab so you get blocked users for example // reloads active tab so you get blocked users for example
activeTabItem = activeTabItem; activeTabItem = activeTabItem;
@@ -213,20 +276,19 @@
const switchTab = async (e) => { const switchTab = async (e) => {
activeTabItem = e.detail; activeTabItem = e.detail;
if (activeTabItem === 'All Users') { if (activeTabItem === "All Users") {
await fetchAllUsers(); await fetchAllUsers_Wrapper();
} else if (activeTabItem === 'My Friends') { } else if (activeTabItem === "My Friends") {
await fetchMyFriendships(); await fetchMyFriendships();
} else if (activeTabItem === 'Friend Requests') { } else if (activeTabItem === "Friend Requests") {
await fetchRequestsReceived(); await fetchRequestsReceived();
} else if (activeTabItem === 'Blocked Users') { } else if (activeTabItem === "Blocked Users") {
await fetchBlockedUsers(); await fetchBlockedUsers();
console.log('fetching blocked users') console.log("fetching blocked users");
} }
if (usernameBeingViewed !== undefined) if (usernameBeingViewed)
fetchFriendshipFull(usernameBeingViewed); fetchFriendshipFull(usernameBeingViewed);
}; };
</script> </script>
@@ -239,7 +301,7 @@
<div class="sidebar-list"> <div class="sidebar-list">
<Tabs items={tabItems} activeItem={activeTabItem} size="small" on:tabChange={switchTab}/> <Tabs items={tabItems} activeItem={activeTabItem} size="small" on:tabChange={switchTab}/>
{#if activeTabItem === 'All Users' && allUsers !== undefined} {#if activeTabItem === 'All Users' && allUsers}
<h3>{activeTabItem}</h3> <h3>{activeTabItem}</h3>
{#if Object.keys(allUsers).length === 0} {#if Object.keys(allUsers).length === 0}
<div class="tip">You are alone on this platform...</div> <div class="tip">You are alone on this platform...</div>
@@ -255,7 +317,7 @@
<div class="status sidebar-item">{aUser.status}</div> <div class="status sidebar-item">{aUser.status}</div>
<br> <br>
{/each} {/each}
{:else if activeTabItem === 'My Friends' && myFriendships !== undefined} {:else if activeTabItem === 'My Friends' && myFriendships}
<h3>{activeTabItem}</h3> <h3>{activeTabItem}</h3>
{#if Object.keys(myFriendships).length === 0} {#if Object.keys(myFriendships).length === 0}
<div class="tip">You don't have any Friends... Yet!</div> <div class="tip">You don't have any Friends... Yet!</div>
@@ -268,7 +330,7 @@
{/if} {/if}
<br> <br>
{/each} {/each}
{:else if activeTabItem === 'Friend Requests' && requestsRecieved !== undefined} {:else if activeTabItem === 'Friend Requests' && requestsRecieved}
<h3>{activeTabItem}</h3> <h3>{activeTabItem}</h3>
{#if Object.keys(requestsRecieved).length === 0} {#if Object.keys(requestsRecieved).length === 0}
<div class="tip">You don't have any Friend Requests</div> <div class="tip">You don't have any Friend Requests</div>
@@ -278,7 +340,7 @@
<div class="status sidebar-item">{aUser.status}</div> <div class="status sidebar-item">{aUser.status}</div>
<br> <br>
{/each} {/each}
{:else if activeTabItem === 'Blocked Users' && blockedUsers !== undefined} {:else if activeTabItem === 'Blocked Users' && blockedUsers}
<h3>{activeTabItem}</h3> <h3>{activeTabItem}</h3>
<!-- seems a little excessive... maybe a lighter way of doing this? doesn't seem like it, i hate it but at least only happens sometimes.default... --> <!-- seems a little excessive... maybe a lighter way of doing this? doesn't seem like it, i hate it but at least only happens sometimes.default... -->
{#if Object.keys(blockedUsers).length === 0} {#if Object.keys(blockedUsers).length === 0}
@@ -294,7 +356,7 @@
<div class="main-display"> <div class="main-display">
{#if usernameBeingViewed !== undefined} {#if usernameBeingViewed}
<DisplayAUser aUsername={usernameBeingViewed}/> <DisplayAUser aUsername={usernameBeingViewed}/>
<div class="buttons-area"> <div class="buttons-area">
@@ -347,7 +409,7 @@
div.top-grid{ div.top-grid{
display: grid; display: grid;
grid-template-columns: repeat(12, 1fr); grid-template-columns: repeat(8, 1fr);
/* max-height: calc(100vh - 30vh); */ /* max-height: calc(100vh - 30vh); */
height: 85vh; height: 85vh;
/* margin: 0; */ /* margin: 0; */
@@ -357,12 +419,15 @@
grid-column: 1 / span 2; grid-column: 1 / span 2;
background: #FB8B24; background: #FB8B24;
padding: 1vw; padding: 1vw;
font-size: smaller;
max-width: 100%; max-width: 100%;
max-height: 100%; max-height: 100%;
box-sizing: border-box; box-sizing: border-box;
-moz-box-sizing: border-box; -moz-box-sizing: border-box;
-webkit-box-sizing: border-box; -webkit-box-sizing: border-box;
border-right: 4px solid #071013; border-right: 4px solid #071013;
border-bottom: 4px solid #071013;
overflow-wrap: break-word;
} }
div.sidebar-item{ div.sidebar-item{

View File

@@ -1,112 +0,0 @@
<script lang="ts">
import { onMount } from 'svelte';
// rename to PotatoCanvas?
let canvas;
// let img;
let loaded = false;
// i feel like they told me not to do this, new Image(), isn't there another way?
// never mind they do seem to do this shit...
// no idea if this should be in onMount...
const img = new Image();
img.src = 'img/potato_logo.png';
img.onload = () => {
loaded = true;
// not sure if i'll use this...
}
// $: scaleRatio = window.innerWidth / 10;
$: scaleRatio = 30;
$: nPotoatoRows = Math.floor(window.innerHeight / 200);
$: nPotoatoCols = Math.floor(window.innerWidth / 200);
// $: spacing = (canvas.height - (img.height / scaleRatio * (nPotoatoRows - 1) )) / nPotoatoRows;
// apparently i might need to move all my reactive statements outside the onMount... not sure why...
onMount(() => {
// in this on mount we will set the canvas and the img
const ctx = canvas.getContext('2d');
// let frame = requestAnimationFrame(loop);
ctx.width = window.innerWidth;
ctx.height = window.innerHeight;
// console.log(nPotoatoCols);
// img = fetch('img/potato_logo.png');
// Moving the IMG stuff from her out of mount
// let nPotoatoRows = 4;
// $: nPotoatoRows = Math.floor(canvas.height / 200);
let spacing = (canvas.height - (img.height / scaleRatio * (nPotoatoRows - 1) )) / nPotoatoRows;
// $: spacing = (canvas.height - (img.height / scaleRatio * (nPotoatoRows - 1) )) / nPotoatoRows;
// i prolly need a number of potatos X and Y vars
// i could do it so there are more potatos than can fit on the screen, translate them over, and then after some point
// shift them all back to the next position they would be in, so it looks like they keep going to infinity
// let dx = 1.5;
let dx = 1;
// let dy = -0.5;
let dy = -1;
// let startX = spacing;
// let startY = spacing;
// let startX = 0;
// let startY = 0;
let startX = -(spacing * 2.5);
let startY = -(spacing * 2.5);
let x = startX;
let y = startY;
let frame = requestAnimationFrame(loop);
// i don't think i need t...
function loop(t) {
// yea ok a loop in a loop in a loop, horrible idea...
ctx.clearRect(0, 0, canvas.width, canvas.height);
// this has to be at the end, no?
frame = requestAnimationFrame(loop);
// if (x > 900) {
// x = startX;
// y = startY;
// }
// else {
// x += dx;
// y += dy;
// }
for (let i = 0; i < 20; i++) {
for (let j = 0; j < 10; j++) {
// ctx.drawImage(img, x + (i * spacing * 2), y + (j * spacing), img.width / scaleRatio, img.height / scaleRatio);
ctx.drawImage(img, x + (i * spacing), y + (j * spacing), img.width / scaleRatio, img.height / scaleRatio);
}
}
}
return () => {
cancelAnimationFrame(frame);
};
});
</script>
<canvas
bind:this={canvas}
width={window.innerWidth}
height={window.innerHeight}
></canvas>
<style>
canvas {
width: 100%;
height: 100%;
background-color: #666;
}
</style>

View File

@@ -2,29 +2,22 @@
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import GenerateUserDisplay from './GenerateUserDisplay.svelte'; import GenerateUserDisplay from './GenerateUserDisplay.svelte';
import { fetchUser } from "../pieces/utils";
export let aUsername; export let aUsername;
let user; let aUser;
onMount( async() => { onMount( async() => {
// console.log('Display aUser username: '+ aUsername) aUser = await fetchUser(aUsername);
user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user?username=${aUsername}`)
.then( (x) => x.json() );
}) })
export const updateUser = async() => { $: aUsername, fetchUser(aUsername);
user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user?username=${aUsername}`)
.then( (x) => x.json() );
};
$: aUsername, updateUser();
</script> </script>
<div class="background-pages"> <div class="background-pages">
{#if user !== undefined} {#if aUser}
<GenerateUserDisplay user={user}/> <GenerateUserDisplay user={aUser}/>
{:else} {:else}
<h2>Sorry</h2> <h2>Sorry</h2>
<div>Failed to load user {aUsername}</div> <div>Failed to load user {aUsername}</div>

View File

@@ -62,11 +62,11 @@
<!-- is this if excessive? --> <!-- is this if excessive? -->
<div class="outer"> <div class="outer">
{#if user !== undefined} {#if user}
<main> <main>
<!-- <img class="icon" src="img/default_user_icon.png" alt="default user icon"> --> <!-- <img class="icon" src="img/default_user_icon.png" alt="default user icon"> -->
<!-- <img class="icon" src="{user.image_url}" alt="default user icon"> --> <!-- <img class="icon" src="{user.image_url}" alt="default user icon"> -->
<img class="avatar" src="{avatar}" alt="default user icon"> <img class="avatar" src="{avatar}" alt="user avatar">
<div class="error">{errors.avatar}</div> <div class="error">{errors.avatar}</div>
<div class="username">{user.username}</div> <div class="username">{user.username}</div>
<div class="rank">Rank: <div class="rank">Rank:
@@ -153,7 +153,7 @@
} }
.error{ .error{
font-size: 0.8em; font-size: 1vw;
font-weight: bold; font-weight: bold;
color: red; color: red;
} }

View File

@@ -9,12 +9,23 @@
$: current = $location; $: current = $location;
let handleClickLogout = async () => { let handleClickLogout = 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',
}
)
.then((response) => {
if (!response.ok) {
throw new Error("HTTP " + response.status);
}
}) })
.then( () => push('/') ) .catch((error) => {
console.log('clicked logout header') console.log("catch handleClickLogout: ", error);
});
push('/');
}; };
</script> </script>
@@ -43,9 +54,9 @@
background-color: #444; background-color: #444;
border-color: #071013; border-color: #071013;
color: white; color: white;
font-family: "Bit5x3"; font-family: "PressStart2P";
border-width: 2px; border-width: 2px;
font-size: 2vw; font-size: 1vw;
} }
@@ -53,9 +64,9 @@
background-color: #008c8c; background-color: #008c8c;
border-color: #071013; border-color: #071013;
color: white; color: white;
font-family: "Bit5x3"; font-family: "PressStart2P";
border-width: 2px; border-width: 2px;
font-size: 2vw; font-size: 1vw;
} }
.header { .header {

View File

@@ -1,7 +1,12 @@
export async function fetchAvatar(username: string) export async function fetchAvatar(username?: string)
{ {
return fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar?username=${username}`) let url = `http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar`;
if (username) {
url += `?username=${username}`;
}
return fetch(url)
.then((response) => { .then((response) => {
if (!response.ok) { if (!response.ok) {
throw new Error("HTTP " + response.status); throw new Error("HTTP " + response.status);
@@ -17,18 +22,20 @@ export async function fetchAvatar(username: string)
}); });
} }
export async function fetchUser() export async function fetchUser(username?: string)
{ {
return fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`) let url = `http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`;
if (username) {
url += `?username=${username}`;
}
return fetch(url)
.then((response) => { .then((response) => {
if (!response.ok) { if (!response.ok) {
throw new Error("HTTP " + response.status); throw new Error("HTTP " + response.status);
} }
return response.json(); return response.json();
}) })
.then((body) => {
return body;
})
.catch((error) => { .catch((error) => {
console.log("catch fetchUser: ", error); console.log("catch fetchUser: ", error);
return null; return null;
@@ -44,9 +51,6 @@ export async function fetchAllUsers()
} }
return response.json(); return response.json();
}) })
.then((body) => {
return body;
})
.catch((error) => { .catch((error) => {
console.log("catch fetchAllUsers: ", error); console.log("catch fetchAllUsers: ", error);
return []; return [];

View File

@@ -7,95 +7,40 @@ import { wrap } from 'svelte-spa-router/wrap'
import Game from '../pages/game/Game.svelte'; import Game from '../pages/game/Game.svelte';
import Ranking from '../pages/game/Ranking.svelte'; import Ranking from '../pages/game/Ranking.svelte';
import GameSpectator from '../pages/game/GameSpectator.svelte'; import GameSpectator from '../pages/game/GameSpectator.svelte';
import { fetchUser } from "../pieces/utils";
async function checkLogin(detail) {
const user = await fetchUser();
if (!user || !user.username) {
return false;
}
else {
return true;
}
}
export const primaryRoutes = { export const primaryRoutes = {
'/': SplashPage, '/': SplashPage,
'/2fa': TwoFactorAuthentication, '/2fa': TwoFactorAuthentication,
'/game': wrap({ '/game': wrap({
component: Game, component: Game,
conditions: [ conditions: [checkLogin]
async(detail) => {
const user = await fetch('http://' + process.env.WEBSITE_HOST + ":" + process.env.WEBSITE_PORT + '/api/v2/user')
.then((resp) => resp.json())
console.log('in /profile what is in user')
console.log(user)
if (user && user.username)
return true;
else
return false;
}
]
}), }),
'/spectator': wrap({ '/spectator': wrap({
component: GameSpectator, component: GameSpectator,
conditions: [ conditions: [checkLogin]
async(detail) => {
const user = await fetch('http://' + process.env.WEBSITE_HOST + ":" + process.env.WEBSITE_PORT + '/api/v2/user')
.then((resp) => resp.json())
console.log('in /profile what is in user')
console.log(user)
if (user && user.username)
return true;
else
return false;
}
]
}), }),
'/ranking': wrap({ '/ranking': wrap({
component: Ranking, component: Ranking,
conditions: [ conditions: [checkLogin]
async(detail) => {
const user = await fetch('http://' + process.env.WEBSITE_HOST + ":" + process.env.WEBSITE_PORT + '/api/v2/user')
.then((resp) => resp.json())
console.log('in /profile what is in user')
console.log(user)
if (user && user.username)
return true;
else
return false;
}
]
}), }),
'/profile': wrap({ '/profile': wrap({
component: ProfilePage, component: ProfilePage,
conditions: [ conditions: [checkLogin]
async(detail) => {
const user = await fetch('http://' + process.env.WEBSITE_HOST + ":" + process.env.WEBSITE_PORT + '/api/v2/user')
.then((resp) => resp.json())
console.log('in /profile what is in user')
console.log(user)
if (user && user.username)
return true;
else
return false;
}
]
}), }),
'/profile/*': wrap({ '/profile/*': wrap({
component: ProfilePage, component: ProfilePage,
conditions: [ conditions: [checkLogin]
async(detail) => {
const user = await fetch('http://' + process.env.WEBSITE_HOST + ":" + process.env.WEBSITE_PORT + '/api/v2/user')
.then((resp) => resp.json())
console.log('in /profile/* what is in user')
console.log(user)
if (user && user.username)
return true;
else
return false;
}
]
}), }),
'/unauthorized-access': UnauthorizedAccessPage, '/unauthorized-access': UnauthorizedAccessPage,
'*': NotFound '*': NotFound