cleanup and add weighted pp hover on score
Some checks failed
deploy / deploy (push) Failing after 1m34s

This commit is contained in:
Lee 2023-10-29 13:25:41 +00:00
parent 7b293b3eff
commit bef899d21e
10 changed files with 69 additions and 31 deletions

@ -3,7 +3,7 @@ import Card from "@/components/Card";
import Container from "@/components/Container"; import Container from "@/components/Container";
import { ScoresaberMetricsHistory } from "@/schemas/fascinated/scoresaberMetricsHistory"; import { ScoresaberMetricsHistory } from "@/schemas/fascinated/scoresaberMetricsHistory";
import { ssrSettings } from "@/ssrSettings"; import { ssrSettings } from "@/ssrSettings";
import { formatNumber } from "@/utils/number"; import { formatNumber } from "@/utils/numberUtils";
import { isProduction } from "@/utils/utils"; import { isProduction } from "@/utils/utils";
import { Metadata } from "next"; import { Metadata } from "next";
import Link from "next/link"; import Link from "next/link";

@ -1,5 +1,5 @@
import Leaderboard from "@/components/leaderboard/Leaderboard"; import Leaderboard from "@/components/leaderboard/Leaderboard";
import { formatNumber } from "@/utils/number"; import { formatNumber } from "@/utils/numberUtils";
import { ScoreSaberAPI } from "@/utils/scoresaber/api"; import { ScoreSaberAPI } from "@/utils/scoresaber/api";
import { scoresaberDifficultyNumberToName } from "@/utils/songUtils"; import { scoresaberDifficultyNumberToName } from "@/utils/songUtils";
import { formatTime } from "@/utils/timeUtils"; import { formatTime } from "@/utils/timeUtils";

@ -1,6 +1,6 @@
import PlayerPage from "@/components/player/PlayerPage"; import PlayerPage from "@/components/player/PlayerPage";
import { ssrSettings } from "@/ssrSettings"; import { ssrSettings } from "@/ssrSettings";
import { formatNumber } from "@/utils/number"; import { formatNumber } from "@/utils/numberUtils";
import { ScoreSaberAPI } from "@/utils/scoresaber/api"; import { ScoreSaberAPI } from "@/utils/scoresaber/api";
import { normalizedRegionName } from "@/utils/utils"; import { normalizedRegionName } from "@/utils/utils";
import { Metadata } from "next"; import { Metadata } from "next";

