Various adjustments

This commit is contained in:
Taevas 2025-03-07 17:43:41 +01:00
parent ec6cb4b355
commit 371171e61d
21 changed files with 30 additions and 52 deletions

View file

@ -11,12 +11,12 @@ bun dev
## Environment variables ## Environment variables
This package uses [`@carbon/icons-react`](https://github.com/carbon-design-system/carbon/tree/main/packages/icons-react), which **installs [a telemetry package which can be disabled](https://github.com/ibm-telemetry/telemetry-js/tree/main#opting-out-of-ibm-telemetry-data-collection):** This website uses [`@carbon/icons-react`](https://github.com/carbon-design-system/carbon/tree/main/packages/icons-react), which **installs [a telemetry package which can be disabled](https://github.com/ibm-telemetry/telemetry-js/tree/main#opting-out-of-ibm-telemetry-data-collection):**
Set the environment variable IBM_TELEMETRY_DISABLED to true Set the environment variable IBM_TELEMETRY_DISABLED to true
This package makes use of several online APIs through Netlify in order to deliver the `Infos` that are available on the right side of the website, accessing most of these APIs requires a key (or similar), which can be set through the following environment variables: This website makes use of several online APIs in order to deliver the `Infos` that are available on the right side of the main page, accessing most of these APIs requires a key (or similar), which can be set through the following environment variables:
- `API_GITHUB` - `API_GITHUB`
- `API_GITLAB` - `API_GITLAB`

View file

@ -19,7 +19,5 @@ export const coding_github: Handler = async () => {
} : undefined, } : undefined,
}; };
return new Response(new Blob([JSON.stringify(info)], { return Response.json(info, {status: 200});
type: "application/json",
}), {status: 200});
}; };

View file

@ -14,8 +14,6 @@ export const coding_gitlab: Handler = async () => {
const activity: GitlabInfo = { const activity: GitlabInfo = {
date: created_at.substring(0, created_at.indexOf("T")), date: created_at.substring(0, created_at.indexOf("T")),
}; };
return new Response(new Blob([JSON.stringify(activity)], { return Response.json(activity, {status: 200});
type: "application/json",
}), {status: 200});
}; };

View file

@ -16,7 +16,5 @@ export const coding_kitsudev: Handler = async () => {
date: kitsudev[0].created date: kitsudev[0].created
}; };
return new Response(new Blob([JSON.stringify(info)], { return Response.json(info, {status: 200});
type: "application/json",
}), {status: 200});
}; };

View file

@ -87,7 +87,5 @@ export const fediverse_kitsuclub: Handler = async () => {
}) })
}; };
return new Response(new Blob([JSON.stringify(activity)], { return Response.json(activity, {status: 200});
type: "application/json",
}), {status: 200});
}; };

View file

@ -26,7 +26,5 @@ export const gaming_osu: Handler = async (params) => {
}, },
}; };
return new Response(new Blob([JSON.stringify(info)], { return Response.json(info, {status: 200});
type: "application/json",
}), {status: 200});
}; };

View file

@ -74,9 +74,7 @@ export const gaming_speedruncom: Handler = async () => {
run.time = run.time.substring(1); run.time = run.time.substring(1);
} }
return new Response(new Blob([JSON.stringify(run)], { return Response.json(run, {status: 200});
type: "application/json",
}), {status: 200});
}; };
// https://gist.github.com/vankasteelj/74ab7793133f4b257ea3 // https://gist.github.com/vankasteelj/74ab7793133f4b257ea3

View file

@ -15,8 +15,6 @@ export const hacking_hackthebox: Handler = async () => {
pwn.machine_avatar = `https://www.hackthebox.com${pwn.machine_avatar}`; pwn.machine_avatar = `https://www.hackthebox.com${pwn.machine_avatar}`;
pwn.date = pwn.date.substring(0, pwn.date.indexOf("T")); pwn.date = pwn.date.substring(0, pwn.date.indexOf("T"));
return new Response(new Blob([JSON.stringify(pwn)], { return Response.json(pwn, {status: 200});
type: "application/json",
}), {status: 200});
}; };

View file

