updating the scores works now yayyy

but also the database is shit so imma rewrite it lol
This commit is contained in:
2026-05-22 16:27:01 +01:00
parent fdfbd4c7c7
commit b4611d262b
6 changed files with 248 additions and 32 deletions

View File

@@ -1,28 +1,6 @@
import { db } from '$lib/server/db';
import * as schema from '$lib/server/db/schema';
import type { Actions } from './$types';
import * as eventManager from '$lib/server/eventManager';
// Literally only here so that the frontend has the right structure
export const load = async () => {
return await getTeams();
return await eventManager.getTeams();
};
export const actions = {
addEntry: async (event) => {
console.log('something');
}
} satisfies Actions;
let testScore = 0;
export async function getTeams() {
const allTeams = await db.select().from(schema.teamScoresView);
console.log(allTeams);
return {
teams: allTeams.map((team) => ({
...team,
name: team.teamName,
color: team.teamColor,
points: team.totalPoints || testScore
}))
};
}

View File

@@ -1,17 +1,62 @@
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import { enhance } from '$app/forms';
// Get initial data from the load thing (innacurate lol)
let { data }: { data: import('./$types').PageData } = $props();
let leaderboard = $derived([...data.teams].sort((a, b) => b.points - a.points));
// Derived unordered
let teams = $derived(data.teams);
//// Layout logic
function getColCount(width: number): number {
if (width < 640) return 1; // sm
if (width < 1024) return 2; // md
// lg: 1 col per item, max 5
return Math.min(teams.length, 5);
}
//// Leaderboard Database logic
// new event source for websocket
let scoreEndpoint: EventSource;
let playerEndpoint: EventSource;
onMount(() => {
// get endpoint
scoreEndpoint = new EventSource('/api/teams');
// when you get a message do something
scoreEndpoint.onmessage = (e) => {
const parsed = JSON.parse(e.data);
// If the message has a teams object update the score thing
if (parsed['teams']) {
teams = parsed['teams'];
console.log('teams updated');
}
};
// Player endpoint
playerEndpoint = new EventSource('/api/players');
playerEndpoint.onmessage = (e) => {
let playerData = JSON.parse(e.data);
console.log(playerData);
};
});
// When window destroyed close the websocket connection
onDestroy(() => scoreEndpoint?.close());
// Order leaderboard so that its displayed correctly
let leaderboard = $derived([...teams].sort((a, b) => b.points - a.points));
</script>
<div
class="grid-cols-1 justify-center p-10 sm:grid sm:grid-cols-2 md:grid-cols-2 lg:flex lg:flex-row"
>
<svelte:window onbeforeunload={() => scoreEndpoint?.close()} />
<div class="p-[2vw]">
{#each leaderboard as house (house.name)}
<div
style="--theme-color: {house.color};"
class="--theme-color: m-5 border-solid {house.color} score-box aspect-1/1 rounded-2xl border-3 first:col-span-2 sm:first:aspect-2/1 lg:w-70"
class="score-box mb-2 aspect-3/1 rounded-2xl border-5 first:aspect-2/1"
>
<div class="text-center">{house.name}</div>
<div class="items-center justify-center text-center"><p>{house.points}</p></div>
@@ -19,7 +64,17 @@
{/each}
</div>
<form method="POST" action="?/addEntry" use:enhance><button>click</button></form>
<button
onclick={() =>
// Onclick send a request to the post endpoint
fetch('/api/teams', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: 'hello' })
})}
>
Send update
</button>
<style>
@import url('https://cdn.jsdelivr.net/npm/@catppuccin/palette/css/catppuccin.css');

View File

@@ -0,0 +1,46 @@
import { globalEmitter, getPlayers } from '$lib/server/eventManager';
// Expose endpoint
export async function GET() {
// expose function type to both start and cancel
let playerList: () => Promise<void>;
// When request recieved open a new websocket
const stream = new ReadableStream({
// Make a new controller so I can send messages
async start(controller) {
// Function for sending messages
const enqueue = (data: any) => {
let transferdata = JSON.stringify(data);
// stringify data and add to controller queue
controller.enqueue(`data: ${transferdata}\n\n`);
};
// Function to grab score from database and add it to message queue
playerList = async () => {
let players = await getPlayers();
enqueue(players);
};
// Update score on connection so everything is synced
enqueue(await getPlayers());
// Update score every time the emitter emits that the score has been changed
globalEmitter.on('playerUpdate', playerList);
},
cancel() {
// Delete the emitter listener so that the server doesnt crash
globalEmitter.off('playerUpdate', playerList);
console.log('closed');
}
});
// Return a response with an eventstream mime type
return new Response(stream, {
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
'X-Accel-Buffering': 'no'
}
});
}

View File

@@ -0,0 +1,54 @@
import { globalEmitter, getTeams } from '$lib/server/eventManager';
// Expose endpoint
export async function GET() {
// expose function type to both start and cancel
let newScore: () => Promise<void>;
// When request recieved open a new websocket
const stream = new ReadableStream({
// Make a new controller so I can send messages
start(controller) {
// Function for sending messages
const enqueue = (data: any) => {
let transferdata = JSON.stringify(data);
// stringify data and add to controller queue
controller.enqueue(`data: ${transferdata}\n\n`);
};
// Function to grab score from database and add it to message queue
newScore = async () => {
let newScores = await getTeams();
enqueue(newScores);
};
// Update score on connection so everything is synced
enqueue(getTeams());
// Update score every time the emitter emits that the score has been changed
globalEmitter.on('scoreUpdate', newScore);
},
cancel() {
// Delete the emitter listener so that the server doesnt crash
globalEmitter.off('scoreUpdate', newScore);
console.log('closed');
}
});
// Return a response with an eventstream mime type
return new Response(stream, {
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
'X-Accel-Buffering': 'no'
}
});
}
// Expose post request
export async function POST({ request }: any) {
// When post request recieved increment testscores by 1
globalEmitter.emit('incrementScores');
// Return ok so the frontend is happy
return new Response('ok');
}