AnimateHeight
for Info
, error handling for the Osu
Info
(#4)
This commit is contained in:
parent
cca62c093f
commit
dad037bed0
5 changed files with 88 additions and 82 deletions
|
@ -13,19 +13,11 @@ const handler: Handler = async () => {
|
|||
},
|
||||
});
|
||||
|
||||
if (gitlab.status !== 200) {
|
||||
return {
|
||||
statusCode: 404,
|
||||
body: "",
|
||||
};
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
const {created_at} = (await gitlab.json() as Record<string, any>)[0];
|
||||
if (typeof created_at !== "string") {
|
||||
return {
|
||||
statusCode: 404,
|
||||
body: "",
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -20,24 +20,22 @@ const handler: Handler = async () => {
|
|||
}),
|
||||
]) as osu.User.Extended[];
|
||||
|
||||
void api.revokeToken();
|
||||
|
||||
const info: OsuInfo = {
|
||||
country: (profile[0]).country.name || "Unknown",
|
||||
osu: {global: 0, country: 0},
|
||||
taiko: {global: 0, country: 0},
|
||||
fruits: {global: 0, country: 0},
|
||||
mania: {global: 0, country: 0},
|
||||
country: (profile[0]).country.name ?? "Unknown",
|
||||
};
|
||||
|
||||
for (const ruleset of profile) {
|
||||
if (ruleset.rank_history) {
|
||||
const stats = ruleset.statistics;
|
||||
info[ruleset.rank_history.mode].global = stats.global_rank ?? 0;
|
||||
info[ruleset.rank_history.mode].country = stats.country_rank ?? 0;
|
||||
info[ruleset.rank_history.mode] = {
|
||||
global: stats.global_rank ?? 0,
|
||||
country: stats.country_rank ?? 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void api.revokeToken();
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
body: JSON.stringify(info),
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React from "react";
|
||||
import React, {useState} from "react";
|
||||
import AnimateHeight, {type Height} from "react-animate-height";
|
||||
|
||||
export default function Info({
|
||||
type,
|
||||
|
@ -13,9 +14,21 @@ export default function Info({
|
|||
}>;
|
||||
error?: boolean;
|
||||
}) {
|
||||
const sections = websites.map((w) => {
|
||||
const [height, setHeight] = useState<Height>(0);
|
||||
|
||||
const sections = websites.map((w, i) => {
|
||||
setTimeout(() => { // somehow necessary to not always rerender
|
||||
setHeight("auto");
|
||||
}, 0);
|
||||
|
||||
return (
|
||||
<div key={w.name} id={w.name.toLowerCase().match(/[a-z]/g)!.join().replace(/,/g, "")}>
|
||||
<AnimateHeight
|
||||
key={w.name}
|
||||
id={w.name.toLowerCase().match(/[a-z]/g)!.join().replace(/,/g, "")}
|
||||
delay={150 * i}
|
||||
duration={150 * (i + 1)}
|
||||
height={height}
|
||||
>
|
||||
<a href={w.link} target="_blank" rel="noreferrer">
|
||||
<h2 className="uppercase text-right font-bold pr-1 bg-white text-red-500">
|
||||
{w.name}
|
||||
|
@ -24,7 +37,7 @@ export default function Info({
|
|||
<div className="info p-3 m-auto">
|
||||
{w.elements}
|
||||
</div>
|
||||
</div>
|
||||
</AnimateHeight>
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
@ -4,80 +4,83 @@ import "../../style/infos/osu.css";
|
|||
|
||||
export type OsuInfo = {
|
||||
country: string;
|
||||
osu: {global: number; country: number};
|
||||
taiko: {global: number; country: number};
|
||||
fruits: {global: number; country: number};
|
||||
mania: {global: number; country: number};
|
||||
} | undefined;
|
||||
osu?: {global: number; country: number};
|
||||
taiko?: {global: number; country: number};
|
||||
fruits?: {global: number; country: number};
|
||||
mania?: {global: number; country: number};
|
||||
};
|
||||
|
||||
export default function Osu() {
|
||||
const [osu, setOsu]: [OsuInfo, React.Dispatch<React.SetStateAction<OsuInfo>>] = useState();
|
||||
const [osu, setOsu]: [OsuInfo, React.Dispatch<React.SetStateAction<OsuInfo>>] = useState({country: "Unknown"});
|
||||
const [error, setError] = useState(false);
|
||||
|
||||
const getOsu = async () => {
|
||||
const response = await fetch("/.netlify/functions/osu").then(async r => r.json());
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
setOsu(response);
|
||||
setOsu(await fetch("/.netlify/functions/osu").then(async r => r.json()));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
void getOsu();
|
||||
getOsu().catch(() => {
|
||||
setError(true);
|
||||
});
|
||||
}, []);
|
||||
|
||||
if (osu === undefined) {
|
||||
return <></>;
|
||||
|
||||
const generateWebsite = (name: string, interalName: string, data: {global: number; country: number} | undefined) => {
|
||||
const website = {
|
||||
name,
|
||||
link: `https://osu.ppy.sh/users/7276846/${interalName}`,
|
||||
elements: [] as React.JSX.Element[],
|
||||
};
|
||||
|
||||
if (data) {
|
||||
website.elements.push(
|
||||
<div key={interalName} className="flex">
|
||||
<img className="m-auto w-16 h-16" alt={`${name} mode logo`} src={`/mode-${interalName}.png`} />
|
||||
<div className="m-auto">
|
||||
<p>Global: <strong>#{data.global}</strong></p>
|
||||
<p>{osu.country}: <strong>#{data.country}</strong></p>
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
}
|
||||
|
||||
return website;
|
||||
};
|
||||
|
||||
const osuWebsite = generateWebsite("osu!", "osu", osu.osu);
|
||||
const taikoWebsite = generateWebsite("osu!taiko", "taiko", osu.taiko);
|
||||
const catchWebsite = generateWebsite("osu!catch", "fruits", osu.fruits);
|
||||
const maniaWebsite = generateWebsite("osu!mania", "mania", osu.mania);
|
||||
|
||||
const websites = [
|
||||
osuWebsite,
|
||||
taikoWebsite,
|
||||
catchWebsite,
|
||||
maniaWebsite,
|
||||
];
|
||||
|
||||
for (const website of websites) {
|
||||
if (!website.elements.length) {
|
||||
return (
|
||||
<Info
|
||||
type="Rhythm games"
|
||||
websites={[]}
|
||||
error={error}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Info
|
||||
type="Rhythm games"
|
||||
websites={[{
|
||||
name: "osu!",
|
||||
link: "https://osu.ppy.sh/users/7276846/osu",
|
||||
elements: [
|
||||
<div key={"osu"} className="flex">
|
||||
<img className="m-auto w-16 h-16" alt="osu mode logo" src="/mode-osu.png" />
|
||||
<div className="m-auto">
|
||||
<p>Global: <strong>#{osu.osu.global}</strong></p>
|
||||
<p>{osu.country}: <strong>#{osu.osu.country}</strong></p>
|
||||
</div>
|
||||
</div>,
|
||||
],
|
||||
}, {
|
||||
name: "osu!taiko",
|
||||
link: "https://osu.ppy.sh/users/7276846/taiko",
|
||||
elements: [
|
||||
<div key={"osu!taiko"} className="flex">
|
||||
<img className="m-auto w-16 h-16" alt="taiko mode logo" src="/mode-taiko.png" />
|
||||
<div className="m-auto">
|
||||
<p>Global: <strong>#{osu.taiko.global}</strong></p>
|
||||
<p>{osu.country}: <strong>#{osu.taiko.country}</strong></p>
|
||||
</div>
|
||||
</div>,
|
||||
],
|
||||
}, {
|
||||
name: "osu!catch",
|
||||
link: "https://osu.ppy.sh/users/7276846/fruits",
|
||||
elements: [
|
||||
<div key={"osu!catch"} className="flex">
|
||||
<img className="m-auto w-16 h-16" alt="ctb mode logo" src="/mode-fruits.png" />
|
||||
<div className="m-auto">
|
||||
<p>Global: <strong>#{osu.fruits.global}</strong></p>
|
||||
<p>{osu.country}: <strong>#{osu.fruits.country}</strong></p>
|
||||
</div>
|
||||
</div>,
|
||||
],
|
||||
}, {
|
||||
name: "osu!mania",
|
||||
link: "https://osu.ppy.sh/users/7276846/mania",
|
||||
elements: [
|
||||
<div key={"osu!mania"} className="flex">
|
||||
<img className="m-auto w-16 h-16" alt="mania mode logo" src="/mode-mania.png" />
|
||||
<div className="m-auto">
|
||||
<p>Global: <strong>#{osu.mania.global}</strong></p>
|
||||
<p>{osu.country}: <strong>#{osu.mania.country}</strong></p>
|
||||
</div>
|
||||
</div>,
|
||||
],
|
||||
}]}
|
||||
websites={[
|
||||
osuWebsite,
|
||||
taikoWebsite,
|
||||
catchWebsite,
|
||||
maniaWebsite,
|
||||
]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ function Infos() {
|
|||
<div id="infos" className="hidden lg:inline-block text-white static m-auto lg:bg-gradient-to-r from-sky-600 to-indigo-600
|
||||
border-solid border-white lg:border-l-3 h-screen lg:fixed lg:right-0 lg:overflow-y-auto">
|
||||
<Lastfm/>
|
||||
{/* <Git/> */}
|
||||
<Git/>
|
||||
<Speedruncom/>
|
||||
<Anilist/>
|
||||
<Wanikani/>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue