From c64f046df357e94c2faa692544f0230fc212a320 Mon Sep 17 00:00:00 2001 From: Liam Date: Thu, 17 Oct 2024 03:08:27 +0100 Subject: [PATCH] fix score leaderboard staying open when switching sort/page --- projects/backend/src/service/score.service.ts | 5 +++++ .../src/types/player/impl/scoresaber-player.ts | 4 ++-- .../src/common => common/src/utils}/cookie-utils.ts | 6 +++--- projects/common/src/utils/utils.ts | 7 +++++++ .../src/app/(pages)/player/[...slug]/page.tsx | 2 +- projects/website/src/common/database/database.ts | 3 +-- .../website/src/components/player/claim-profile.tsx | 2 +- .../website/src/components/player/player-scores.tsx | 2 +- projects/website/src/components/score/score.tsx | 13 +++++++++++++ 9 files changed, 34 insertions(+), 10 deletions(-) rename projects/{website/src/common => common/src/utils}/cookie-utils.ts (93%) diff --git a/projects/backend/src/service/score.service.ts b/projects/backend/src/service/score.service.ts index 3a249b7..34e2442 100644 --- a/projects/backend/src/service/score.service.ts +++ b/projects/backend/src/service/score.service.ts @@ -7,6 +7,11 @@ import { formatPp } from "@ssr/common/utils/number-utils"; import { isProduction } from "@ssr/common/utils/utils"; export class ScoreService { + /** + * Notifies the number one score in Discord. + * + * @param playerScore the score to notify + */ public static async notifyNumberOne(playerScore: ScoreSaberPlayerScoreToken) { // Only notify in production if (!isProduction()) { diff --git a/projects/common/src/types/player/impl/scoresaber-player.ts b/projects/common/src/types/player/impl/scoresaber-player.ts index d6c8d61..e99c812 100644 --- a/projects/common/src/types/player/impl/scoresaber-player.ts +++ b/projects/common/src/types/player/impl/scoresaber-player.ts @@ -4,9 +4,9 @@ import { PlayerHistory } from "../player-history"; import ScoreSaberPlayerToken from "../../token/scoresaber/score-saber-player-token"; import { formatDateMinimal, getDaysAgoDate, getMidnightAlignedDate } from "../../../utils/time-utils"; import { getPageFromRank } from "../../../utils/utils"; -import { getCookieValue } from "website/src/common/cookie-utils"; import { db } from "website/src/common/database/database"; import { isServer } from "@tanstack/react-query"; +import { getCookieValue } from "@ssr/utils/cookie-utils"; /** * A ScoreSaber player. @@ -107,7 +107,7 @@ export async function getScoreSaberPlayerFromToken( .get<{ statistics: { [key: string]: PlayerHistory }; }>( - `${apiUrl}/player/history/${token.id}${playerIdCookie && playerIdCookie == token.id ? "?createIfMissing=true" : ""}` + `${apiUrl}/player/history/${token.id}${playerIdCookie && playerIdCookie === token.id ? "?createIfMissing=true" : ""}` ) .json(); if (history) { diff --git a/projects/website/src/common/cookie-utils.ts b/projects/common/src/utils/cookie-utils.ts similarity index 93% rename from projects/website/src/common/cookie-utils.ts rename to projects/common/src/utils/cookie-utils.ts index b7a3d95..9ef76b9 100644 --- a/projects/website/src/common/cookie-utils.ts +++ b/projects/common/src/utils/cookie-utils.ts @@ -1,4 +1,4 @@ -import { isServer } from "@tanstack/react-query"; +import { isServer } from "./utils"; export type CookieName = "playerId" | "lastScoreSort"; @@ -11,7 +11,7 @@ export type CookieName = "playerId" | "lastScoreSort"; */ export async function getCookieValue(name: CookieName, defaultValue?: string): Promise { let value: string | undefined; - if (isServer) { + if (isServer()) { const { cookies } = await import("next/headers"); const cookieStore = await cookies(); @@ -32,7 +32,7 @@ export async function getCookieValue(name: CookieName, defaultValue?: string): P * @param value the value of the cookie */ export async function setCookieValue(name: CookieName, value: string) { - if (isServer) { + if (isServer()) { const { cookies } = await import("next/headers"); const cookieStore = await cookies(); diff --git a/projects/common/src/utils/utils.ts b/projects/common/src/utils/utils.ts index fba847c..66c8d46 100644 --- a/projects/common/src/utils/utils.ts +++ b/projects/common/src/utils/utils.ts @@ -7,6 +7,13 @@ export function isProduction() { return process.env.NODE_ENV === "production"; } +/** + * Checks if we're running on the server + */ +export function isServer() { + return typeof window === "undefined"; +} + /** * Delays a promise * diff --git a/projects/website/src/app/(pages)/player/[...slug]/page.tsx b/projects/website/src/app/(pages)/player/[...slug]/page.tsx index a3dd4a6..53109eb 100644 --- a/projects/website/src/app/(pages)/player/[...slug]/page.tsx +++ b/projects/website/src/app/(pages)/player/[...slug]/page.tsx @@ -9,7 +9,7 @@ import ScoreSaberPlayerScoresPageToken from "@ssr/common/types/token/scoresaber/ import ScoreSaberPlayer, { getScoreSaberPlayerFromToken } from "@ssr/common/types/player/impl/scoresaber-player"; import { config } from "../../../../../config"; import NodeCache from "node-cache"; -import { getCookieValue } from "@/common/cookie-utils"; +import { getCookieValue } from "@ssr/common/utils/cookie-utils"; const UNKNOWN_PLAYER = { title: "ScoreSaber Reloaded - Unknown Player", diff --git a/projects/website/src/common/database/database.ts b/projects/website/src/common/database/database.ts index 6b5d91b..a5e34d9 100644 --- a/projects/website/src/common/database/database.ts +++ b/projects/website/src/common/database/database.ts @@ -1,13 +1,12 @@ import Dexie, { EntityTable } from "dexie"; import BeatSaverMap from "./types/beatsaver-map"; import Settings from "./types/settings"; -import { setCookieValue } from "@/common/cookie-utils"; import { Friend } from "@/common/database/types/friends"; import ScoreSaberPlayerToken from "@ssr/common/types/token/scoresaber/score-saber-player-token"; import { scoresaberService } from "@ssr/common/service/impl/scoresaber"; +import { setCookieValue } from "@ssr/common/utils/cookie-utils"; const SETTINGS_ID = "SSR"; // DO NOT CHANGE -const FRIENDS_ID = "FRIENDS"; // DO NOT CHANGE export default class Database extends Dexie { /** diff --git a/projects/website/src/components/player/claim-profile.tsx b/projects/website/src/components/player/claim-profile.tsx index 79fb192..3921468 100644 --- a/projects/website/src/components/player/claim-profile.tsx +++ b/projects/website/src/components/player/claim-profile.tsx @@ -7,7 +7,7 @@ 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"; +import { setCookieValue } from "@ssr/common/utils/cookie-utils"; type Props = { /** diff --git a/projects/website/src/components/player/player-scores.tsx b/projects/website/src/components/player/player-scores.tsx index e71318d..ba7b585 100644 --- a/projects/website/src/components/player/player-scores.tsx +++ b/projects/website/src/components/player/player-scores.tsx @@ -16,7 +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"; +import { setCookieValue } from "@ssr/common/utils/cookie-utils"; type Props = { initialScoreData?: ScoreSaberPlayerScoresPageToken; diff --git a/projects/website/src/components/score/score.tsx b/projects/website/src/components/score/score.tsx index 9d1feaf..562aba9 100644 --- a/projects/website/src/components/score/score.tsx +++ b/projects/website/src/components/score/score.tsx @@ -48,16 +48,29 @@ export default function Score({ player, playerScore, settings }: Props) { setBeatSaverMap(beatSaverMapData); }, [leaderboard.songHash, settings?.noScoreButtons]); + /** + * Set the base score + */ useEffect(() => { if (playerScore?.score?.baseScore) { setBaseScore(playerScore.score.baseScore); } }, [playerScore]); + /** + * Fetch the beatSaver data on page load + */ useEffect(() => { fetchBeatSaverData(); }, [fetchBeatSaverData]); + /** + * Close the leaderboard when the score changes + */ + useEffect(() => { + setIsLeaderboardExpanded(false); + }, [score]); + const accuracy = (baseScore / leaderboard.maxScore) * 100; const pp = baseScore === score.baseScore ? score.pp : scoresaberService.getPp(leaderboard.stars, accuracy);