@ -1,7 +1,6 @@
import { ScoresaberLeaderboardInfo } from "@/schemas/scoresaber/leaderboard"; import { ScoresaberLeaderboardInfo } from "@/schemas/scoresaber/leaderboard";
import { ScoresaberScore } from "@/schemas/scoresaber/score"; import { ScoresaberScore } from "@/schemas/scoresaber/score";
import { formatNumber } from "@/utils/number"; import { formatNumber } from "@/utils/numberUtils";
import { scoresaberDifficultyNumberToName } from "@/utils/songUtils";
import { formatDate, formatTimeAgo } from "@/utils/timeUtils"; import { formatDate, formatTimeAgo } from "@/utils/timeUtils";
import Image from "next/image"; import Image from "next/image";
import Link from "next/link"; import Link from "next/link";
@ -18,9 +17,6 @@ export default function LeaderboardScore({
player, player,
leaderboard, leaderboard,
}: ScoreProps) { }: ScoreProps) {
const diffName = scoresaberDifficultyNumberToName(
leaderboard.difficulty.difficulty,
);
const accuracy = ((score.baseScore / leaderboard.maxScore) * 100).toFixed(2); const accuracy = ((score.baseScore / leaderboard.maxScore) * 100).toFixed(2);
return ( return (

@ -1,5 +1,5 @@
import { ScoresaberPlayer } from "@/schemas/scoresaber/player"; import { ScoresaberPlayer } from "@/schemas/scoresaber/player";
import { formatNumber } from "@/utils/number"; import { formatNumber } from "@/utils/numberUtils";
import { import {
CategoryScale, CategoryScale,
Chart as ChartJS, Chart as ChartJS,

@ -1,7 +1,7 @@
import { ScoresaberPlayer } from "@/schemas/scoresaber/player"; import { ScoresaberPlayer } from "@/schemas/scoresaber/player";
import { useScoresaberScoresStore } from "@/store/scoresaberScoresStore"; import { useScoresaberScoresStore } from "@/store/scoresaberScoresStore";
import { useSettingsStore } from "@/store/settingsStore"; import { useSettingsStore } from "@/store/settingsStore";
import { formatNumber } from "@/utils/number"; import { formatNumber } from "@/utils/numberUtils";
import { import {
calcPpBoundary, calcPpBoundary,
getAveragePp, getAveragePp,

@ -1,7 +1,8 @@
import { ScoresaberLeaderboardInfo } from "@/schemas/scoresaber/leaderboard"; import { ScoresaberLeaderboardInfo } from "@/schemas/scoresaber/leaderboard";
import { ScoresaberPlayer } from "@/schemas/scoresaber/player"; import { ScoresaberPlayer } from "@/schemas/scoresaber/player";
import { ScoresaberScore } from "@/schemas/scoresaber/score"; import { ScoresaberScore } from "@/schemas/scoresaber/score";
import { formatNumber } from "@/utils/number"; import { formatNumber } from "@/utils/numberUtils";
import { getPpGainedFromScore } from "@/utils/scoresaber/scores";
import { import {
scoresaberDifficultyNumberToName, scoresaberDifficultyNumberToName,
songDifficultyToColor, songDifficultyToColor,
@ -120,6 +121,10 @@ export default function Score({ score, player, leaderboard }: ScoreProps) {
<ScoreStatLabel <ScoreStatLabel
className="bg-blue-500 text-center" className="bg-blue-500 text-center"
value={formatNumber(score.pp.toFixed(2)) + "pp"} value={formatNumber(score.pp.toFixed(2)) + "pp"}
title={`Weighted pp ${formatNumber(
getPpGainedFromScore(player.id, score),
2,
)}pp`}
/> />
)} )}

@ -1,12 +0,0 @@
/**
* Formats a number to a string with commas
*
* @param number the number to format
* @returns the formatted number
*/
export function formatNumber(number: any) {
if (number === undefined) {
return "";
}
return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

@ -7,3 +7,25 @@
export function isNumber(value: any): boolean { export function isNumber(value: any): boolean {
return !isNaN(value); return !isNaN(value);
} }
/**
* Formats a number to a string with commas
*
* @param number the number to format
* @returns the formatted number
*/
export function formatNumber(number: any, decimals?: number) {
if (decimals === undefined) {
decimals = 0;
}
if (number === undefined) {
return "";
}
if (typeof number !== "number") {
return number;
}
return number.toLocaleString(undefined, {
minimumFractionDigits: decimals,
maximumFractionDigits: decimals,
});
}

@ -1,6 +1,7 @@
// Yoinked from https://github.com/Shurdoof/pp-calculator // Yoinked from https://github.com/Shurdoof/pp-calculator
// Thank for for this I have no fucking idea what the maths is doing but it works! // Thank for for this I have no fucking idea what the maths is doing but it works!
import { ScoresaberScore } from "@/schemas/scoresaber/score";
import { useScoresaberScoresStore } from "@/store/scoresaberScoresStore"; import { useScoresaberScoresStore } from "@/store/scoresaberScoresStore";
export const WEIGHT_COEFFICIENT = 0.965; export const WEIGHT_COEFFICIENT = 0.965;
@ -168,6 +169,38 @@ export function calcPpBoundary(playerId: string, expectedPp = 1) {
} }
} }
/**
* Gets the ranked scores of the player
*
* @param playerId the player id
* @returns all ranked scores of the player
*/
export function getRankedScores(playerId: string, sorted: boolean = false) {
const scores = useScoresaberScoresStore
.getState()
.players.find((p) => p.id === playerId)
?.scores?.filter((s) => s.score.pp !== undefined);
if (sorted && scores) {
return scores.sort((a, b) => b.score.pp - a.score.pp);
}
return scores;
}
/**
* Gets the global pp gained from the score
*
* @param playerId the player id
* @param score the score to get the pp gained from
* @returns the pp gained from the score
*/
export function getPpGainedFromScore(playerId: string, score: ScoresaberScore) {
const scores = getRankedScores(playerId, true);
if (!scores) return null;
const scoreIndex = scores.map((s) => s.score.id).indexOf(score.id);
return score.pp * Math.pow(WEIGHT_COEFFICIENT, scoreIndex);
}
/** /**
* Get the highest pp play of a player * Get the highest pp play of a player
* *
@ -195,16 +228,10 @@ export function getHighestPpPlay(playerId: string) {
* @param limit the amount of top scores to average (default: 50) * @param limit the amount of top scores to average (default: 50)
*/ */
export function getAveragePp(playerId: string, limit: number = 50) { export function getAveragePp(playerId: string, limit: number = 50) {
const rankedScores = useScoresaberScoresStore const rankedScores = getRankedScores(playerId, true);
.getState()
.players.find((p) => p.id === playerId)
?.scores?.filter((s) => s.score.pp !== undefined);
if (!rankedScores) return null; if (!rankedScores) return null;
const rankedScorePps = rankedScores const rankedScorePps = rankedScores.map((s) => s.score.pp).slice(0, limit);
.map((s) => s.score.pp)
.sort((a, b) => b - a)
.slice(0, limit);
return ( return (
rankedScorePps.reduce((cum, pp) => cum + pp, 0) / rankedScorePps.length rankedScorePps.reduce((cum, pp) => cum + pp, 0) / rankedScorePps.length