make mapper name clickable on the leaderboard
This commit is contained in:
parent
4d8debe333
commit
57a9780fe8
11
projects/common/src/utils/beatsaver.util.ts
Normal file
11
projects/common/src/utils/beatsaver.util.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { BeatSaverMap } from "../model/beatsaver/beatsaver-map";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the beatSaver mapper profile url.
|
||||||
|
*
|
||||||
|
* @param map the beatsaver map
|
||||||
|
* @returns the beatsaver mapper profile url
|
||||||
|
*/
|
||||||
|
export function getBeatSaverMapperProfileUrl(map?: BeatSaverMap) {
|
||||||
|
return map != undefined ? `https://beatsaver.com/profile/${map?.author.id}` : undefined;
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import ScoreSaberPlayerToken from "./types/token/scoresaber/score-saber-player-token";
|
import ScoreSaberPlayerToken from "../types/token/scoresaber/score-saber-player-token";
|
||||||
import ScoreSaberLeaderboardPlayerInfoToken from "./types/token/scoresaber/score-saber-leaderboard-player-info-token";
|
import ScoreSaberLeaderboardPlayerInfoToken from "../types/token/scoresaber/score-saber-leaderboard-player-info-token";
|
||||||
import ScoreSaberPlayer from "./player/impl/scoresaber-player";
|
import ScoreSaberPlayer from "../player/impl/scoresaber-player";
|
||||||
|
|
||||||
type ScoreSaberRole = {
|
type ScoreSaberRole = {
|
||||||
/**
|
/**
|
@ -4,6 +4,8 @@ import { LeaderboardSongStarCount } from "@/components/leaderboard/leaderboard-s
|
|||||||
import ScoreButtons from "@/components/score/score-buttons";
|
import ScoreButtons from "@/components/score/score-buttons";
|
||||||
import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard";
|
import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard";
|
||||||
import { BeatSaverMap } from "@ssr/common/model/beatsaver/beatsaver-map";
|
import { BeatSaverMap } from "@ssr/common/model/beatsaver/beatsaver-map";
|
||||||
|
import { getBeatSaverMapperProfileUrl } from "@ssr/common/utils/beatsaver.util";
|
||||||
|
import FallbackLink from "@/components/fallback-link";
|
||||||
|
|
||||||
type LeaderboardInfoProps = {
|
type LeaderboardInfoProps = {
|
||||||
/**
|
/**
|
||||||
@ -35,7 +37,12 @@ export function LeaderboardInfo({ leaderboard, beatSaverMap }: LeaderboardInfoPr
|
|||||||
{/* Song Stats */}
|
{/* Song Stats */}
|
||||||
<div className="text-sm">
|
<div className="text-sm">
|
||||||
<p>
|
<p>
|
||||||
Mapper: <span className="text-pp font-semibold">{leaderboard.levelAuthorName}</span>
|
Mapper:{" "}
|
||||||
|
<FallbackLink href={getBeatSaverMapperProfileUrl(beatSaverMap)}>
|
||||||
|
<span className="text-pp font-semibold hover:brightness-[66%] transform-gpu transition-all">
|
||||||
|
{leaderboard.levelAuthorName}
|
||||||
|
</span>
|
||||||
|
</FallbackLink>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Plays: <span className="font-semibold">{leaderboard.plays}</span> ({leaderboard.dailyPlays} today)
|
Plays: <span className="font-semibold">{leaderboard.plays}</span> ({leaderboard.dailyPlays} today)
|
||||||
|
@ -139,9 +139,9 @@ 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>
|
||||||
|
|
||||||
|
{showDifficulties && (
|
||||||
<div className="flex gap-2 justify-center items-center flex-wrap">
|
<div className="flex gap-2 justify-center items-center flex-wrap">
|
||||||
{showDifficulties &&
|
{leaderboard.difficulties.map(({ difficultyRaw, leaderboardId }) => {
|
||||||
leaderboard.difficulties.map(({ difficultyRaw, leaderboardId }) => {
|
|
||||||
const difficulty = getDifficultyFromRawDifficulty(difficultyRaw);
|
const difficulty = getDifficultyFromRawDifficulty(difficultyRaw);
|
||||||
// todo: add support for other gamemodes?
|
// todo: add support for other gamemodes?
|
||||||
if (difficulty.gamemode !== "Standard") {
|
if (difficulty.gamemode !== "Standard") {
|
||||||
@ -167,6 +167,7 @@ export default function LeaderboardScores({
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="overflow-x-auto relative">
|
<div className="overflow-x-auto relative">
|
||||||
<table className="table w-full table-auto border-spacing-2 border-none text-left text-sm">
|
<table className="table w-full table-auto border-spacing-2 border-none text-left text-sm">
|
||||||
@ -179,7 +180,7 @@ export default function LeaderboardScores({
|
|||||||
<th className="px-2 py-1 text-center">Accuracy</th>
|
<th className="px-2 py-1 text-center">Accuracy</th>
|
||||||
<th className="px-2 py-1 text-center">Misses</th>
|
<th className="px-2 py-1 text-center">Misses</th>
|
||||||
<th className="px-2 py-1 text-center">PP</th>
|
<th className="px-2 py-1 text-center">PP</th>
|
||||||
<th className="px-2 py-1 text-center">Modifiers</th>
|
<th className="px-2 py-1 text-center">Mods</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<motion.tbody initial="hidden" animate={controls} className="border-none" variants={scoreAnimation}>
|
<motion.tbody initial="hidden" animate={controls} className="border-none" variants={scoreAnimation}>
|
||||||
|
@ -3,9 +3,9 @@ import CountryFlag from "@/components/country-flag";
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import ScoreSaberPlayerToken from "@ssr/common/types/token/scoresaber/score-saber-player-token";
|
import ScoreSaberPlayerToken from "@ssr/common/types/token/scoresaber/score-saber-player-token";
|
||||||
import ScoreSaberLeaderboardPlayerInfoToken from "@ssr/common/types/token/scoresaber/score-saber-leaderboard-player-info-token";
|
import ScoreSaberLeaderboardPlayerInfoToken from "@ssr/common/types/token/scoresaber/score-saber-leaderboard-player-info-token";
|
||||||
import { getScoreSaberRole } from "@ssr/common/scoresaber.util";
|
|
||||||
import ScoreSaberPlayer from "@ssr/common/player/impl/scoresaber-player";
|
import ScoreSaberPlayer from "@ssr/common/player/impl/scoresaber-player";
|
||||||
import { clsx } from "clsx";
|
import { clsx } from "clsx";
|
||||||
|
import { getScoreSaberRole } from "@ssr/common/scoresaber.util";
|
||||||
|
|
||||||
type TablePlayerProps = {
|
type TablePlayerProps = {
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user