much progress on layout the foundations of the Friendship page in the front, also refactored some code to reuse displaying a users profile info
This commit is contained in:
@@ -50,6 +50,7 @@ export class UsersController {
|
||||
@Get('search')
|
||||
findOneByUsername(@Query('username') username: string, @Req() req) {
|
||||
const user : User = req.user;
|
||||
console.log('searching for user' + user.username);
|
||||
return this.usersService.findOneByUsername(user.id.toString(),username);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
<script lang="ts">
|
||||
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
import { location } from 'svelte-spa-router';
|
||||
import GenerateUserDisplay from './GenerateUserDisplay.svelte';
|
||||
|
||||
// using location won't work cuz i do a fetch but i don't change the page fragment, so means nothing to location...
|
||||
|
||||
// this is how you access /:first for example
|
||||
// export let params = {}
|
||||
// <p>Your name is: <b>{params.first}</b> <b>{#if params.last}{params.last}{/if}</b></p>
|
||||
|
||||
// If i export these vars, maybe as an nice tidy object, i could pass whatever i like to them
|
||||
// The current user, some other user, whatever, and thus reuse this Componente for the user and their friends or whatever
|
||||
// will have to coordinate with Back, will know more once the Game stats are in the back
|
||||
// wait maybe this won't work, cuz like it's still going through a route, i would have to update a Store Var each time...
|
||||
// not sure if that's what i want...
|
||||
|
||||
|
||||
// maybe the rank is determined dynamically just in the front based on win loss ratio or something no one cares about
|
||||
// why bother storing that shit in the back...
|
||||
// maybe i need a Rank.svelte component
|
||||
// ohhh i could make above a certain rank glitter! like that CSS tutorial showed me!
|
||||
|
||||
export let aUsername;
|
||||
|
||||
let user;
|
||||
let rank = '';
|
||||
let avatar;
|
||||
|
||||
// i think i don't need to do this once i sort out the {wrap} conditions: in theory i could pass values to the Route
|
||||
// once the async authentication check is done
|
||||
onMount( async() => {
|
||||
console.log('Display aUser username: '+ aUsername)
|
||||
// http://transcendance:8080/api/v2/user?username=NomDuUserATrouver
|
||||
user = await fetch(`http://transcendance:8080/api/v2/user?username=${aUsername}`)
|
||||
.then( (x) => x.json() );
|
||||
|
||||
console.log('Display a user: ' + user.username)
|
||||
|
||||
|
||||
// console.log('profile display did my fetch')
|
||||
// should i be updating the userStore or is that unnecessary?
|
||||
|
||||
if (user.loseGame > user.winGame) {
|
||||
rank = 'Bitch Ass Loser!'
|
||||
} else if (user.loseGame === user.winGame) {
|
||||
rank = 'Fine i guess...'
|
||||
} else {
|
||||
rank = 'Yea you da Boss!'
|
||||
}
|
||||
|
||||
await fetch("http://transcendance:8080/api/v2/user/avatar", {method: "GET"})
|
||||
.then(response => {return response.blob()})
|
||||
.then(data => {
|
||||
const url = URL.createObjectURL(data);
|
||||
avatar = url;
|
||||
});
|
||||
|
||||
// tmp
|
||||
// console.log('mounted Profile Display')
|
||||
// console.log(user);
|
||||
|
||||
|
||||
})
|
||||
|
||||
// Glittery Stars and such for Rank
|
||||
|
||||
let index = 0, interval = 1000;
|
||||
|
||||
const rand = (min, max) =>
|
||||
Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
|
||||
// it's unhappy that "star" isn't typeset, no idea what to do about it...
|
||||
const animate = (star) => {
|
||||
// the if seems to have fixed the type issue
|
||||
if (star) {
|
||||
star.style.setProperty("--star-left", `${rand(-10, 100)}%`);
|
||||
star.style.setProperty("--star-top", `${rand(-40, 80)}%`);
|
||||
|
||||
star.style.animation = "none";
|
||||
star.offsetHeight;
|
||||
star.style.animation = "";
|
||||
}
|
||||
}
|
||||
|
||||
// This is the part i invented, it was kinda a fucking nightmare...
|
||||
let stars = [];
|
||||
|
||||
for (let i = 0; i < 3; i++) {
|
||||
setTimeout(() => {
|
||||
animate(stars[i]);
|
||||
|
||||
setInterval(() => animate(stars[i]), 1000);
|
||||
}, index++ * (interval / 3))
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
{#if user !== undefined}
|
||||
<GenerateUserDisplay {user}/>
|
||||
{:else}
|
||||
<h2>Sorry</h2>
|
||||
<div>Failed to load user {aUsername}</div>
|
||||
{/if}
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,305 @@
|
||||
<script lang="ts">
|
||||
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
import { location } from 'svelte-spa-router';
|
||||
// this is how you access /:first for example
|
||||
// export let params = {}
|
||||
// <p>Your name is: <b>{params.first}</b> <b>{#if params.last}{params.last}{/if}</b></p>
|
||||
|
||||
// If i export these vars, maybe as an nice tidy object, i could pass whatever i like to them
|
||||
// The current user, some other user, whatever, and thus reuse this Componente for the user and their friends or whatever
|
||||
// will have to coordinate with Back, will know more once the Game stats are in the back
|
||||
// wait maybe this won't work, cuz like it's still going through a route, i would have to update a Store Var each time...
|
||||
// not sure if that's what i want...
|
||||
|
||||
|
||||
// maybe the rank is determined dynamically just in the front based on win loss ratio or something no one cares about
|
||||
// why bother storing that shit in the back...
|
||||
// maybe i need a Rank.svelte component
|
||||
// ohhh i could make above a certain rank glitter! like that CSS tutorial showed me!
|
||||
|
||||
let user;
|
||||
let rank = '';
|
||||
let avatar;
|
||||
|
||||
// i think i don't need to do this once i sort out the {wrap} conditions: in theory i could pass values to the Route
|
||||
// once the async authentication check is done
|
||||
onMount( async() => {
|
||||
// console.log('mounting profile display')
|
||||
user = await fetch('http://transcendance:8080/api/v2/user')
|
||||
.then( (x) => x.json() );
|
||||
|
||||
// console.log('profile display did my fetch')
|
||||
// should i be updating the userStore or is that unnecessary?
|
||||
|
||||
if (user.loseGame > user.winGame) {
|
||||
rank = 'Bitch Ass Loser!'
|
||||
} else if (user.loseGame === user.winGame) {
|
||||
rank = 'Fine i guess...'
|
||||
} else {
|
||||
rank = 'Yea you da Boss!'
|
||||
}
|
||||
|
||||
await fetch("http://transcendance:8080/api/v2/user/avatar", {method: "GET"})
|
||||
.then(response => {return response.blob()})
|
||||
.then(data => {
|
||||
const url = URL.createObjectURL(data);
|
||||
avatar = url;
|
||||
});
|
||||
|
||||
// tmp
|
||||
// console.log('mounted Profile Display')
|
||||
// console.log(user);
|
||||
|
||||
|
||||
})
|
||||
|
||||
// Glittery Stars and such for Rank
|
||||
|
||||
let index = 0, interval = 1000;
|
||||
|
||||
const rand = (min, max) =>
|
||||
Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
|
||||
// it's unhappy that "star" isn't typeset, no idea what to do about it...
|
||||
const animate = (star) => {
|
||||
// the if seems to have fixed the type issue
|
||||
if (star) {
|
||||
star.style.setProperty("--star-left", `${rand(-10, 100)}%`);
|
||||
star.style.setProperty("--star-top", `${rand(-40, 80)}%`);
|
||||
|
||||
star.style.animation = "none";
|
||||
star.offsetHeight;
|
||||
star.style.animation = "";
|
||||
}
|
||||
}
|
||||
|
||||
// This is the part i invented, it was kinda a fucking nightmare...
|
||||
let stars = [];
|
||||
|
||||
for (let i = 0; i < 3; i++) {
|
||||
setTimeout(() => {
|
||||
animate(stars[i]);
|
||||
|
||||
setInterval(() => animate(stars[i]), 1000);
|
||||
}, index++ * (interval / 3))
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<!-- is this if excessive? -->
|
||||
<div class="outer">
|
||||
{#if user !== undefined}
|
||||
<main>
|
||||
<!-- <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="avatar" src="{avatar}" alt="default user icon">
|
||||
<div class="username">{user.username}</div>
|
||||
<div class="rank">Rank:
|
||||
<span class="glitter">
|
||||
<span bind:this={stars[0]} class="glitter-star">
|
||||
<svg viewBox="0 0 512 512">
|
||||
<path d="M512 255.1c0 11.34-7.406 20.86-18.44 23.64l-171.3 42.78l-42.78 171.1C276.7 504.6 267.2 512 255.9 512s-20.84-7.406-23.62-18.44l-42.66-171.2L18.47 279.6C7.406 276.8 0 267.3 0 255.1c0-11.34 7.406-20.83 18.44-23.61l171.2-42.78l42.78-171.1C235.2 7.406 244.7 0 256 0s20.84 7.406 23.62 18.44l42.78 171.2l171.2 42.78C504.6 235.2 512 244.6 512 255.1z" />
|
||||
</svg>
|
||||
</span>
|
||||
<span bind:this={stars[1]} class="glitter-star">
|
||||
<svg viewBox="0 0 512 512">
|
||||
<path d="M512 255.1c0 11.34-7.406 20.86-18.44 23.64l-171.3 42.78l-42.78 171.1C276.7 504.6 267.2 512 255.9 512s-20.84-7.406-23.62-18.44l-42.66-171.2L18.47 279.6C7.406 276.8 0 267.3 0 255.1c0-11.34 7.406-20.83 18.44-23.61l171.2-42.78l42.78-171.1C235.2 7.406 244.7 0 256 0s20.84 7.406 23.62 18.44l42.78 171.2l171.2 42.78C504.6 235.2 512 244.6 512 255.1z" />
|
||||
</svg>
|
||||
</span>
|
||||
<span bind:this={stars[2]} class="glitter-star">
|
||||
<svg viewBox="0 0 512 512">
|
||||
<path d="M512 255.1c0 11.34-7.406 20.86-18.44 23.64l-171.3 42.78l-42.78 171.1C276.7 504.6 267.2 512 255.9 512s-20.84-7.406-23.62-18.44l-42.66-171.2L18.47 279.6C7.406 276.8 0 267.3 0 255.1c0-11.34 7.406-20.83 18.44-23.61l171.2-42.78l42.78-171.1C235.2 7.406 244.7 0 256 0s20.84 7.406 23.62 18.44l42.78 171.2l171.2 42.78C504.6 235.2 512 244.6 512 255.1z" />
|
||||
</svg>
|
||||
</span>
|
||||
<span class="glitter-text">{rank}</span>
|
||||
</span>
|
||||
</div>
|
||||
<section class="main-stats">
|
||||
<h4>Match Statistics</h4>
|
||||
<p>Total: {user.stats.totalGame}</p>
|
||||
<p>Victories: {user.stats.winGame}</p>
|
||||
<p>Losses: {user.stats.loseGame}</p>
|
||||
<p>Draws: {user.stats.drawGame}</p>
|
||||
</section>
|
||||
</main>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
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>
|
||||
@@ -1,129 +1,32 @@
|
||||
<script lang="ts">
|
||||
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
import { location } from 'svelte-spa-router';
|
||||
// this is how you access /:first for example
|
||||
// export let params = {}
|
||||
// <p>Your name is: <b>{params.first}</b> <b>{#if params.last}{params.last}{/if}</b></p>
|
||||
|
||||
// If i export these vars, maybe as an nice tidy object, i could pass whatever i like to them
|
||||
// The current user, some other user, whatever, and thus reuse this Componente for the user and their friends or whatever
|
||||
// will have to coordinate with Back, will know more once the Game stats are in the back
|
||||
// wait maybe this won't work, cuz like it's still going through a route, i would have to update a Store Var each time...
|
||||
// not sure if that's what i want...
|
||||
|
||||
|
||||
// maybe the rank is determined dynamically just in the front based on win loss ratio or something no one cares about
|
||||
// why bother storing that shit in the back...
|
||||
// maybe i need a Rank.svelte component
|
||||
// ohhh i could make above a certain rank glitter! like that CSS tutorial showed me!
|
||||
import GenerateUserDisplay from '../../pieces/GenerateUserDisplay.svelte';
|
||||
|
||||
let user;
|
||||
let rank = '';
|
||||
let avatar;
|
||||
|
||||
// i think i don't need to do this once i sort out the {wrap} conditions: in theory i could pass values to the Route
|
||||
// once the async authentication check is done
|
||||
onMount( async() => {
|
||||
// console.log('mounting profile display')
|
||||
user = await fetch('http://transcendance:8080/api/v2/user')
|
||||
.then( (x) => x.json() );
|
||||
|
||||
// console.log('profile display did my fetch')
|
||||
// should i be updating the userStore or is that unnecessary?
|
||||
|
||||
if (user.loseGame > user.winGame) {
|
||||
rank = 'Bitch Ass Loser!'
|
||||
} else if (user.loseGame === user.winGame) {
|
||||
rank = 'Fine i guess...'
|
||||
} else {
|
||||
rank = 'Yea you da Boss!'
|
||||
}
|
||||
|
||||
await fetch("http://transcendance:8080/api/v2/user/avatar", {method: "GET"})
|
||||
.then(response => {return response.blob()})
|
||||
.then(data => {
|
||||
const url = URL.createObjectURL(data);
|
||||
avatar = url;
|
||||
});
|
||||
|
||||
// tmp
|
||||
// console.log('mounted Profile Display')
|
||||
// console.log(user);
|
||||
|
||||
|
||||
|
||||
})
|
||||
|
||||
// Glittery Stars and such for Rank
|
||||
|
||||
let index = 0, interval = 1000;
|
||||
|
||||
const rand = (min, max) =>
|
||||
Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
|
||||
// it's unhappy that "star" isn't typeset, no idea what to do about it...
|
||||
const animate = (star) => {
|
||||
// the if seems to have fixed the type issue
|
||||
if (star) {
|
||||
star.style.setProperty("--star-left", `${rand(-10, 100)}%`);
|
||||
star.style.setProperty("--star-top", `${rand(-40, 80)}%`);
|
||||
|
||||
star.style.animation = "none";
|
||||
star.offsetHeight;
|
||||
star.style.animation = "";
|
||||
}
|
||||
}
|
||||
|
||||
// This is the part i invented, it was kinda a fucking nightmare...
|
||||
let stars = [];
|
||||
|
||||
for (let i = 0; i < 3; i++) {
|
||||
setTimeout(() => {
|
||||
animate(stars[i]);
|
||||
|
||||
setInterval(() => animate(stars[i]), 1000);
|
||||
}, index++ * (interval / 3))
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<!-- is this if excessive? -->
|
||||
{#if user !== undefined}
|
||||
<main>
|
||||
<!-- <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="avatar" src="{avatar}" alt="default user icon">
|
||||
<div class="username">{user.username}</div>
|
||||
<div class="rank">Rank:
|
||||
<span class="glitter">
|
||||
<span bind:this={stars[0]} class="glitter-star">
|
||||
<svg viewBox="0 0 512 512">
|
||||
<path d="M512 255.1c0 11.34-7.406 20.86-18.44 23.64l-171.3 42.78l-42.78 171.1C276.7 504.6 267.2 512 255.9 512s-20.84-7.406-23.62-18.44l-42.66-171.2L18.47 279.6C7.406 276.8 0 267.3 0 255.1c0-11.34 7.406-20.83 18.44-23.61l171.2-42.78l42.78-171.1C235.2 7.406 244.7 0 256 0s20.84 7.406 23.62 18.44l42.78 171.2l171.2 42.78C504.6 235.2 512 244.6 512 255.1z" />
|
||||
</svg>
|
||||
</span>
|
||||
<span bind:this={stars[1]} class="glitter-star">
|
||||
<svg viewBox="0 0 512 512">
|
||||
<path d="M512 255.1c0 11.34-7.406 20.86-18.44 23.64l-171.3 42.78l-42.78 171.1C276.7 504.6 267.2 512 255.9 512s-20.84-7.406-23.62-18.44l-42.66-171.2L18.47 279.6C7.406 276.8 0 267.3 0 255.1c0-11.34 7.406-20.83 18.44-23.61l171.2-42.78l42.78-171.1C235.2 7.406 244.7 0 256 0s20.84 7.406 23.62 18.44l42.78 171.2l171.2 42.78C504.6 235.2 512 244.6 512 255.1z" />
|
||||
</svg>
|
||||
</span>
|
||||
<span bind:this={stars[2]} class="glitter-star">
|
||||
<svg viewBox="0 0 512 512">
|
||||
<path d="M512 255.1c0 11.34-7.406 20.86-18.44 23.64l-171.3 42.78l-42.78 171.1C276.7 504.6 267.2 512 255.9 512s-20.84-7.406-23.62-18.44l-42.66-171.2L18.47 279.6C7.406 276.8 0 267.3 0 255.1c0-11.34 7.406-20.83 18.44-23.61l171.2-42.78l42.78-171.1C235.2 7.406 244.7 0 256 0s20.84 7.406 23.62 18.44l42.78 171.2l171.2 42.78C504.6 235.2 512 244.6 512 255.1z" />
|
||||
</svg>
|
||||
</span>
|
||||
<span class="glitter-text">{rank}</span>
|
||||
</span>
|
||||
</div>
|
||||
<section class="main-stats">
|
||||
<h4>Match Statistics</h4>
|
||||
<p>Total: {user.stats.totalGame}</p>
|
||||
<p>Victories: {user.stats.winGame}</p>
|
||||
<p>Losses: {user.stats.loseGame}</p>
|
||||
<p>Draws: {user.stats.drawGame}</p>
|
||||
</section>
|
||||
</main>
|
||||
{/if}
|
||||
<div class="outer">
|
||||
<!-- OHHHH i could use #await instead of if and have an nice loading page! -->
|
||||
{#if user !== undefined}
|
||||
<GenerateUserDisplay {user} primary={true}/>
|
||||
{: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}
|
||||
</div>
|
||||
|
||||
<div>testing when there's tons of stuff</div>
|
||||
<div>testing when there's tons of stuff</div>
|
||||
@@ -161,6 +64,11 @@
|
||||
|
||||
<style>
|
||||
|
||||
div.outer{
|
||||
max-width: 960px;
|
||||
margin: 40px auto;
|
||||
}
|
||||
|
||||
/* The main part */
|
||||
main{
|
||||
max-width: 960px;
|
||||
|
||||
@@ -2,6 +2,26 @@
|
||||
|
||||
import { onMount } from "svelte";
|
||||
import Button from "../../pieces/Button.svelte";
|
||||
import DisplayAUser from "../../pieces/DisplayAUser.svelte";
|
||||
|
||||
// Ok so i need to test all the paths Cherif has made but a major one doesn't work yet...
|
||||
// in the mean time, i need to make some other stuff look nice
|
||||
// what do i want?
|
||||
|
||||
/*
|
||||
Ideas
|
||||
- a list of all users and if they're active
|
||||
could be a list of friends and if they're active but i can't see that yet
|
||||
- I click on a thing and it lets me see all the users and i get a button that lets me add them
|
||||
- would that be like a serachable list of all users?
|
||||
- am i skipping optimization? i mean for now yes, but like
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
let errors = {friendRequest: '',};
|
||||
let set = {friendUsername: '', friendId: Number}
|
||||
@@ -9,8 +29,9 @@
|
||||
let user;
|
||||
let myFriends;
|
||||
let requestsMade, requestsRecieved;
|
||||
// http://transcendance:8080/api/v2/network/received the ones you have recieved
|
||||
// http://transcendance:8080/api/v2/network/pending the ones you have sent
|
||||
let allUsers;
|
||||
let allFriends;
|
||||
let userToDisplay;
|
||||
|
||||
|
||||
onMount( async() => {
|
||||
@@ -42,16 +63,23 @@
|
||||
console.log('Requests received ');
|
||||
console.log(requestsRecieved);
|
||||
|
||||
allUsers = await fetch('http://transcendance:8080/api/v2/user/all')
|
||||
.then( x => x.json() );
|
||||
console.log('got all users ' + allUsers)
|
||||
|
||||
allFriends = await fetch('http://transcendance:8080/api/v2/network/myfriends')
|
||||
.then( x => x.json() );
|
||||
console.log('got all friends ' + allFriends)
|
||||
|
||||
})
|
||||
|
||||
let allUsers;
|
||||
const displayAllUsers = async() => {
|
||||
allUsers = await fetch('http://transcendance:8080/api/v2/user/all')
|
||||
.then( x => x.json() );
|
||||
console.log('got all users ' + allUsers)
|
||||
};
|
||||
|
||||
let allFriends;
|
||||
|
||||
const displayAllFriends = async() => {
|
||||
allFriends = await fetch('http://transcendance:8080/api/v2/network/myfriends')
|
||||
.then( x => x.json() );
|
||||
@@ -112,78 +140,140 @@
|
||||
.then (x => console.log({...x}));
|
||||
|
||||
// should i then update requtestsMade with another fetch?
|
||||
|
||||
// maybe also check if the request went through?
|
||||
|
||||
}
|
||||
|
||||
// body: JSON.stringify({
|
||||
// "requesterUsername": user.username,
|
||||
// "addresseeUsername": set.friendUsername,
|
||||
// "status": r
|
||||
|
||||
// "requesterId": user.username,
|
||||
// "addresseeId": set.friendUsername,
|
||||
|
||||
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<h1>Friendship page</h1>
|
||||
|
||||
{#if user && user.username}
|
||||
<div>You are {user.username}</div>
|
||||
{/if}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div class="top-grid">
|
||||
|
||||
<!-- <div>My friends obj</div> -->
|
||||
<!-- <div>{myFriends}</div> -->
|
||||
<!-- <br> -->
|
||||
<Button on:click={displayAllUsers}>Get All Users</Button>
|
||||
{#if allUsers !== undefined}
|
||||
{#each allUsers as user}
|
||||
<div>{user.username}</div>
|
||||
{/each}
|
||||
{/if}
|
||||
<div class="all-users-sidebar">
|
||||
<h3>All Users</h3>
|
||||
{#if allUsers === undefined}
|
||||
<div class="error">Failed to load all users</div>
|
||||
{:else}
|
||||
<!-- problem, i can't use user.id since Cherif doesn't want to expost that to the front...
|
||||
is there something else i could use? -->
|
||||
{#each allUsers as aUser }
|
||||
<!-- <div class="a-user" on:click={() => displayAUser(aUser.username)}>{aUser.username}</div> -->
|
||||
<div class="a-user" on:click={() => userToDisplay = aUser.username}>{aUser.username}</div>
|
||||
<!-- i could make an indicator component? like green for connected or something?
|
||||
i could use words but color them?
|
||||
i could make it so if they're in a game -->
|
||||
<div class="status a-user">{aUser.status}</div>
|
||||
<br>
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
<br>
|
||||
|
||||
<Button on:click={displayAllFriends}>Get All Friends</Button>
|
||||
{#if allFriends !== undefined}
|
||||
<div>{allFriends}</div>
|
||||
{#each allFriends as friend}
|
||||
<div>{friend}{friend.username}</div>
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
<br>
|
||||
|
||||
<div>Make a Friend!</div>
|
||||
<form on:submit|preventDefault={() => friendUserByUsername(set.friendUsername)}>
|
||||
<input type="text" placeholder="friend's username" bind:value={set.friendUsername}>
|
||||
<div class="error">{errors.friendRequest}</div>
|
||||
<Button type="secondary">Send Friend Request</Button>
|
||||
</form>
|
||||
|
||||
<br> <br>
|
||||
<!-- here i want to list all the requests you and have an accept and a decline button -->
|
||||
|
||||
<!-- {#each requestsRecieved as request} -->
|
||||
|
||||
<br> <br>
|
||||
<!-- I want to list all the requests made by this user -->
|
||||
|
||||
<Button on:click={displayRequestsMade}>Display Requests Made</Button>
|
||||
|
||||
{#if requestsMade !== undefined}
|
||||
{#each requestsMade as requestMade}
|
||||
<div>{requestMade}</div>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- <h1>Friendship page</h1> -->
|
||||
|
||||
<div class="main-display">
|
||||
|
||||
<h1>Main Display</h1>
|
||||
|
||||
<!-- use an #await here too? -->
|
||||
<!-- you can do better, like an on load sort of thing -->
|
||||
{#if userToDisplay !== undefined}
|
||||
<DisplayAUser aUsername={userToDisplay}/>
|
||||
{/if}
|
||||
|
||||
<!-- {#if user && user.username}
|
||||
<div>You are {user.username}</div>
|
||||
{/if} -->
|
||||
|
||||
<!-- <Button on:click={displayAllUsers}>Get All Users</Button>
|
||||
{#if allUsers !== undefined}
|
||||
{#each allUsers as user}
|
||||
<div>{user.username}</div>
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
<br> -->
|
||||
|
||||
<!-- <Button on:click={displayAllFriends}>Get All Friends</Button>
|
||||
{#if allFriends !== undefined}
|
||||
<div>{allFriends}</div>
|
||||
{#each allFriends as friend}
|
||||
<div>{friend}{friend.username}</div>
|
||||
{/each}
|
||||
{/if} -->
|
||||
|
||||
<!-- <br>
|
||||
|
||||
<div>Make a Friend!</div>
|
||||
<form on:submit|preventDefault={() => friendUserByUsername(set.friendUsername)}>
|
||||
<input type="text" placeholder="friend's username" bind:value={set.friendUsername}>
|
||||
<div class="error">{errors.friendRequest}</div>
|
||||
<Button type="secondary">Send Friend Request</Button>
|
||||
</form> -->
|
||||
|
||||
<!-- <br> <br> -->
|
||||
<!-- here i want to list all the requests you and have an accept and a decline button -->
|
||||
|
||||
<!-- {#each requestsRecieved as request} -->
|
||||
|
||||
<!-- <br> <br> -->
|
||||
<!-- I want to list all the requests made by this user -->
|
||||
|
||||
<!-- <Button on:click={displayRequestsMade}>Display Requests Made</Button>
|
||||
|
||||
{#if requestsMade !== undefined}
|
||||
{#each requestsMade as requestMade}
|
||||
<div>{requestMade}</div>
|
||||
{/each}
|
||||
{/if} -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
||||
/* ok so i want a 12 column grid with a sidebar */
|
||||
|
||||
div.top-grid{
|
||||
display: grid;
|
||||
grid-template-columns: repeat(12, 1fr);
|
||||
/* max-height: calc(100vh - 30vh); */
|
||||
height: 85vh;
|
||||
/* margin: 0; */
|
||||
}
|
||||
|
||||
div.all-users-sidebar{
|
||||
grid-column: 1 / span 2;
|
||||
background: white;
|
||||
}
|
||||
|
||||
div.a-user{
|
||||
/* yea i mean that seems fine... */
|
||||
display: inline-block;
|
||||
/* somehting about the buttons too, smaller ? */
|
||||
}
|
||||
div.status{
|
||||
font-size: 0.6em;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* selector attributes to get only divs with .a-user */
|
||||
/* you gotta be careful with Svelte cuz it tacks classes on to the end of basically all elems! */
|
||||
div[class^="a-user"]:hover{
|
||||
text-decoration: underline;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div.main-display{
|
||||
grid-column: 3 / span 10;
|
||||
}
|
||||
|
||||
|
||||
.error{
|
||||
font-size: 0.8em;
|
||||
font-weight: bold;
|
||||
|
||||
@@ -28,10 +28,11 @@
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
/* this doesn't work, fucks up all my sub routes */
|
||||
/* div {
|
||||
max-width: 960px;
|
||||
margin: 40px auto;
|
||||
}
|
||||
} */
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<script lang="ts">
|
||||
|
||||
import { onMount } from 'svelte';
|
||||
import GenerateUserDisplay from './GenerateUserDisplay.svelte';
|
||||
|
||||
export let aUsername;
|
||||
let user;
|
||||
|
||||
onMount( async() => {
|
||||
console.log('Display aUser username: '+ aUsername)
|
||||
// http://transcendance:8080/api/v2/user?username=NomDuUserATrouver
|
||||
user = await fetch(`http://transcendance:8080/api/v2/user?username=${aUsername}`)
|
||||
.then( (x) => x.json() );
|
||||
|
||||
console.log('Display a user: ' + user.username)
|
||||
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<!-- OHHHH i could use #await instead of if and have an nice loading page! -->
|
||||
{#if user !== undefined}
|
||||
<GenerateUserDisplay {user} primary={true}/>
|
||||
{:else}
|
||||
<h2>Sorry</h2>
|
||||
<div>Failed to load user {aUsername}</div>
|
||||
{/if}
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,251 @@
|
||||
<script lang="ts">
|
||||
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
export let user;
|
||||
export let primary;
|
||||
let rank = '';
|
||||
let avatar;
|
||||
|
||||
|
||||
onMount( async() => {
|
||||
// using this for now cuz for some reason there is yet to be a way to fet another person's avatar
|
||||
if (primary) {
|
||||
await fetch("http://transcendance:8080/api/v2/user/avatar", {method: "GET"})
|
||||
.then(response => {return response.blob()})
|
||||
.then(data => {
|
||||
const url = URL.createObjectURL(data);
|
||||
avatar = url;
|
||||
});
|
||||
}
|
||||
// tmp
|
||||
// console.log('mounted Profile Display')
|
||||
// console.log(user);
|
||||
|
||||
})
|
||||
|
||||
if (user.loseGame > user.winGame) {
|
||||
rank = 'Bitch Ass Loser!'
|
||||
} else if (user.loseGame === user.winGame) {
|
||||
rank = 'Fine i guess...'
|
||||
} else {
|
||||
rank = 'Yea you da Boss!'
|
||||
}
|
||||
|
||||
|
||||
// Glittery Stars and such for Rank
|
||||
|
||||
let index = 0, interval = 1000;
|
||||
|
||||
const rand = (min, max) =>
|
||||
Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
|
||||
// it's unhappy that "star" isn't typeset, no idea what to do about it...
|
||||
const animate = (star) => {
|
||||
// the if seems to have fixed the type issue
|
||||
if (star) {
|
||||
star.style.setProperty("--star-left", `${rand(-10, 100)}%`);
|
||||
star.style.setProperty("--star-top", `${rand(-40, 80)}%`);
|
||||
|
||||
star.style.animation = "none";
|
||||
star.offsetHeight;
|
||||
star.style.animation = "";
|
||||
}
|
||||
}
|
||||
|
||||
// This is the part i invented, it was kinda a fucking nightmare...
|
||||
let stars = [];
|
||||
|
||||
for (let i = 0; i < 3; i++) {
|
||||
setTimeout(() => {
|
||||
animate(stars[i]);
|
||||
|
||||
setInterval(() => animate(stars[i]), 1000);
|
||||
}, index++ * (interval / 3))
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<!-- is this if excessive? -->
|
||||
<div class="outer">
|
||||
{#if user !== undefined}
|
||||
<main>
|
||||
<!-- <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="avatar" src="{avatar}" alt="default user icon">
|
||||
<div class="username">{user.username}</div>
|
||||
<div class="rank">Rank:
|
||||
<span class="glitter">
|
||||
<span bind:this={stars[0]} class="glitter-star">
|
||||
<svg viewBox="0 0 512 512">
|
||||
<path d="M512 255.1c0 11.34-7.406 20.86-18.44 23.64l-171.3 42.78l-42.78 171.1C276.7 504.6 267.2 512 255.9 512s-20.84-7.406-23.62-18.44l-42.66-171.2L18.47 279.6C7.406 276.8 0 267.3 0 255.1c0-11.34 7.406-20.83 18.44-23.61l171.2-42.78l42.78-171.1C235.2 7.406 244.7 0 256 0s20.84 7.406 23.62 18.44l42.78 171.2l171.2 42.78C504.6 235.2 512 244.6 512 255.1z" />
|
||||
</svg>
|
||||
</span>
|
||||
<span bind:this={stars[1]} class="glitter-star">
|
||||
<svg viewBox="0 0 512 512">
|
||||
<path d="M512 255.1c0 11.34-7.406 20.86-18.44 23.64l-171.3 42.78l-42.78 171.1C276.7 504.6 267.2 512 255.9 512s-20.84-7.406-23.62-18.44l-42.66-171.2L18.47 279.6C7.406 276.8 0 267.3 0 255.1c0-11.34 7.406-20.83 18.44-23.61l171.2-42.78l42.78-171.1C235.2 7.406 244.7 0 256 0s20.84 7.406 23.62 18.44l42.78 171.2l171.2 42.78C504.6 235.2 512 244.6 512 255.1z" />
|
||||
</svg>
|
||||
</span>
|
||||
<span bind:this={stars[2]} class="glitter-star">
|
||||
<svg viewBox="0 0 512 512">
|
||||
<path d="M512 255.1c0 11.34-7.406 20.86-18.44 23.64l-171.3 42.78l-42.78 171.1C276.7 504.6 267.2 512 255.9 512s-20.84-7.406-23.62-18.44l-42.66-171.2L18.47 279.6C7.406 276.8 0 267.3 0 255.1c0-11.34 7.406-20.83 18.44-23.61l171.2-42.78l42.78-171.1C235.2 7.406 244.7 0 256 0s20.84 7.406 23.62 18.44l42.78 171.2l171.2 42.78C504.6 235.2 512 244.6 512 255.1z" />
|
||||
</svg>
|
||||
</span>
|
||||
<span class="glitter-text">{rank}</span>
|
||||
</span>
|
||||
</div>
|
||||
<section class="main-stats">
|
||||
<h4>Match Statistics</h4>
|
||||
<p>Total: {user.stats.totalGame}</p>
|
||||
<p>Victories: {user.stats.winGame}</p>
|
||||
<p>Losses: {user.stats.loseGame}</p>
|
||||
<p>Draws: {user.stats.drawGame}</p>
|
||||
</section>
|
||||
</main>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
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>
|
||||
Reference in New Issue
Block a user