From 4a24577689a27b89d910b5c70c8af61b062b723f Mon Sep 17 00:00:00 2001 From: hopperelec Date: Tue, 12 Mar 2024 10:54:26 +0000 Subject: [PATCH] Live leaderboard page --- src/lib/server/ably-server.ts | 16 +++++- src/routes/game/[gameId=id]/+page.svelte | 15 ++--- src/routes/game/[gameId=id]/answer/+server.ts | 6 +- .../[gameId=id]/leaderboard/+page.server.ts | 40 ++++++++++++++ .../game/[gameId=id]/leaderboard/+page.svelte | 55 +++++++++++++++++++ src/routes/game/[gameId=id]/shop/+page.svelte | 14 +---- .../shop/[itemId=id]/buy/+server.ts | 13 +++-- 7 files changed, 128 insertions(+), 31 deletions(-) create mode 100644 src/routes/game/[gameId=id]/leaderboard/+page.server.ts create mode 100644 src/routes/game/[gameId=id]/leaderboard/+page.svelte diff --git a/src/lib/server/ably-server.ts b/src/lib/server/ably-server.ts index 03d7e31..a8a0969 100644 --- a/src/lib/server/ably-server.ts +++ b/src/lib/server/ably-server.ts @@ -1,4 +1,18 @@ import ably from "ably"; import { ABLY_API_KEY } from "$env/static/private"; -export default new ably.Realtime.Promise({ key: ABLY_API_KEY }); +const ablyServer = new ably.Realtime.Promise({ key: ABLY_API_KEY }); +export default ablyServer; + +export async function updatePoints( + gameId: number, + userId: number, + points: number, +) { + await ablyServer.channels + .get("player:" + gameId + ":" + userId) + .publish("points", { points: points }); + await ablyServer.channels + .get("game:" + gameId + ":points") + .publish("points", { userId, points }); +} diff --git a/src/routes/game/[gameId=id]/+page.svelte b/src/routes/game/[gameId=id]/+page.svelte index eed3ce2..93bc3e8 100644 --- a/src/routes/game/[gameId=id]/+page.svelte +++ b/src/routes/game/[gameId=id]/+page.svelte @@ -70,12 +70,6 @@ setTimeout(() => elm.remove(), 1000); } - function claimRoom(svgRef: number) { - data.currPoints += 1; - movePlayer(data.userId, svgRef); - addPtsChangeGlyph(1); - } - async function askQuestion(question: string): Promise { const res = await fetch("answer", { method: "POST", @@ -100,7 +94,6 @@ while (askAgain) { if (await askQuestion(question)) askAgain = false; } - claimRoom(clickedSvgRef); } else { alert( "An unexpected error occurred while trying to choose a question for you.", @@ -132,7 +125,10 @@ Points: {data.currPoints}

-{#if data.isHost}End game{/if} +
+ Leaderboard + {#if data.isHost}End game{/if} +
diff --git a/src/routes/game/[gameId=id]/answer/+server.ts b/src/routes/game/[gameId=id]/answer/+server.ts index eea77c8..255a48a 100644 --- a/src/routes/game/[gameId=id]/answer/+server.ts +++ b/src/routes/game/[gameId=id]/answer/+server.ts @@ -1,6 +1,6 @@ import { error, json } from "@sveltejs/kit"; import prisma from "$lib/server/prisma"; -import ablyServer from "$lib/server/ably-server"; +import ablyServer, { updatePoints } from "$lib/server/ably-server"; export const POST = async ({ request, params, locals }) => { const player = await prisma.player.findUnique({ @@ -27,7 +27,7 @@ export const POST = async ({ request, params, locals }) => { "i", ).test(await request.text()); if (correct) { - await prisma.player.update({ + const newPlayerData = await prisma.player.update({ where: { id: player.id }, data: { currQuestionId: null, @@ -35,6 +35,7 @@ export const POST = async ({ request, params, locals }) => { currRoomId: player.currMove.id, currMoveId: null, }, + select: { points: true }, }); await ablyServer.channels .get("game:" + params.gameId + ":positions") @@ -42,6 +43,7 @@ export const POST = async ({ request, params, locals }) => { userId: locals.user.id, svgRef: player.currMove.svgRef, }); + await updatePoints(+params.gameId, locals.user.id, newPlayerData.points); } return json({ correct }); }; diff --git a/src/routes/game/[gameId=id]/leaderboard/+page.server.ts b/src/routes/game/[gameId=id]/leaderboard/+page.server.ts new file mode 100644 index 0000000..5b98503 --- /dev/null +++ b/src/routes/game/[gameId=id]/leaderboard/+page.server.ts @@ -0,0 +1,40 @@ +import getPlayer from "$lib/server/get-player"; +import prisma from "$lib/server/prisma"; +import { error } from "@sveltejs/kit"; + +export const load = async ({ params, locals }) => { + const player = await getPlayer(locals.user, +params.gameId); + const ret = await prisma.player.findUnique({ + where: { id: player.id }, + select: { + isHost: true, + user: { select: { id: true } }, + game: { + select: { + players: { + select: { + user: { select: { id: true, name: true } }, + points: true, + }, + }, + }, + }, + }, + }); + if (!ret) + error( + 500, + "An unexpected error occurred while trying to retrieve your player data", + ); + return { + userId: ret.user.id, + isHost: ret.isHost, + players: ret.game.players.map((player) => { + return { + id: player.user.id, + name: player.user.name, + points: player.points, + }; + }), + }; +}; diff --git a/src/routes/game/[gameId=id]/leaderboard/+page.svelte b/src/routes/game/[gameId=id]/leaderboard/+page.svelte new file mode 100644 index 0000000..992a9a3 --- /dev/null +++ b/src/routes/game/[gameId=id]/leaderboard/+page.svelte @@ -0,0 +1,55 @@ + + +
+
+ +
+ Back to game +
+ + diff --git a/src/routes/game/[gameId=id]/shop/+page.svelte b/src/routes/game/[gameId=id]/shop/+page.svelte index 3cc990a..a28f517 100644 --- a/src/routes/game/[gameId=id]/shop/+page.svelte +++ b/src/routes/game/[gameId=id]/shop/+page.svelte @@ -5,14 +5,6 @@ export let data; - const itemCosts = data.shopItems.reduce( - (acc, item) => { - acc[item.id] = item.cost; - return acc; - }, - {} as { [key: number]: number }, - ); - ablyClientStore.subscribe(async (ablyClient) => { if (!ablyClient) return; await ablyClient.channels @@ -28,11 +20,7 @@ async function buyItem(itemId: number) { const res = await fetch(`${itemId}/buy`); - if (res.ok) { - data.points -= itemCosts[itemId]; - } else { - alert((await res.json()).message); - } + if (!res.ok) alert((await res.json()).message); } diff --git a/src/routes/game/[gameId=id]/shop/[itemId=id]/buy/+server.ts b/src/routes/game/[gameId=id]/shop/[itemId=id]/buy/+server.ts index 5f8b604..8f33c29 100644 --- a/src/routes/game/[gameId=id]/shop/[itemId=id]/buy/+server.ts +++ b/src/routes/game/[gameId=id]/shop/[itemId=id]/buy/+server.ts @@ -1,6 +1,6 @@ import { error } from "@sveltejs/kit"; import prisma from "$lib/server/prisma"; -import ablyServer from "$lib/server/ably-server"; +import ablyServer, { updatePoints } from "$lib/server/ably-server"; import type { User } from "@prisma/client"; type ActionDetails = { @@ -130,11 +130,7 @@ const ACTIONS: { [key: string]: (details: ActionDetails) => Promise } = { where: { id: Number(randPlayer.id) }, data: { points: newPoints }, }); - await ablyServer.channels - .get("player:" + gameId + ":" + randPlayer.userId) - .publish("points", { - points: newPoints, - }); + await updatePoints(gameId, Number(randPlayer.userId), newPoints); }, }; @@ -177,5 +173,10 @@ export const GET = async ({ params, locals }) => { where: { id: player.id }, data: { points: { decrement: shopItem.cost } }, }); + await updatePoints( + +params.gameId, + locals.user.id, + player.points - shopItem.cost, + ); return new Response(); };