pull fixed conflicts

This commit is contained in:
simplonco
2023-01-12 00:52:43 +01:00
25 changed files with 245 additions and 24799 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -1,9 +1,6 @@
<script lang="ts">
// routing
// may not need {link} here
import Router, { link, replace } from "svelte-spa-router";
import Router, { replace } from "svelte-spa-router";
import { primaryRoutes } from "./routes/primaryRoutes.js";
// import primaryRoutes from "./routes/primaryRoutes.svelte";
const conditionsFailed = (event) => {
console.error('conditionsFailed event', event.detail);
@@ -15,6 +12,5 @@
</script>
<!-- <h1>Testing</h1> -->
<Router routes={primaryRoutes} on:conditionsFailed={conditionsFailed}/>

View File

@@ -4,14 +4,7 @@
<h1>We are sorry!</h1>
<p>This isn't a url that we use.</p>
<!-- <img src="https://picsum.photos/id/685/800/400" alt="img"> -->
<p>Go home you're drunk.</p>
<a href="/" use:link>
<h2>Take me home →</h2>
</a>
<style>
/* img {
width: 100%;
} */
</style>
</a>

View File

@@ -74,7 +74,6 @@
overflow-y: hidden;
} */
header {
/* didn't work... */
overflow-y: hidden;

View File

@@ -1,9 +1,10 @@
<script lang="ts">
import { onMount, onDestroy } from "svelte";
import Header from '../../pieces/Header.svelte';
import { fade, fly } from 'svelte/transition';
import Header from '../../pieces/Header.svelte';
import { fetchAvatar } from "../../pieces/utils";
import * as pong from "./client/pong";
import { gameState } from "./client/ws";
@@ -12,6 +13,9 @@
let user;
let allUsers;
let playerOneAvatar;
let playerTwoAvatar;
//Game's stuff
const options = new pong.InitOptions();
const gameAreaId = "game_area";
@@ -26,9 +30,10 @@
let showWaitPage = false;
let invitations = [];
let watchGameStateInterval;
const watchGameStateIntervalRate = 142;
let watchMatchStartInterval;
const watchMatchStartIntervalRate = 111;
onMount( async() => {
user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`)
@@ -39,6 +44,7 @@
})
onDestroy( async() => {
clearInterval(watchMatchStartInterval);
clearInterval(watchGameStateInterval);
pong.destroy();
})
@@ -76,6 +82,7 @@
showWaitPage = false;
if (response.ok && token)
{
watchMatchStartInterval = setInterval(watchMatchStart, watchMatchStartIntervalRate);
watchGameStateInterval = setInterval(watchGameState, watchGameStateIntervalRate);
pong.init(matchOptions, options, gameAreaId, token);
hiddenGame = false;
@@ -106,6 +113,7 @@
console.log(invitation);
if (invitation.token)
{
watchMatchStartInterval = setInterval(watchMatchStart, watchMatchStartIntervalRate);
watchGameStateInterval = setInterval(watchGameState, watchGameStateIntervalRate);
options.playerOneUsername = invitation.playerOneUsername;
options.playerTwoUsername = invitation.playerTwoUsername;
@@ -117,16 +125,24 @@
}
}
async function watchMatchStart()
{
if (gameState.matchStarted)
{
clearInterval(watchMatchStartInterval);
playerOneAvatar = await fetchAvatar(gameState.playerOneUsername);
playerTwoAvatar = await fetchAvatar(gameState.playerTwoUsername);
gameState.matchStarted = gameState.matchStarted; // trigger Svelte reactivity
}
}
const watchGameState = () => {
console.log("watchGameState");
if (gameState) { // trigger Svelte reactivity
gameState.matchStarted = gameState.matchStarted;
gameState.matchEnded = gameState.matchEnded;
gameState.matchAborted = gameState.matchAborted;
}
if (gameState.matchAborted || gameState.matchEnded)
{
clearInterval(watchGameStateInterval);
gameState.matchEnded = gameState.matchEnded; // trigger Svelte reactivity
gameState.matchAborted = gameState.matchAborted; // trigger Svelte reactivity
console.log("watchGameState, end");
setTimeout(() => {
resetPage();
@@ -176,6 +192,7 @@
}
function leaveMatch() {
clearInterval(watchMatchStartInterval);
clearInterval(watchGameStateInterval);
resetPage();
};
@@ -213,6 +230,14 @@
</div>
{#if !hiddenGame}
{#if gameState.matchStarted}
<div class="div_game">
<img class="avatar" src="{playerOneAvatar}" alt="player one avatar">
'{gameState.playerOneUsername}' VS '{gameState.playerTwoUsername}'
<img class="avatar" src="{playerTwoAvatar}" alt="player two avatar">
</div>
{/if}
{#if gameState.matchStarted && !gameState.matchEnded}
<div class="div_game">
<button class="pong_button" on:click={leaveMatch}>forfeit</button>
@@ -356,5 +381,11 @@ canvas {
font-size: x-large;
padding: 10px;
}
.avatar {
min-height: 100px;
min-width: 100px;
max-width: 100px;
max-height: 100px;
}
</style>

View File

@@ -1,10 +1,12 @@
<script lang="ts">
import { onMount, onDestroy } from "svelte";
import Header from '../../pieces/Header.svelte';
import MatchListElem from "../../pieces/MatchListElem.svelte";
import { fade, fly } from 'svelte/transition';
import Header from '../../pieces/Header.svelte';
import MatchListElem from "../../pieces/MatchListElem.svelte";
import type { Match } from "../../pieces/Match";
import { fetchAvatar } from "../../pieces/utils";
import * as pongSpectator from "./client/pongSpectator";
import { gameState } from "./client/ws";
@@ -13,14 +15,17 @@
let user;
let allUsers;
//Game's stuff client side only
let playerOneAvatar;
let playerTwoAvatar;
//Game's stuff
const gameAreaId = "game_area";
let sound = "off";
let matchList = [];
//html boolean for pages
let hiddenGame = true;
let matchList: Match[] = [];
let watchGameStateInterval;
const watchGameStateIntervalRate = 142;
@@ -39,22 +44,27 @@
pongSpectator.destroy();
})
async function initGameSpectator(gameSessionId: string, matchOptions: pongSpectator.MatchOptions)
async function initGameSpectator(match: Match)
{
watchGameStateInterval = setInterval(watchGameState, watchGameStateIntervalRate);
pongSpectator.init(matchOptions, sound, gameAreaId, gameSessionId);
pongSpectator.init(match.gameOptions, sound, gameAreaId, match.gameServerIdOfTheMatch);
// Users avatar
gameState.playerOneUsername = match.playerOneUsername;
gameState.playerTwoUsername = match.playerTwoUsername;
playerOneAvatar = await fetchAvatar(gameState.playerOneUsername);
playerTwoAvatar = await fetchAvatar(gameState.playerTwoUsername);
hiddenGame = false;
};
const watchGameState = () => {
console.log("watchGameState")
if (gameState) { // trigger Svelte reactivity
gameState.matchStarted = gameState.matchStarted;
gameState.matchEnded = gameState.matchEnded;
gameState.matchAborted = gameState.matchAborted;
}
// gameState.matchStarted = gameState.matchStarted; // trigger Svelte reactivity
if (gameState.matchAborted || gameState.matchEnded)
{
gameState.matchEnded = gameState.matchEnded; // trigger Svelte reactivity
gameState.matchAborted = gameState.matchAborted; // trigger Svelte reactivity
clearInterval(watchGameStateInterval);
console.log("watchGameState, end")
setTimeout(() => {
@@ -80,7 +90,6 @@
.then( x => x.json() );
};
</script>
<!-- -->
@@ -102,6 +111,12 @@
</div>
{#if !hiddenGame}
<div class="div_game">
<img class="avatar" src="{playerOneAvatar}" alt="player one avatar">
'{gameState.playerOneUsername}' VS '{gameState.playerTwoUsername}'
<img class="avatar" src="{playerTwoAvatar}" alt="player two avatar">
</div>
{#if !gameState.matchEnded}
<div class="div_game">
<button class="pong_button" on:click={leaveMatch}>leave</button>
@@ -127,7 +142,7 @@
{#if matchList.length !== 0}
<menu id="match_list">
{#each matchList as match}
<MatchListElem match={match} on:click={(e) => initGameSpectator(match.gameServerIdOfTheMatch, match.gameOptions)} />
<MatchListElem match={match} on:click={(e) => initGameSpectator(match)} />
{/each}
</menu>
{:else}
@@ -195,10 +210,15 @@ canvas {
font-size: x-large;
padding: 10px;
}
#match_list {
font-family: 'Courier New', Courier, monospace;
font-size: large;
}
.avatar {
min-height: 100px;
min-width: 100px;
max-width: 100px;
max-height: 100px;
}
</style>

View File

@@ -3,7 +3,7 @@ import * as c from "./constants.js"
import * as en from "../shared_js/enums.js"
import { GameArea } from "./class/GameArea.js";
import { GameComponentsClient } from "./class/GameComponentsClient.js";
import { socket, resetGameState } from "./ws.js";
import { socket, gameState } from "./ws.js";
import { initAudio } from "./audio.js";
import type { InitOptions } from "./class/InitOptions.js";
@@ -57,5 +57,5 @@ export function destroyBase()
}
setGc(null);
setMatchOptions(null);
resetGameState();
gameState.resetGameState();
}

View File

@@ -8,7 +8,6 @@ import { initBase, destroyBase, computeMatchOptions } from "./init.js";
export { computeMatchOptions } from "./init.js";
export { MatchOptions } from "../shared_js/enums.js"
/* TODO: A way to delay the init of variables, but still use "const" not "let" ? */
import { pong, gc } from "./global.js"
import { setStartFunction } from "./global.js"

View File

@@ -10,16 +10,22 @@ import { muteFlag, soundRoblox } from "./audio.js"
import { sleep } from "./utils.js";
import { Vector, VectorInteger } from "../shared_js/class/Vector.js";
export const gameState = {
matchStarted: false,
matchEnded: false,
matchAborted: false
}
export function resetGameState() {
gameState.matchStarted = false;
gameState.matchEnded = false;
gameState.matchAborted = false;
class GameState {
matchStarted: boolean;
matchEnded: boolean;
matchAborted: boolean;
playerOneUsername: string;
playerTwoUsername: string;
constructor() {
this.resetGameState();
}
resetGameState() {
this.matchStarted = false;
this.matchEnded = false;
this.matchAborted = false;
this.playerOneUsername = "";
this.playerTwoUsername = "";
}
}
class ClientInfo {
@@ -39,6 +45,7 @@ class ClientInfoSpectator {
const wsUrl = "ws://" + process.env.WEBSITE_HOST + ":" + process.env.WEBSITE_PORT + "/pong";
export let socket: WebSocket;
export const gameState = new GameState();
export const clientInfo = new ClientInfo();
export const clientInfoSpectator = new ClientInfoSpectator(); // WIP, could refactor this
@@ -85,6 +92,8 @@ function preMatchListener(this: WebSocket, event: MessageEvent)
break;
case en.EventTypes.matchmakingComplete:
clientInfo.side = (<ev.EventMatchmakingComplete>data).side;
gameState.playerOneUsername = (<ev.EventMatchmakingComplete>data).playerOneUsername;
gameState.playerTwoUsername = (<ev.EventMatchmakingComplete>data).playerTwoUsername;
if (clientInfo.side === en.PlayerSide.left)
{
clientInfo.racket = gc.playerLeft;

View File

@@ -18,10 +18,13 @@ export class EventAssignId extends ServerEvent {
}
export class EventMatchmakingComplete extends ServerEvent {
side: en.PlayerSide;
constructor(side: en.PlayerSide) {
side: en.PlayerSide = en.PlayerSide.noSide;
playerOneUsername: string;
playerTwoUsername: string;
constructor(playerOneUsername: string, playerTwoUsername: string) {
super(en.EventTypes.matchmakingComplete);
this.side = side;
this.playerOneUsername = playerOneUsername;
this.playerTwoUsername = playerTwoUsername;
}
}

View File

@@ -2,7 +2,7 @@
import { onMount } from 'svelte';
import GenerateUserDisplay from '../../pieces/GenerateUserDisplay.svelte';
import { push } from 'svelte-spa-router';
import Chat from '../../pieces/chat/Chat.svelte';
@@ -19,13 +19,11 @@
<Chat color="bisque"/>
<!-- is this if excessive? -->
<div class="outer">
<!-- OHHHH i could use #await instead of if and have an nice loading page! -->
{#if user !== undefined}
<GenerateUserDisplay user={user} primary={true}/>
<GenerateUserDisplay user={user}/>
<button on:click={() => (push('/profile/settings'))}>Profile Settings</button>
{:else}
<!-- might be unnecessary since you can't access the page without fetching the user -->
<h2>Sorry</h2>
<div>Failed to load current</div>
{/if}
@@ -36,140 +34,7 @@
div.outer{
max-width: 960px;
margin: 40px auto;
}
/* The main part */
main{
max-width: 960px;
margin: 40px auto;
text-align: center;
}
/* Normal CSS stuff */
.avatar{
max-width: 150px;
/* padding: 5px; */
}
/* The variable rich section */
section.main-stats{
max-width: 600px;
margin: 40px auto;
text-align: center;
/* i think i want to use a grid? */
display: grid;
grid-template-columns: repeat(3, 1fr);
/* not sure about this, maybe top should be larger? */
grid-template-rows: repeat(3, 1fr);
}
/* the stuff in the grid*/
section.main-stats h4{
grid-column: 1 / span 3;
}
div.username{
font-size: 1.5em;
font-weight: bold;
padding-bottom: 5px;
}
div.rank {
/* color: black; */
font-size: 1.2em;
font-weight: bold;
}
/* Glittery Star Stuff */
:root {
--purple: rgb(123, 31, 162);
--violet: rgb(103, 58, 183);
--pink: rgb(244, 143, 177);
/* make shit gold? */
}
@keyframes background-pan {
from {
background-position: 0% center;
}
to {
background-position: -200% center;
}
}
@keyframes scale {
from, to {
transform: scale(0);
}
50% {
transform: scale(1);
}
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(180deg);
}
}
div > .glitter {
display: inline-block;
position: relative;
}
div > .glitter > .glitter-star {
--size: clamp(20px, 1.5vw, 30px);
animation: scale 700ms ease forwards;
display: block;
height: var(--size);
left: var(--star-left);
position: absolute;
top: var(--star-top);
width: var(--size);
}
div > .glitter > .glitter-star > svg {
animation: rotate 1000ms linear infinite;
display: block;
opacity: 0.7;
}
div > .glitter > .glitter-star > svg > path {
fill: var(--violet);
}
div > .glitter > .glitter-text {
animation: background-pan 3s linear infinite;
/* background-image: linear-gradient( */
background: linear-gradient(
to right,
var(--purple),
var(--violet),
var(--pink),
var(--purple)
);
background-size: 200%;
/* Keep these for Safari and chrome */
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
/* These are for Firefox */
background-clip: text;
color: transparent;
white-space: nowrap;
}
</style>

View File

@@ -177,7 +177,7 @@
console.log('Block a non friend user, their username')
console.log(aUsername)
sentFriendRequest = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations`, {
let sentFriendRequest = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations`, {
method : "POST",
headers: { 'Content-Type': 'application/json'},
body: JSON.stringify({

View File

@@ -1,5 +1,4 @@
<script lang="ts">
import Header from "../../pieces/Header.svelte";
import Router from "svelte-spa-router";
import { profileRoutes, prefix } from "../../routes/profileRoutes.js";

View File

@@ -3,8 +3,9 @@
import Card from '../../pieces/Card.svelte';
import {onMount} from 'svelte';
import { push } from 'svelte-spa-router';
import Button from '../../pieces/Button.svelte';
import { fetchAvatar } from "../../pieces/utils";
let user;
let avatar, newAvatar;
@@ -16,40 +17,21 @@
const errors = { username: '', checkbox: '', avatar: ''};
let success = {username: '', avatar: '' };
onMount( async() => {
user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`)
.then( (x) => x.json() );
// do a .catch?
onMount( async() => {
user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`)
.then( (x) => x.json() );
// do a .catch?
if (user === undefined) {
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
nameTmp = user.username;
console.log(user.username)
if (user === undefined) {
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
nameTmp = user.username;
set.tfa = user.isEnabledTwoFactorAuth;
set.tfa = user.isEnabledTwoFactorAuth;
// tmp
// console.log('this is what is in the avatar before fetch')
// console.log(avatar)
await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar`, {method: "GET"})
.then(response => {return response.blob()})
.then(data => {
const url = URL.createObjectURL(data);
avatar = url;
})
.catch(() => errors.avatar = 'Sorry your avatar could not be loaded' );
// .then(() => errors.avatar = '' ) // unnecessary i think cuz in on mount...
// tmp
// console.log('this is what is in the avatar')
// console.log(avatar)
// console.log('this is what is in the NEW Avatar')
// console.log(newAvatar)
})
avatar = await fetchAvatar(user.username);
})
const settingsHandler = async() => {
// I don't really care which i use at this point...
@@ -91,39 +73,33 @@
// .then(() => console.log('successful sub of new settings'))
};
const uploadAvatar = async() => {
errors.avatar = '';
if (newAvatar === undefined) {
errors.avatar = 'You need to pick a file.'
return;
}
const data = new FormData();
data.append("file", newAvatar[0]);
const uploadAvatar = async() => {
errors.avatar = '';
if (newAvatar === undefined) {
errors.avatar = 'You need to pick a file.'
return;
}
const data = new FormData();
data.append("file", newAvatar[0]);
// tmp
console.log(data);
// tmp
console.log(data);
const responseWhenChangeAvatar = fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar`,
{
method : 'POST',
body : data,
})
const responseFromServer = await responseWhenChangeAvatar;
if (responseFromServer.ok === true) {
uploadAvatarSuccess = true;
success.avatar = 'Your avatar has been updated';
}
else {
errors.avatar = responseFromServer.statusText;
}
await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar`, {method: "GET"})
.then(response => {return response.blob()})
.then(data => {
const url = URL.createObjectURL(data);
avatar = url;
const responseWhenChangeAvatar = fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar`,
{
method : 'POST',
body : data,
})
.catch(() => errors.avatar = 'Sorry your avatar could not be loaded' );
const responseFromServer = await responseWhenChangeAvatar;
if (responseFromServer.ok === true) {
uploadAvatarSuccess = true;
success.avatar = 'Your avatar has been updated';
}
else {
errors.avatar = responseFromServer.statusText;
}
avatar = await fetchAvatar(user.username);
}
</script>

View File

@@ -39,8 +39,7 @@
{#if user !== undefined}
<GenerateUserDisplay user={user} primary={false}/>
<!-- <GenerateUserDisplay user={user} primary={true}/> -->
<GenerateUserDisplay user={user}/>
{:else}
<h2>Sorry</h2>
<div>Failed to load user {aUsername}</div>

View File

@@ -2,9 +2,9 @@
import { onMount } from 'svelte';
import { fetchAvatar } from "./utils";
export let user;
export let primary; // kinda useless, not sure what i was going for... Might be userful after all
let rank = '';
let avatar;
// avatar needs to be updated!!!
@@ -12,28 +12,10 @@
// add errors
let errors = {avatar: ''};
onMount( async() => {
// console.log('Generate User Display, on mount ' + user.username)
if (primary) {
await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar`, {method: "GET"})
.then(response => {return response.blob()})
.then(data => {
const url = URL.createObjectURL(data);
avatar = url;
})
.catch(() => errors.avatar = 'Sorry your avatar could not be loaded' );
// console.log('avatar: ')
// console.log(avatar)
} else {
await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar?username=${user.username}`, {method: "GET"})
.then(response => {return response.blob()})
.then(data => {
const url = URL.createObjectURL(data);
avatar = url;
})
.catch(() => errors.avatar = 'Sorry your avatar could not be loaded' );
}
})
onMount( async() => {
// console.log('Generate User Display, on mount ' + user.username)
avatar = await fetchAvatar(user.username);
})
/**** THIS IS BASICALLY ALL THE RANK LOGIC ERIC HAS MADE ****/

View File

@@ -3,9 +3,11 @@
import { location } from 'svelte-spa-router';
// no need, it's just for links
import active from 'svelte-spa-router/active'
// or i could leave them all and not display if they're active?
$: current = $location;
let handleClickLogout = async () => {
await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/auth/logout`, {
@@ -23,16 +25,13 @@
<img src="/img/potato_logo.png" alt="Potato Pong Logo" on:click={() => (push('/'))}>
<h1>Potato Pong</h1>
<nav>
<button on:click={() => (push('/game'))}>Play</button>
<button on:click={() => (push('/spectator'))}>Spectate</button>
<button on:click={() => (push('/ranking'))}>Ranking</button>
{#if $location !== '/profile'}
<button on:click={() => (push('/profile'))}>My Profile</button>
{:else if $location === '/profile'}
<button on:click={() => (push('/profile/settings'))}>Settings</button>
{/if}
<button on:click={() => (push('/profile/friends'))}>Friends</button>
<button on:click={handleClickLogout}>Log Out</button>
<button class:selected="{current === '/game'}" on:click={() => (push('/game'))}>Play</button>
<button class:selected="{current === '/spectator'}" on:click={() => (push('/spectator'))}>Spectate</button>
<button class:selected="{current === '/ranking'}" on:click={() => (push('/ranking'))}>Ranking</button>
<button class:selected="{current === '/profile'}" on:click={() => (push('/profile'))}>My Profile</button>
<!-- <button class:selected="{current === '/profile/settings'}" on:click={() => (push('/profile/settings'))}>Settings</button> -->
<button class:selected="{current === '/profile/friends'}" on:click={() => (push('/profile/friends'))}>Friends</button>
<button on:click={handleClickLogout}>Log Out</button>
</nav>
</header>
@@ -54,6 +53,13 @@
}
.selected {
background-color: chocolate;
text-decoration: underline;
/* TMP so it's obvious but we need to pick good colors */
}
/* There is a bunch of unncessary shit in here... why so many flex grids, why is everything the same class? just seemed easier but... */

View File

@@ -0,0 +1,10 @@
import type { MatchOptions } from "../pages/game/client/pongSpectator";
export { MatchOptions } from "../pages/game/client/pongSpectator";
export class Match {
gameServerIdOfTheMatch: string;
gameOptions: MatchOptions;
playerOneUsername: string;
playerTwoUsername: string;
}

View File

@@ -1,14 +1,9 @@
<script lang="ts">
import { onMount, onDestroy } from "svelte";
import { MatchOptions } from "../pages/game/client/pongSpectator";
import { Match, MatchOptions} from "./Match";
export let match: {
gameServerIdOfTheMatch: string,
gameOptions: MatchOptions,
playerOneUsername: string,
playerTwoUsername: string
};
export let match: Match;
let matchOptionsString = "";
@@ -32,7 +27,7 @@
<li>
<button on:click>
"{match.playerOneUsername}" VS "{match.playerTwoUsername}"
'{match.playerOneUsername}' VS '{match.playerTwoUsername}'
<br/> [{matchOptionsString}]
</button>
</li>

View File

@@ -0,0 +1,17 @@
export async function fetchAvatar(username: string)
{
return fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar?username=${username}`)
.then((response) => {
if (!response.ok) {
throw new Error("Avatar not retrieved");
}
return response.blob();
})
.then((blob) => {
return URL.createObjectURL(blob);
})
.catch((error) => {
console.log("catch fetchAvatar: ", error);
});
}

View File

@@ -9,7 +9,6 @@ import Ranking from '../pages/game/Ranking.svelte';
import GameSpectator from '../pages/game/GameSpectator.svelte';
export const primaryRoutes = {
'/': SplashPage,
'/2fa': TwoFactorAuthentication,