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
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
const {created_at} = (await gitlab.json() as Record<string, any>)[0];
|
const {created_at} = (await gitlab.json() as Record<string, any>)[0];
|
||||||
if (typeof created_at !== "string") {
|
if (typeof created_at !== "string") {
|
||||||
return {
|
return {
|
||||||
statusCode: 404,
|
statusCode: 404,
|
||||||
body: "",
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,24 +20,22 @@ const handler: Handler = async () => {
|
||||||
}),
|
}),
|
||||||
]) as osu.User.Extended[];
|
]) as osu.User.Extended[];
|
||||||
|
|
||||||
|
void api.revokeToken();
|
||||||
|
|
||||||
const info: OsuInfo = {
|
const info: OsuInfo = {
|
||||||
country: (profile[0]).country.name || "Unknown",
|
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},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const ruleset of profile) {
|
for (const ruleset of profile) {
|
||||||
if (ruleset.rank_history) {
|
if (ruleset.rank_history) {
|
||||||
const stats = ruleset.statistics;
|
const stats = ruleset.statistics;
|
||||||
info[ruleset.rank_history.mode].global = stats.global_rank ?? 0;
|
info[ruleset.rank_history.mode] = {
|
||||||
info[ruleset.rank_history.mode].country = stats.country_rank ?? 0;
|
global: stats.global_rank ?? 0,
|
||||||
|
country: stats.country_rank ?? 0,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void api.revokeToken();
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
body: JSON.stringify(info),
|
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({
|
export default function Info({
|
||||||
type,
|
type,
|
||||||
|
@ -13,9 +14,21 @@ export default function Info({
|
||||||
}>;
|
}>;
|
||||||
error?: boolean;
|
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 (
|
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">
|
<a href={w.link} target="_blank" rel="noreferrer">
|
||||||
<h2 className="uppercase text-right font-bold pr-1 bg-white text-red-500">
|
<h2 className="uppercase text-right font-bold pr-1 bg-white text-red-500">
|
||||||
{w.name}
|
{w.name}
|
||||||
|
@ -24,7 +37,7 @@ export default function Info({
|
||||||
<div className="info p-3 m-auto">
|
<div className="info p-3 m-auto">
|
||||||
{w.elements}
|
{w.elements}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</AnimateHeight>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -4,80 +4,83 @@ import "../../style/infos/osu.css";
|
||||||
|
|
||||||
export type OsuInfo = {
|
export type OsuInfo = {
|
||||||
country: string;
|
country: string;
|
||||||
osu: {global: number; country: number};
|
osu?: {global: number; country: number};
|
||||||
taiko: {global: number; country: number};
|
taiko?: {global: number; country: number};
|
||||||
fruits: {global: number; country: number};
|
fruits?: {global: number; country: number};
|
||||||
mania: {global: number; country: number};
|
mania?: {global: number; country: number};
|
||||||
} | undefined;
|
};
|
||||||
|
|
||||||
export default function Osu() {
|
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 getOsu = async () => {
|
||||||
const response = await fetch("/.netlify/functions/osu").then(async r => r.json());
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||||
setOsu(response);
|
setOsu(await fetch("/.netlify/functions/osu").then(async r => r.json()));
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
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 (
|
return (
|
||||||
<Info
|
<Info
|
||||||
type="Rhythm games"
|
type="Rhythm games"
|
||||||
websites={[{
|
websites={[
|
||||||
name: "osu!",
|
osuWebsite,
|
||||||
link: "https://osu.ppy.sh/users/7276846/osu",
|
taikoWebsite,
|
||||||
elements: [
|
catchWebsite,
|
||||||
<div key={"osu"} className="flex">
|
maniaWebsite,
|
||||||
<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>,
|
|
||||||
],
|
|
||||||
}]}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
<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">
|
border-solid border-white lg:border-l-3 h-screen lg:fixed lg:right-0 lg:overflow-y-auto">
|
||||||
<Lastfm/>
|
<Lastfm/>
|
||||||
{/* <Git/> */}
|
<Git/>
|
||||||
<Speedruncom/>
|
<Speedruncom/>
|
||||||
<Anilist/>
|
<Anilist/>
|
||||||
<Wanikani/>
|
<Wanikani/>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue