Add itch.io to the GameDev Info

Surely something new will appear there soon
This commit is contained in:
Taevas 2025-04-14 17:37:27 +02:00
parent 35274fbe80
commit 98f4e9057d
Signed by: Taevas
SSH key fingerprint: SHA256:Y5Hv18xwPvUKSlgkx1sPnRO3L2mc03ehC7BzrnZVEyY
6 changed files with 102 additions and 5 deletions

View file

@ -31,6 +31,7 @@ This website makes use of several online APIs in order to deliver the `Infos` th
- `URL_POSTGRESQL` - `URL_POSTGRESQL`
- `API_GITHUB` - `API_GITHUB`
- `API_GITLAB` - `API_GITLAB`
- `API_ITCHIO`
- `API_KITSUCLUB` - `API_KITSUCLUB`
- `API_LASTFM` - `API_LASTFM`
- `API_OSU` - `API_OSU`

View file

@ -6,6 +6,7 @@ import { kitsuclub } from "./infos/fediverse/kitsuclub";
// import { osu } from "./infos/gaming/osu"; // import { osu } from "./infos/gaming/osu";
import { speedruncom } from "./infos/gaming/speedruncom"; import { speedruncom } from "./infos/gaming/speedruncom";
import { alakajam } from "./infos/gamedev/alakajam"; import { alakajam } from "./infos/gamedev/alakajam";
import { itchio } from "./infos/gamedev/itchio";
// import { hackthebox } from "./infos/hacking/hackthebox"; // import { hackthebox } from "./infos/hacking/hackthebox";
// import { wanikani } from "./infos/japanese/wanikani"; // import { wanikani } from "./infos/japanese/wanikani";
import { anilist } from "./infos/media/anilist"; import { anilist } from "./infos/media/anilist";
@ -17,7 +18,7 @@ const info_routes: Record<string, Handler[]> = {
coding: [github, gitlab, kitsudev], coding: [github, gitlab, kitsudev],
fediverse: [kitsuclub], fediverse: [kitsuclub],
gaming: [speedruncom], gaming: [speedruncom],
gamedev: [alakajam], gamedev: [alakajam, itchio],
// hacking: [hackthebox], // hacking: [hackthebox],
// japanese: [wanikani], // japanese: [wanikani],
media: [anilist, lastfm], media: [anilist, lastfm],

View file

@ -0,0 +1,37 @@
import type { ItchioInfo } from "#Infos/GameDev/Itchio.tsx";
import type { Handler } from "../..";
export const itchio: Handler = async () => {
/** https://itch.io/docs/api/serverside#reference/profilegames-httpsitchioapi1keymy-games */
const response = await (await fetch(`https://itch.io/api/1/${process.env["API_ITCHIO"]}/my-games`)).json() as {
games: {
published_at?: string
title: string
short_text?: string
url: string
cover_url?: string
user: {
display_name: string
url: string
}
}[];
};
/** Do not show games that are unpublished (a game that is not public; still in development but has a page) */
const published_games = response.games.filter((game) => game.published_at);
const activity: ItchioInfo = {
user: {
name: published_games[0].user.display_name,
url: published_games[0].user.url
},
game: {
name: published_games[0].title,
description: published_games[0].short_text,
date: published_games[0].published_at!,
url: published_games[0].url,
cover_url: published_games[0].cover_url
}
};
return Response.json(activity, {status: 200});
};

View file

@ -1,6 +1,5 @@
import React, {useState, useEffect} from "react"; import React, {useState, useEffect} from "react";
import Website from "../Website.tsx"; import Website from "../Website.tsx";
import ButtonLink from "#parts/ButtonLink.tsx";
import DataHandler from "#parts/DataHandler.tsx"; import DataHandler from "#parts/DataHandler.tsx";
import Link from "#parts/Link.tsx"; import Link from "#parts/Link.tsx";
@ -45,8 +44,7 @@ export default function Alakajam() {
</> </>
} }
/>, />,
<>{data.results.overall.rating ? <p key="results" className="text-left mt-2">With an overall rating of <b>{data.results.overall.rating.substring(0, 3)}/10</b>, this game <b>was ranked #{data.results.overall.ranking}</b> when the gamejam ended!</p> : <></>}</> <>{data.results.overall.rating ? <p key="results" className="text-left mt-2">With an overall rating of <b>{data.results.overall.rating.substring(0, 3)}/10</b>, this game <b>was ranked #{data.results.overall.ranking} overall</b> when the gamejam ended!</p> : <></>}</>
]); ]);
} catch { } catch {
setError(true); setError(true);

View file

@ -0,0 +1,57 @@
import React, {useState, useEffect} from "react";
import Website from "../Website.tsx";
import DataHandler from "#parts/DataHandler.tsx";
import Link from "#parts/Link.tsx";
export type ItchioInfo = {
user: {
name: string
url: string
}
game: {
name: string
description?: string
date: string
url: string
cover_url?: string
}
} | undefined;
export default function Itchio() {
const {data, error, setError} = DataHandler<ItchioInfo>("infos/gamedev/itchio", 60 * 120);
const [elements, setElements] = useState([] as React.JSX.Element[]);
useEffect(() => {
if (data) {
try {
setElements([
<Link
key="presentation"
classes="p-2 inline-block bg-white font-bold text-blue-800"
link={data.game.url}
text={
<>
<h2 className="text-2xl">{data.game.name}</h2>
<>{data.game.description ? <p className="mt-2 leading-[1.3]">{data.game.description}</p> : <></>}</>
<>{data.game.cover_url ? <img className="mt-2" alt="Game cover" src={data.game.cover_url}/> : <></>}</>
</>
}
/>,
<br key="space"/>,
<time key="date" dateTime={data.game.date}>{data.game.date.substring(0, 10)}</time>
]);
} catch {
setError(true);
}
}
}, [data]);
return (
<Website
name="itch.io"
link={data?.user.url ?? "https://tttaevas.itch.io/"}
elements={elements}
error={error}
/>
);
}

View file

@ -1,15 +1,18 @@
import React from "react"; import React from "react";
import Info from "../Info.tsx"; import Info from "../Info.tsx";
import Alakajam from "./Alakajam.tsx"; import Alakajam from "./Alakajam.tsx";
import Itchio from "./Itchio.tsx";
export default function GameDev() { export default function GameDev() {
const alakajam = <Alakajam key="alakajam"/>; const alakajam = <Alakajam key="alakajam"/>;
const itchio = <Itchio key="itchio"/>;
return ( return (
<Info <Info
type="Game Dev" type="Game Dev"
websites={[ websites={[
alakajam alakajam,
itchio
]} ]}
/> />
); );