Compare commits
No commits in common. "803edb4fd58412d24433d37e2ef7c8490ec7510c" and "e1c665193b6bd5a3950cb3d441c9f7f9555904e0" have entirely different histories.
803edb4fd5
...
e1c665193b
@ -1,6 +1,6 @@
|
|||||||
import { MapDifficulty } from "@ssr/common/score/map-difficulty";
|
import { MapDifficulty } from "@ssr/common/score/map-difficulty";
|
||||||
|
|
||||||
export type Difficulty = {
|
type Difficulty = {
|
||||||
/**
|
/**
|
||||||
* The name of the difficulty
|
* The name of the difficulty
|
||||||
*/
|
*/
|
||||||
@ -63,21 +63,14 @@ export function getScoreBadgeFromAccuracy(acc: number): ScoreBadge {
|
|||||||
return scoreBadges[scoreBadges.length - 1];
|
return scoreBadges[scoreBadges.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a random difficulty, except ExpertPlus.
|
|
||||||
*/
|
|
||||||
export function getRandomDifficulty(): Difficulty {
|
|
||||||
return difficulties[Math.floor(Math.random() * (difficulties.length - 1))];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a {@link Difficulty} from its name
|
* Gets a {@link Difficulty} from its name
|
||||||
*
|
*
|
||||||
* @param diff the name of the difficulty
|
* @param diff the name of the difficulty
|
||||||
* @returns the difficulty
|
* @returns the difficulty
|
||||||
*/
|
*/
|
||||||
export function getDifficulty(diff: Difficulty | MapDifficulty) {
|
export function getDifficulty(diff: MapDifficulty) {
|
||||||
const difficulty = difficulties.find(d => d.name === (typeof diff === "string" ? diff : diff.name));
|
const difficulty = difficulties.find(d => d.name === diff);
|
||||||
if (!difficulty) {
|
if (!difficulty) {
|
||||||
throw new Error(`Unknown difficulty: ${diff}`);
|
throw new Error(`Unknown difficulty: ${diff}`);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { UsersRound } from "lucide-react";
|
import { Database } from "lucide-react";
|
||||||
|
|
||||||
export default function Friends() {
|
export default function Friends() {
|
||||||
return (
|
return (
|
||||||
@ -6,7 +6,7 @@ export default function Friends() {
|
|||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="flex flex-col gap-2.5 text-right items-end">
|
<div className="flex flex-col gap-2.5 text-right items-end">
|
||||||
<div className="flex flex-row-reverse gap-3 items-center text-purple-600">
|
<div className="flex flex-row-reverse gap-3 items-center text-purple-600">
|
||||||
<UsersRound className="p-2 size-11 bg-purple-800/15 rounded-lg" />
|
<Database className="p-2 size-11 bg-purple-800/15 rounded-lg" />
|
||||||
<h1 className="text-3xl sm:text-4xl font-bold">Friends</h1>
|
<h1 className="text-3xl sm:text-4xl font-bold">Friends</h1>
|
||||||
</div>
|
</div>
|
||||||
<p className="max-w-5xl text-sm sm:text-base opacity-85">
|
<p className="max-w-5xl text-sm sm:text-base opacity-85">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { ChartNoAxesCombined, Database, Flame } from "lucide-react";
|
import { Database } from "lucide-react";
|
||||||
import { getRandomInteger } from "@/common/utils";
|
import { getRandomInteger } from "@/common/utils";
|
||||||
import { GlobeAmericasIcon } from "@heroicons/react/24/solid";
|
import { GlobeAmericasIcon } from "@heroicons/react/24/solid";
|
||||||
import { Difficulty, getDifficulty, getRandomDifficulty } from "@/common/song-utils";
|
import { getDifficulty } from "@/common/song-utils";
|
||||||
import { AnimatedList } from "@/components/ui/animated-list";
|
import { AnimatedList } from "@/components/ui/animated-list";
|
||||||
|
|
||||||
type ScoreProps = {
|
type ScoreProps = {
|
||||||
@ -28,7 +28,7 @@ let scores: ScoreProps[] = [
|
|||||||
songArt: "https://cdn.scoresaber.com/covers/8E4B7917C01E5987A5B3FF13FAA3CA8F27D21D34.png",
|
songArt: "https://cdn.scoresaber.com/covers/8E4B7917C01E5987A5B3FF13FAA3CA8F27D21D34.png",
|
||||||
songName: "RATATA",
|
songName: "RATATA",
|
||||||
songAuthor: "Skrillex, Missy Elliot & Mr. Oizo",
|
songAuthor: "Skrillex, Missy Elliot & Mr. Oizo",
|
||||||
setBy: "Rainnny",
|
setBy: "Minion",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
songArt: "https://cdn.scoresaber.com/covers/98F73BD330852EAAEBDC695140EAC8F2027AEEC8.png",
|
songArt: "https://cdn.scoresaber.com/covers/98F73BD330852EAAEBDC695140EAC8F2027AEEC8.png",
|
||||||
@ -47,14 +47,14 @@ scores = Array.from({ length: 32 }, () => scores).flat();
|
|||||||
|
|
||||||
export default function RealtimeScores() {
|
export default function RealtimeScores() {
|
||||||
return (
|
return (
|
||||||
<div className="px-5 -mt-20 flex flex-col lg:flex-row-reverse gap-10 select-none">
|
<div className="px-5 -mt-20 flex flex-row-reverse gap-10 select-none">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="flex flex-col gap-2.5 text-right items-end">
|
<div className="flex flex-col gap-2.5 text-right items-end">
|
||||||
<div className="flex flex-row-reverse gap-3 items-center text-yellow-400">
|
<div className="flex flex-row-reverse gap-3 items-center text-yellow-400">
|
||||||
<Flame className="p-2 size-11 bg-yellow-800/15 rounded-lg" />
|
<Database className="p-2 size-11 bg-yellow-800/15 rounded-lg" />
|
||||||
<h1 className="text-3xl sm:text-4xl font-bold">Realtime Scores</h1>
|
<h1 className="text-3xl sm:text-4xl font-bold">Realtime Scores</h1>
|
||||||
</div>
|
</div>
|
||||||
<p className="max-w-2xl lg:max-w-5xl text-sm sm:text-base opacity-85">
|
<p className="max-w-5xl text-sm sm:text-base opacity-85">
|
||||||
<span className="text-lg font-semibold text-yellow-500">Nec detracto voluptatibus!</span> Vulputate duis
|
<span className="text-lg font-semibold text-yellow-500">Nec detracto voluptatibus!</span> Vulputate duis
|
||||||
dolorum iuvaret disputationi ceteros te noluisse himenaeos bibendum dolores molestiae lorem elaboraret porro
|
dolorum iuvaret disputationi ceteros te noluisse himenaeos bibendum dolores molestiae lorem elaboraret porro
|
||||||
brute tation simul laudem netus odio has in tibique.
|
brute tation simul laudem netus odio has in tibique.
|
||||||
@ -62,8 +62,8 @@ export default function RealtimeScores() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Content */}
|
{/* Content */}
|
||||||
<div className="w-full flex flex-col justify-center items-center overflow-hidden">
|
<div className="w-full flex flex-col justify-center items-center">
|
||||||
<AnimatedList className="w-full max-w-[32rem] h-96 divide-y divide-muted" delay={1500}>
|
<AnimatedList className="h-96 divide-y divide-muted overflow-hidden">
|
||||||
{scores.map((score, index) => (
|
{scores.map((score, index) => (
|
||||||
<Score key={index} {...score} />
|
<Score key={index} {...score} />
|
||||||
))}
|
))}
|
||||||
@ -74,9 +74,8 @@ export default function RealtimeScores() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Score({ songArt, songName, songAuthor, setBy }: ScoreProps) {
|
function Score({ songArt, songName, songAuthor, setBy }: ScoreProps) {
|
||||||
const difficulty: Difficulty = getRandomDifficulty();
|
|
||||||
return (
|
return (
|
||||||
<figure className="py-2 flex flex-col text-sm">
|
<figure className="w-[32rem] py-2 flex flex-col text-sm">
|
||||||
{/* Set By */}
|
{/* Set By */}
|
||||||
<span>
|
<span>
|
||||||
Set by <span className="text-ssr">{setBy}</span>
|
Set by <span className="text-ssr">{setBy}</span>
|
||||||
@ -99,10 +98,10 @@ function Score({ songArt, songName, songAuthor, setBy }: ScoreProps) {
|
|||||||
<div
|
<div
|
||||||
className="absolute inset-x-0 bottom-0 py-px flex justify-center text-xs rounded-t-lg"
|
className="absolute inset-x-0 bottom-0 py-px flex justify-center text-xs rounded-t-lg"
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: getDifficulty(difficulty).color + "f0", // Transparency value (in hex 0-255)
|
backgroundColor: getDifficulty("Hard").color + "f0", // Transparency value (in hex 0-255)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{difficulty.name}
|
Hard
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ChartNoAxesCombined, Database } from "lucide-react";
|
import { Database } from "lucide-react";
|
||||||
import { kyFetch } from "@ssr/common/utils/utils";
|
import { kyFetch } from "@ssr/common/utils/utils";
|
||||||
import { AppStatistics } from "@ssr/common/types/backend/app-statistics";
|
import { AppStatistics } from "@ssr/common/types/backend/app-statistics";
|
||||||
import { Config } from "@ssr/common/config";
|
import { Config } from "@ssr/common/config";
|
||||||
@ -11,7 +11,7 @@ export default async function SiteStats() {
|
|||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="flex flex-col gap-2.5">
|
<div className="flex flex-col gap-2.5">
|
||||||
<div className="flex gap-3 items-center text-orange-600">
|
<div className="flex gap-3 items-center text-orange-600">
|
||||||
<ChartNoAxesCombined className="p-2 size-11 bg-orange-800/15 rounded-lg" />
|
<Database className="p-2 size-11 bg-orange-800/15 rounded-lg" />
|
||||||
<h1 className="text-3xl sm:text-4xl font-bold">Site Statistics</h1>
|
<h1 className="text-3xl sm:text-4xl font-bold">Site Statistics</h1>
|
||||||
</div>
|
</div>
|
||||||
<p className="max-w-5xl text-sm sm:text-base opacity-85">
|
<p className="max-w-5xl text-sm sm:text-base opacity-85">
|
||||||
|
Reference in New Issue
Block a user