@ -57,7 +57,7 @@ export const japanese_wanikani: Handler = async () => {
const toRequest = urlsToRequest.map((url) => new Promise(async (resolve) => { const toRequest = urlsToRequest.map((url) => new Promise(async (resolve) => {
const response = await fetch(url, {headers: { const response = await fetch(url, {headers: {
"Authorization": `Bearer ${process.env["API_WANIKANI"]}`, "Authorization": `Bearer ${process.env["API_WANIKANI"]}`,
"Content-Type": "application.json", "Content-Type": "application/json",
}}); }});
resolve(await response.json()); resolve(await response.json());
})); }));
@ -93,7 +93,7 @@ export const japanese_wanikani: Handler = async () => {
const subjectIdsAll = subjectIdsLessons.concat(subjectIdsReviews); const subjectIdsAll = subjectIdsLessons.concat(subjectIdsReviews);
const subjects = await (await fetch(`https://api.wanikani.com/v2/subjects?ids=${subjectIdsAll.toString()}`, {headers: { const subjects = await (await fetch(`https://api.wanikani.com/v2/subjects?ids=${subjectIdsAll.toString()}`, {headers: {
"Authorization": `Bearer ${process.env["API_WANIKANI"]}`, "Authorization": `Bearer ${process.env["API_WANIKANI"]}`,
"Content-Type": "application.json", "Content-Type": "application/json",
}})).json() as {data: Subject[]}; }})).json() as {data: Subject[]};
const lessons = addStuffToLearn(subjectIdsLessons, summary.data.lessons, subjects.data); const lessons = addStuffToLearn(subjectIdsLessons, summary.data.lessons, subjects.data);
@ -107,7 +107,5 @@ export const japanese_wanikani: Handler = async () => {
moreThingsToReviewAt, moreThingsToReviewAt,
}; };
return new Response(new Blob([JSON.stringify(info)], { return Response.json(info, {status: 200});
type: "application/json",
}), {status: 200});
}; };

View file

@ -62,8 +62,6 @@ export const media_anilist: Handler = async () => {
anime.startDate = anime.startDate.substring(0, anime.startDate.indexOf("T")); anime.startDate = anime.startDate.substring(0, anime.startDate.indexOf("T"));
anime.updateDate = anime.updateDate.substring(0, anime.updateDate.indexOf("T")); anime.updateDate = anime.updateDate.substring(0, anime.updateDate.indexOf("T"));
anime.endDate = anime.endDate.substring(0, anime.endDate.indexOf("T")); anime.endDate = anime.endDate.substring(0, anime.endDate.indexOf("T"));
return new Response(new Blob([JSON.stringify(anime)], { return Response.json(anime, {status: 200});
type: "application/json",
}), {status: 200});
}; };

View file

@ -39,7 +39,5 @@ export const media_lastfm: Handler = async () => {
date: lastfm.recenttracks.track[0].date?.uts ?? String(Date.now()), date: lastfm.recenttracks.track[0].date?.uts ?? String(Date.now()),
}; };
return new Response(new Blob([JSON.stringify(track)], { return Response.json(track, {status: 200});
type: "application/json",
}), {status: 200});
}; };

View file

@ -17,7 +17,7 @@ export const website_umami: Handler = async () => {
const now = new Date(); const now = new Date();
const response = await fetch(`${api_server}/websites/${website_id}/stats?startAt=${Number(new Date("2025"))}&endAt=${Number(now)}`, { const response = await fetch(`${api_server}/websites/${website_id}/stats?startAt=${Number(new Date("2025"))}&endAt=${Number(now)}`, {
headers: { headers: {
"Accept": "application.json", "Accept": "application/json",
"Authorization": `Bearer ${token?.access_token}` "Authorization": `Bearer ${token?.access_token}`
}, },
}); });
@ -43,7 +43,5 @@ export const website_umami: Handler = async () => {
totaltime: umami.totaltime.value totaltime: umami.totaltime.value
}; };
return new Response(new Blob([JSON.stringify(info)], { return Response.json(info, {status: 200});
type: "application/json",
}), {status: 200});
}; };

View file

