2024-10-04 18:25:37 +01:00
|
|
|
"use client";
|
|
|
|
|
|
|
|
import LeaderboardScores from "@/components/leaderboard/leaderboard-scores";
|
|
|
|
import { LeaderboardInfo } from "@/components/leaderboard/leaderboard-info";
|
|
|
|
import { useQuery } from "@tanstack/react-query";
|
2024-10-09 01:17:00 +01:00
|
|
|
import { useEffect, useState } from "react";
|
2024-10-04 18:25:37 +01:00
|
|
|
import BeatSaverMap from "@/common/database/types/beatsaver-map";
|
2024-10-09 01:17:00 +01:00
|
|
|
import ScoreSaberLeaderboardScoresPageToken from "@ssr/common/types/token/scoresaber/score-saber-leaderboard-scores-page-token";
|
|
|
|
import ScoreSaberLeaderboardToken from "@ssr/common/types/token/scoresaber/score-saber-leaderboard-token";
|
|
|
|
import { scoresaberService } from "@ssr/common/service/impl/scoresaber";
|
2024-10-04 18:25:37 +01:00
|
|
|
|
|
|
|
type LeaderboardDataProps = {
|
|
|
|
/**
|
|
|
|
* The page to show when opening the leaderboard.
|
|
|
|
*/
|
|
|
|
initialPage?: number;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The initial scores to show.
|
|
|
|
*/
|
|
|
|
initialScores?: ScoreSaberLeaderboardScoresPageToken;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The leaderboard to display.
|
|
|
|
*/
|
|
|
|
initialLeaderboard: ScoreSaberLeaderboardToken;
|
|
|
|
};
|
|
|
|
|
|
|
|
export function LeaderboardData({ initialPage, initialScores, initialLeaderboard }: LeaderboardDataProps) {
|
|
|
|
const [beatSaverMap, setBeatSaverMap] = useState<BeatSaverMap | undefined>();
|
|
|
|
const [selectedLeaderboardId, setSelectedLeaderboardId] = useState(initialLeaderboard.id);
|
|
|
|
const [currentLeaderboard, setCurrentLeaderboard] = useState(initialLeaderboard);
|
|
|
|
|
|
|
|
const { data: leaderboard } = useQuery({
|
|
|
|
queryKey: ["leaderboard-" + initialLeaderboard.id, selectedLeaderboardId],
|
|
|
|
queryFn: () => scoresaberService.lookupLeaderboard(selectedLeaderboardId + ""),
|
|
|
|
initialData: initialLeaderboard,
|
|
|
|
staleTime: 30 * 1000, // Cache data for 30 seconds
|
|
|
|
});
|
|
|
|
|
2024-10-09 01:17:00 +01:00
|
|
|
// todo: fix
|
|
|
|
// const fetchBeatSaverData = useCallback(async () => {
|
|
|
|
// const beatSaverMap = await beatsaverService.lookupMap(initialLeaderboard.songHash);
|
|
|
|
// setBeatSaverMap(beatSaverMap);
|
|
|
|
// }, [initialLeaderboard.songHash]);
|
|
|
|
//
|
|
|
|
// useEffect(() => {
|
|
|
|
// fetchBeatSaverData();
|
|
|
|
// }, [fetchBeatSaverData]);
|
2024-10-04 18:25:37 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* When the leaderboard changes, update the previous and current leaderboards.
|
|
|
|
* This is to prevent flickering between leaderboards.
|
|
|
|
*/
|
|
|
|
useEffect(() => {
|
|
|
|
if (leaderboard) {
|
|
|
|
setCurrentLeaderboard(leaderboard);
|
|
|
|
}
|
|
|
|
}, [leaderboard]);
|
|
|
|
|
|
|
|
if (!currentLeaderboard) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<main className="flex flex-col-reverse xl:flex-row w-full gap-2">
|
|
|
|
<LeaderboardScores
|
|
|
|
leaderboard={currentLeaderboard}
|
|
|
|
initialScores={initialScores}
|
|
|
|
initialPage={initialPage}
|
|
|
|
showDifficulties
|
|
|
|
isLeaderboardPage
|
|
|
|
leaderboardChanged={id => setSelectedLeaderboardId(id)}
|
|
|
|
/>
|
|
|
|
<LeaderboardInfo leaderboard={currentLeaderboard} beatSaverMap={beatSaverMap} />
|
|
|
|
</main>
|
|
|
|
);
|
|
|
|
}
|