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}
+
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 @@
+
+
+
+
+
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();
};