feat(projects): render preview in top screen, also prepare for markdown rendering
This commit is contained in:
@@ -1,18 +1,70 @@
|
||||
// import PIHKAAL_ME_THUMBNAIL from "/assets/images/projects/bottom-screen/thumbnails/pihkaal.me.webp";
|
||||
// import TLOCK_THUMBNAIL from "/assets/images/projects/bottom-screen/thumbnails/tlock.webp";
|
||||
// import SIMPLE_QR_THUMBNAIL from "/assets/images/projects/bottom-screen/thumbnails/simple-qr.webp";
|
||||
// import LILOU_CAT_THUMBNAIL from "/assets/images/projects/bottom-screen/thumbnails/lilou.cat.webp";
|
||||
// import LBF_BOT_THUMBNAIL from "/assets/images/projects/bottom-screen/thumbnails/lbf-bot.webp";
|
||||
// import RAYLIB_SPEENDRUNS_THUMBNAIL from "/assets/images/projects/bottom-screen/thumbnails/raylib-speedruns.webp";
|
||||
// import SP3WEB_THUMBNAIL from "/assets/images/projects/bottom-screen/thumbnails/s3pweb.webp";
|
||||
// import BIOBLEUD_THUMBNAIL from "/assets/images/projects/bottom-screen/thumbnails/biobleud.webp";
|
||||
import type { MarkdownRoot } from "@nuxt/content";
|
||||
|
||||
type MarkdownBody = (
|
||||
| {
|
||||
type: "h1" | "p";
|
||||
text: string;
|
||||
}
|
||||
| {
|
||||
type: "img";
|
||||
image: HTMLImageElement;
|
||||
}
|
||||
)[];
|
||||
|
||||
const createImage = (src: string): HTMLImageElement => {
|
||||
// TODO: how to cleanup ?
|
||||
const img = document.createElement("img");
|
||||
img.src = src;
|
||||
return img;
|
||||
};
|
||||
|
||||
// TODO: move to utils or smth maybe
|
||||
const simplifyMarkdownAST = (root: MarkdownRoot) => {
|
||||
const body: MarkdownBody = [];
|
||||
for (const node of root.value) {
|
||||
if (Array.isArray(node)) {
|
||||
const [type, props, value] = node;
|
||||
console.log("--------------");
|
||||
console.log(`type = ${type}`);
|
||||
console.log(`props = ${JSON.stringify(props)}`);
|
||||
console.log(`value = ${value}`);
|
||||
|
||||
switch (type) {
|
||||
case "h1":
|
||||
case "p": {
|
||||
if (typeof value !== "string")
|
||||
throw `Unsupported node value for '${type}': '${value}'`;
|
||||
body.push({ type, text: value });
|
||||
break;
|
||||
}
|
||||
|
||||
case "img": {
|
||||
if (typeof props["src"] !== "string")
|
||||
throw `Unsupported type or missing node prop "src" for '${type}': '${JSON.stringify(props)}'`;
|
||||
body.push({ type, image: createImage(props.src) });
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
throw `Unsupported '${type}'`;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw `Unsupported node kind 'string'`;
|
||||
}
|
||||
}
|
||||
|
||||
return body;
|
||||
};
|
||||
|
||||
export const useProjectsStore = defineStore("projects", {
|
||||
state: () => ({
|
||||
projects: [] as {
|
||||
description: string;
|
||||
thumbnail: string;
|
||||
preview: HTMLImageElement;
|
||||
url: string | null;
|
||||
body: MarkdownBody;
|
||||
}[],
|
||||
currentProject: 0,
|
||||
}),
|
||||
@@ -23,7 +75,18 @@ export const useProjectsStore = defineStore("projects", {
|
||||
queryCollection("projects").order("order", "ASC").all(),
|
||||
);
|
||||
if (!projects.value) throw "Cannot load projects";
|
||||
this.projects = projects.value;
|
||||
|
||||
this.projects = [];
|
||||
|
||||
for (const project of projects.value) {
|
||||
this.projects.push({
|
||||
description: project.description,
|
||||
thumbnail: project.thumbnail,
|
||||
preview: createImage(project.preview),
|
||||
url: project.url,
|
||||
body: simplifyMarkdownAST(project.body),
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
visitProject() {
|
||||
|
||||
Reference in New Issue
Block a user