From ccedfa26455360fcc73b7f09a73d34e325b254be Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 11 Oct 2024 19:35:39 +0100 Subject: [PATCH] add daily, weekly and monthly change to rank, countryRank and pp as a hover --- .../types/player/impl/scoresaber-player.ts | 40 ++++++++------ projects/common/src/types/player/player.ts | 6 +- .../src/components/player/player-header.tsx | 55 +++++++++++++++---- 3 files changed, 74 insertions(+), 27 deletions(-) diff --git a/projects/common/src/types/player/impl/scoresaber-player.ts b/projects/common/src/types/player/impl/scoresaber-player.ts index ee0fb05..4b0cb67 100644 --- a/projects/common/src/types/player/impl/scoresaber-player.ts +++ b/projects/common/src/types/player/impl/scoresaber-player.ts @@ -158,31 +158,27 @@ export async function getScoreSaberPlayerFromToken( .sort((a, b) => Date.parse(b[0]) - Date.parse(a[0])) .reduce((obj, [key, value]) => ({ ...obj, [key]: value }), {}); - const yesterdayDate = formatDateMinimal(getMidnightAlignedDate(getDaysAgoDate(1))); - const todayStats = statisticHistory[todayDate]; - const yesterdayStats = statisticHistory[yesterdayDate]; - const hasChange = !!(todayStats && yesterdayStats); - /** * Gets the change in the given stat * * @param statType the stat to check + * @param daysAgo the amount of days ago to get the stat for * @return the change */ - const getChange = (statType: "rank" | "countryRank" | "pp"): number => { + const getChange = (statType: "rank" | "countryRank" | "pp", daysAgo: number = 1): number => { + const todayStats = statisticHistory[todayDate]; + const otherDate = formatDateMinimal(getMidnightAlignedDate(getDaysAgoDate(daysAgo))); + const otherStats = statisticHistory[otherDate]; + const hasChange = !!(todayStats && otherStats); + if (!hasChange) { return 0; } const statToday = todayStats[`${statType}`]; - const statYesterday = yesterdayStats[`${statType}`]; - return !!(statToday && statYesterday) ? statToday - statYesterday : 0; + const statOther = otherStats[`${statType}`]; + return (!!(statToday && statOther) ? statToday - statOther : 0) * -1; }; - // Calculate the changes - const rankChange = getChange("rank"); - const countryRankChange = getChange("countryRank"); - const ppChange = getChange("pp"); - const getRankPosition = (rank: number): number => { return Math.floor(rank / 50) + 1; }; @@ -198,9 +194,21 @@ export async function getScoreSaberPlayerFromToken( bio: bio, pp: token.pp, statisticChange: { - rank: rankChange * -1, // Reverse the rank change - countryRank: countryRankChange * -1, // Reverse the country rank change - pp: ppChange, + today: { + rank: getChange("rank", 1), + countryRank: getChange("countryRank", 1), + pp: getChange("pp", 1), + }, + weekly: { + rank: getChange("rank", 7), + countryRank: getChange("countryRank", 7), + pp: getChange("pp", 7), + }, + monthly: { + rank: getChange("rank", 30), + countryRank: getChange("countryRank", 30), + pp: getChange("pp", 30), + }, }, role: role, badges: badges, diff --git a/projects/common/src/types/player/player.ts b/projects/common/src/types/player/player.ts index 868c7dd..da47c5d 100644 --- a/projects/common/src/types/player/player.ts +++ b/projects/common/src/types/player/player.ts @@ -55,4 +55,8 @@ export default class Player { } } -export type StatisticChange = PlayerHistory; +export type StatisticChange = { + today: PlayerHistory; + weekly: PlayerHistory; + monthly: PlayerHistory; +}; diff --git a/projects/website/src/components/player/player-header.tsx b/projects/website/src/components/player/player-header.tsx index 771a0c1..c620a15 100644 --- a/projects/website/src/components/player/player-header.tsx +++ b/projects/website/src/components/player/player-header.tsx @@ -18,7 +18,7 @@ import Link from "next/link"; * @param tooltip the tooltip to display * @param format the function to format the value */ -const renderChange = (change: number, tooltip: ReactElement, format?: (value: number) => string) => { +const renderDailyChange = (change: number, tooltip: ReactElement, format?: (value: number) => string) => { format = format ?? formatNumberWithCommas; return ( @@ -31,6 +31,34 @@ const renderChange = (change: number, tooltip: ReactElement, format?: (value: nu ); }; +/** + * Renders the change over time a stat eg: rank, country rank + * + * @param player the player to get the stats for + * @param children the children to render + * @param type the type of stat to get the change for + */ +const renderChange = (player: ScoreSaberPlayer, type: "rank" | "countryRank" | "pp", children: ReactElement) => { + const todayStats = player.statisticChange?.today; + const weeklyStats = player.statisticChange?.weekly; + const monthlyStats = player.statisticChange?.monthly; + + return ( + +

Daily Change: {todayStats?.[type] || "Missing Data"}

+

Weekly Change: {weeklyStats?.[type] || "Missing Data"}

+

Monthly Change: {monthlyStats?.[type] || "Missing Data"}

+ + } + > + {children} +
+ ); +}; + const playerData = [ { showWhenInactiveOrBanned: false, @@ -39,13 +67,15 @@ const playerData = [ }, render: (player: ScoreSaberPlayer) => { const statisticChange = player.statisticChange; - const rankChange = statisticChange?.rank ?? 0; + const rankChange = statisticChange?.today?.rank ?? 0; - return ( + return renderChange( + player, + "rank",

#{formatNumberWithCommas(player.rank)}

- {rankChange != 0 && renderChange(rankChange,

The change in your rank compared to yesterday

)} + {rankChange != 0 && renderDailyChange(rankChange,

The change in your rank compared to yesterday

)}
); @@ -58,15 +88,18 @@ const playerData = [ }, render: (player: ScoreSaberPlayer) => { const statisticChange = player.statisticChange; - const rankChange = statisticChange?.countryRank ?? 0; + const rankChange = statisticChange?.today?.countryRank ?? 0; - return ( + return renderChange( + player, + "countryRank",

#{formatNumberWithCommas(player.countryRank)}

- {rankChange != 0 && renderChange(rankChange,

The change in your country rank compared to yesterday

)} + {rankChange != 0 && + renderDailyChange(rankChange,

The change in your country rank compared to yesterday

)}
); @@ -76,13 +109,15 @@ const playerData = [ showWhenInactiveOrBanned: true, render: (player: ScoreSaberPlayer) => { const statisticChange = player.statisticChange; - const ppChange = statisticChange?.pp ?? 0; + const ppChange = statisticChange?.today?.pp ?? 0; - return ( + return renderChange( + player, + "pp",

{formatPp(player.pp)}pp

{ppChange != 0 && - renderChange(ppChange,

The change in your pp compared to yesterday

, number => { + renderDailyChange(ppChange,

The change in your pp compared to yesterday

, number => { return `${formatPp(number)}pp`; })}