This commit is contained in:
parent
a7aaff537f
commit
262032b4e3
|
@ -11,37 +11,46 @@ export default class TSCompiler extends Plugin {
|
|||
minify = false;
|
||||
constructor() {
|
||||
super();
|
||||
if(process.argv.includes("--prod")) {
|
||||
if (process.argv.includes("--prod")) {
|
||||
this.minify = true;
|
||||
}
|
||||
}
|
||||
async rewriteFile(file: string, filePath: string) {
|
||||
|
||||
const 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,
|
||||
});
|
||||
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;
|
||||
}
|
||||
|
||||
if(result.errors.length != 0) {
|
||||
console.log("TS compiler errored.")
|
||||
result.errors.forEach(element => {
|
||||
console.error(element);
|
||||
});
|
||||
if (result.errors.length != 0) {
|
||||
console.log("TS compiler errored.");
|
||||
result.errors.forEach((element) => {
|
||||
console.error(element);
|
||||
});
|
||||
} else {
|
||||
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() {
|
||||
super();
|
||||
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");
|
||||
if (fs.existsSync(templatePath)) {
|
||||
|
|
|
@ -3,21 +3,7 @@ __TEMPLATE_HEAD__
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<h1> sophie's blog </h1>
|
||||
<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>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="scripts/blog.js"></script>
|
||||
</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