chore: upgrade to nuxt 4
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
@import "base.scss";
|
@use "base.scss";
|
||||||
|
|
||||||
.prose article {
|
.prose article {
|
||||||
@include headings {
|
@include base.headings {
|
||||||
& > a:hover,
|
& > a:hover,
|
||||||
& > a:active {
|
& > a:active {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
Before Width: | Height: | Size: 490 B After Width: | Height: | Size: 490 B |
Before Width: | Height: | Size: 339 B After Width: | Height: | Size: 339 B |
Before Width: | Height: | Size: 712 B After Width: | Height: | Size: 712 B |
@@ -1,20 +1,30 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { GithubPushEvent } from "@/shared/github";
|
import type { GithubPushEvent } from "@/shared/github";
|
||||||
import type { Ref } from "vue";
|
|
||||||
|
|
||||||
const FEED_URL = "https://api.github.com/users/potatoeggy/events";
|
const FEED_URL = "https://api.github.com/users/potatoeggy/events";
|
||||||
const imgUrl = ref("");
|
|
||||||
const href = ref("");
|
|
||||||
|
|
||||||
onMounted(async () => {
|
const { data: results } = await useFetch<GithubPushEvent[]>(FEED_URL, {
|
||||||
const results = (await useFetch(FEED_URL)).data as Ref<GithubPushEvent[]>;
|
onResponse(res) {
|
||||||
const latestEvent = results.value.find(
|
res.response.json;
|
||||||
(event) => event.type === "PushEvent"
|
},
|
||||||
) as GithubPushEvent;
|
|
||||||
const latestCommit = latestEvent.payload.commits[0];
|
|
||||||
imgUrl.value = `https://opengraph.githubassets.com/hash/${latestEvent.repo.name}/commit/${latestCommit.sha}`;
|
|
||||||
href.value = `https://github.com/${latestEvent.repo.name}/commit/${latestCommit.sha}`;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const latestEvent = results.value?.find(
|
||||||
|
(event: GithubPushEvent) => event.type === "PushEvent"
|
||||||
|
);
|
||||||
|
|
||||||
|
const latestCommitSha = latestEvent.payload.head;
|
||||||
|
|
||||||
|
const imgUrl = computed(() =>
|
||||||
|
results.value
|
||||||
|
? `https://opengraph.githubassets.com/hash/${latestEvent.repo.name}/commit/${latestCommitSha}`
|
||||||
|
: ""
|
||||||
|
);
|
||||||
|
const href = computed(() =>
|
||||||
|
results.value
|
||||||
|
? `https://github.com/${latestEvent.repo.name}/commit/${latestCommitSha}`
|
||||||
|
: ""
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
@@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { getPrettyDate, getUtcDate } from "~~/shared/metadata";
|
import { getPrettyDate, getUtcDate } from "@/shared/metadata";
|
||||||
import type { AnyParsedContent } from "~~/shared/types";
|
import type { AnyParsedContent } from "@/shared/types";
|
||||||
|
|
||||||
const { doc } = defineProps<{ doc: AnyParsedContent }>();
|
const { doc } = defineProps<{ doc: AnyParsedContent }>();
|
||||||
|
|
@@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import ColourPicker from "./ColourPicker.vue";
|
import ColourPicker from "./ColourPicker.vue";
|
||||||
import { navItems } from "@/data/navItems";
|
import { navItems } from "~/data/navItems";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
@@ -13,40 +13,44 @@
|
|||||||
</p>
|
</p>
|
||||||
<!-- i could make this a list but god i'm so tired with nuxt -->
|
<!-- i could make this a list but god i'm so tired with nuxt -->
|
||||||
<div class="flex justify-around flex-wrap gap-8 items-center">
|
<div class="flex justify-around flex-wrap gap-8 items-center">
|
||||||
<ServiceCard name="Gitea" href="https://git.eggworld.me" img="gitea.svg">
|
<ServiceCard
|
||||||
|
name="Gitea"
|
||||||
|
href="https://git.eggipelago.com"
|
||||||
|
img="gitea.svg"
|
||||||
|
>
|
||||||
Self-hosted GitHub
|
Self-hosted GitHub
|
||||||
</ServiceCard>
|
</ServiceCard>
|
||||||
<ServiceCard
|
<ServiceCard
|
||||||
name="Eifueo"
|
name="Eifueo"
|
||||||
href="https://eifueo.eggworld.me"
|
href="https://eifueo.eggipelago.com"
|
||||||
img="eifueo.svg"
|
img="eifueo.svg"
|
||||||
>
|
>
|
||||||
Note collection
|
Note collection
|
||||||
</ServiceCard>
|
</ServiceCard>
|
||||||
<ServiceCard
|
<ServiceCard
|
||||||
name="Primoprod"
|
name="Primoprod"
|
||||||
href="https://primoprod.eggworld.me"
|
href="https://primoprod.vercel.app"
|
||||||
img="primogem.webp"
|
img="primogem.webp"
|
||||||
>
|
>
|
||||||
Wish simulator
|
Wish simulator
|
||||||
</ServiceCard>
|
</ServiceCard>
|
||||||
<ServiceCard
|
<ServiceCard
|
||||||
name="Calibre"
|
name="Calibre"
|
||||||
href="https://calibre.eggworld.me"
|
href="https://calibre.eggipelago.com"
|
||||||
img="calibre-web.webp"
|
img="calibre-web.webp"
|
||||||
>
|
>
|
||||||
Kobo Cloud
|
Kobo Cloud
|
||||||
</ServiceCard>
|
</ServiceCard>
|
||||||
<ServiceCard
|
<ServiceCard
|
||||||
name="Jellyfin"
|
name="Jellyfin"
|
||||||
href="https://jellyfin.eggworld.me"
|
href="https://jellyfin.eggipelago.com"
|
||||||
img="jellyfin.svg"
|
img="jellyfin.svg"
|
||||||
>
|
>
|
||||||
FOSS media server
|
FOSS media server
|
||||||
</ServiceCard>
|
</ServiceCard>
|
||||||
<ServiceCard
|
<ServiceCard
|
||||||
name="Minecraft"
|
name="Minecraft"
|
||||||
href="minecraft.eggworld.me"
|
href="minecraft.eggipelago.com"
|
||||||
img="minecraft.svg"
|
img="minecraft.svg"
|
||||||
unclickable
|
unclickable
|
||||||
broken
|
broken
|
@@ -34,7 +34,7 @@ useHead({ title: "Oeufs?" });
|
|||||||
GitHub</a
|
GitHub</a
|
||||||
>
|
>
|
||||||
and
|
and
|
||||||
<a class="underline" href="https://git.eggworld.me/eggy/public">
|
<a class="underline" href="https://git.eggipelago.com/eggy/public">
|
||||||
Gitea
|
Gitea
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
@@ -7,7 +7,7 @@ tags:
|
|||||||
- featured
|
- featured
|
||||||
---
|
---
|
||||||
|
|
||||||
Welcome to the very first [Primoprod](https://primoprod.eggworld.me) progress report! In a similar vein to quite a few open source emulation projects (such as those I follow myself using [emufeed](https://github.com/potatoeggy/emufeed/blob/master/sources.py)), I'll be releasing these tidbits in lieu of daily Unstagnation shorts sometimes.
|
Welcome to the very first [Primoprod](https://primoprod.vercel.app) progress report! In a similar vein to quite a few open source emulation projects (such as those I follow myself using [emufeed](https://github.com/potatoeggy/emufeed/blob/master/sources.py)), I'll be releasing these tidbits in lieu of daily Unstagnation shorts sometimes.
|
||||||
|
|
||||||
In this hopefully small series of development notes, I'll be laying out my experiences learning web development as an absolute amateur.
|
In this hopefully small series of development notes, I'll be laying out my experiences learning web development as an absolute amateur.
|
||||||
|
|
||||||
|
@@ -6,7 +6,7 @@ tags:
|
|||||||
- retrospective
|
- retrospective
|
||||||
---
|
---
|
||||||
|
|
||||||
For three and a half years, the [Eifueo project](https://eifueo.eggworld.me) has dutifully carried out its task of collecting and organising notes in a way that would be quick and easy to review. Although this worked out wonderfully in high school, the method is both inefficient and insufficient for the pace of higher education.
|
For three and a half years, the [Eifueo project](https://eifueo.eggipelago.com) has dutifully carried out its task of collecting and organising notes in a way that would be quick and easy to review. Although this worked out wonderfully in high school, the method is both inefficient and insufficient for the pace of higher education.
|
||||||
|
|
||||||
So how can we make it better?
|
So how can we make it better?
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ So how can we make it better?
|
|||||||
|
|
||||||
We can't.
|
We can't.
|
||||||
|
|
||||||
At their core, engineering courses in university are about problem-solving. Instead of blindly memorising rules to be applied once to get you the answer, you blindly memorise rules to be applied *two or more times* to get you the answer.
|
At their core, engineering courses in university are about problem-solving. Instead of blindly memorising rules to be applied once to get you the answer, you blindly memorise rules to be applied _two or more times_ to get you the answer.
|
||||||
|
|
||||||
If we have to do that, it's much easier to write plenty of practice problems instead of rewriting plenty of notes.
|
If we have to do that, it's much easier to write plenty of practice problems instead of rewriting plenty of notes.
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ Reformatting notes is not an easy endeavour. We have to re-examine our old notes
|
|||||||
|
|
||||||
Me? A writer? Imagine.
|
Me? A writer? Imagine.
|
||||||
|
|
||||||
This one isn't actually too bad, and doing practice problems instead isn't going to help much, but think of all the other fun things I could be doing instead. I already *have* the notes. If I need them, I'll just look back at them.
|
This one isn't actually too bad, and doing practice problems instead isn't going to help much, but think of all the other fun things I could be doing instead. I already _have_ the notes. If I need them, I'll just look back at them.
|
||||||
|
|
||||||
Anyway, by the end of Eifueo's lifespan, most of the content was regurgitated onto the site.
|
Anyway, by the end of Eifueo's lifespan, most of the content was regurgitated onto the site.
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ High school had many courses that were "expression"-focused, and those were the
|
|||||||
|
|
||||||
Unfortunately, the physics courses are antithetical to everything Eifueo stands for. They have a rigid structure that you can't bullshit your way out of but are also flexible enough that you can't simply apply a formula. The best way to get good is simply to do more problems.
|
Unfortunately, the physics courses are antithetical to everything Eifueo stands for. They have a rigid structure that you can't bullshit your way out of but are also flexible enough that you can't simply apply a formula. The best way to get good is simply to do more problems.
|
||||||
|
|
||||||
You'll have to understand that this greatly saddened me as a person who tries his hardest to do *less* problems. The cost-benefit ratio isn't worth it anymore.
|
You'll have to understand that this greatly saddened me as a person who tries his hardest to do _less_ problems. The cost-benefit ratio isn't worth it anymore.
|
||||||
|
|
||||||
## Retrospective
|
## Retrospective
|
||||||
|
|
||||||
@@ -48,6 +48,4 @@ With a heavy heart, I must bid farewell to one of the first services I ever depl
|
|||||||
|
|
||||||
o7 It has served me well.
|
o7 It has served me well.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
|
@@ -1,7 +0,0 @@
|
|||||||
export const navItems = [
|
|
||||||
{ href: "/#about", title: "About" },
|
|
||||||
{ href: "/blog", title: "Blog" },
|
|
||||||
{ href: "/stories", title: "Stories" },
|
|
||||||
];
|
|
||||||
|
|
||||||
export default navItems;
|
|
129
data/projects.ts
129
data/projects.ts
@@ -1,129 +0,0 @@
|
|||||||
export type Language =
|
|
||||||
| "python"
|
|
||||||
| "javascript"
|
|
||||||
| "java"
|
|
||||||
| "typescript"
|
|
||||||
| "vue"
|
|
||||||
| "react"
|
|
||||||
| "markdown"
|
|
||||||
| "flutter"
|
|
||||||
| "android"
|
|
||||||
| "rust"
|
|
||||||
| "golang";
|
|
||||||
export interface Project {
|
|
||||||
name: string;
|
|
||||||
href: string;
|
|
||||||
img?: string;
|
|
||||||
description?: string;
|
|
||||||
longDescription?: string;
|
|
||||||
langs: Language[];
|
|
||||||
license?: "AGPL-3.0" | "GPL-3.0" | "MIT" | "LGPL-3.0";
|
|
||||||
type: "web" | "tool" | "embedded" | "service";
|
|
||||||
}
|
|
||||||
|
|
||||||
export const projects: Project[] = [
|
|
||||||
{
|
|
||||||
name: "Mandown",
|
|
||||||
href: "https://github.com/potatoeggy/mandown",
|
|
||||||
description:
|
|
||||||
"A comic downloader and converter to CBZ / EPUB / PDF for my Kobo.",
|
|
||||||
longDescription: "Available via CLI and a Qt GUI!",
|
|
||||||
langs: ["python"],
|
|
||||||
license: "AGPL-3.0",
|
|
||||||
img: "mandown.webp",
|
|
||||||
type: "tool",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Noveldown",
|
|
||||||
href: "https://github.com/potatoeggy/noveldown",
|
|
||||||
langs: ["python"],
|
|
||||||
license: "LGPL-3.0",
|
|
||||||
description:
|
|
||||||
"A webnovel downloader and EPUB converter for my Kobo, with lots of metadata!",
|
|
||||||
longDescription: "Heavily borrows Mandown's design.",
|
|
||||||
type: "tool",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Jeopardy",
|
|
||||||
href: "https://github.com/potatoeggy/jeopardy",
|
|
||||||
img: "jeopardy.webp",
|
|
||||||
langs: ["typescript", "vue"],
|
|
||||||
license: "AGPL-3.0",
|
|
||||||
description: "Kahoot-inspired Jeopardy! game, including Final Jeopardy!",
|
|
||||||
longDescription: "Created for Bayview's Computer Club.",
|
|
||||||
type: "web",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Primoprod",
|
|
||||||
href: "https://github.com/potatoeggy/primoprod",
|
|
||||||
img: "primoprod.webp",
|
|
||||||
langs: ["typescript", "vue"],
|
|
||||||
license: "AGPL-3.0",
|
|
||||||
description:
|
|
||||||
"A game simulator to increase productivity with quests and gambling.",
|
|
||||||
longDescription: "My first project with a JS framework!",
|
|
||||||
type: "web",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "PillowⓇ",
|
|
||||||
href: "https://github.com/potatoeggy/ece198",
|
|
||||||
description:
|
|
||||||
"A water quality statistics aggregator written for the STM32 microcontroller with a display and keypad.",
|
|
||||||
langs: ["rust"],
|
|
||||||
license: "GPL-3.0",
|
|
||||||
type: "embedded",
|
|
||||||
img: "pillow.webp",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Napbot",
|
|
||||||
href: "https://github.com/potatoeggy/napbot",
|
|
||||||
langs: ["python"],
|
|
||||||
license: "AGPL-3.0",
|
|
||||||
description:
|
|
||||||
"A Discord music bot with synchronised lyrics, originally a sleep tracking bot to encourage sleeping.",
|
|
||||||
img: "napbot.webp",
|
|
||||||
type: "service",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "AutoFicFare",
|
|
||||||
href: "https://github.com/potatoeggy/autoficfare",
|
|
||||||
langs: ["python"],
|
|
||||||
license: "GPL-3.0",
|
|
||||||
description:
|
|
||||||
"Automatically update fanfiction in a Calibre database to instantly update them on your Kobo.",
|
|
||||||
type: "tool",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const unreleasedProjects: Project[] = [
|
|
||||||
{
|
|
||||||
name: "Aleister",
|
|
||||||
href: "https://github.com/potatoeggy/aleister",
|
|
||||||
langs: ["rust"],
|
|
||||||
license: "AGPL-3.0",
|
|
||||||
type: "service",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Aoto",
|
|
||||||
href: "https://github.com/potatoeggy/aoto",
|
|
||||||
langs: ["golang", "typescript", "react"],
|
|
||||||
license: "AGPL-3.0",
|
|
||||||
type: "web",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Kobink",
|
|
||||||
href: "https://github.com/potatoeggy/kobink",
|
|
||||||
langs: ["rust"],
|
|
||||||
license: "AGPL-3.0",
|
|
||||||
type: "service",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "GBARR",
|
|
||||||
href: "https://github.com/potatoeggy/gbarr",
|
|
||||||
langs: ["rust"],
|
|
||||||
license: "GPL-3.0",
|
|
||||||
type: "embedded",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export default projects;
|
|
@@ -1,13 +0,0 @@
|
|||||||
interface SiteRevision {
|
|
||||||
title: string;
|
|
||||||
url: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const revisions: SiteRevision[] = [
|
|
||||||
{
|
|
||||||
title: "Nuxt 3 (2022)",
|
|
||||||
url: "https://eggworld.me",
|
|
||||||
},
|
|
||||||
{ title: "Eleventy (2021)", url: "https://2021.eggworld.me" },
|
|
||||||
{ title: "Vanilla (2019-2020)", url: "https://2020.eggworld.me" },
|
|
||||||
];
|
|
@@ -1,3 +0,0 @@
|
|||||||
export const SpecialTags: string[] = [
|
|
||||||
"featured",
|
|
||||||
];
|
|
@@ -1,79 +0,0 @@
|
|||||||
export interface TagData {
|
|
||||||
name?: string;
|
|
||||||
description?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const tagInfo: Record<string, TagData> = {
|
|
||||||
barin: {
|
|
||||||
name: "Barin",
|
|
||||||
description:
|
|
||||||
"Welcome to Barin — a world in constant conflict between productivity and procrastination.",
|
|
||||||
},
|
|
||||||
bsscc: {
|
|
||||||
name: "BSSCC",
|
|
||||||
description: "Posts related to Bayview's Computer Club.",
|
|
||||||
},
|
|
||||||
ibia: {
|
|
||||||
name: "Ibia",
|
|
||||||
description:
|
|
||||||
"A Kurious child struggles to fight the misinformation brought by the Six Goddesses of the Subjects.",
|
|
||||||
},
|
|
||||||
misc: { name: "Miscellaneous" },
|
|
||||||
poetry: {
|
|
||||||
name: "Poetry",
|
|
||||||
description:
|
|
||||||
"Poetry is interesting in that there is a lot of implied stuff that is normally said directly in prose.",
|
|
||||||
},
|
|
||||||
primoprod: {
|
|
||||||
name: "Primoprod",
|
|
||||||
description:
|
|
||||||
'Reports following the development of <a href="https://github.com/potatoeggy/primoprod">Primoprod</a>.',
|
|
||||||
},
|
|
||||||
tech: { name: "Technology" },
|
|
||||||
unstagnation: {
|
|
||||||
name: "Unstagnation Short",
|
|
||||||
description:
|
|
||||||
"A collection of very short stories written to do something productive during June–August 2020 and August 2021.",
|
|
||||||
},
|
|
||||||
albatross: {
|
|
||||||
name: "The FOSS Albatross",
|
|
||||||
description:
|
|
||||||
'Articles about free and open source software. Also available on <a href="https://medium.com/the-foss-albatross">Medium</a>.',
|
|
||||||
},
|
|
||||||
birds: {
|
|
||||||
name: "Bird Family",
|
|
||||||
description:
|
|
||||||
"A large, loving family of birds who have found in each other a kindred soul for eternal suffering.",
|
|
||||||
},
|
|
||||||
birdseye: {
|
|
||||||
name: "Bird's-Eye View",
|
|
||||||
description: "What's the world like to a pair of human-watching bluebirds?",
|
|
||||||
},
|
|
||||||
uoft: {
|
|
||||||
name: "University of Teyvat",
|
|
||||||
description: "A <em>Genshin Impact</em> university AU.",
|
|
||||||
},
|
|
||||||
nanowrimo: {
|
|
||||||
name: "NaNoWriMo",
|
|
||||||
description:
|
|
||||||
"Story snippets written during National Novel Writing Month as part of a larger work.",
|
|
||||||
},
|
|
||||||
skyprojections: {
|
|
||||||
name: "Projections in the Sky",
|
|
||||||
description: "Dreams or reality — what is the difference?",
|
|
||||||
},
|
|
||||||
featured: {
|
|
||||||
name: "Featured",
|
|
||||||
description: "Works that are less rambly and more actually good!",
|
|
||||||
},
|
|
||||||
"monoceros (novel)": {
|
|
||||||
name: "Monoceros (novel)",
|
|
||||||
description: "A coffee shop where six students meet and become friends.",
|
|
||||||
},
|
|
||||||
"emma the narwhal": {
|
|
||||||
name: "Emma the Narwhal",
|
|
||||||
description:
|
|
||||||
'A mystery-betrayal story written by April Evans in <a href="/tags/stories/monoceros (novel)"><em>Monoceros</em> (novel)</a>.',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
export default tagInfo;
|
|
@@ -1,8 +1,9 @@
|
|||||||
import { defineNuxtConfig } from "nuxt/config";
|
import { defineNuxtConfig } from "nuxt/config";
|
||||||
import svgLoader from "vite-svg-loader";
|
import svgLoader from "vite-svg-loader";
|
||||||
|
|
||||||
// https://v3.nuxtjs.org/api/configuration/nuxt.config
|
// https://v3.nuxtjs.org/api/configuration/nuxt.config
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
compatibilityDate: "2024-10-16",
|
compatibilityDate: "2025-10-19",
|
||||||
app: {
|
app: {
|
||||||
head: {
|
head: {
|
||||||
htmlAttrs: {
|
htmlAttrs: {
|
||||||
@@ -23,7 +24,6 @@ export default defineNuxtConfig({
|
|||||||
{
|
{
|
||||||
defer: true,
|
defer: true,
|
||||||
src: "/script.js",
|
src: "/script.js",
|
||||||
hid: "stupidEmergencyScript",
|
|
||||||
type: "module",
|
type: "module",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -45,7 +45,7 @@ export default defineNuxtConfig({
|
|||||||
shim: false,
|
shim: false,
|
||||||
},
|
},
|
||||||
site: {
|
site: {
|
||||||
url: process.env.BASE_URL || "https://eggworld.me",
|
url: process.env.BASE_URL || "https://eggipelago.com",
|
||||||
},
|
},
|
||||||
sitemap: {
|
sitemap: {
|
||||||
strictNuxtContentPaths: true,
|
strictNuxtContentPaths: true,
|
||||||
|
19
package.json
19
package.json
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "nuxt build",
|
"build": "nuxt build",
|
||||||
"dev": "nuxt dev",
|
"dev": "nuxt dev",
|
||||||
@@ -8,19 +9,19 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxt/content": "^2.13.4",
|
"@nuxt/content": "^2.13.4",
|
||||||
"@nuxtjs/color-mode": "^3.5.1",
|
"@nuxtjs/color-mode": "^3.5.2",
|
||||||
"@nuxtjs/sitemap": "^6.1.2",
|
"@nuxtjs/sitemap": "^7.4.7",
|
||||||
"@nuxtjs/tailwindcss": "^6.12.1",
|
"@nuxtjs/tailwindcss": "^6.14.0",
|
||||||
"@tailwindcss/typography": "^0.5.15",
|
"@tailwindcss/typography": "^0.5.19",
|
||||||
"@types/node": "^22.7.5",
|
"@types/node": "^22.7.5",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.18",
|
||||||
"nuxt": "3.13.2",
|
"nuxt": "^4.1.3",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.6.2",
|
||||||
"reading-time": "^2.0.0-1",
|
"reading-time": "^2.0.0-1",
|
||||||
"rehype-katex": "^7.0.1",
|
"rehype-katex": "^7.0.1",
|
||||||
"remark-math": "^6.0.0",
|
"remark-math": "^6.0.0",
|
||||||
"sass": "^1.79.5",
|
"sass": "^1.93.2",
|
||||||
"typescript": "^5.6.3",
|
"typescript": "^5.9.3",
|
||||||
"vite-svg-loader": "^5.1.0"
|
"vite-svg-loader": "^5.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
Sitemap: https://eggworld.me/sitemap.xml
|
Sitemap: https://eggipelago.com/sitemap.xml
|
||||||
User-agent: *
|
User-agent: *
|
||||||
Disallow:
|
Disallow:
|
@@ -23,13 +23,13 @@ if (darkToggle) {
|
|||||||
const FEED_URL = "https://api.github.com/users/potatoeggy/events";
|
const FEED_URL = "https://api.github.com/users/potatoeggy/events";
|
||||||
const results = (await (await fetch(FEED_URL)).json());
|
const results = (await (await fetch(FEED_URL)).json());
|
||||||
const latestEvent = results.find((e) => e.type === "PushEvent");
|
const latestEvent = results.find((e) => e.type === "PushEvent");
|
||||||
const latestCommit = latestEvent.payload.commits[0];
|
const latestCommit = latestEvent.payload.head;
|
||||||
const commitImg = document.getElementById("github-commit-img");
|
const commitImg = document.getElementById("github-commit-img");
|
||||||
const commitAnchor = document.getElementById("github-commit-a");
|
const commitAnchor = document.getElementById("github-commit-a");
|
||||||
if (commitImg) {
|
if (commitImg) {
|
||||||
commitImg.src = `https://opengraph.githubassets.com/hash/${latestEvent.repo.name}/commit/${latestCommit.sha}`;
|
commitImg.src = `https://opengraph.githubassets.com/hash/${latestEvent.repo.name}/commit/${latestCommitSha}`;
|
||||||
}
|
}
|
||||||
if (commitAnchor) {
|
if (commitAnchor) {
|
||||||
commitAnchor.href = `https://github.com/${latestEvent.repo.name}/commit/${latestCommit.sha}`;
|
commitAnchor.href = `https://github.com/${latestEvent.repo.name}/commit/${latestCommitSha}`;
|
||||||
}
|
}
|
||||||
export {};
|
export {};
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
// of all the nuxt bs while we wait for static generation
|
// of all the nuxt bs while we wait for static generation
|
||||||
// to actually become a thing in nuxt 3
|
// to actually become a thing in nuxt 3
|
||||||
|
|
||||||
import type { GithubPushEvent } from "../shared/github";
|
import type { GithubPushEvent } from "../app/shared/github";
|
||||||
|
|
||||||
const html = document.getElementsByTagName("html")[0];
|
const html = document.getElementsByTagName("html")[0];
|
||||||
html.className = localStorage.theme ?? "light";
|
html.className = localStorage.theme ?? "light";
|
||||||
@@ -36,7 +36,7 @@ const results = (await (await fetch(FEED_URL)).json()) as GithubPushEvent[];
|
|||||||
const latestEvent = results.find(
|
const latestEvent = results.find(
|
||||||
(e) => e.type === "PushEvent"
|
(e) => e.type === "PushEvent"
|
||||||
) as GithubPushEvent;
|
) as GithubPushEvent;
|
||||||
const latestCommit = latestEvent.payload.commits[0];
|
const latestCommitSha = latestEvent.payload.head;
|
||||||
|
|
||||||
const commitImg = document.getElementById(
|
const commitImg = document.getElementById(
|
||||||
"github-commit-img"
|
"github-commit-img"
|
||||||
@@ -46,11 +46,11 @@ const commitAnchor = document.getElementById(
|
|||||||
) as HTMLAnchorElement;
|
) as HTMLAnchorElement;
|
||||||
|
|
||||||
if (commitImg) {
|
if (commitImg) {
|
||||||
commitImg.src = `https://opengraph.githubassets.com/hash/${latestEvent.repo.name}/commit/${latestCommit.sha}`;
|
commitImg.src = `https://opengraph.githubassets.com/hash/${latestEvent.repo.name}/commit/${latestCommitSha}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commitAnchor) {
|
if (commitAnchor) {
|
||||||
commitAnchor.href = `https://github.com/${latestEvent.repo.name}/commit/${latestCommit.sha}`;
|
commitAnchor.href = `https://github.com/${latestEvent.repo.name}/commit/${latestCommitSha}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// to make this an esm module for top-level await
|
// to make this an esm module for top-level await
|
||||||
|
117
shared/github.d.ts
vendored
117
shared/github.d.ts
vendored
@@ -1,117 +0,0 @@
|
|||||||
// i know i can import one but
|
|
||||||
// i can't find one so here we are
|
|
||||||
|
|
||||||
export interface GithubUser {
|
|
||||||
id: number;
|
|
||||||
login: string;
|
|
||||||
display_login: string;
|
|
||||||
gravatar_id: string;
|
|
||||||
url: string;
|
|
||||||
avatar_url: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GithubRepo {
|
|
||||||
id: number;
|
|
||||||
name: string;
|
|
||||||
url: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GithubCommit {
|
|
||||||
sha: string;
|
|
||||||
author: {
|
|
||||||
email: string;
|
|
||||||
name: string;
|
|
||||||
};
|
|
||||||
message: string;
|
|
||||||
distinct: boolean;
|
|
||||||
url: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GithubPullRequest {
|
|
||||||
url: string;
|
|
||||||
id: number;
|
|
||||||
node_id: string;
|
|
||||||
html_url: string;
|
|
||||||
diff_url: string;
|
|
||||||
patch_url: string;
|
|
||||||
issue_url: string;
|
|
||||||
number: number;
|
|
||||||
state: string;
|
|
||||||
locked: boolean;
|
|
||||||
title: string;
|
|
||||||
body: string;
|
|
||||||
created_at: string;
|
|
||||||
updated_at: string;
|
|
||||||
closed_at: string | null;
|
|
||||||
merged_at: string | null;
|
|
||||||
merge_commit_sha: string | null;
|
|
||||||
draft: boolean;
|
|
||||||
// there's more but i don't wanna
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GithubRelease {
|
|
||||||
url: string;
|
|
||||||
assets_url: string;
|
|
||||||
upload_url: string;
|
|
||||||
html_url: string;
|
|
||||||
id: number;
|
|
||||||
// author: AUTHOR
|
|
||||||
node_id: string;
|
|
||||||
tag_name: string;
|
|
||||||
target_commitish: string;
|
|
||||||
name: string;
|
|
||||||
draft: boolean;
|
|
||||||
prerelease: boolean;
|
|
||||||
created_at: string;
|
|
||||||
published_at: string;
|
|
||||||
tarball_url: string;
|
|
||||||
zipball_url: string;
|
|
||||||
body: string;
|
|
||||||
short_description_html: string;
|
|
||||||
is_short_description_html_truncated: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GithubCommitEventPayload {
|
|
||||||
push_id: number;
|
|
||||||
size: number;
|
|
||||||
distinct_size: number;
|
|
||||||
ref: string;
|
|
||||||
head: string;
|
|
||||||
before: string;
|
|
||||||
commits: GithubCommit[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GithubPullRequestEventPayload {
|
|
||||||
action: string;
|
|
||||||
number: number;
|
|
||||||
pull_request: GithubPullRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GithubReleaseEventPayload {
|
|
||||||
action: string;
|
|
||||||
release: GithubRelease;
|
|
||||||
public: boolean;
|
|
||||||
created_at: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GithubEvent {
|
|
||||||
id: string;
|
|
||||||
type: "PushEvent" | "CreateEvent" | "ReleaseEvent" | "PullRequestEvent";
|
|
||||||
actor: GithubUser;
|
|
||||||
repo: GithubRepo;
|
|
||||||
payload:
|
|
||||||
| GithubCommitEventPayload
|
|
||||||
| GithubPullRequestEventPayload
|
|
||||||
| GithubReleaseEventPayload;
|
|
||||||
public: boolean;
|
|
||||||
created_at: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GithubPushEvent extends GithubEvent {
|
|
||||||
type: "PushEvent";
|
|
||||||
payload: GithubCommitEventPayload;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GithubCreateEvent {}
|
|
||||||
|
|
||||||
export interface GithubReleaseEvent {}
|
|
@@ -1,44 +0,0 @@
|
|||||||
import type { AnyParsedContent } from "./types";
|
|
||||||
import readingTime from "reading-time";
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
import utc from "dayjs/plugin/utc.js";
|
|
||||||
|
|
||||||
dayjs.extend(utc);
|
|
||||||
|
|
||||||
function countWords(str: string) {
|
|
||||||
let words = 0;
|
|
||||||
for (const c of str) {
|
|
||||||
if (c === " " || c === "/") {
|
|
||||||
words++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return words;
|
|
||||||
}
|
|
||||||
|
|
||||||
function search(obj: Record<string, any>, results: string[] = []) {
|
|
||||||
if (obj.value) {
|
|
||||||
results.push(obj.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (obj.children) {
|
|
||||||
for (const el of obj.children) {
|
|
||||||
search(el, results);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function calcReadingTime(doc: AnyParsedContent) {
|
|
||||||
let body: string[] = search(doc.body);
|
|
||||||
return readingTime(body.join(" "));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getPrettyDate(doc: AnyParsedContent) {
|
|
||||||
const date = dayjs(doc.date).utc();
|
|
||||||
return date.format("DD MMM YYYY");
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getUtcDate(doc: AnyParsedContent) {
|
|
||||||
const date = dayjs(doc.date).utc();
|
|
||||||
return date.format("YYYY-MM-DD");
|
|
||||||
}
|
|
28
shared/types.d.ts
vendored
28
shared/types.d.ts
vendored
@@ -1,28 +0,0 @@
|
|||||||
import type { ParsedContent } from "@nuxt/content/dist/runtime/types";
|
|
||||||
|
|
||||||
interface ReadingTime {
|
|
||||||
text: string;
|
|
||||||
minutes: number;
|
|
||||||
time: number;
|
|
||||||
words: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface BlogParsedContent extends ParsedContent {
|
|
||||||
date: Date;
|
|
||||||
title: string;
|
|
||||||
tags: string[];
|
|
||||||
description?: string;
|
|
||||||
readingTime: ReadingTime;
|
|
||||||
nopreview?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface StoryParsedContent extends ParsedContent {
|
|
||||||
date: Date;
|
|
||||||
title: string;
|
|
||||||
tags: string[];
|
|
||||||
description?: string;
|
|
||||||
readingTime: ReadingTime;
|
|
||||||
nopreview?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
type AnyParsedContent = BlogParsedContent | StoryParsedContent;
|
|
@@ -18,6 +18,6 @@
|
|||||||
"noImplicitAny": true,
|
"noImplicitAny": true,
|
||||||
"strictNullChecks": true,
|
"strictNullChecks": true,
|
||||||
"strictFunctionTypes": true,
|
"strictFunctionTypes": true,
|
||||||
"alwaysStrict": true
|
"alwaysStrict": true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user