diff --git a/src/common/song-utils.ts b/src/common/song-utils.ts index 7909628..a966b7a 100644 --- a/src/common/song-utils.ts +++ b/src/common/song-utils.ts @@ -1,3 +1,25 @@ +export const diffColors: Record = { + easy: "MediumSeaGreen", + normal: "#59b0f4", + hard: "tomato", + expert: "#bf2a42", + expertPlus: "#8f48db", +}; + +const badgesDef: { + name: string; + min: number | null; + max: number | null; + color: string; +}[] = [ + { name: "SS+", min: 95, max: null, color: diffColors.expertPlus }, + { name: "SS", min: 90, max: 95, color: diffColors.expert }, + { name: "S+", min: 85, max: 90, color: diffColors.hard }, + { name: "S", min: 80, max: 85, color: diffColors.normal }, + { name: "A", min: 70, max: 80, color: diffColors.easy }, + { name: "-", min: null, max: 70, color: "hsl(var(--accent))" }, +]; + /** * Turns the difficulty of a song into a color * @@ -5,18 +27,24 @@ * @returns the color for the difficulty */ export function songDifficultyToColor(diff: string) { - switch (diff.toLowerCase()) { - case "easy": - return "#3cb371"; - case "normal": - return "#59b0f4"; - case "hard": - return "#FF6347"; - case "expert": - return "#bf2a42"; - case "expert+": - return "#8f48db"; - default: - return "gray"; - } + diff = diff.replace("+", "Plus"); + return diffColors[diff.toLowerCase() as keyof typeof diffColors]; +} + +/** + * Formats the accuracy into a color + * + * @param acc the accuracy to get the color for + */ +export function accuracyToColor(acc: number): string { + for (const badge of badgesDef) { + if ( + (badge.min === null || acc >= badge.min) && + (badge.max === null || acc < badge.max) + ) { + return badge.color; + } + } + // Return a default color if no badge matches + return "#000000"; // black or any default color } diff --git a/src/components/player/player-rank-chart.tsx b/src/components/player/player-rank-chart.tsx index fa594a6..2be7393 100644 --- a/src/components/player/player-rank-chart.tsx +++ b/src/components/player/player-rank-chart.tsx @@ -114,7 +114,7 @@ export default function PlayerRankChart({ player }: Props) { lineTension: 0.5, data: playerRankHistory, label: "Rank", - borderColor: "#a147fa", + borderColor: "#606fff", fill: false, color: "#fff", }, diff --git a/src/components/player/score/score-stats.tsx b/src/components/player/score/score-stats.tsx index f44645d..580dd7e 100644 --- a/src/components/player/score/score-stats.tsx +++ b/src/components/player/score/score-stats.tsx @@ -4,9 +4,14 @@ import { formatNumberWithCommas } from "@/common/number-utils"; import StatValue from "@/components/stat-value"; import { XMarkIcon } from "@heroicons/react/24/solid"; import clsx from "clsx"; +import { accuracyToColor } from "@/common/song-utils"; type Badge = { name: string; + color?: ( + score: ScoreSaberScore, + leaderboard: ScoreSaberLeaderboard, + ) => string | undefined; create: ( score: ScoreSaberScore, leaderboard: ScoreSaberLeaderboard, @@ -16,6 +21,9 @@ type Badge = { const badges: Badge[] = [ { name: "PP", + color: () => { + return "bg-pp"; + }, create: (score: ScoreSaberScore) => { const pp = score.pp; if (pp === 0) { @@ -26,6 +34,10 @@ const badges: Badge[] = [ }, { name: "Accuracy", + color: (score: ScoreSaberScore, leaderboard: ScoreSaberLeaderboard) => { + const acc = (score.baseScore / leaderboard.maxScore) * 100; + return accuracyToColor(acc); + }, create: (score: ScoreSaberScore, leaderboard: ScoreSaberLeaderboard) => { const acc = (score.baseScore / leaderboard.maxScore) * 100; return `${acc.toFixed(2)}%`; @@ -78,11 +90,11 @@ export default function ScoreStats({ score, leaderboard }: Props) {
{badges.map((badge, index) => { const toRender = badge.create(score, leaderboard); + let color = badge.color?.(score, leaderboard); if (toRender === undefined) { return
; } - - return ; + return ; })}
); diff --git a/src/components/stat-value.tsx b/src/components/stat-value.tsx index 813edbc..dc980c9 100644 --- a/src/components/stat-value.tsx +++ b/src/components/stat-value.tsx @@ -1,4 +1,4 @@ -import clsx, { ClassValue } from "clsx"; +import clsx from "clsx"; type Props = { /** @@ -9,7 +9,7 @@ type Props = { /** * The background color of the stat. */ - color?: ClassValue; + color?: string; /** * The value of the stat. @@ -24,6 +24,9 @@ export default function StatValue({ name, color, value }: Props) { "flex min-w-16 gap-2 h-[28px] p-1 items-center justify-center rounded-md text-sm", color ? color : "bg-accent", )} + style={{ + backgroundColor: (!color?.includes("bg") && color) || undefined, + }} > {name && ( <> diff --git a/tailwind.config.ts b/tailwind.config.ts index 4b5a9cc..0220a13 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -10,7 +10,7 @@ const config: Config = { theme: { extend: { colors: { - pp: "#a147fa", + pp: "#606fff", background: "hsl(var(--background))", foreground: "hsl(var(--foreground))", card: {