highlight correct player on leaderboard scores and make player name clickable on a leaderboard score
Some checks failed
Deploy Website / docker (ubuntu-latest) (push) Has been cancelled

This commit is contained in:
Lee 2024-10-26 11:45:34 +01:00
parent 413d72182d
commit e0c719eaba
5 changed files with 27 additions and 9 deletions

@ -8,6 +8,7 @@ import { ScoreTimeSet } from "@/components/score/score-time-set";
import { ScoreModifiers } from "@/components/score/score-modifiers"; import { ScoreModifiers } from "@/components/score/score-modifiers";
import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard"; import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard";
import ScoreMissesBadge from "@/components/score/badges/score-misses"; import ScoreMissesBadge from "@/components/score/badges/score-misses";
import ScoreSaberPlayer from "@ssr/common/player/impl/scoresaber-player";
type Props = { type Props = {
/** /**
@ -23,10 +24,10 @@ type Props = {
/** /**
* The claimed player. * The claimed player.
*/ */
claimedPlayer?: ScoreSaberPlayerToken; highlightedPlayer?: ScoreSaberPlayer;
}; };
export default function LeaderboardScore({ score, leaderboard, claimedPlayer }: Props) { export default function LeaderboardScore({ score, leaderboard, highlightedPlayer }: Props) {
const scorePlayer = score.playerInfo; const scorePlayer = score.playerInfo;
return ( return (
@ -36,7 +37,7 @@ export default function LeaderboardScore({ score, leaderboard, claimedPlayer }:
{/* Player */} {/* Player */}
<td className="px-4 py-2 flex gap-2 whitespace-nowrap"> <td className="px-4 py-2 flex gap-2 whitespace-nowrap">
<PlayerInfo player={scorePlayer} highlightedPlayer={claimedPlayer} /> <PlayerInfo player={scorePlayer} highlightedPlayer={highlightedPlayer} useLink />
</td> </td>
{/* Time Set */} {/* Time Set */}

@ -16,6 +16,7 @@ import LeaderboardScoresResponse from "@ssr/common/response/leaderboard-scores-r
import useDatabase from "@/hooks/use-database"; import useDatabase from "@/hooks/use-database";
import { useLiveQuery } from "dexie-react-hooks"; import { useLiveQuery } from "dexie-react-hooks";
import LeaderboardScoresSkeleton from "@/components/leaderboard/skeleton/leaderboard-scores-skeleton"; import LeaderboardScoresSkeleton from "@/components/leaderboard/skeleton/leaderboard-scores-skeleton";
import ScoreSaberPlayer from "@ssr/common/player/impl/scoresaber-player";
type LeaderboardScoresProps = { type LeaderboardScoresProps = {
initialPage?: number; initialPage?: number;
@ -25,6 +26,7 @@ type LeaderboardScoresProps = {
isLeaderboardPage?: boolean; isLeaderboardPage?: boolean;
leaderboardChanged?: (id: number) => void; leaderboardChanged?: (id: number) => void;
disableUrlChanging?: boolean; disableUrlChanging?: boolean;
highlightedPlayer?: ScoreSaberPlayer;
}; };
export default function LeaderboardScores({ export default function LeaderboardScores({
@ -35,12 +37,11 @@ export default function LeaderboardScores({
isLeaderboardPage, isLeaderboardPage,
leaderboardChanged, leaderboardChanged,
disableUrlChanging, disableUrlChanging,
highlightedPlayer,
}: LeaderboardScoresProps) { }: LeaderboardScoresProps) {
if (!initialPage) { if (!initialPage) {
initialPage = 1; initialPage = 1;
} }
const database = useDatabase();
const claimedPlayer = useLiveQuery(() => database.getClaimedPlayer());
const { width } = useWindowDimensions(); const { width } = useWindowDimensions();
const controls = useAnimation(); const controls = useAnimation();
@ -182,7 +183,7 @@ export default function LeaderboardScores({
<motion.tbody initial="hidden" animate={controls} className="border-none" variants={scoreAnimation}> <motion.tbody initial="hidden" animate={controls} className="border-none" variants={scoreAnimation}>
{currentScores.scores.map((playerScore, index) => ( {currentScores.scores.map((playerScore, index) => (
<motion.tr key={index} className="border-b border-border" variants={scoreAnimation}> <motion.tr key={index} className="border-b border-border" variants={scoreAnimation}>
<LeaderboardScore score={playerScore} leaderboard={leaderboard} claimedPlayer={claimedPlayer} /> <LeaderboardScore score={playerScore} leaderboard={leaderboard} highlightedPlayer={highlightedPlayer} />
</motion.tr> </motion.tr>
))} ))}
</motion.tbody> </motion.tbody>

@ -218,7 +218,12 @@ export default function PlayerScores({ initialScoreData, initialSearch, player,
> >
{scores.scores.map((score, index) => ( {scores.scores.map((score, index) => (
<motion.div key={index} variants={scoreAnimation}> <motion.div key={index} variants={scoreAnimation}>
<Score score={score.score} leaderboard={score.leaderboard} beatSaverMap={score.beatSaver} /> <Score
score={score.score}
leaderboard={score.leaderboard}
beatSaverMap={score.beatSaver}
highlightedPlayer={player}
/>
</motion.div> </motion.div>
))} ))}
</motion.div> </motion.div>

@ -4,8 +4,14 @@ import { ScoreStatsToken } from "@ssr/common/types/token/beatleader/score-stats/
import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard"; import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard";
import LeaderboardScoresResponse from "@ssr/common/response/leaderboard-scores-response"; import LeaderboardScoresResponse from "@ssr/common/response/leaderboard-scores-response";
import { ScoreSaberScore } from "@ssr/common/model/score/impl/scoresaber-score"; import { ScoreSaberScore } from "@ssr/common/model/score/impl/scoresaber-score";
import ScoreSaberPlayer from "@ssr/common/player/impl/scoresaber-player";
type ScoreOverviewProps = { type ScoreOverviewProps = {
/**
* The player to highlight
*/
highlightedPlayer?: ScoreSaberPlayer;
/** /**
* The initial page to show * The initial page to show
*/ */
@ -27,7 +33,7 @@ type ScoreOverviewProps = {
scores?: LeaderboardScoresResponse<ScoreSaberScore, ScoreSaberLeaderboard>; scores?: LeaderboardScoresResponse<ScoreSaberScore, ScoreSaberLeaderboard>;
}; };
export function ScoreOverview({ scoreStats, initialPage, leaderboard, scores }: ScoreOverviewProps) { export function ScoreOverview({ highlightedPlayer, scoreStats, initialPage, leaderboard, scores }: ScoreOverviewProps) {
return ( return (
<> <>
{scoreStats && ( {scoreStats && (
@ -40,6 +46,7 @@ export function ScoreOverview({ scoreStats, initialPage, leaderboard, scores }:
initialPage={initialPage} initialPage={initialPage}
initialScores={scores} initialScores={scores}
leaderboard={leaderboard} leaderboard={leaderboard}
highlightedPlayer={highlightedPlayer}
disableUrlChanging disableUrlChanging
/> />
</> </>

@ -26,8 +26,11 @@ import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leade
import { BeatSaverMap } from "@ssr/common/model/beatsaver/map"; import { BeatSaverMap } from "@ssr/common/model/beatsaver/map";
import LeaderboardScoresResponse from "@ssr/common/response/leaderboard-scores-response"; import LeaderboardScoresResponse from "@ssr/common/response/leaderboard-scores-response";
import { ScoreStatsToken } from "@ssr/common/types/token/beatleader/score-stats/score-stats"; import { ScoreStatsToken } from "@ssr/common/types/token/beatleader/score-stats/score-stats";
import ScoreSaberPlayerToken from "@ssr/common/types/token/scoresaber/score-saber-player-token";
import ScoreSaberPlayer from "@ssr/common/player/impl/scoresaber-player";
type Props = { type Props = {
highlightedPlayer?: ScoreSaberPlayer;
score: ScoreSaberScore; score: ScoreSaberScore;
leaderboard: ScoreSaberLeaderboard; leaderboard: ScoreSaberLeaderboard;
beatSaverMap?: BeatSaverMap; beatSaverMap?: BeatSaverMap;
@ -53,7 +56,7 @@ const modes: Mode[] = [
{ name: "Score History", icon: <TrendingUpIcon className="w-4 h-4" /> }, { name: "Score History", icon: <TrendingUpIcon className="w-4 h-4" /> },
]; ];
export default function Score({ leaderboard, beatSaverMap, score, settings }: Props) { export default function Score({ leaderboard, beatSaverMap, score, settings, highlightedPlayer }: Props) {
const [baseScore, setBaseScore] = useState(score.score); const [baseScore, setBaseScore] = useState(score.score);
const [isLeaderboardExpanded, setIsLeaderboardExpanded] = useState(false); const [isLeaderboardExpanded, setIsLeaderboardExpanded] = useState(false);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
@ -176,6 +179,7 @@ export default function Score({ leaderboard, beatSaverMap, score, settings }: Pr
leaderboard={leaderboard} leaderboard={leaderboard}
initialPage={scoresPage} initialPage={scoresPage}
scoreStats={dropdownData.scoreStats} scoreStats={dropdownData.scoreStats}
highlightedPlayer={highlightedPlayer}
/> />
)} )}