LETS GO BABY
This commit is contained in:
@ -1,7 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { scoresaberService } from "@/common/service/impl/scoresaber";
|
||||
import ScoreSaberPlayerToken from "@/common/model/token/scoresaber/score-saber-player-token";
|
||||
import { formatNumberWithCommas } from "@/common/number-utils";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import Link from "next/link";
|
||||
@ -13,6 +11,8 @@ import { Button } from "../ui/button";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel } from "../ui/form";
|
||||
import { Input } from "../ui/input";
|
||||
import { ScrollArea } from "../ui/scroll-area";
|
||||
import ScoreSaberPlayerToken from "@ssr/common/types/token/scoresaber/score-saber-player-token";
|
||||
import { scoresaberService } from "@ssr/common/service/impl/scoresaber";
|
||||
|
||||
const formSchema = z.object({
|
||||
username: z.string().min(3).max(50),
|
||||
|
@ -1,14 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import ScoreSaberLeaderboardScoresPageToken from "@/common/model/token/scoresaber/score-saber-leaderboard-scores-page-token";
|
||||
import ScoreSaberLeaderboardToken from "@/common/model/token/scoresaber/score-saber-leaderboard-token";
|
||||
import LeaderboardScores from "@/components/leaderboard/leaderboard-scores";
|
||||
import { LeaderboardInfo } from "@/components/leaderboard/leaderboard-info";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { scoresaberService } from "@/common/service/impl/scoresaber";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import BeatSaverMap from "@/common/database/types/beatsaver-map";
|
||||
import { beatsaverService } from "@/common/service/impl/beatsaver";
|
||||
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";
|
||||
|
||||
type LeaderboardDataProps = {
|
||||
/**
|
||||
@ -39,14 +38,15 @@ export function LeaderboardData({ initialPage, initialScores, initialLeaderboard
|
||||
staleTime: 30 * 1000, // Cache data for 30 seconds
|
||||
});
|
||||
|
||||
const fetchBeatSaverData = useCallback(async () => {
|
||||
const beatSaverMap = await beatsaverService.lookupMap(initialLeaderboard.songHash);
|
||||
setBeatSaverMap(beatSaverMap);
|
||||
}, [initialLeaderboard.songHash]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchBeatSaverData();
|
||||
}, [fetchBeatSaverData]);
|
||||
// todo: fix
|
||||
// const fetchBeatSaverData = useCallback(async () => {
|
||||
// const beatSaverMap = await beatsaverService.lookupMap(initialLeaderboard.songHash);
|
||||
// setBeatSaverMap(beatSaverMap);
|
||||
// }, [initialLeaderboard.songHash]);
|
||||
//
|
||||
// useEffect(() => {
|
||||
// fetchBeatSaverData();
|
||||
// }, [fetchBeatSaverData]);
|
||||
|
||||
/**
|
||||
* When the leaderboard changes, update the previous and current leaderboards.
|
||||
|
@ -1,9 +1,9 @@
|
||||
import Card from "@/components/card";
|
||||
import ScoreSaberLeaderboardToken from "@/common/model/token/scoresaber/score-saber-leaderboard-token";
|
||||
import Image from "next/image";
|
||||
import { LeaderboardSongStarCount } from "@/components/leaderboard/leaderboard-song-star-count";
|
||||
import ScoreButtons from "@/components/score/score-buttons";
|
||||
import BeatSaverMap from "@/common/database/types/beatsaver-map";
|
||||
import ScoreSaberLeaderboardToken from "@ssr/common/types/token/scoresaber/score-saber-leaderboard-token";
|
||||
|
||||
type LeaderboardInfoProps = {
|
||||
/**
|
||||
|
@ -1,7 +1,7 @@
|
||||
import ScoreSaberPlayer from "@/common/model/player/impl/scoresaber-player";
|
||||
import ScoreSaberScoreToken from "@/common/model/token/scoresaber/score-saber-score-token";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import ScoreSaberScoreToken from "@ssr/common/types/token/scoresaber/score-saber-score-token";
|
||||
import ScoreSaberPlayer from "@ssr/common/types/player/impl/scoresaber-player";
|
||||
|
||||
type Props = {
|
||||
/**
|
||||
|
@ -1,11 +1,11 @@
|
||||
import ScoreSaberLeaderboardToken from "@/common/model/token/scoresaber/score-saber-leaderboard-token";
|
||||
import ScoreSaberScoreToken from "@/common/model/token/scoresaber/score-saber-score-token";
|
||||
import { formatNumberWithCommas } from "@/common/number-utils";
|
||||
import { XMarkIcon } from "@heroicons/react/24/solid";
|
||||
import clsx from "clsx";
|
||||
import { getScoreBadgeFromAccuracy } from "@/common/song-utils";
|
||||
import Tooltip from "@/components/tooltip";
|
||||
import { ScoreBadge, ScoreBadges } from "@/components/score/score-badge";
|
||||
import ScoreSaberScoreToken from "@ssr/common/types/token/scoresaber/score-saber-score-token";
|
||||
import ScoreSaberLeaderboardToken from "@ssr/common/types/token/scoresaber/score-saber-leaderboard-token";
|
||||
|
||||
const badges: ScoreBadge[] = [
|
||||
{
|
||||
|
@ -1,9 +1,9 @@
|
||||
import ScoreSaberLeaderboardToken from "@/common/model/token/scoresaber/score-saber-leaderboard-token";
|
||||
import ScoreSaberScoreToken from "@/common/model/token/scoresaber/score-saber-score-token";
|
||||
import LeaderboardPlayer from "./leaderboard-player";
|
||||
import LeaderboardScoreStats from "./leaderboard-score-stats";
|
||||
import ScoreRankInfo from "@/components/score/score-rank-info";
|
||||
import ScoreSaberPlayer from "@/common/model/player/impl/scoresaber-player";
|
||||
import ScoreSaberPlayer from "@ssr/common/types/player/impl/scoresaber-player";
|
||||
import ScoreSaberScoreToken from "@ssr/common/types/token/scoresaber/score-saber-score-token";
|
||||
import ScoreSaberLeaderboardToken from "@ssr/common/types/token/scoresaber/score-saber-leaderboard-token";
|
||||
|
||||
type Props = {
|
||||
/**
|
||||
|
@ -1,8 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { scoresaberService } from "@/common/service/impl/scoresaber";
|
||||
import ScoreSaberLeaderboardToken from "@/common/model/token/scoresaber/score-saber-leaderboard-token";
|
||||
import ScoreSaberLeaderboardScoresPageToken from "@/common/model/token/scoresaber/score-saber-leaderboard-scores-page-token";
|
||||
import useWindowDimensions from "@/hooks/use-window-dimensions";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { motion, useAnimation } from "framer-motion";
|
||||
@ -11,10 +8,13 @@ import Card from "../card";
|
||||
import Pagination from "../input/pagination";
|
||||
import LeaderboardScore from "./leaderboard-score";
|
||||
import { scoreAnimation } from "@/components/score/score-animation";
|
||||
import ScoreSaberPlayer from "@/common/model/player/impl/scoresaber-player";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { clsx } from "clsx";
|
||||
import { getDifficultyFromRawDifficulty } from "@/common/song-utils";
|
||||
import ScoreSaberLeaderboardScoresPageToken from "@ssr/common/types/token/scoresaber/score-saber-leaderboard-scores-page-token";
|
||||
import ScoreSaberPlayer from "@ssr/common/types/player/impl/scoresaber-player";
|
||||
import ScoreSaberLeaderboardToken from "@ssr/common/types/token/scoresaber/score-saber-leaderboard-token";
|
||||
import { scoresaberService } from "@ssr/common/service/impl/scoresaber";
|
||||
|
||||
type LeaderboardScoresProps = {
|
||||
/**
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { songDifficultyToColor } from "@/common/song-utils";
|
||||
import { StarIcon } from "@heroicons/react/24/solid";
|
||||
import ScoreSaberLeaderboardToken from "@/common/model/token/scoresaber/score-saber-leaderboard-token";
|
||||
import { getDifficultyFromScoreSaberDifficulty } from "@/common/scoresaber-utils";
|
||||
import ScoreSaberLeaderboardToken from "@ssr/common/types/token/scoresaber/score-saber-leaderboard-token";
|
||||
|
||||
type LeaderboardSongStarCountProps = {
|
||||
/**
|
||||
|
@ -1,10 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import { parseDate } from "@/common/time-utils";
|
||||
import ScoreSaberPlayer from "@/common/model/player/impl/scoresaber-player";
|
||||
import React from "react";
|
||||
import GenericChart, { DatasetConfig } from "@/components/chart/generic-chart";
|
||||
import { getValueFromHistory } from "@/common/player-utils";
|
||||
import ScoreSaberPlayer from "@ssr/common/types/player/impl/scoresaber-player";
|
||||
import { parseDate } from "@ssr/common/utils/time-utils";
|
||||
|
||||
type Props = {
|
||||
/**
|
||||
|
@ -1,9 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import ScoreSaberPlayer from "@/common/model/player/impl/scoresaber-player";
|
||||
import React from "react";
|
||||
import { DatasetConfig } from "@/components/chart/generic-chart";
|
||||
import GenericPlayerChart from "@/components/player/chart/generic-player-chart";
|
||||
import ScoreSaberPlayer from "@ssr/common/types/player/impl/scoresaber-player";
|
||||
|
||||
type Props = {
|
||||
player: ScoreSaberPlayer;
|
||||
|
@ -1,12 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import ScoreSaberPlayer from "@/common/model/player/impl/scoresaber-player";
|
||||
import PlayerRankingChart from "@/components/player/chart/player-ranking-chart";
|
||||
import { FC, useState } from "react";
|
||||
import Tooltip from "@/components/tooltip";
|
||||
import PlayerAccuracyChart from "@/components/player/chart/player-accuracy-chart";
|
||||
import { GlobeAmericasIcon } from "@heroicons/react/24/solid";
|
||||
import { TrendingUpIcon } from "lucide-react";
|
||||
import ScoreSaberPlayer from "@ssr/common/types/player/impl/scoresaber-player";
|
||||
|
||||
type PlayerChartsProps = {
|
||||
/**
|
||||
|
@ -1,10 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import { formatNumberWithCommas } from "@/common/number-utils";
|
||||
import ScoreSaberPlayer from "@/common/model/player/impl/scoresaber-player";
|
||||
import React from "react";
|
||||
import { DatasetConfig } from "@/components/chart/generic-chart";
|
||||
import GenericPlayerChart from "@/components/player/chart/generic-player-chart";
|
||||
import ScoreSaberPlayer from "@ssr/common/types/player/impl/scoresaber-player";
|
||||
|
||||
type Props = {
|
||||
player: ScoreSaberPlayer;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import ScoreSaberPlayer from "@/common/model/player/impl/scoresaber-player";
|
||||
import Image from "next/image";
|
||||
import Tooltip from "@/components/tooltip";
|
||||
import ScoreSaberPlayer from "@ssr/common/types/player/impl/scoresaber-player";
|
||||
|
||||
type Props = {
|
||||
player: ScoreSaberPlayer;
|
||||
|
@ -1,19 +1,20 @@
|
||||
"use client";
|
||||
|
||||
import ScoreSaberPlayerScoresPageToken from "@/common/model/token/scoresaber/score-saber-player-scores-page-token";
|
||||
import { scoresaberService } from "@/common/service/impl/scoresaber";
|
||||
import { ScoreSort } from "@/common/model/score/score-sort";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import Mini from "../ranking/mini";
|
||||
import PlayerHeader from "./player-header";
|
||||
import PlayerScores from "./player-scores";
|
||||
import ScoreSaberPlayer from "@/common/model/player/impl/scoresaber-player";
|
||||
import Card from "@/components/card";
|
||||
import PlayerBadges from "@/components/player/player-badges";
|
||||
import { useIsMobile } from "@/hooks/use-is-mobile";
|
||||
import { useIsVisible } from "@/hooks/use-is-visible";
|
||||
import { useRef } from "react";
|
||||
import PlayerCharts from "@/components/player/chart/player-charts";
|
||||
import ScoreSaberPlayer, { getScoreSaberPlayerFromToken } from "@ssr/common/types/player/impl/scoresaber-player";
|
||||
import ScoreSaberPlayerScoresPageToken from "@ssr/common/types/token/scoresaber/score-saber-player-scores-page-token";
|
||||
import { ScoreSort } from "@ssr/common/types/score/score-sort";
|
||||
import { scoresaberService } from "@ssr/common/service/impl/scoresaber";
|
||||
import { config } from "../../../config";
|
||||
|
||||
type Props = {
|
||||
initialPlayerData: ScoreSaberPlayer;
|
||||
@ -37,12 +38,18 @@ export default function PlayerData({
|
||||
let player = initialPlayerData;
|
||||
const { data, isLoading, isError } = useQuery({
|
||||
queryKey: ["player", player.id],
|
||||
queryFn: () => scoresaberService.lookupPlayer(player.id),
|
||||
queryFn: async (): Promise<ScoreSaberPlayer | undefined> => {
|
||||
const playerResponse = await scoresaberService.lookupPlayer(player.id);
|
||||
if (playerResponse == undefined) {
|
||||
return undefined;
|
||||
}
|
||||
return await getScoreSaberPlayerFromToken(playerResponse, config.siteApi);
|
||||
},
|
||||
staleTime: 1000 * 60 * 5, // Cache data for 5 minutes
|
||||
});
|
||||
|
||||
if (data && (!isLoading || !isError)) {
|
||||
player = data.player;
|
||||
player = data;
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -7,15 +7,15 @@ import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import Card from "../card";
|
||||
import Pagination from "../input/pagination";
|
||||
import { Button } from "../ui/button";
|
||||
import { ScoreSort } from "@/common/model/score/score-sort";
|
||||
import ScoreSaberPlayerScoresPageToken from "@/common/model/token/scoresaber/score-saber-player-scores-page-token";
|
||||
import Score from "@/components/score/score";
|
||||
import ScoreSaberPlayer from "@/common/model/player/impl/scoresaber-player";
|
||||
import { scoresaberService } from "@/common/service/impl/scoresaber";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { clsx } from "clsx";
|
||||
import { useDebounce } from "@uidotdev/usehooks";
|
||||
import { scoreAnimation } from "@/components/score/score-animation";
|
||||
import ScoreSaberPlayer from "@ssr/common/types/player/impl/scoresaber-player";
|
||||
import ScoreSaberPlayerScoresPageToken from "@ssr/common/types/token/scoresaber/score-saber-player-scores-page-token";
|
||||
import { ScoreSort } from "@ssr/common/types/score/score-sort";
|
||||
import { scoresaberService } from "@ssr/common/service/impl/scoresaber";
|
||||
|
||||
type Props = {
|
||||
initialScoreData?: ScoreSaberPlayerScoresPageToken;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { formatNumberWithCommas } from "@/common/number-utils";
|
||||
import StatValue from "@/components/stat-value";
|
||||
import ScoreSaberPlayer from "@/common/model/player/impl/scoresaber-player";
|
||||
import ScoreSaberPlayer from "@ssr/common/types/player/impl/scoresaber-player";
|
||||
|
||||
type Badge = {
|
||||
name: string;
|
||||
|
@ -1,15 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import ScoreSaberPlayer from "@/common/model/player/impl/scoresaber-player";
|
||||
import ky from "ky";
|
||||
import { config } from "../../../config";
|
||||
import Tooltip from "@/components/tooltip";
|
||||
import { InformationCircleIcon } from "@heroicons/react/16/solid";
|
||||
import { format } from "@formkit/tempo";
|
||||
import { PlayerTrackedSince } from "@/common/player/player-tracked-since";
|
||||
import { getDaysAgo } from "@/common/time-utils";
|
||||
import { formatNumberWithCommas } from "@/common/number-utils";
|
||||
import { PlayerTrackedSince } from "@ssr/common/types/player/player-tracked-since";
|
||||
import ScoreSaberPlayer from "@ssr/common/types/player/impl/scoresaber-player";
|
||||
|
||||
type Props = {
|
||||
player: ScoreSaberPlayer;
|
||||
@ -18,32 +16,19 @@ type Props = {
|
||||
export default function PlayerTrackedStatus({ player }: Props) {
|
||||
const { data, isLoading, isError } = useQuery({
|
||||
queryKey: ["playerIsBeingTracked", player.id],
|
||||
queryFn: () => ky.get<PlayerTrackedSince>(`${config.siteUrl}/api/player/isbeingtracked?id=${player.id}`).json(),
|
||||
queryFn: () => ky.get<PlayerTrackedSince>(`${config.siteApi}/player/tracked/${player.id}`).json(),
|
||||
});
|
||||
|
||||
if (isLoading || isError || !data?.tracked) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const trackedSince = new Date(data.trackedSince!);
|
||||
const daysAgo = getDaysAgo(trackedSince) + 1;
|
||||
let daysAgoFormatted = `${formatNumberWithCommas(daysAgo)} day${daysAgo > 1 ? "s" : ""} ago`;
|
||||
if (daysAgo === 1) {
|
||||
daysAgoFormatted = "Today";
|
||||
}
|
||||
if (daysAgo === 2) {
|
||||
daysAgoFormatted = "Yesterday";
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex gap-2">
|
||||
<Tooltip
|
||||
display={
|
||||
<div className="flex flex-col justify-center items-center">
|
||||
<p>This player is having their statistics tracked!</p>
|
||||
<p>
|
||||
Tracked Since: {format(trackedSince)} ({daysAgoFormatted})
|
||||
</p>
|
||||
<p>Days Tracked: {formatNumberWithCommas(data.daysTracked!)}</p>
|
||||
</div>
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
import ScoreSaberPlayerToken from "@/common/model/token/scoresaber/score-saber-player-token";
|
||||
import { ScoreSaberPlayersPageToken } from "@/common/model/token/scoresaber/score-saber-players-page-token";
|
||||
import { formatNumberWithCommas, formatPp } from "@/common/number-utils";
|
||||
import { GlobeAmericasIcon } from "@heroicons/react/24/solid";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
@ -8,9 +6,11 @@ import { ReactElement } from "react";
|
||||
import Card from "../card";
|
||||
import CountryFlag from "../country-flag";
|
||||
import { Avatar, AvatarImage } from "../ui/avatar";
|
||||
import ScoreSaberPlayer from "@/common/model/player/impl/scoresaber-player";
|
||||
import { scoresaberService } from "@/common/service/impl/scoresaber";
|
||||
import { PlayerRankingSkeleton } from "@/components/ranking/player-ranking-skeleton";
|
||||
import ScoreSaberPlayer from "@ssr/common/types/player/impl/scoresaber-player";
|
||||
import { ScoreSaberPlayersPageToken } from "@ssr/common/types/token/scoresaber/score-saber-players-page-token";
|
||||
import { scoresaberService } from "@ssr/common/service/impl/scoresaber";
|
||||
import ScoreSaberPlayerToken from "@ssr/common/types/token/scoresaber/score-saber-player-token";
|
||||
|
||||
const PLAYER_NAME_MAX_LENGTH = 18;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import Card from "@/components/card";
|
||||
import { Skeleton } from "@/app/components/ui/skeleton";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
|
||||
export function PlayerRankingSkeleton() {
|
||||
const skeletonArray = new Array(5).fill(0);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import ScoreSaberScoreToken from "@/common/model/token/scoresaber/score-saber-score-token";
|
||||
import ScoreSaberLeaderboardToken from "@/common/model/token/scoresaber/score-saber-leaderboard-token";
|
||||
import StatValue from "@/components/stat-value";
|
||||
import ScoreSaberScoreToken from "@ssr/common/types/token/scoresaber/score-saber-score-token";
|
||||
import ScoreSaberLeaderboardToken from "@ssr/common/types/token/scoresaber/score-saber-leaderboard-token";
|
||||
|
||||
/**
|
||||
* A badge to display in the score stats.
|
||||
|
@ -1,6 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { copyToClipboard } from "../../../../common/src/utils/browser-utils";
|
||||
import BeatSaverMap from "@/common/database/types/beatsaver-map";
|
||||
import { songNameToYouTubeLink } from "@/common/youtube-utils";
|
||||
import BeatSaverLogo from "@/components/logos/beatsaver-logo";
|
||||
@ -9,7 +8,8 @@ import { useToast } from "@/hooks/use-toast";
|
||||
import { Dispatch, SetStateAction } from "react";
|
||||
import LeaderboardButton from "./leaderboard-button";
|
||||
import ScoreButton from "./score-button";
|
||||
import ScoreSaberLeaderboardToken from "@/common/model/token/scoresaber/score-saber-leaderboard-token";
|
||||
import { copyToClipboard } from "@/common/browser-utils";
|
||||
import ScoreSaberLeaderboardToken from "@ssr/common/types/token/scoresaber/score-saber-leaderboard-token";
|
||||
|
||||
type Props = {
|
||||
leaderboard: ScoreSaberLeaderboardToken;
|
||||
|
@ -1,5 +1,4 @@
|
||||
import BeatSaverMap from "@/common/database/types/beatsaver-map";
|
||||
import ScoreSaberLeaderboardToken from "@/common/model/token/scoresaber/score-saber-leaderboard-token";
|
||||
import { getDifficultyFromScoreSaberDifficulty } from "@/common/scoresaber-utils";
|
||||
import FallbackLink from "@/components/fallback-link";
|
||||
import Tooltip from "@/components/tooltip";
|
||||
@ -8,6 +7,7 @@ import clsx from "clsx";
|
||||
import Image from "next/image";
|
||||
import { songDifficultyToColor } from "@/common/song-utils";
|
||||
import Link from "next/link";
|
||||
import ScoreSaberLeaderboardToken from "@ssr/common/types/token/scoresaber/score-saber-leaderboard-token";
|
||||
|
||||
type Props = {
|
||||
leaderboard: ScoreSaberLeaderboardToken;
|
||||
|
@ -1,9 +1,9 @@
|
||||
import ScoreSaberScoreToken from "@/common/model/token/scoresaber/score-saber-score-token";
|
||||
import { formatNumberWithCommas } from "@/common/number-utils";
|
||||
import { timeAgo } from "@/common/time-utils";
|
||||
import { format } from "@formkit/tempo";
|
||||
import { GlobeAmericasIcon } from "@heroicons/react/24/solid";
|
||||
import Tooltip from "../tooltip";
|
||||
import ScoreSaberScoreToken from "@ssr/common/types/token/scoresaber/score-saber-score-token";
|
||||
import { timeAgo } from "@ssr/common/utils/time-utils";
|
||||
|
||||
type Props = {
|
||||
score: ScoreSaberScoreToken;
|
||||
|
@ -1,16 +1,15 @@
|
||||
"use client";
|
||||
|
||||
import BeatSaverMap from "@/common/database/types/beatsaver-map";
|
||||
import ScoreSaberPlayerScoreToken from "@/common/model/token/scoresaber/score-saber-player-score-token";
|
||||
import { beatsaverService } from "@/common/service/impl/beatsaver";
|
||||
import LeaderboardScores from "@/components/leaderboard/leaderboard-scores";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useState } from "react";
|
||||
import ScoreButtons from "./score-buttons";
|
||||
import ScoreSongInfo from "./score-info";
|
||||
import ScoreRankInfo from "./score-rank-info";
|
||||
import ScoreStats from "./score-stats";
|
||||
import ScoreSaberPlayer from "@/common/model/player/impl/scoresaber-player";
|
||||
import { motion } from "framer-motion";
|
||||
import ScoreSaberPlayer from "@ssr/common/types/player/impl/scoresaber-player";
|
||||
import ScoreSaberPlayerScoreToken from "@ssr/common/types/token/scoresaber/score-saber-player-score-token";
|
||||
|
||||
type Props = {
|
||||
/**
|
||||
@ -29,14 +28,15 @@ export default function Score({ player, playerScore }: Props) {
|
||||
const [beatSaverMap, setBeatSaverMap] = useState<BeatSaverMap | undefined>();
|
||||
const [isLeaderboardExpanded, setIsLeaderboardExpanded] = useState(false);
|
||||
|
||||
const fetchBeatSaverData = useCallback(async () => {
|
||||
const beatSaverMap = await beatsaverService.lookupMap(leaderboard.songHash);
|
||||
setBeatSaverMap(beatSaverMap);
|
||||
}, [leaderboard.songHash]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchBeatSaverData();
|
||||
}, [fetchBeatSaverData]);
|
||||
// todo: fix
|
||||
// const fetchBeatSaverData = useCallback(async () => {
|
||||
// const beatSaverMap = await beatsaverService.lookupMap(leaderboard.songHash);
|
||||
// setBeatSaverMap(beatSaverMap);
|
||||
// }, [leaderboard.songHash]);
|
||||
//
|
||||
// useEffect(() => {
|
||||
// fetchBeatSaverData();
|
||||
// }, [fetchBeatSaverData]);
|
||||
|
||||
const page = Math.floor(score.rank / 12) + 1;
|
||||
return (
|
||||
|
7
projects/website/src/components/ui/skeleton.tsx
Normal file
7
projects/website/src/components/ui/skeleton.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
import { cn } from "@/common/utils";
|
||||
|
||||
function Skeleton({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
||||
return <div className={cn("animate-pulse rounded-md bg-primary/10", className)} {...props} />;
|
||||
}
|
||||
|
||||
export { Skeleton };
|
Reference in New Issue
Block a user