add daily, weekly and monthly change to rank, countryRank and pp as a hover
This commit is contained in:
parent
a0681d7b1c
commit
ccedfa2645
@ -158,31 +158,27 @@ export async function getScoreSaberPlayerFromToken(
|
|||||||
.sort((a, b) => Date.parse(b[0]) - Date.parse(a[0]))
|
.sort((a, b) => Date.parse(b[0]) - Date.parse(a[0]))
|
||||||
.reduce((obj, [key, value]) => ({ ...obj, [key]: value }), {});
|
.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
|
* Gets the change in the given stat
|
||||||
*
|
*
|
||||||
* @param statType the stat to check
|
* @param statType the stat to check
|
||||||
|
* @param daysAgo the amount of days ago to get the stat for
|
||||||
* @return the change
|
* @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) {
|
if (!hasChange) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
const statToday = todayStats[`${statType}`];
|
const statToday = todayStats[`${statType}`];
|
||||||
const statYesterday = yesterdayStats[`${statType}`];
|
const statOther = otherStats[`${statType}`];
|
||||||
return !!(statToday && statYesterday) ? statToday - statYesterday : 0;
|
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 => {
|
const getRankPosition = (rank: number): number => {
|
||||||
return Math.floor(rank / 50) + 1;
|
return Math.floor(rank / 50) + 1;
|
||||||
};
|
};
|
||||||
@ -198,9 +194,21 @@ export async function getScoreSaberPlayerFromToken(
|
|||||||
bio: bio,
|
bio: bio,
|
||||||
pp: token.pp,
|
pp: token.pp,
|
||||||
statisticChange: {
|
statisticChange: {
|
||||||
rank: rankChange * -1, // Reverse the rank change
|
today: {
|
||||||
countryRank: countryRankChange * -1, // Reverse the country rank change
|
rank: getChange("rank", 1),
|
||||||
pp: ppChange,
|
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,
|
role: role,
|
||||||
badges: badges,
|
badges: badges,
|
||||||
|
@ -55,4 +55,8 @@ export default class Player {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type StatisticChange = PlayerHistory;
|
export type StatisticChange = {
|
||||||
|
today: PlayerHistory;
|
||||||
|
weekly: PlayerHistory;
|
||||||
|
monthly: PlayerHistory;
|
||||||
|
};
|
||||||
|
@ -18,7 +18,7 @@ import Link from "next/link";
|
|||||||
* @param tooltip the tooltip to display
|
* @param tooltip the tooltip to display
|
||||||
* @param format the function to format the value
|
* @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;
|
format = format ?? formatNumberWithCommas;
|
||||||
|
|
||||||
return (
|
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 (
|
||||||
|
<Tooltip
|
||||||
|
side="bottom"
|
||||||
|
display={
|
||||||
|
<div>
|
||||||
|
<p>Daily Change: {todayStats?.[type] || "Missing Data"}</p>
|
||||||
|
<p>Weekly Change: {weeklyStats?.[type] || "Missing Data"}</p>
|
||||||
|
<p>Monthly Change: {monthlyStats?.[type] || "Missing Data"}</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const playerData = [
|
const playerData = [
|
||||||
{
|
{
|
||||||
showWhenInactiveOrBanned: false,
|
showWhenInactiveOrBanned: false,
|
||||||
@ -39,13 +67,15 @@ const playerData = [
|
|||||||
},
|
},
|
||||||
render: (player: ScoreSaberPlayer) => {
|
render: (player: ScoreSaberPlayer) => {
|
||||||
const statisticChange = player.statisticChange;
|
const statisticChange = player.statisticChange;
|
||||||
const rankChange = statisticChange?.rank ?? 0;
|
const rankChange = statisticChange?.today?.rank ?? 0;
|
||||||
|
|
||||||
return (
|
return renderChange(
|
||||||
|
player,
|
||||||
|
"rank",
|
||||||
<Link href={`/ranking/${player.rankPages.global}`}>
|
<Link href={`/ranking/${player.rankPages.global}`}>
|
||||||
<div className="text-gray-300 flex gap-1 items-center">
|
<div className="text-gray-300 flex gap-1 items-center">
|
||||||
<p className="hover:brightness-75 transition-all transform-gpu">#{formatNumberWithCommas(player.rank)}</p>
|
<p className="hover:brightness-75 transition-all transform-gpu">#{formatNumberWithCommas(player.rank)}</p>
|
||||||
{rankChange != 0 && renderChange(rankChange, <p>The change in your rank compared to yesterday</p>)}
|
{rankChange != 0 && renderDailyChange(rankChange, <p>The change in your rank compared to yesterday</p>)}
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
@ -58,15 +88,18 @@ const playerData = [
|
|||||||
},
|
},
|
||||||
render: (player: ScoreSaberPlayer) => {
|
render: (player: ScoreSaberPlayer) => {
|
||||||
const statisticChange = player.statisticChange;
|
const statisticChange = player.statisticChange;
|
||||||
const rankChange = statisticChange?.countryRank ?? 0;
|
const rankChange = statisticChange?.today?.countryRank ?? 0;
|
||||||
|
|
||||||
return (
|
return renderChange(
|
||||||
|
player,
|
||||||
|
"countryRank",
|
||||||
<Link href={`/ranking/${player.country}/${player.rankPages.country}`}>
|
<Link href={`/ranking/${player.country}/${player.rankPages.country}`}>
|
||||||
<div className="text-gray-300 flex gap-1 items-center">
|
<div className="text-gray-300 flex gap-1 items-center">
|
||||||
<p className="hover:brightness-75 transition-all transform-gpu">
|
<p className="hover:brightness-75 transition-all transform-gpu">
|
||||||
#{formatNumberWithCommas(player.countryRank)}
|
#{formatNumberWithCommas(player.countryRank)}
|
||||||
</p>
|
</p>
|
||||||
{rankChange != 0 && renderChange(rankChange, <p>The change in your country rank compared to yesterday</p>)}
|
{rankChange != 0 &&
|
||||||
|
renderDailyChange(rankChange, <p>The change in your country rank compared to yesterday</p>)}
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
@ -76,13 +109,15 @@ const playerData = [
|
|||||||
showWhenInactiveOrBanned: true,
|
showWhenInactiveOrBanned: true,
|
||||||
render: (player: ScoreSaberPlayer) => {
|
render: (player: ScoreSaberPlayer) => {
|
||||||
const statisticChange = player.statisticChange;
|
const statisticChange = player.statisticChange;
|
||||||
const ppChange = statisticChange?.pp ?? 0;
|
const ppChange = statisticChange?.today?.pp ?? 0;
|
||||||
|
|
||||||
return (
|
return renderChange(
|
||||||
|
player,
|
||||||
|
"pp",
|
||||||
<div className="text-pp flex gap-1 items-center">
|
<div className="text-pp flex gap-1 items-center">
|
||||||
<p>{formatPp(player.pp)}pp</p>
|
<p>{formatPp(player.pp)}pp</p>
|
||||||
{ppChange != 0 &&
|
{ppChange != 0 &&
|
||||||
renderChange(ppChange, <p>The change in your pp compared to yesterday</p>, number => {
|
renderDailyChange(ppChange, <p>The change in your pp compared to yesterday</p>, number => {
|
||||||
return `${formatPp(number)}pp`;
|
return `${formatPp(number)}pp`;
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
Reference in New Issue
Block a user