mobile leaderboard fixes and hide diffs that aren't standard (for now)
Some checks failed
Deploy / deploy (push) Has been cancelled
Some checks failed
Deploy / deploy (push) Has been cancelled
This commit is contained in:
parent
f60f34c0c2
commit
50414d848a
@ -1,11 +1,19 @@
|
|||||||
const diffColors: Record<string, string> = {
|
type Difficulty = {
|
||||||
easy: "#3CB371",
|
name: DifficultyName;
|
||||||
normal: "#59b0f4",
|
gamemode?: string;
|
||||||
hard: "#FF6347",
|
color: string;
|
||||||
expert: "#bf2a42",
|
|
||||||
expertplus: "#8f48db",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type DifficultyName = "Easy" | "Normal" | "Hard" | "Expert" | "Expert+";
|
||||||
|
|
||||||
|
const difficulties: Difficulty[] = [
|
||||||
|
{ name: "Easy", color: "#59b0f4" },
|
||||||
|
{ name: "Normal", color: "#59b0f4" },
|
||||||
|
{ name: "Hard", color: "#FF6347" },
|
||||||
|
{ name: "Expert", color: "#bf2a42" },
|
||||||
|
{ name: "Expert+", color: "#8f48db" },
|
||||||
|
];
|
||||||
|
|
||||||
export type ScoreBadge = {
|
export type ScoreBadge = {
|
||||||
name: string;
|
name: string;
|
||||||
min: number | null;
|
min: number | null;
|
||||||
@ -14,11 +22,11 @@ export type ScoreBadge = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const scoreBadges: ScoreBadge[] = [
|
const scoreBadges: ScoreBadge[] = [
|
||||||
{ name: "SS+", min: 95, max: null, color: diffColors.expertplus },
|
{ name: "SS+", min: 95, max: null, color: getDifficulty("Expert+")!.color },
|
||||||
{ name: "SS", min: 90, max: 95, color: diffColors.expert },
|
{ name: "SS", min: 90, max: 95, color: getDifficulty("Expert")!.color },
|
||||||
{ name: "S+", min: 85, max: 90, color: diffColors.hard },
|
{ name: "S+", min: 85, max: 90, color: getDifficulty("Hard")!.color },
|
||||||
{ name: "S", min: 80, max: 85, color: diffColors.normal },
|
{ name: "S", min: 80, max: 85, color: getDifficulty("Normal")!.color },
|
||||||
{ name: "A", min: 70, max: 80, color: diffColors.easy },
|
{ name: "A", min: 70, max: 80, color: getDifficulty("Easy")!.color },
|
||||||
{ name: "-", min: null, max: 70, color: "hsl(var(--accent))" },
|
{ name: "-", min: null, max: 70, color: "hsl(var(--accent))" },
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -49,6 +57,39 @@ export function getScoreBadgeFromAccuracy(acc: number): ScoreBadge {
|
|||||||
return scoreBadges[scoreBadges.length - 1];
|
return scoreBadges[scoreBadges.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a raw difficulty into a {@link Difficulty}
|
||||||
|
* Example: _Easy_SoloStandard -> { name: "Easy", type: "Standard", color: "#59b0f4" }
|
||||||
|
*
|
||||||
|
* @param rawDifficulty the raw difficulty to parse
|
||||||
|
* @return the parsed difficulty
|
||||||
|
*/
|
||||||
|
export function getDifficultyFromRawDifficulty(rawDifficulty: string): Difficulty {
|
||||||
|
const [name, ...type] = rawDifficulty
|
||||||
|
.replace("Plus", "+") // Replaces Plus with + so we can match it to our difficulty names
|
||||||
|
.replace("Solo", "") // Removes "Solo"
|
||||||
|
.replace(/^_+|_+$/g, "") // Removes leading and trailing underscores
|
||||||
|
.split("_");
|
||||||
|
const difficulty = difficulties.find(d => d.name === name);
|
||||||
|
if (!difficulty) {
|
||||||
|
throw new Error(`Unknown difficulty: ${rawDifficulty}`);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...difficulty,
|
||||||
|
gamemode: type.join("_"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a {@link Difficulty} from its name
|
||||||
|
*
|
||||||
|
* @param diff the name of the difficulty
|
||||||
|
* @returns the difficulty
|
||||||
|
*/
|
||||||
|
export function getDifficulty(diff: DifficultyName) {
|
||||||
|
return difficulties.find(d => d.name === diff);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turns the difficulty of a song into a color
|
* Turns the difficulty of a song into a color
|
||||||
*
|
*
|
||||||
@ -56,6 +97,5 @@ export function getScoreBadgeFromAccuracy(acc: number): ScoreBadge {
|
|||||||
* @returns the color for the difficulty
|
* @returns the color for the difficulty
|
||||||
*/
|
*/
|
||||||
export function songDifficultyToColor(diff: string) {
|
export function songDifficultyToColor(diff: string) {
|
||||||
diff = diff.replace("+", "Plus");
|
return getDifficultyFromRawDifficulty(diff).color;
|
||||||
return diffColors[diff.toLowerCase() as keyof typeof diffColors];
|
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ export function LeaderboardInfo({ leaderboard, beatSaverMap }: LeaderboardInfoPr
|
|||||||
<Image
|
<Image
|
||||||
src={leaderboard.coverImage}
|
src={leaderboard.coverImage}
|
||||||
alt={`${leaderboard.songName} Cover Image`}
|
alt={`${leaderboard.songName} Cover Image`}
|
||||||
className="rounded-md w-fit h-fit"
|
className="rounded-md w-[96px] h-[96px]"
|
||||||
width={96}
|
width={96}
|
||||||
height={96}
|
height={96}
|
||||||
/>
|
/>
|
||||||
|
@ -13,8 +13,8 @@ import LeaderboardScore from "./leaderboard-score";
|
|||||||
import { scoreAnimation } from "@/components/score/score-animation";
|
import { scoreAnimation } from "@/components/score/score-animation";
|
||||||
import ScoreSaberPlayer from "@/common/model/player/impl/scoresaber-player";
|
import ScoreSaberPlayer from "@/common/model/player/impl/scoresaber-player";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { getDifficultyFromScoreSaberDifficulty } from "@/common/scoresaber-utils";
|
|
||||||
import { clsx } from "clsx";
|
import { clsx } from "clsx";
|
||||||
|
import { getDifficultyFromRawDifficulty } from "@/common/song-utils";
|
||||||
|
|
||||||
type LeaderboardScoresProps = {
|
type LeaderboardScoresProps = {
|
||||||
/**
|
/**
|
||||||
@ -130,14 +130,14 @@ export default function LeaderboardScores({
|
|||||||
* scores when new scores are loaded.
|
* scores when new scores are loaded.
|
||||||
*/
|
*/
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (topOfScoresRef.current) {
|
if (topOfScoresRef.current && shouldFetch) {
|
||||||
const topOfScoresPosition = topOfScoresRef.current.getBoundingClientRect().top + window.scrollY;
|
const topOfScoresPosition = topOfScoresRef.current.getBoundingClientRect().top + window.scrollY;
|
||||||
window.scrollTo({
|
window.scrollTo({
|
||||||
top: topOfScoresPosition - 75, // Navbar height (plus some padding)
|
top: topOfScoresPosition - 75, // Navbar height (plus some padding)
|
||||||
behavior: "smooth",
|
behavior: "smooth",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [currentPage, topOfScoresRef]);
|
}, [currentPage, topOfScoresRef, shouldFetch]);
|
||||||
|
|
||||||
if (currentScores === undefined) {
|
if (currentScores === undefined) {
|
||||||
return undefined;
|
return undefined;
|
||||||
@ -153,18 +153,24 @@ export default function LeaderboardScores({
|
|||||||
{currentScores.scores.length === 0 && <p>No scores found. Invalid Page?</p>}
|
{currentScores.scores.length === 0 && <p>No scores found. Invalid Page?</p>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex gap-2 justify-center items-center">
|
<div className="flex gap-2 justify-center items-center flex-wrap">
|
||||||
{showDifficulties &&
|
{showDifficulties &&
|
||||||
leaderboard.difficulties.map(({ difficulty, leaderboardId }) => {
|
leaderboard.difficulties.map(({ difficultyRaw, leaderboardId }) => {
|
||||||
|
const difficulty = getDifficultyFromRawDifficulty(difficultyRaw);
|
||||||
|
// todo: add support for other gamemodes?
|
||||||
|
if (difficulty.gamemode !== "Standard") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
key={difficulty}
|
key={difficultyRaw}
|
||||||
variant={leaderboardId === selectedLeaderboardId ? "default" : "outline"}
|
variant={leaderboardId === selectedLeaderboardId ? "default" : "outline"}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handleLeaderboardChange(leaderboardId);
|
handleLeaderboardChange(leaderboardId);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{getDifficultyFromScoreSaberDifficulty(difficulty)}
|
{difficulty.name}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
Reference in New Issue
Block a user