diff --git a/package-lock.json b/package-lock.json index a1ddde3..ba3e446 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "sequelize": "^6.37.1", "sqlite3": "^5.1.7", "svelte-countup": "^0.2.6", + "svelte-markdown": "^0.4.1", "typeorm": "^0.3.20", "uuid": "^9.0.1", "verify-hcaptcha": "^1.0.0", @@ -1592,6 +1593,11 @@ "@types/node": "*" } }, + "node_modules/@types/marked": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/marked/-/marked-5.0.2.tgz", + "integrity": "sha512-OucS4KMHhFzhz27KxmWg7J+kIYqyqoW5kdIEI319hqARQQUTqhao3M/F+uFnDXD0Rg72iDDZxZNxq5gvctmLlg==" + }, "node_modules/@types/ms": { "version": "0.7.34", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", @@ -8061,6 +8067,17 @@ "node": ">=0.10.0" } }, + "node_modules/marked": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-5.1.2.tgz", + "integrity": "sha512-ahRPGXJpjMjwSOlBoTMZAK7ATXkli5qCPxZ21TG44rx1KEo44bii4ekgTDQPNRQ4Kh7JMb9Ub1PVk1NxRSsorg==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 16" + } + }, "node_modules/matchdep": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", @@ -11918,6 +11935,18 @@ "svelte": "^3.19.0 || ^4.0.0" } }, + "node_modules/svelte-markdown": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/svelte-markdown/-/svelte-markdown-0.4.1.tgz", + "integrity": "sha512-pOlLY6EruKJaWI9my/2bKX8PdTeP5CM0s4VMmwmC2prlOkjAf+AOmTM4wW/l19Y6WZ87YmP8+ZCJCCwBChWjYw==", + "dependencies": { + "@types/marked": "^5.0.1", + "marked": "^5.1.2" + }, + "peerDependencies": { + "svelte": "^4.0.0" + } + }, "node_modules/svelte-parse-markup": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/svelte-parse-markup/-/svelte-parse-markup-0.1.2.tgz", diff --git a/package.json b/package.json index 55c75f5..ee903cb 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "sequelize": "^6.37.1", "sqlite3": "^5.1.7", "svelte-countup": "^0.2.6", + "svelte-markdown": "^0.4.1", "typeorm": "^0.3.20", "uuid": "^9.0.1", "verify-hcaptcha": "^1.0.0", diff --git a/src/lib/util/animation/index.ts b/src/lib/util/animation/index.ts new file mode 100644 index 0000000..5487394 --- /dev/null +++ b/src/lib/util/animation/index.ts @@ -0,0 +1,24 @@ +interface Animation { + duration: number; + delay: number; + property: string | string[]; + timingFunction: string; +} + +export const transition = + "linear(0,0.006,0.025 2.8%,0.101 6.1%,0.539 18.9%,0.721 25.3%,0.849 31.5%,0.937 38.1%,0.968 41.8%,0.991 45.7%,1.006 50.1%,1.015 55%,1.017 63.9%,1.001)"; + +export function generateTransition(animations: Animation[]) { + return animations + .map((animation) => + Array.isArray(animation.property) + ? animation.property + .map( + (property) => + `${property} ${animation.duration}ms ${animation.timingFunction} ${animation.delay * 50}ms`, + ) + .join(", ") + : `${animation.property} ${animation.duration}ms ${animation.timingFunction} ${animation.delay * 50}ms`, + ) + .join(", "); +} diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index fd66ae2..5a6ed4b 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -9,6 +9,7 @@ import type { TransitionConfig } from "svelte/transition"; import type { PageData } from "./$types"; import { bounceOut } from "svelte/easing"; + import { generateTransition, transition } from "$lib/util/animation"; export let data: PageData; @@ -18,31 +19,7 @@ href: string; } - interface Animation { - duration: number; - delay: number; - property: string | string[]; - timingFunction: string; - } - - function generateTransition(animations: Animation[]) { - return animations - .map((animation) => - Array.isArray(animation.property) - ? animation.property - .map( - (property) => - `${property} ${animation.duration}ms ${animation.timingFunction} ${animation.delay * 50}ms`, - ) - .join(", ") - : `${animation.property} ${animation.duration}ms ${animation.timingFunction} ${animation.delay * 50}ms`, - ) - .join(", "); - } - const token = writable(""); - const transition = - "linear(0,0.006,0.025 2.8%,0.101 6.1%,0.539 18.9%,0.721 25.3%,0.849 31.5%,0.937 38.1%,0.968 41.8%,0.991 45.7%,1.006 50.1%,1.015 55%,1.017 63.9%,1.001)"; function transitionIn(node: HTMLElement, { duration = 360 }: TransitionConfig) { const UA = navigator.userAgent; @@ -117,7 +94,7 @@ ], { easing: transition, - duration, + duration: duration, }, ); return { @@ -139,7 +116,7 @@ const navItems: NavItem[] = [ { name: "Blog", - href: "/coming-soon", + href: "/blog", }, { name: "Docs", @@ -251,7 +228,7 @@
diff --git a/src/routes/blog/+page.server.ts b/src/routes/blog/+page.server.ts new file mode 100644 index 0000000..38f0748 --- /dev/null +++ b/src/routes/blog/+page.server.ts @@ -0,0 +1,37 @@ +import path from "path"; +import fs from "fs/promises"; +import { error } from "@sveltejs/kit"; + +export async function load({ params }) { + const basePath = "static/blog"; + const files = await fs.readdir(basePath); + // get all file contents in an array + const posts = await Promise.all( + files.map(async (filename) => { + const filePath = path.join(basePath, filename); + let contents = await fs.readFile(filePath, "utf-8"); + const title = + contents + .split("\n") + .find((line) => line.startsWith("#")) + ?.slice(1) || + filename + .split("-") + .slice(1) + .join(" ") + .split(".md") + .slice(0, -1) + .join(".md") + .replace(/^\w/gm, (c) => c.toUpperCase()); + // remove title from contents + return { + contents: contents.split("\n").slice(1).join("\n"), + title, + slug: filename.split(".md").slice(0, -1).join(".md").split("-").slice(1).join("-"), + }; + }), + ); + return { + posts, + }; +} diff --git a/src/routes/blog/+page.svelte b/src/routes/blog/+page.svelte new file mode 100644 index 0000000..ecd8152 --- /dev/null +++ b/src/routes/blog/+page.svelte @@ -0,0 +1,121 @@ + + +
+