Score are dynamically displayed and saved in local storage
This commit is contained in:
72
src/lib/components/LeaderBoard.svelte
Normal file
72
src/lib/components/LeaderBoard.svelte
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
export let scores = []
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ul class="leaderboard">
|
||||||
|
|
||||||
|
{#each scores as score, i}
|
||||||
|
<li class="item">
|
||||||
|
<div class="name"><img src="" alt=""/> {score.playerName} </div><div class="score"> {score.value} pts.</div>
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
.leaderboard
|
||||||
|
{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
width: 60vw;
|
||||||
|
height: 65vh;
|
||||||
|
|
||||||
|
padding: 0 2vw 2vw 2vw;
|
||||||
|
overflow: scroll;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaderboard::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
li
|
||||||
|
{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 1.25vh;
|
||||||
|
margin: 1.5vh;
|
||||||
|
border: 2px solid #A1674A;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #f1ecec;
|
||||||
|
box-shadow: 0 0 10px #343232;
|
||||||
|
}
|
||||||
|
|
||||||
|
li:hover
|
||||||
|
{
|
||||||
|
transform: scale(1.075);
|
||||||
|
background-color: #F5F5F5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name, .score
|
||||||
|
{
|
||||||
|
color: black;
|
||||||
|
margin-left: 3vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name
|
||||||
|
{
|
||||||
|
flex-grow: 100;
|
||||||
|
border-right: 1px solid #A1674A;
|
||||||
|
}
|
||||||
|
|
||||||
|
.score
|
||||||
|
{
|
||||||
|
flex-grow: 20;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
3
src/lib/components/ListItem.svelte
Normal file
3
src/lib/components/ListItem.svelte
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<li class="item">
|
||||||
|
<slot></slot>
|
||||||
|
</li>
|
||||||
11
src/lib/models/score.ts
Normal file
11
src/lib/models/score.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
export class Score {
|
||||||
|
|
||||||
|
readonly playerName : string;
|
||||||
|
readonly value: number;
|
||||||
|
|
||||||
|
constructor({playerName = "", value = 0}) {
|
||||||
|
this.playerName = playerName;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
34
src/lib/stores/scoreStore.ts
Normal file
34
src/lib/stores/scoreStore.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import {writable} from "svelte/store";
|
||||||
|
import {Score} from "../models/score";
|
||||||
|
import {browser} from "$app/environment"
|
||||||
|
|
||||||
|
let localStorageKey = "scores"
|
||||||
|
|
||||||
|
function isBrowser() {
|
||||||
|
return typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';
|
||||||
|
}
|
||||||
|
|
||||||
|
function createStore(){
|
||||||
|
|
||||||
|
const storedValue = isBrowser() ? localStorage.getItem(localStorageKey) : null;
|
||||||
|
|
||||||
|
const { set, update, subscribe } = writable<Score[]>(!storedValue ? [] : JSON.parse(storedValue));
|
||||||
|
|
||||||
|
if (isBrowser()) subscribe(value => localStorage.setItem(localStorageKey, JSON.stringify(value)));
|
||||||
|
|
||||||
|
return {
|
||||||
|
update,
|
||||||
|
subscribe,
|
||||||
|
set : (value : Score[]) => set(!value ? [] : value),
|
||||||
|
reset : () => set([]),
|
||||||
|
add : (playerName : string, value : number) => {
|
||||||
|
update(scores => {
|
||||||
|
let s = [...scores, new Score({playerName : playerName, value : value})];
|
||||||
|
if(s.length >= 2) s.sort((s1 : Score, s2 : Score) => s1.value - s2.value)
|
||||||
|
return s;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const scoreStore = createStore();
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
import github_mark from '$lib/assets/github-mark-white.svg';
|
import github_mark from '$lib/assets/github-mark-white.svg';
|
||||||
import twitter_mark from '$lib/assets/twitter-mark-white.svg';
|
import twitter_mark from '$lib/assets/twitter-mark-white.svg';
|
||||||
|
|
||||||
import NavLink from "$lib/components/NavLink.svelte";
|
|
||||||
import {onMount} from "svelte";
|
import {onMount} from "svelte";
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
|
|||||||
@@ -1,101 +1,9 @@
|
|||||||
<ul class="leaderboard">
|
<script>
|
||||||
|
import {scoreStore} from "$lib/stores/scoreStore.ts"
|
||||||
|
import LeaderBoard from "$lib/components/LeaderBoard.svelte";
|
||||||
|
|
||||||
<li class="item">
|
</script>
|
||||||
<div class="name"><img src="" alt=""/> Player 1</div><div class="score">0 pts.</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="item">
|
<button on:click={() => {scoreStore.reset()}}>Clear leaderboard</button>
|
||||||
<div class="name"><img src="" alt=""/> Player 2</div><div class="score">1 pts.</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="item">
|
<LeaderBoard bind:scores={$scoreStore}></LeaderBoard>
|
||||||
<div class="name"><img src="" alt=""/> Player 3</div><div class="score">2 pts.</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="item">
|
|
||||||
<div class="name"><img src="" alt=""/> Player 4</div><div class="score">3 pts.</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="item">
|
|
||||||
<div class="name"><img src="" alt=""/> Player 5</div><div class="score">4 pts.</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="item">
|
|
||||||
<div class="name"><img src="" alt=""/> Player 6</div><div class="score">5 pts.</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="item">
|
|
||||||
<div class="name"><img src="" alt=""/> Player 7</div><div class="score">6 pts.</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="item">
|
|
||||||
<div class="name"><img src="" alt=""/> Player 8</div><div class="score">7 pts.</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="item">
|
|
||||||
<div class="name"><img src="" alt=""/> Player 9</div><div class="score">8 pts.</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="item">
|
|
||||||
<div class="name"><img src="" alt=""/> Player 10</div><div class="score">9 pts.</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
|
|
||||||
.leaderboard
|
|
||||||
{
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
width: 60vw;
|
|
||||||
height: 65vh;
|
|
||||||
|
|
||||||
padding: 0 2vw 2vw 2vw;
|
|
||||||
overflow: scroll;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leaderboard::-webkit-scrollbar {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
li
|
|
||||||
{
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-around;
|
|
||||||
padding: 1.25vh;
|
|
||||||
margin: 1.5vh;
|
|
||||||
border: 2px solid #A1674A;
|
|
||||||
border-radius: 10px;
|
|
||||||
background-color: #f1ecec;
|
|
||||||
box-shadow: 0 0 10px #343232;
|
|
||||||
}
|
|
||||||
|
|
||||||
li:hover
|
|
||||||
{
|
|
||||||
transform: scale(1.075);
|
|
||||||
color: #424242;
|
|
||||||
background-color: #F5F5F5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.name, .score
|
|
||||||
{
|
|
||||||
color: black;
|
|
||||||
margin-left: 3vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.name
|
|
||||||
{
|
|
||||||
flex-grow: 100;
|
|
||||||
border-right: 1px solid #A1674A;
|
|
||||||
}
|
|
||||||
|
|
||||||
.score
|
|
||||||
{
|
|
||||||
flex-grow: 20;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
@@ -1 +1 @@
|
|||||||
<p>It was revealed to me in my dream</p>
|
<p>It was revealed to me in a dream</p>
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
<script>
|
<script>
|
||||||
|
|
||||||
import {onMount} from "svelte";
|
import {onMount} from "svelte";
|
||||||
|
import {scoreStore} from "$lib/stores/scoreStore.ts";
|
||||||
|
|
||||||
|
let playerName = undefined;
|
||||||
let range = 100;
|
let range = 100;
|
||||||
let result = 0;
|
let result = 0;
|
||||||
|
|
||||||
@@ -23,6 +25,8 @@
|
|||||||
|
|
||||||
toggleLoading();
|
toggleLoading();
|
||||||
window.$(".result").text(`Result : ${result}/${range}`)
|
window.$(".result").text(`Result : ${result}/${range}`)
|
||||||
|
|
||||||
|
scoreStore.add(playerName, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleLoading(){
|
function toggleLoading(){
|
||||||
@@ -41,6 +45,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="player">
|
<div class="player">
|
||||||
|
<input class="name" placeholder="Your name" bind:value={playerName}/>
|
||||||
<button on:click={roll}>Let's roll !</button>
|
<button on:click={roll}>Let's roll !</button>
|
||||||
<div class="result"></div>
|
<div class="result"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -48,12 +53,7 @@
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
.disabled
|
.container, .player
|
||||||
{
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container
|
|
||||||
{
|
{
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -62,6 +62,25 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.disabled
|
||||||
|
{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player
|
||||||
|
{
|
||||||
|
gap: 2vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name
|
||||||
|
{
|
||||||
|
width: 17vw;
|
||||||
|
height: 6vh;
|
||||||
|
border: 2px solid #A1674A;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 0 10px #343232;
|
||||||
|
}
|
||||||
|
|
||||||
.circular-loader
|
.circular-loader
|
||||||
{
|
{
|
||||||
stroke-dasharray: 100, 125;
|
stroke-dasharray: 100, 125;
|
||||||
@@ -79,7 +98,7 @@
|
|||||||
{
|
{
|
||||||
color: black;
|
color: black;
|
||||||
width: 18vw;
|
width: 18vw;
|
||||||
height: 18vh;
|
height: 15vh;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background-color: #f1ecec;
|
background-color: #f1ecec;
|
||||||
border: 2px solid #A1674A;
|
border: 2px solid #A1674A;
|
||||||
@@ -87,7 +106,7 @@
|
|||||||
box-shadow: 0 0 10px #343232;
|
box-shadow: 0 0 10px #343232;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:hover{
|
.name:hover, button:hover{
|
||||||
transform: scale(1.1);
|
transform: scale(1.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user