Add favicon, misc code changes

This commit is contained in:
Taevas 2025-04-10 22:05:49 +02:00
parent 89d7cab81f
commit 9b6c1649a7
Signed by: Taevas
SSH key fingerprint: SHA256:Y5Hv18xwPvUKSlgkx1sPnRO3L2mc03ehC7BzrnZVEyY
35 changed files with 91 additions and 103 deletions

View file

@ -28,7 +28,7 @@ export const kitsudev: Handler = async () => {
const info: KitsudevInfo = {
url: kitsudev[0].html_url,
message: kitsudev[0].commit.message,
message: kitsudev[0].commit.message.substring(0, kitsudev[0].commit.message.indexOf("\n")),
author: kitsudev[0].commit.author.name,
date: kitsudev[0].commit.author.date,
files_modified: kitsudev[0].files.length,

BIN
assets/blobcatlain.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
bun.lockb

Binary file not shown.

View file

@ -1,6 +1,8 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Site - taevas.xyz</title>
<link rel="icon" type="image/x-icon" href="/assets/blobcatlain.png">
<meta charset="UTF-8" />
<meta
name="viewport"
@ -8,7 +10,6 @@
/>
<link rel="stylesheet" href="./index.css">
<script defer src="https://visitors.taevas.xyz/script.js" data-website-id="f196d626-e609-4841-9a80-0dc60f523ed5"></script>
<title>Site - taevas.xyz</title>
</head>
<body class="bg-linear-to-tl from-amber-100 via-sky-300 to-amber-100 bg-fixed">
<span id="links" style="display: none;">
@ -39,7 +40,7 @@
<span class="p-region">Brittany</span>
<span class="p-country-name">France</span>
</div>
<div id="root">
<div id="root" class="flex text-center">
</div>
<script type="module" src="./src/App.tsx"></script>

View file

@ -8,7 +8,7 @@
},
"dependencies": {
"@bachmacintosh/wanikani-api-types": "^1.8.0",
"@carbon/icons-react": "^11.57.0",
"@carbon/icons-react": "^11.58.0",
"@gitbeaker/rest": "^42.2.0",
"@octokit/rest": "^20.1.2",
"osu-api-v2-js": "^1.1.2",
@ -22,9 +22,9 @@
"@stylistic/eslint-plugin": "^3.1.0",
"@tailwindcss/forms": "^0.5.10",
"@tailwindcss/postcss": "^4.1.3",
"@types/bun": "^1.2.8",
"@types/bun": "^1.2.9",
"@types/react": "^19.1.0",
"@types/react-dom": "^19.1.1",
"@types/react-dom": "^19.1.2",
"dotenv": "^16.4.7",
"eslint": "^9.24.0",
"eslint-config-xo-typescript": "^7.0.0",
@ -34,7 +34,7 @@
"tailwindcss": "^4.1.3",
"typescript": "^5.8.3",
"typescript-eslint": "^8.29.1",
"vite": "^6.2.5"
"vite": "^6.2.6"
},
"imports": {
"#Main/*": "./src/Main/*",

View file

@ -33,7 +33,7 @@
font-style: normal;
}
.App {
body {
font-family: "IBMPlexMono", "Arial", sans-serif;
}

View file

@ -8,9 +8,7 @@ import Infos from "./Infos/index.tsx";
const root = createRoot(document.getElementById("root")!);
root.render(
<React.StrictMode>
<div className="App flex text-center bg-linear-to-tl from-amber-100 via-sky-300 to-amber-100 bg-fixed">
<MainContent/>
<Infos/>
</div>
</React.StrictMode>,
);

View file

@ -24,13 +24,13 @@ export default function GitHub() {
if (data.private) {
elms.push(
<p key={"github-date-private"} className={data.public ? "mb-2" : ""}>Latest <strong>private</strong> push: <strong>{data.private.date}</strong></p>,
<p key="github-date-private" className={data.public ? "mb-2" : ""}>Latest <strong>private</strong> push: <time>{data.private.date}</time></p>,
);
}
if (data.public) {
elms.push(
<p key={"github-date-public"}>Latest <strong>public</strong> push: <strong>{data.public.date}</strong></p>,
<p key="github-date-public">Latest <strong>public</strong> push: <time>{data.public.date}</time></p>,
);
elms.push(
<Link classes="mt-1 px-1 py-2 inline-block w-full font-bold leading-[18px] bg-white text-blue-800" link={`https://github.com/${data.public.repo}`} text={data.public.repo}/>

View file

@ -14,7 +14,7 @@ export default function GitLab() {
if (data) {
try {
setElements([
<p key={"gitlab-date"}>Latest push: <strong>{data.date}</strong></p>,
<p key="gitlab-date">Latest push: <time>{data.date}</time></p>,
]);
} catch {
setError(true);

View file

@ -17,8 +17,8 @@ export default function KitsuDev() {
if (data) {
try {
setElements([
<p key={"kitsudev-date"}>Latest activity: <strong>{data.date.substring(0, data.date.indexOf("T"))}</strong></p>,
<Link key={"kitsudev-link"} classes="mt-1 px-1 py-2 inline-block w-full font-bold leading-[18px] bg-white text-blue-800" link={data.url} text={data.name}/>
<p key="kitsudev-date">Latest activity: <time dateTime={data.date}>{data.date.substring(0, data.date.indexOf("T"))}</time></p>,
<Link key="kitsudev-link" classes="mt-1 px-1 py-2 inline-block w-full font-bold leading-[18px] bg-white text-blue-800" link={data.url} text={data.name}/>
]);
} catch {
setError(true);

View file

@ -5,9 +5,9 @@ import GitLab from "./GitLab.tsx";
import KitsuDev from "./KitsuDev.tsx";
export default function Coding() {
const github = <GitHub key={"github"}/>;
const gitlab = <GitLab key={"gitlab"}/>;
const kitsudev = <KitsuDev key={"kitsudev"}/>;
const github = <GitHub key="github"/>;
const gitlab = <GitLab key="gitlab"/>;
const kitsudev = <KitsuDev key="kitsudev"/>;
return (
<Info

View file

@ -27,17 +27,17 @@ export default function KitsuClub() {
const date = new Date(data.date).toISOString();
const images: React.JSX.Element[] = data.images.map((i, index) => <img className="mt-2" key={`img-${index}`} src={i.url} alt={i.alt}/>);
setElements([
<div key={"kitsuclub-details"} className="text-left mb-2">
<img key={"kitsuclub-avatar"} src={data.avatar} alt="avatar" className="float-left rounded-lg w-12 mr-2"/>
<strong key={"kitsuclub-username"} className="inline-flex">{...emojify(data.username, data.emojis)}</strong>
<div key="kitsuclub-details" className="text-left mb-2">
<img key="kitsuclub-avatar" src={data.avatar} alt="avatar" className="float-left rounded-lg w-12 mr-2"/>
<strong key="kitsuclub-username" className="inline-flex">{...emojify(data.username, data.emojis)}</strong>
<br/>
<time key={"kitsuclub-date"} className="inline-flex text-sm" dateTime={date}>
<time key="kitsuclub-date" className="inline-flex text-sm" dateTime={date}>
{date.substring(0, date.indexOf("T")).concat(" " + date.substring(date.indexOf("T") + 1, date.indexOf(".")) + " UTC")}
</time>
</div>,
// emojis that are only in the post aren't in the response yet :(
<Link classes="mt-1 px-2 py-2 inline-block font-bold leading-[24px] bg-white text-blue-800 text-left text-sm"
key={"link"} link={`https://kitsunes.club/notes/${data.note_id}`} text={<p>{
key="link" link={`https://kitsunes.club/notes/${data.note_id}`} text={<p>{
...data.text.split("\n").map((te) => emojify(te, data.emojis).concat(<br/>))
.concat(images)
}</p>}

View file

@ -3,7 +3,7 @@ import Info from "../Info.tsx";
import KitsuClub from "./KitsuClub.tsx";
export default function Hacking() {
const kitsuclub = <KitsuClub key={"kitsuclub"}/>;
const kitsuclub = <KitsuClub key="kitsuclub"/>;
return (
<Info

View file

@ -23,17 +23,17 @@ export default function Speedruncom() {
if (data) {
try {
setElements([
<div key={"data"} className="flex pb-2">
<div key="data" className="flex pb-2">
<img alt="game thumbnail" src={data.thumbnail} className="h-24 m-auto" />
<div className="m-auto ml-4 w-full">
<Link key={"more"} classes="text-lg/6 inline-block px-1 py-2 w-full font-bold bg-white text-blue-800" link={data.link}
<Link key="more" classes="text-lg/6 inline-block px-1 py-2 w-full font-bold bg-white text-blue-800" link={data.link}
text={`${data.game} (${data.details.toString()}) in ${data.time}`}/>
</div>
</div>,
<p key="placement" className="mt-2">Placed <strong>#{data.place}</strong></p>,
<p key="date" className="font-bold">{data.date}</p>,
<time key="date">{data.date}</time>,
<> {
data.video ? <ButtonLink key={"youtube"} link={data.video} text="YouTube video"/> : ""
data.video ? <ButtonLink key="youtube" link={data.video} text="YouTube video"/> : ""
} </>
]);

View file

@ -11,15 +11,15 @@ export default function RhythmGames() {
const [websites, setWebsites] = useState([] as React.JSX.Element[]);
useEffect(() => {
setWebsites([<Speedruncom key={"speedruncom"}/>]);
setWebsites([<Speedruncom key="speedruncom"/>]);
}, []);
// useEffect(() => {
// if (data) {
// const osu = <Osu ruleset={Ruleset.osu} key={"osu"}/>;
// const taiko = <Osu ruleset={Ruleset.taiko} key={"taiko"}/>;
// const fruits = <Osu ruleset={Ruleset.fruits} key={"fruits"}/>;
// const mania = <Osu ruleset={Ruleset.mania} key={"mania"}/>;
// const osu = <Osu ruleset={Ruleset.osu} key="osu"/>;
// const taiko = <Osu ruleset={Ruleset.taiko} key="taiko"/>;
// const fruits = <Osu ruleset={Ruleset.fruits} key="fruits"/>;
// const mania = <Osu ruleset={Ruleset.mania} key="mania"/>;
// setWebsites(websites.concat([osu, taiko, fruits, mania]));
// }
// }, [data]);

View file

@ -21,7 +21,7 @@ export default function Hackthebox() {
if (data) {
try {
setElements([
<div key={"data"} className="flex">
<div key="data" className="flex">
{
data.type === "user" ?
<img className="m-auto h-16 w-16" alt="machine thumbnail" src={data.machine_avatar}/> :
@ -34,8 +34,8 @@ export default function Hackthebox() {
<p>({data.type})</p>
</div>
</div>,
<p key={"date"} className="mt-2 font-bold">{data.date}</p>,
<ButtonLink key={"more"} link={`https://app.hackthebox.com/machines/${data.name}`} text="Machine Link" />,
<time key="date" className="mt-2">{data.date}</time>,
<ButtonLink key="more" link={`https://app.hackthebox.com/machines/${data.name}`} text="Machine Link" />,
]);
} catch {
setError(true);

View file

@ -3,7 +3,7 @@ import Info from "../Info.tsx";
import Hackthebox from "./Hackthebox.tsx";
export default function Hacking() {
const hackthebox = <Hackthebox key={"hackthebox"}/>;
const hackthebox = <Hackthebox key="hackthebox"/>;
return (
<Info

View file

@ -1,5 +1,5 @@
import {MisuseOutline} from "@carbon/icons-react";
import React, {Component} from "react";
import {MisuseOutline} from "@carbon/icons-react";
export default class Info extends Component<{
type: string;
@ -10,7 +10,7 @@ export default class Info extends Component<{
const state = this.props.websites.length ? 1 : this.props.error ? 2 : 0;
return (
<div className="m-2.5 flex w-80 hover:scale-[1.02] active:scale-[1.02]">
<article className="m-2.5 flex w-80 hover:scale-[1.02] active:scale-[1.02]">
<h2 className={`[text-orientation:upright] [writing-mode:vertical-rl]
uppercase text-start text-2xl tracking-[-.1em] font-bold pt-2 pb-2
rounded-l-xl bg-white select-none
@ -43,7 +43,7 @@ export default class Info extends Component<{
</div>
}
</div>
</div>
</article>
);
}
}

View file

@ -95,9 +95,9 @@ export default function Wanikani() {
setElements([
resets,
level,
<p key={"lessons"} className="text-xl font-bold">Available lessons ({filteredLessons.length})</p>,
<p key="lessons" className="text-xl font-bold">Available lessons ({filteredLessons.length})</p>,
lessonsDiv,
<p key={"reviews"} className="mt-4 text-xl font-bold">Available reviews ({filteredReviews.length})</p>,
<p key="reviews" className="mt-4 text-xl font-bold">Available reviews ({filteredReviews.length})</p>,
reviewsDiv,
whenNextToReview,
]);

View file

@ -3,7 +3,7 @@ import Info from "../Info.tsx";
import Wanikani from "./Wanikani.tsx";
export default function Japanese() {
const wanikani = <Wanikani key={"wanikani"}/>;
const wanikani = <Wanikani key="wanikani"/>;
return (
<Info

View file

@ -25,16 +25,16 @@ export default function Anilist() {
if (data) {
try {
setElements([
<div key={"data"} className="flex mb-4">
<div key="data" className="flex mb-4">
<img className="mx-auto w-18 h-24" alt="anime cover" src={data.cover} />
<div className="m-auto ml-4 w-full">
<Link classes="text-lg/6 inline-block px-1 py-2 w-full font-bold bg-white text-blue-800" link={data.url} text={data.title}/>
</div>
</div>,
<p key="start" className="text-left">Started: <strong>{data.startDate}</strong></p>,
<p key="start" className="text-left">Started: <time>{data.startDate}</time></p>,
<p key="last" className="text-left">{data.episodes.watched >= data.episodes.total ?
<>Finished: <strong>{data.endDate}</strong></> :
<>Ep. {data.episodes.watched}: <strong>{data.updateDate}</strong></>}</p>,
<>Finished: <time>{data.endDate}</time></> :
<>Ep. {data.episodes.watched}: <time>{data.updateDate}</time></>}</p>,
<p key="status" className="text-left">{data.episodes.watched >= data.episodes.total ?
<>I gave it a <strong>{data.score}/10</strong></> :
<><strong>{data.episodes.watched}/{data.episodes.total}</strong> episodes watched</>}</p>,

View file

@ -34,7 +34,7 @@ export default function Lastfm() {
<>{
data.listening ?
<p key="date" className="mt-2 font-bold">Currently listening!</p> :
<p key="date" className="text-left">When: <strong>{format(date)}</strong></p>
<p key="date" className="text-left">When: <time dateTime={date.toISOString()}>{format(date)}</time></p>
}</>,
]);
} catch {

View file

@ -4,8 +4,8 @@ import Lastfm from "./Lastfm.tsx";
import Anilist from "./Anilist.tsx";
export default function Media() {
const lastfm = <Lastfm key={"Lastfm"}/>;
const anilist = <Anilist key={"Anilist"}/>;
const lastfm = <Lastfm key="Lastfm"/>;
const anilist = <Anilist key="Anilist"/>;
return (
<Info

View file

@ -21,9 +21,9 @@ export default function KitsuDev() {
if (data) {
try {
setElements([
<Link key={"kitsudev-link"} classes="mb-1 px-1 py-2 inline-block w-full font-bold leading-[18px] bg-white text-blue-800" link={data.url} text={data.message}/>,
<p key={"kitsudev-date"}><strong>{data.date.substring(0, data.date.indexOf("T"))}</strong></p>,
<p key={"kitsudev-changes"}>{data.files_modified} files changed <span className="whitespace-nowrap">(<span className="text-green-400">+{data.lines_added}</span> <span className="text-red-400">-{data.lines_removed}</span>)</span></p>
<Link key="kitsudev-link" classes="mb-1 px-1 py-2 inline-block w-full font-bold leading-[18px] bg-white text-blue-800" link={data.url} text={data.message}/>,
<time key="kitsudev-date" dateTime={data.date}>{data.date.substring(0, data.date.indexOf("T"))}</time>,
<p key="kitsudev-changes">{data.files_modified} files changed <span className="whitespace-nowrap">(<span className="text-green-400">+{data.lines_added}</span> <span className="text-red-400">-{data.lines_removed}</span>)</span></p>
]);
} catch {
setError(true);

View file

@ -20,7 +20,7 @@ export default function Umami() {
try {
const plural = data.visits.value !== 1;
setElements([
<p className="text-left" key={"info"}>Throughout <b>the last 7 days,</b> my website has been visited <b>{data.visits.value} time{plural ? "s" : ""}!</b></p>,
<p className="text-left" key="info">Throughout <b>the last 7 days,</b> my website has been visited <b>{data.visits.value} time{plural ? "s" : ""}!</b></p>,
]);
} catch {
setError(true);

View file

@ -9,12 +9,12 @@ export default function Website() {
const [websites, setWebsites] = useState([] as React.JSX.Element[]);
useEffect(() => {
setWebsites([<KitsuDev key={"kitsudev"}/>]);
setWebsites([<KitsuDev key="kitsudev"/>]);
}, []);
useEffect(() => {
if (data) {
const umami = <Umami key={"umami"}/>;
const umami = <Umami key="umami"/>;
setWebsites(websites.concat([umami]));
}
}, [data]);

View file

@ -12,7 +12,7 @@ export default class Infos extends Component {
private readonly collection = React.createRef<HTMLDivElement>();
render() {
return <div ref={this.collection} className="text-base z-110 lg:z-0 w-[27px] lg:w-[360px] fixed right-0 h-screen outline outline-4 outline-white overflow-y-auto
return <aside ref={this.collection} className="text-base z-110 lg:z-0 w-[27px] lg:w-[360px] fixed right-0 h-screen outline outline-4 outline-white overflow-y-auto
bg-linear-to-r from-sky-600 to-indigo-600">
<div draggable="false" ref={this.dragbar} className="z-100 h-full w-[25px] fixed right-[7px] lg:right-[340px] cursor-ew-resize select-none hover:bg-linear-to-r from-white/80 to-white/1 active:to-white/20"></div>
<div className="z-90 p-2.5 flex flex-wrap text-white">
@ -24,7 +24,7 @@ export default class Infos extends Component {
{/*<Hacking/>*/}
<Website/>
</div>
</div>;
</aside>;
}
componentDidMount(): void {

View file

@ -31,7 +31,7 @@ export default function TabButtons({
};
return (
<div className="relative justify-center items-center">
<nav className="relative justify-center items-center">
<TabButton
colors={"from-slate-500 to-slate-600 hover:from-slate-700 hover:to-slate-600"}
onClick={() => {
@ -46,8 +46,8 @@ export default function TabButtons({
}}
content={
<Translatable
en={"About me"}
fr={"À propos de moi"}
en="About me"
fr="À propos de moi"
/>
}
/>
@ -58,8 +58,8 @@ export default function TabButtons({
}}
content={
<Translatable
en={"My projects"}
fr={"Mes projets"}
en="My projects"
fr="Mes projets"
/>
}
/>
@ -70,8 +70,8 @@ export default function TabButtons({
}}
content={
<Translatable
en={"Contact me"}
fr={"Me contacter"}
en="Contact me"
fr="Me contacter"
/>
}
/>
@ -82,8 +82,8 @@ export default function TabButtons({
}}
content={
<Translatable
en={"Support me"}
fr={"Me soutenir"}
en="Support me"
fr="Me soutenir"
/>
}
/>
@ -92,13 +92,8 @@ export default function TabButtons({
onClick={() => {
toggleTab("webrings");
}}
content={
<Translatable
en={"Webrings"}
fr={"Webrings"}
content="Webrings"
/>
}
/>
</div>
</nav>
);
}

View file

@ -11,7 +11,7 @@ export default function About({
setTabs: React.Dispatch<React.SetStateAction<TabDetails[]>>;
}) {
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">
<img className="m-4 float-right h-24" src="/assets/brittany.jpg" alt="Flag of Brittany" title="Flag of Brittany"/>
<Translatable
@ -57,8 +57,8 @@ export default function About({
id="about"
name={
<Translatable
en={"About"}
fr={"À propos"}
en="About"
fr="À propos"
/>
}
elements={elements}

View file

@ -13,7 +13,7 @@ export default function Contact({
setTabs: React.Dispatch<React.SetStateAction<TabDetails[]>>;
}) {
const elements = [(
<div className="m-4 text-white text-left" key={"contact"}>
<div className="m-4 text-white text-left" key="contact">
<Translatable
en={<p>It is my belief that it's actually difficult to communicate with the people you want on the internet, I find emails to be bad for real-time communication, some other platforms enshittify themselves too much, while others do not quite offer the best user experience in my honest opinion.</p>}
fr={<p>Je pense en fait que c'est difficile de communiquer avec les gens qu'on veut sur internet, je trouve que les e-mails ne conviennent pas pour la communication en temps réel, certaines plateformes deviennent horribles, pendant que d'autres n'offrent pas vraiment une bonne expérience.</p>}
@ -42,8 +42,8 @@ export default function Contact({
id="contact"
name={
<Translatable
en={"Contact"}
fr={"Contacter"}
en="Contact"
fr="Contacter"
/>
}
elements={elements}

View file

@ -11,7 +11,7 @@ export default function Projects({
setTabs: React.Dispatch<React.SetStateAction<TabDetails[]>>;
}) {
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">
<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
@ -114,8 +114,8 @@ export default function Projects({
id="projects"
name={
<Translatable
en={"Projects"}
fr={"Projets"}
en="Projects"
fr="Projets"
/>
}
elements={elements}

View file

@ -11,7 +11,7 @@ export default function Support({
setTabs: React.Dispatch<React.SetStateAction<TabDetails[]>>;
}) {
const elements = [(
<div className="m-4 pb-2 text-white" key={"support"}>
<div className="m-4 pb-2 text-white" key="support">
<p>
<b>
<Translatable
@ -45,8 +45,8 @@ export default function Support({
id="support"
name={
<Translatable
en={"Support"}
fr={"Soutenir"}
en="Support"
fr="Soutenir"
/>
}
elements={elements}

View file

@ -45,13 +45,7 @@ export default class Tab extends Component<{
</div>
<div className="drop-shadow-2xl max-h-[500px] overflow-y-auto
[&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-track]:bg-gray-300 [&::-webkit-scrollbar-thumb]:bg-indigo-500 [&::-webkit-scrollbar-track]:rounded-full [&::-webkit-scrollbar-thumb]:rounded-full">
{
this.props.elements.map((e, i) =>
<div key={`element-${i}}`}>
{e}
</div>,
)
}
{...this.props.elements}
</div>
</AnimateHeight>
)}

View file

@ -10,7 +10,7 @@ export default function Webrings({
setTabs: React.Dispatch<React.SetStateAction<TabDetails[]>>;
}) {
const elements = [(
<div className="m-4 pb-2 text-white" key={"webrings"}>
<div className="m-4 pb-2 text-white" key="webrings">
<p>
<b>
<Translatable
@ -28,8 +28,8 @@ export default function Webrings({
id="webrings"
name={
<Translatable
en={"Webrings"}
fr={"Webrings"}
en="Webrings"
fr="Webrings"
/>
}
elements={elements}

View file

@ -12,13 +12,13 @@ export default function MainContent() {
}, [lang]);
return (
<div className="text-lg/6 h-screen w-screen max-w-[1632px] m-auto lg:pl-[50px] lg:pr-[413px] lg:py-12">
<main className="text-lg/6 h-screen w-screen max-w-[1632px] m-auto lg:pl-[50px] lg:pr-[413px] lg:py-12">
<LanguageContext.Provider value={lang}>
<TabContext.Provider value={tabs}>
<MainWindow setLang={setLang} setTabs={setTabs}/>
<Tabs setTabs={setTabs}/>
</TabContext.Provider>
</LanguageContext.Provider>
</div>
</main>
);
}