diff --git a/projects/website/src/components/score/hand-accuracy.tsx b/projects/website/src/components/score/badges/hand-accuracy.tsx similarity index 81% rename from projects/website/src/components/score/hand-accuracy.tsx rename to projects/website/src/components/score/badges/hand-accuracy.tsx index ace23cf..3c8e423 100644 --- a/projects/website/src/components/score/hand-accuracy.tsx +++ b/projects/website/src/components/score/badges/hand-accuracy.tsx @@ -1,21 +1,16 @@ import Tooltip from "@/components/tooltip"; import { Change } from "@/common/change"; -import ScoreSaberScore from "@ssr/common/score/impl/scoresaber-score"; import { capitalizeFirstLetter } from "@/common/string-utils"; +import { ScoreBadgeProps } from "@/components/score/badges/badge-props"; -type HandAccuracyProps = { - /** - * The score to get the hand accuracy from - */ - score: ScoreSaberScore; - +type HandAccuracyProps = ScoreBadgeProps & { /** * The hand to get the hand accuracy from */ hand: "left" | "right"; }; -export function HandAccuracy({ score, hand }: HandAccuracyProps) { +export function HandAccuracyBadge({ score, hand }: HandAccuracyProps) { if (!score.additionalData) { return undefined; } diff --git a/projects/website/src/components/score/badges/score-accuracy.tsx b/projects/website/src/components/score/badges/score-accuracy.tsx new file mode 100644 index 0000000..715a59f --- /dev/null +++ b/projects/website/src/components/score/badges/score-accuracy.tsx @@ -0,0 +1,67 @@ +import { getScoreBadgeFromAccuracy } from "@/common/song-utils"; +import { Modifier } from "@ssr/common/score/modifier"; +import Tooltip from "@/components/tooltip"; +import { ScoreModifiers } from "@/components/score/score-modifiers"; +import { Change } from "@/common/change"; +import { ScoreBadgeProps } from "@/components/score/badges/badge-props"; +import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard"; + +type ScoreAccuracyProps = ScoreBadgeProps & { + /** + * The leaderboard the score was set on. + */ + leaderboard: ScoreSaberLeaderboard; +}; + +export function ScoreAccuracyBadge({ score, leaderboard }: ScoreAccuracyProps) { + const scoreImprovement = score.additionalData?.scoreImprovement; + const previousAccuracy = scoreImprovement ? score.accuracy - scoreImprovement.accuracy : undefined; + + const fcAccuracy = score.additionalData?.fcAccuracy; + const scoreBadge = getScoreBadgeFromAccuracy(score.accuracy); + let accDetails = `${scoreBadge.name != "-" ? scoreBadge.name : ""}`; + if (scoreBadge.max == null) { + accDetails += ` (> ${scoreBadge.min}%)`; + } else if (scoreBadge.min == null) { + accDetails += ` (< ${scoreBadge.max}%)`; + } else { + accDetails += ` (${scoreBadge.min}% - ${scoreBadge.max}%)`; + } + + const failed = score.modifiers.includes("No Fail" as Modifier); + const modCount = score.modifiers.length; + return ( + <> +
+ +
+

Accuracy

+

Score: {accDetails}

+ {!score.fullCombo && fcAccuracy &&

Full Combo: {fcAccuracy.toFixed(2)}%

} +
+ + {modCount > 0 && ( +
+

Modifiers

+ +
+ )} + {failed &&

Failed

} +
+ } + > +

+ {score.accuracy.toFixed(2)}% {modCount > 0 && } +

+ + {scoreImprovement && previousAccuracy && ( + + `${num.toFixed(2)}%`} /> + + )} + + + ); +} diff --git a/projects/website/src/components/score/badges/score-pp.tsx b/projects/website/src/components/score/badges/score-pp.tsx new file mode 100644 index 0000000..93200d6 --- /dev/null +++ b/projects/website/src/components/score/badges/score-pp.tsx @@ -0,0 +1,49 @@ +import { ScoreBadgeProps } from "@/components/score/badges/badge-props"; +import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard"; +import Tooltip from "@/components/tooltip"; +import { formatPp } from "@ssr/common/utils/number-utils"; +import { scoresaberService } from "@ssr/common/service/impl/scoresaber"; +import { Change } from "@/common/change"; + +type ScorePpProps = ScoreBadgeProps & { + /** + * The leaderboard the score was set on. + */ + leaderboard: ScoreSaberLeaderboard; +}; + +export function ScorePpBadge({ score, leaderboard }: ScorePpProps) { + const scoreImprovement = score.additionalData?.scoreImprovement; + const previousAccuracy = scoreImprovement ? score.accuracy - scoreImprovement?.accuracy : undefined; + const fcAccuracy = score.additionalData?.fcAccuracy; + const pp = score.pp; + const weight = score.weight; + if (pp === 0 || pp === undefined || weight === undefined) { + return undefined; + } + const weightedPp = pp * weight; + const previousPp = fcAccuracy ? scoresaberService.getPp(leaderboard.stars, fcAccuracy).toFixed(0) : undefined; + const isSamePp = previousPp === pp.toFixed(0); + + return ( + <> + +

Performance Points

+

Raw: {formatPp(pp)}pp

+

+ Weighted: {formatPp(weightedPp)}pp ({(100 * weight).toFixed(2)}%) +

+ {previousPp && !isSamePp &&

Full Combo: {previousPp}pp

} + + } + > +
+

{formatPp(pp)}pp