@ -37,7 +37,6 @@ export default tseslint.config(
}, },
{ {
ignores: [ ignores: [
".netlify/*",
"dist/*", "dist/*",
"*.js", "*.js",
"*.cjs", "*.cjs",

View file

@ -1563,7 +1563,7 @@ video {
@font-face { @font-face {
font-family: "LexendDeca"; font-family: "LexendDeca";
src: url("./assets/fonts/LexendDeca-Regular.ttf") format("truetype"); src: url("assets/fonts/LexendDeca-Regular.ttf") format("truetype");
font-weight: normal; font-weight: normal;

View file

@ -38,7 +38,7 @@ const builds = await Bun.build({
}); });
const server = Bun.serve({ const server = Bun.serve({
port: 8080, idleTimeout: 30,
fetch: async (req) => { fetch: async (req) => {
const url = new URL(req.url); const url = new URL(req.url);
const parameters = url.searchParams; const parameters = url.searchParams;

View file

@ -2,7 +2,8 @@
"scripts": { "scripts": {
"dev": "bunx bun css && bun --hot index.ts", "dev": "bunx bun css && bun --hot index.ts",
"css": "bun tailwindcss -i ./src/App.css -o index.css", "css": "bun tailwindcss -i ./src/App.css -o index.css",
"lint": "bunx eslint ." "lint": "bunx eslint .",
"start": "bun run index.ts"
}, },
"dependencies": { "dependencies": {
"@bachmacintosh/wanikani-api-types": "^1.7.0", "@bachmacintosh/wanikani-api-types": "^1.7.0",

View file

@ -4,7 +4,7 @@
@font-face { @font-face {
font-family: "LexendDeca"; font-family: "LexendDeca";
src: url("./assets/fonts/LexendDeca-Regular.ttf") format("truetype"); src: url("assets/fonts/LexendDeca-Regular.ttf") format("truetype");
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
} }

View file

@ -1,7 +1,7 @@
import React, {useState, useEffect} from "react"; import React, {useState, useEffect} from "react";
/** Takes care of getting data regularly */ /** Takes care of getting data regularly */
export default function DataHandler<T extends unknown | undefined>(netlifyFunctionName: string, updateEveryXSeconds: number, expectData = true) { export default function DataHandler<T extends unknown | undefined>(apiEndpoint: string, updateEveryXSeconds: number, expectData = true) {
const [data, setData]: [T | undefined, React.Dispatch<React.SetStateAction<T | undefined>>] = useState(); const [data, setData]: [T | undefined, React.Dispatch<React.SetStateAction<T | undefined>>] = useState();
const [error, setError] = useState(false); const [error, setError] = useState(false);
const [count, setCount] = useState(0); const [count, setCount] = useState(0);
@ -9,7 +9,7 @@ export default function DataHandler<T extends unknown | undefined>(netlifyFuncti
// Try to get and set data // Try to get and set data
const updateData = async () => { const updateData = async () => {
try { try {
const response = await fetch("/api/" + netlifyFunctionName); const response = await fetch("/api/" + apiEndpoint);
if (!response.ok) {throw "failed";}; if (!response.ok) {throw "failed";};
setData(expectData ? await response.json() : true); setData(expectData ? await response.json() : true);
setError(false); setError(false);

View file

@ -28,7 +28,7 @@ export default function Osu(args: {ruleset: Ruleset}) {
try { try {
setElements([ setElements([
<div key={`osu-${ruleset}`} className="flex"> <div key={`osu-${ruleset}`} className="flex">
<img className="m-auto w-16 h-16" alt={`${ruleset} mode logo`} src={`./assets/osu_rulesets/${ruleset}.png`}/> <img className="m-auto w-16 h-16" alt={`${ruleset} mode logo`} src={`/assets/osu_rulesets/${ruleset}.png`}/>
<div className="m-auto"> <div className="m-auto">
<p>Global: <strong>#{data.ranks.global}</strong></p> <p>Global: <strong>#{data.ranks.global}</strong></p>
<p>{data.country}: <strong>#{data.ranks.country}</strong></p> <p>{data.country}: <strong>#{data.ranks.country}</strong></p>

View file

@ -13,7 +13,7 @@ export default function About({
const elements = [( const elements = [(
<div className="m-4 text-white order-1" key={"about"}> <div className="m-4 text-white order-1" key={"about"}>
<div className="ml-auto max-w-3xl text-left"> <div className="ml-auto max-w-3xl text-left">
<img className="m-4 float-right h-24" src="/brittany.jpg" alt="Flag of Brittany" title="Flag of Brittany"/> <img className="m-4 float-right h-24" src="/assets/brittany.jpg" alt="Flag of Brittany" title="Flag of Brittany"/>
<Translatable <Translatable
en={<p>o/ <b>I'm Taevas</b>, a young person from <b><Link link="https://en.wikipedia.org/wiki/Brittany" text="Brittany"/> (western France)</b> who is currently invested in <b>game development.</b> I also do stuff related to web development, networking, and cybersecurity more rarely!</p>} en={<p>o/ <b>I'm Taevas</b>, a young person from <b><Link link="https://en.wikipedia.org/wiki/Brittany" text="Brittany"/> (western France)</b> who is currently invested in <b>game development.</b> I also do stuff related to web development, networking, and cybersecurity more rarely!</p>}
fr={<p>o/ <b>Je m'appelle Taevas</b>, je suis une jeune personne de <b>Bretagne</b> qui s'investit dans le <b>développement de jeux-vidéos.</b> Je fais aussi des trucs qui touchent au développement web, aux réseaux, et plus rarement à la cybersécurité!</p>} fr={<p>o/ <b>Je m'appelle Taevas</b>, je suis une jeune personne de <b>Bretagne</b> qui s'investit dans le <b>développement de jeux-vidéos.</b> Je fais aussi des trucs qui touchent au développement web, aux réseaux, et plus rarement à la cybersécurité!</p>}
@ -31,7 +31,7 @@ export default function About({
</div> </div>
<div className="mr-auto mt-8 max-w-3xl text-right"> <div className="mr-auto mt-8 max-w-3xl text-right">
<a href="https://www.pixiv.net/en/artworks/85330094" target="_blank" rel="noreferrer"> <a href="https://www.pixiv.net/en/artworks/85330094" target="_blank" rel="noreferrer">
<img className="m-4 float-left h-24 w-24" src="/lain.png" alt="A drawing of Lain" title="A drawing of Lain"/> <img className="m-4 float-left h-24 w-24" src="/assets/lain.png" alt="A drawing of Lain" title="A drawing of Lain"/>
</a> </a>
<Translatable <Translatable
en={<p>I really like Japanese media! I'll pretty much always choose to have some drawing of <b>Lain Iwakura from <Link link="https://en.wikipedia.org/wiki/Serial_Experiments_Lain" text="Serial Experiments Lain"/></b> as my profile picture on the various websites I have an account on, as it is a piece of media I deeply enjoy.</p>} en={<p>I really like Japanese media! I'll pretty much always choose to have some drawing of <b>Lain Iwakura from <Link link="https://en.wikipedia.org/wiki/Serial_Experiments_Lain" text="Serial Experiments Lain"/></b> as my profile picture on the various websites I have an account on, as it is a piece of media I deeply enjoy.</p>}

View file

@ -13,7 +13,7 @@ export default function Projects({
const elements = [( const elements = [(
<div className="inline-block m-4 text-white text-left" key={"projects"}> <div className="inline-block m-4 text-white text-left" key={"projects"}>
<div className="border-b-4 pb-4"> <div className="border-b-4 pb-4">
<a href="https://tttaevas.itch.io/swordventure" target="_blank" rel="noreferrer"><img className="m-4 float-right w-40" src="/swordventure.png" alt="SwordVenture thumbnail"/></a> <a href="https://tttaevas.itch.io/swordventure" target="_blank" rel="noreferrer"><img className="m-4 float-right w-40" src="/assets/swordventure.png" alt="SwordVenture thumbnail"/></a>
<Translatable <Translatable
en={<p><b><Link link="https://tttaevas.itch.io/swordventure" text="SwordVenture"/></b> initially was <Link link="https://github.com/RemiL-Nel/Clicker-game" text="a game made by a friend in React which I helped develop,"/> but months after the project ended, I made the choice to <b>recode it from scratch in <Link link="https://godotengine.org/" text="Godot"/></b>, a proper game engine!</p>} en={<p><b><Link link="https://tttaevas.itch.io/swordventure" text="SwordVenture"/></b> initially was <Link link="https://github.com/RemiL-Nel/Clicker-game" text="a game made by a friend in React which I helped develop,"/> but months after the project ended, I made the choice to <b>recode it from scratch in <Link link="https://godotengine.org/" text="Godot"/></b>, a proper game engine!</p>}
fr={<p><b><Link link="https://tttaevas.itch.io/swordventure" text="SwordVenture"/></b> était à la base <Link link="https://github.com/RemiL-Nel/Clicker-game" text="un jeu fait par un ami en React auquel j'ai contribué côté développement,"/> mais quelques mois plus tard, j'ai fait le choix de <b>le refaire en entier dans <Link link="https://godotengine.org/" text="Godot"/></b>, qui est un véritable moteur de jeu vidéo !</p>} fr={<p><b><Link link="https://tttaevas.itch.io/swordventure" text="SwordVenture"/></b> était à la base <Link link="https://github.com/RemiL-Nel/Clicker-game" text="un jeu fait par un ami en React auquel j'ai contribué côté développement,"/> mais quelques mois plus tard, j'ai fait le choix de <b>le refaire en entier dans <Link link="https://godotengine.org/" text="Godot"/></b>, qui est un véritable moteur de jeu vidéo !</p>}