This commit is contained in:
parent
a7aaff537f
commit
262032b4e3
|
@ -11,37 +11,46 @@ export default class TSCompiler extends Plugin {
|
||||||
minify = false;
|
minify = false;
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
if(process.argv.includes("--prod")) {
|
if (process.argv.includes("--prod")) {
|
||||||
this.minify = true;
|
this.minify = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async rewriteFile(file: string, filePath: string) {
|
async rewriteFile(file: string, filePath: string) {
|
||||||
|
let result;
|
||||||
|
try {
|
||||||
|
result = await esbuild.build({
|
||||||
|
stdin: {
|
||||||
|
contents: file,
|
||||||
|
resolveDir: filePath.split("/")?.slice(0, -1).join("/"),
|
||||||
|
sourcefile: filePath.split("/").at(-1),
|
||||||
|
loader: filePath.split("/").at(-1)?.split(".").at(-1) as
|
||||||
|
| "ts"
|
||||||
|
| "tsx"
|
||||||
|
| "jsx",
|
||||||
|
},
|
||||||
|
jsxFragment: "Fragment",
|
||||||
|
jsxFactory: "Nano.h",
|
||||||
|
jsxImportSource: "nano-jsx",
|
||||||
|
jsx: "transform",
|
||||||
|
write: false,
|
||||||
|
bundle: true,
|
||||||
|
outdir: "out",
|
||||||
|
minify: this.minify,
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
console.log("Errored!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const result = await esbuild.build({
|
if (result.errors.length != 0) {
|
||||||
stdin: {
|
console.log("TS compiler errored.");
|
||||||
contents: file,
|
result.errors.forEach((element) => {
|
||||||
resolveDir: filePath.split("/")?.slice(0,-1).join("/"),
|
console.error(element);
|
||||||
sourcefile: filePath.split("/").at(-1),
|
});
|
||||||
loader: filePath.split("/").at(-1)?.split(".").at(-1) as "ts"|"tsx"|"jsx"
|
|
||||||
},
|
|
||||||
jsxFragment: "Fragment",
|
|
||||||
jsxFactory: "Nano.h",
|
|
||||||
jsxImportSource: "nano-jsx",
|
|
||||||
jsx: "transform",
|
|
||||||
write: false,
|
|
||||||
bundle: true,
|
|
||||||
outdir: 'out',
|
|
||||||
minify: this.minify,
|
|
||||||
});
|
|
||||||
|
|
||||||
if(result.errors.length != 0) {
|
|
||||||
console.log("TS compiler errored.")
|
|
||||||
result.errors.forEach(element => {
|
|
||||||
console.error(element);
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
const output = result.outputFiles[0].contents;
|
const output = result.outputFiles[0].contents;
|
||||||
return (new TextDecoder()).decode(output);
|
return new TextDecoder().decode(output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ export default class Variables extends Plugin {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.variables["__BLOG_POSTS__"] = JSON.stringify(
|
this.variables["__BLOG_POSTS__"] = JSON.stringify(
|
||||||
fs.readdirSync("./website/blogs")
|
fs.readdirSync("./website/blogs").map((z) => z.replace(".md", ""))
|
||||||
);
|
);
|
||||||
const templatePath = path.resolve(__dirname, "../../website/templates");
|
const templatePath = path.resolve(__dirname, "../../website/templates");
|
||||||
if (fs.existsSync(templatePath)) {
|
if (fs.existsSync(templatePath)) {
|
||||||
|
|
|
@ -3,21 +3,7 @@ __TEMPLATE_HEAD__
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<h1> sophie's blog </h1>
|
<div id="root"></div>
|
||||||
<a id="return_back" href="/blog.html" style="display:none;font-size:xx-large;">return back?</a>
|
|
||||||
<div>Scroll to bottom for comments ↓</div>
|
|
||||||
<ul id="html_list" style="display: none">
|
|
||||||
</ul>
|
|
||||||
<div id="renderer"></div>
|
|
||||||
<div style="color:red;font-size:larger;font-weight:bolder;display:none;" id="error">
|
|
||||||
Blog post <span></span> does not exist.
|
|
||||||
</div>
|
|
||||||
<div class="giscus"></div>
|
|
||||||
<script src="https://giscus.app/client.js" data-repo="fucksophie/blog_comments" data-repo-id="R_kgDOMY4cfw"
|
|
||||||
data-category="General" data-category-id="DIC_kwDOMY4cf84ChCRR" data-mapping="url" data-strict="1"
|
|
||||||
data-reactions-enabled="1" data-emit-metadata="0" data-input-position="bottom" data-theme="noborder_dark"
|
|
||||||
data-lang="en" data-loading="lazy" crossorigin="anonymous" async>
|
|
||||||
</script>
|
|
||||||
<script type="module" src="scripts/blog.js"></script>
|
<script type="module" src="scripts/blog.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
async function blog() {
|
|
||||||
const uriParams = new URLSearchParams(location.search);
|
|
||||||
if (uriParams.has("md")) {
|
|
||||||
const error = document.getElementById("error")!;
|
|
||||||
const renderer = document.getElementById("renderer")!;
|
|
||||||
const return_back = document.getElementById("return_back")!;
|
|
||||||
const req = await fetch("/blogs/" + uriParams.get("md") + ".html");
|
|
||||||
const giscus = document.querySelector(".giscus")! as HTMLDivElement;
|
|
||||||
if (req.status != 200) {
|
|
||||||
error.style.display = "block";
|
|
||||||
giscus.style.display = "none";
|
|
||||||
} else {
|
|
||||||
let text = await req.text();
|
|
||||||
renderer.innerHTML = text;
|
|
||||||
}
|
|
||||||
return_back.style.display = "block";
|
|
||||||
} else {
|
|
||||||
//@ts-expect-error
|
|
||||||
const blog_posts = __BLOG_POSTS__.map((z) => z.replace(".md", ""));
|
|
||||||
const html_list = document.getElementById("html_list")!;
|
|
||||||
html_list.style.display = "block";
|
|
||||||
for (const blog_post of blog_posts) {
|
|
||||||
const req = await fetch("/blogs/" + blog_post + ".json");
|
|
||||||
const metadata = await req.json();
|
|
||||||
const li = document.createElement("li");
|
|
||||||
const a = document.createElement("a");
|
|
||||||
a.href = "/blog.html?md=" + encodeURIComponent(blog_post);
|
|
||||||
a.innerText = `${metadata.title} (created ${new Date(
|
|
||||||
metadata.time * 1000
|
|
||||||
//@ts-expect-error
|
|
||||||
).toGMTString()})`;
|
|
||||||
li.appendChild(a);
|
|
||||||
html_list.appendChild(li);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
blog();
|
|
84
website/scripts/blog.tsx
Normal file
84
website/scripts/blog.tsx
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
import Nano, { Component, Fragment, Suspense } from "nano-jsx"
|
||||||
|
import { BlogPage } from "./blog_page";
|
||||||
|
import { Giscus } from "./giscus";
|
||||||
|
import { useState } from "nano-jsx/esm/hooks/useState.js";
|
||||||
|
|
||||||
|
export interface Metadata {
|
||||||
|
title: string;
|
||||||
|
// time in seconds since epoch (*1000 for MS)
|
||||||
|
time: number;
|
||||||
|
filename: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
//@ts-expect-error
|
||||||
|
const blog_posts = __BLOG_POSTS__ as string[];
|
||||||
|
|
||||||
|
const fetchBlogPosts = async () => {
|
||||||
|
const metadatas: Metadata[] = [];
|
||||||
|
|
||||||
|
for await (const blog of blog_posts) {
|
||||||
|
const req = await fetch("/blogs/" + blog + ".json");
|
||||||
|
const json = await req.json()
|
||||||
|
json.filename = blog;
|
||||||
|
metadatas.push(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
return metadatas
|
||||||
|
}
|
||||||
|
|
||||||
|
class Main extends Component {
|
||||||
|
async didMount() {
|
||||||
|
const blogPosts = await fetchBlogPosts()
|
||||||
|
this.update(blogPosts)
|
||||||
|
}
|
||||||
|
|
||||||
|
list(metadatas: Metadata[]) {
|
||||||
|
const pageOpen = useState<Metadata | undefined>(undefined, "pageOpen");
|
||||||
|
console.log("abcd")
|
||||||
|
return <ul>
|
||||||
|
{metadatas.map((n) => {
|
||||||
|
return <li>
|
||||||
|
<a onClick={
|
||||||
|
() => {
|
||||||
|
pageOpen[1](n);
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
}>{n.title} (created {new Date(n.time * 1000).toLocaleString()})</a>
|
||||||
|
</li>
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
}
|
||||||
|
render(blogPosts: Metadata[]) {
|
||||||
|
|
||||||
|
const pageOpen = useState<Metadata | undefined>(undefined, "pageOpen");
|
||||||
|
const md = new URLSearchParams(location.search).get("md");
|
||||||
|
|
||||||
|
if (blogPosts) {
|
||||||
|
const found = blogPosts.find(z => z.filename == md);
|
||||||
|
if (found) {
|
||||||
|
console.log(found);
|
||||||
|
pageOpen[1](found);
|
||||||
|
//@ts-expect-error
|
||||||
|
pageOpen[0] = found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pageOpen[0]) {
|
||||||
|
return <BlogPage metadata={pageOpen[0]}></BlogPage>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return <>
|
||||||
|
<h1> sophie's blog </h1>
|
||||||
|
<div>Scroll to bottom for comments ↓</div>
|
||||||
|
|
||||||
|
{() => {
|
||||||
|
if (blogPosts) return this.list(blogPosts)
|
||||||
|
else return <h3>Loading...</h3>
|
||||||
|
}}
|
||||||
|
<Giscus searchTerm="main"></Giscus>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Nano.render(<Main></Main>, document.getElementById("root"))
|
43
website/scripts/blog_page.tsx
Normal file
43
website/scripts/blog_page.tsx
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import { Component } from "nano-jsx"
|
||||||
|
import { Giscus } from "./giscus";
|
||||||
|
import { useState } from "nano-jsx/esm/hooks/useState.js";
|
||||||
|
import type { Metadata } from "./blog";
|
||||||
|
|
||||||
|
const fetchBlogPost = async (metadata: Metadata) => {
|
||||||
|
return (await fetch("/blogs/" + metadata.filename + ".html")).text();
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BlogPage extends Component {
|
||||||
|
metadata: Metadata;
|
||||||
|
|
||||||
|
constructor(props: { metadata: Metadata }) {
|
||||||
|
super(props);
|
||||||
|
this.metadata = props.metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
async didMount() {
|
||||||
|
const blogPost = await fetchBlogPost(this.metadata)
|
||||||
|
this.update(blogPost)
|
||||||
|
}
|
||||||
|
|
||||||
|
render(blogPost: string) {
|
||||||
|
const pageOpen = useState<string | undefined>(undefined, "pageOpen");
|
||||||
|
history.replaceState({}, "", location.pathname+"?md=" + this.metadata.filename);
|
||||||
|
|
||||||
|
return <>
|
||||||
|
<h1> sophie's blog </h1>
|
||||||
|
<a href="/blog.html" style="font-size:xx-large;" onClick={() => {
|
||||||
|
pageOpen[1](undefined);
|
||||||
|
this.update();
|
||||||
|
}}>return back?</a>
|
||||||
|
|
||||||
|
{
|
||||||
|
() => {
|
||||||
|
if (!blogPost) return <h1>Loading...</h1>
|
||||||
|
else return <div dangerouslySetInnerHTML={{ __html: blogPost }}></div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<Giscus searchTerm={this.metadata.filename}></Giscus>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
}
|
24
website/scripts/giscus.tsx
Normal file
24
website/scripts/giscus.tsx
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
export function Giscus({searchTerm}: {searchTerm: string}) {
|
||||||
|
let config: Record<string, string> = {
|
||||||
|
"repo": "fucksophie/blog_comments",
|
||||||
|
"repo-id": "R_kgDOMY4cfw",
|
||||||
|
"category": "General",
|
||||||
|
"category-id": "DIC_kwDOMY4cf84ChCRR",
|
||||||
|
"mapping": "specific",
|
||||||
|
"term": searchTerm,
|
||||||
|
"strict": "1",
|
||||||
|
"reactions-enabled": "1",
|
||||||
|
"emit-metadata": "0",
|
||||||
|
"input-position": "bottom",
|
||||||
|
"theme": "noborder_dark",
|
||||||
|
"lang": "en",
|
||||||
|
"loading": "lazy",
|
||||||
|
}
|
||||||
|
for(const x of Object.entries(config)) {
|
||||||
|
delete config[x[0]];
|
||||||
|
config["data-"+x[0]] = x[1];
|
||||||
|
}
|
||||||
|
return <div>
|
||||||
|
<script src="https://giscus.app/client.js" {...config} crossorigin="anonymous" async></script>
|
||||||
|
</div>
|
||||||
|
}
|
Loading…
Reference in a new issue