+ {previousAccuracy && } +
+
+ + ); +} diff --git a/projects/website/src/components/score/badges/score-score.tsx b/projects/website/src/components/score/badges/score-score.tsx new file mode 100644 index 0000000..2b653f5 --- /dev/null +++ b/projects/website/src/components/score/badges/score-score.tsx @@ -0,0 +1,14 @@ +import { ScoreBadgeProps } from "@/components/score/badges/badge-props"; +import { formatNumberWithCommas } from "@ssr/common/utils/number-utils"; +import { Change } from "@/common/change"; + +export function ScoreScoreBadge({ score }: ScoreBadgeProps) { + const scoreImprovement = score.additionalData?.scoreImprovement; + + return ( +
+

{formatNumberWithCommas(Number(score.score.toFixed(0)))}

+ {scoreImprovement && } +
+ ); +} diff --git a/projects/website/src/components/score/score-stats.tsx b/projects/website/src/components/score/score-stats.tsx index cf03867..e0daede 100644 --- a/projects/website/src/components/score/score-stats.tsx +++ b/projects/website/src/components/score/score-stats.tsx @@ -1,15 +1,12 @@ -import { formatNumberWithCommas, formatPp } from "@ssr/common/utils/number-utils"; import { getScoreBadgeFromAccuracy } from "@/common/song-utils"; -import Tooltip from "@/components/tooltip"; import { ScoreBadge, ScoreBadges } from "@/components/score/score-badge"; import ScoreSaberScore from "@ssr/common/score/impl/scoresaber-score"; import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard"; import ScoreMissesBadge from "@/components/score/badges/score-misses"; -import { Modifier } from "@ssr/common/score/modifier"; -import { ScoreModifiers } from "@/components/score/score-modifiers"; -import { Change } from "@/common/change"; -import { scoresaberService } from "@ssr/common/service/impl/scoresaber"; -import { HandAccuracy } from "@/components/score/hand-accuracy"; +import { HandAccuracyBadge } from "@/components/score/badges/hand-accuracy"; +import { ScoreAccuracyBadge } from "@/components/score/badges/score-accuracy"; +import { ScorePpBadge } from "@/components/score/badges/score-pp"; +import { ScoreScoreBadge } from "@/components/score/badges/score-score"; const badges: ScoreBadge[] = [ { @@ -18,37 +15,10 @@ const badges: ScoreBadge[] = [ return "bg-pp"; }, create: (score: ScoreSaberScore, leaderboard: ScoreSaberLeaderboard) => { - const scoreImprovement = score.additionalData?.scoreImprovement; - const previousAccuracy = scoreImprovement ? score.accuracy - scoreImprovement?.accuracy : undefined; - const fcAccuracy = score.additionalData?.fcAccuracy; - const pp = score.pp; - const weight = score.weight; - if (pp === 0 || pp === undefined || weight === undefined) { + if (!score.pp) { return undefined; } - const weightedPp = pp * weight; - - return ( - <> - -

Performance Points

-

Raw: {formatPp(pp)}pp

-

- Weighted: {formatPp(weightedPp)}pp ({(100 * weight).toFixed(2)}%) -

- {fcAccuracy &&

Full Combo: {scoresaberService.getPp(leaderboard.stars, fcAccuracy).toFixed(0)}pp

} - - } - > -
-

{formatPp(pp)}pp

- {previousAccuracy && } -
-
- - ); + return ; }, }, { @@ -58,67 +28,13 @@ const badges: ScoreBadge[] = [ return getScoreBadgeFromAccuracy(acc).color; }, create: (score: ScoreSaberScore, leaderboard: ScoreSaberLeaderboard) => { - const scoreImprovement = score.additionalData?.scoreImprovement; - - const acc = (score.score / leaderboard.maxScore) * 100; - const fcAccuracy = score.additionalData?.fcAccuracy; - const scoreBadge = getScoreBadgeFromAccuracy(acc); - let accDetails = `${scoreBadge.name != "-" ? scoreBadge.name : ""}`; - if (scoreBadge.max == null) { - accDetails += ` (> ${scoreBadge.min}%)`; - } else if (scoreBadge.min == null) { - accDetails += ` (< ${scoreBadge.max}%)`; - } else { - accDetails += ` (${scoreBadge.min}% - ${scoreBadge.max}%)`; - } - - const failed = score.modifiers.includes("No Fail" as Modifier); - const modCount = score.modifiers.length; - return ( - <> - -
-

Accuracy

-

Score: {accDetails}

- {fcAccuracy &&

Full Combo: {fcAccuracy.toFixed(2)}%

} -
- - {modCount > 0 && ( -
-

Modifiers

- -
- )} - {failed &&

Failed

} - - } - > -
-

- {acc.toFixed(2)}% {modCount > 0 && } -

- {scoreImprovement && ( - `${num.toFixed(2)}%`} /> - )} -
-
- - ); + return ; }, }, { name: "Score", create: (score: ScoreSaberScore) => { - const scoreImprovement = score.additionalData?.scoreImprovement; - - return ( -
-

{formatNumberWithCommas(Number(score.score.toFixed(0)))}

- {scoreImprovement && } -
- ); + return ; }, }, { @@ -128,7 +44,7 @@ const badges: ScoreBadge[] = [ if (!score.additionalData) { return undefined; } - return ; + return ; }, }, { @@ -138,7 +54,7 @@ const badges: ScoreBadge[] = [ if (!score.additionalData) { return undefined; } - return ; + return ; }, }, {