From ee212150fde6fc5ea8ac49b12610df73bb2ffe61 Mon Sep 17 00:00:00 2001 From: Liam Date: Sun, 13 Oct 2024 03:49:33 +0100 Subject: [PATCH] add default score sort (last selected) --- .../src/app/(pages)/player/[...slug]/page.tsx | 7 ++- projects/website/src/common/cookie-utils.ts | 47 +++++++++++++++++++ .../website/src/common/database/database.ts | 4 +- projects/website/src/common/website-utils.ts | 20 -------- .../src/components/player/claim-profile.tsx | 4 +- .../src/components/player/player-data.tsx | 4 +- .../src/components/player/player-scores.tsx | 4 +- 7 files changed, 59 insertions(+), 31 deletions(-) create mode 100644 projects/website/src/common/cookie-utils.ts diff --git a/projects/website/src/app/(pages)/player/[...slug]/page.tsx b/projects/website/src/app/(pages)/player/[...slug]/page.tsx index e01bba1..c651d13 100644 --- a/projects/website/src/app/(pages)/player/[...slug]/page.tsx +++ b/projects/website/src/app/(pages)/player/[...slug]/page.tsx @@ -10,8 +10,8 @@ import { scoresaberService } from "@ssr/common/service/impl/scoresaber"; import ScoreSaberPlayerScoresPageToken from "@ssr/common/types/token/scoresaber/score-saber-player-scores-page-token"; import ScoreSaberPlayer, { getScoreSaberPlayerFromToken } from "@ssr/common/types/player/impl/scoresaber-player"; import { config } from "../../../../../config"; -import { cookies } from "next/headers"; import NodeCache from "node-cache"; +import { getCookieValue } from "@/common/cookie-utils"; const UNKNOWN_PLAYER = { title: "ScoreSaber Reloaded - Unknown Player", @@ -47,7 +47,7 @@ const playerCache = new NodeCache({ stdTTL: 60, checkperiod: 120 }); const getPlayerData = async ({ params }: Props, fetchScores: boolean = true): Promise => { const { slug } = await params; const id = slug[0]; // The players id - const sort: ScoreSort = (slug[1] as ScoreSort) || "recent"; // The sorting method + const sort: ScoreSort = (slug[1] as ScoreSort) || (await getCookieValue("lastScoreSort", "recent")); // The sorting method const page = parseInt(slug[2]) || 1; // The page number const search = (slug[3] as string) || ""; // The search query @@ -58,8 +58,7 @@ const getPlayerData = async ({ params }: Props, fetchScores: boolean = true): Pr const playerToken = await scoresaberService.lookupPlayer(id); const player = - playerToken && - (await getScoreSaberPlayerFromToken(playerToken, config.siteApi, (await cookies()).get("playerId")?.value)); + playerToken && (await getScoreSaberPlayerFromToken(playerToken, config.siteApi, await getCookieValue("playerId"))); let scores: ScoreSaberPlayerScoresPageToken | undefined; if (fetchScores) { scores = await scoresaberService.lookupPlayerScores({ diff --git a/projects/website/src/common/cookie-utils.ts b/projects/website/src/common/cookie-utils.ts new file mode 100644 index 0000000..cb769b2 --- /dev/null +++ b/projects/website/src/common/cookie-utils.ts @@ -0,0 +1,47 @@ +import { isServer } from "@tanstack/react-query"; + +export type CookieName = "playerId" | "lastScoreSort"; + +/** + * Gets the value of a cookie + * + * @param name the name of the cookie + * @param defaultValue the fallback value + * @returns the value of the cookie, or the fallback value (undefined if no fallback value is provided) + */ +export async function getCookieValue(name: CookieName, defaultValue?: string): Promise { + let value: string | undefined; + if (isServer) { + const { cookies } = await import("next/headers"); + + const cookieStore = await cookies(); + const cookieValue = cookieStore.get(name)?.value; + value = cookieValue ? cookieValue : defaultValue ? defaultValue : undefined; + } else { + const { get } = (await import("js-cookie")).default; + value = get(name) || defaultValue ? defaultValue : undefined; + } + + return value; +} + +/** + * Sets the value of a cookie + * + * @param name the name of the cookie + * @param value the value of the cookie + */ +export async function setCookieValue(name: CookieName, value: string) { + if (isServer) { + const { cookies } = await import("next/headers"); + + const cookieStore = await cookies(); + cookieStore.set(name, value, { + path: "/", + }); + } + const { set } = (await import("js-cookie")).default; + return set(name, value, { + path: "/", + }); +} diff --git a/projects/website/src/common/database/database.ts b/projects/website/src/common/database/database.ts index 6cd5697..14e7929 100644 --- a/projects/website/src/common/database/database.ts +++ b/projects/website/src/common/database/database.ts @@ -1,7 +1,7 @@ import Dexie, { EntityTable } from "dexie"; -import { setPlayerIdCookie } from "../website-utils"; import BeatSaverMap from "./types/beatsaver-map"; import Settings from "./types/settings"; +import { setCookieValue } from "@/common/cookie-utils"; const SETTINGS_ID = "SSR"; // DO NOT CHANGE @@ -38,7 +38,7 @@ export default class Database extends Dexie { if (settings == undefined || settings.playerId == undefined) { return; } - setPlayerIdCookie(settings.playerId); + await setCookieValue("playerId", settings.playerId); }); } diff --git a/projects/website/src/common/website-utils.ts b/projects/website/src/common/website-utils.ts index c2ffdf8..f20486a 100644 --- a/projects/website/src/common/website-utils.ts +++ b/projects/website/src/common/website-utils.ts @@ -1,23 +1,3 @@ -import Cookies from "js-cookie"; - -/** - * Sets the player id cookie - * - * @param playerId the player id to set - */ -export function setPlayerIdCookie(playerId: string) { - Cookies.set("playerId", playerId, { path: "/" }); -} - -/** - * Gets the player id cookie - * - * @returns the player id cookie - */ -export function getPlayerIdCookie() { - return Cookies.get("playerId"); -} - /** * Gets if we're in production */ diff --git a/projects/website/src/components/player/claim-profile.tsx b/projects/website/src/components/player/claim-profile.tsx index d69dc32..79fb192 100644 --- a/projects/website/src/components/player/claim-profile.tsx +++ b/projects/website/src/components/player/claim-profile.tsx @@ -2,12 +2,12 @@ import { CheckIcon } from "@heroicons/react/24/solid"; import { useLiveQuery } from "dexie-react-hooks"; -import { setPlayerIdCookie } from "@/common/website-utils"; import useDatabase from "../../hooks/use-database"; import { useToast } from "@/hooks/use-toast"; import Tooltip from "../tooltip"; import { Button } from "../ui/button"; import { revalidatePath } from "next/cache"; +import { setCookieValue } from "@/common/cookie-utils"; type Props = { /** @@ -28,7 +28,7 @@ export default function ClaimProfile({ playerId }: Props) { const settings = await database.getSettings(); settings?.setPlayerId(playerId); - setPlayerIdCookie(playerId); + await setCookieValue("playerId", playerId); toast({ title: "Profile Claimed", description: "You have claimed this profile.", diff --git a/projects/website/src/components/player/player-data.tsx b/projects/website/src/components/player/player-data.tsx index 9f13d00..f5cd453 100644 --- a/projects/website/src/components/player/player-data.tsx +++ b/projects/website/src/components/player/player-data.tsx @@ -15,9 +15,9 @@ import ScoreSaberPlayerScoresPageToken from "@ssr/common/types/token/scoresaber/ import { ScoreSort } from "@ssr/common/types/score/score-sort"; import { scoresaberService } from "@ssr/common/service/impl/scoresaber"; import { config } from "../../../config"; -import { getPlayerIdCookie } from "@/common/website-utils"; import useDatabase from "@/hooks/use-database"; import { useLiveQuery } from "dexie-react-hooks"; +import { getCookieValue } from "@/common/cookie-utils"; const REFRESH_INTERVAL = 1000 * 60 * 5; @@ -50,7 +50,7 @@ export default function PlayerData({ if (playerResponse == undefined) { return undefined; } - return await getScoreSaberPlayerFromToken(playerResponse, config.siteApi, getPlayerIdCookie()); + return await getScoreSaberPlayerFromToken(playerResponse, config.siteApi, await getCookieValue("playerId")); }, staleTime: REFRESH_INTERVAL, refetchInterval: REFRESH_INTERVAL, diff --git a/projects/website/src/components/player/player-scores.tsx b/projects/website/src/components/player/player-scores.tsx index 3ad43bf..e71318d 100644 --- a/projects/website/src/components/player/player-scores.tsx +++ b/projects/website/src/components/player/player-scores.tsx @@ -16,6 +16,7 @@ import ScoreSaberPlayer from "@ssr/common/types/player/impl/scoresaber-player"; import ScoreSaberPlayerScoresPageToken from "@ssr/common/types/token/scoresaber/score-saber-player-scores-page-token"; import { ScoreSort } from "@ssr/common/types/score/score-sort"; import { scoresaberService } from "@ssr/common/service/impl/scoresaber"; +import { setCookieValue } from "@/common/cookie-utils"; type Props = { initialScoreData?: ScoreSaberPlayerScoresPageToken; @@ -88,10 +89,11 @@ export default function PlayerScores({ initialScoreData, initialSearch, player, * * @param newSort the new sort */ - const handleSortChange = (newSort: ScoreSort) => { + const handleSortChange = async (newSort: ScoreSort) => { if (newSort !== pageState.sort) { setPageState({ page: 1, sort: newSort }); setShouldFetch(true); // Set to true to trigger fetch + await setCookieValue("lastScoreSort", newSort); // Set the default score sort } };