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
Some checks failed
Deploy Website / docker (ubuntu-latest) (push) Has been cancelled
This commit is contained in:
parent
413d72182d
commit
e0c719eaba
@ -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}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user