feat: display projects as pokemons in pokemon platinum
This commit is contained in:
@@ -1,74 +1,15 @@
|
||||
import type { MarkdownRoot } from "@nuxt/content";
|
||||
import type {
|
||||
DataCollectionItemBase,
|
||||
ProjectsCollectionItem,
|
||||
} from "@nuxt/content";
|
||||
import gsap from "gsap";
|
||||
|
||||
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: string;
|
||||
url: string | null;
|
||||
technologies: string[];
|
||||
scope: "hobby" | "work";
|
||||
body: MarkdownBody;
|
||||
}[],
|
||||
projects: [] as (Omit<
|
||||
ProjectsCollectionItem,
|
||||
keyof DataCollectionItemBase
|
||||
> & { id: string })[],
|
||||
currentProject: 0,
|
||||
loading: true,
|
||||
offsetX: 0,
|
||||
@@ -77,33 +18,37 @@ export const useProjectsStore = defineStore("projects", {
|
||||
actions: {
|
||||
async loadProjects() {
|
||||
this.loading = true;
|
||||
|
||||
const { data: projects } = await useAsyncData("projects", () =>
|
||||
queryCollection("projects").order("order", "ASC").all(),
|
||||
queryCollection("projects")
|
||||
.order("order", "ASC")
|
||||
.select(
|
||||
"id",
|
||||
"order",
|
||||
"scope",
|
||||
"title",
|
||||
"link",
|
||||
"description",
|
||||
"summary",
|
||||
"technologies",
|
||||
"tasks",
|
||||
)
|
||||
.all(),
|
||||
);
|
||||
if (!projects.value) throw "Cannot load projects";
|
||||
this.projects = projects.value.map((project) => ({
|
||||
...project,
|
||||
id: project.id.split("/")[2]!,
|
||||
}));
|
||||
|
||||
this.projects = [];
|
||||
|
||||
for (const project of projects.value) {
|
||||
const parts = project.id.replace(".md", "").split("/");
|
||||
const id = parts[parts.length - 2]!;
|
||||
this.projects.push({
|
||||
description: project.description,
|
||||
thumbnail: `/images/projects/${id}/thumbnail.webp`,
|
||||
preview: `/images/projects/${id}/preview.webp`,
|
||||
url: project.url,
|
||||
technologies: project.technologies,
|
||||
scope: project.scope,
|
||||
body: simplifyMarkdownAST(project.body),
|
||||
});
|
||||
}
|
||||
console.log(this.projects);
|
||||
|
||||
this.loading = false;
|
||||
},
|
||||
|
||||
visitProject() {
|
||||
const url = this.projects[this.currentProject]!.url;
|
||||
if (url) navigateTo(url, { external: true, open: { target: "_blank" } });
|
||||
const link = this.projects[this.currentProject]?.link;
|
||||
if (link) navigateTo(link, { open: { target: "_blank" } });
|
||||
},
|
||||
|
||||
scrollProjects(direction: "left" | "right") {
|
||||
@@ -133,6 +78,7 @@ export const useProjectsStore = defineStore("projects", {
|
||||
}
|
||||
},
|
||||
|
||||
// TODO: not used anymore
|
||||
scrollToProject(index: number) {
|
||||
if (index === this.currentProject) return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user