diff options
| author | Yuqian Yang <crupest@crupest.life> | 2026-01-23 23:16:45 +0800 |
|---|---|---|
| committer | Yuqian Yang <crupest@crupest.life> | 2026-01-23 23:16:45 +0800 |
| commit | 78e3e234877cb10ca1088df31e831b36fa4a12c0 (patch) | |
| tree | a4b86275895b33d47df4686e5ce8f98b57016f90 /www-2/src | |
| parent | 3af5ef00b38c6962c6e3f63add0312fa6537b74b (diff) | |
| download | crupest-78e3e234877cb10ca1088df31e831b36fa4a12c0.tar.gz crupest-78e3e234877cb10ca1088df31e831b36fa4a12c0.tar.bz2 crupest-78e3e234877cb10ca1088df31e831b36fa4a12c0.zip | |
HALF WORK!
Diffstat (limited to 'www-2/src')
| -rw-r--r-- | www-2/src/assets/css/todos.css | 17 | ||||
| -rw-r--r-- | www-2/src/assets/img/github.png | bin | 0 -> 6393 bytes | |||
| -rw-r--r-- | www-2/src/components/ArticlePreview.astro | 68 | ||||
| -rw-r--r-- | www-2/src/components/Friend.astro | 49 | ||||
| -rw-r--r-- | www-2/src/components/Nav.astro | 23 | ||||
| -rw-r--r-- | www-2/src/content.config.ts | 17 | ||||
| -rw-r--r-- | www-2/src/layouts/ArticlePage.astro | 50 | ||||
| -rw-r--r-- | www-2/src/layouts/PageBase.astro | 181 | ||||
| -rw-r--r-- | www-2/src/pages/[...id].astro | 18 | ||||
| -rw-r--r-- | www-2/src/pages/index.astro | 124 |
10 files changed, 547 insertions, 0 deletions
diff --git a/www-2/src/assets/css/todos.css b/www-2/src/assets/css/todos.css new file mode 100644 index 0000000..f9aa23b --- /dev/null +++ b/www-2/src/assets/css/todos.css @@ -0,0 +1,17 @@ +h3.todo { + &::before { + font-size: small; + } + + &.working::before { + content: "(working) "; + } + + &.done::before { + content: "(done) "; + } + + &.give-up::before { + content: "(give up) "; + } +} diff --git a/www-2/src/assets/img/github.png b/www-2/src/assets/img/github.png Binary files differnew file mode 100644 index 0000000..6cb3b70 --- /dev/null +++ b/www-2/src/assets/img/github.png diff --git a/www-2/src/components/ArticlePreview.astro b/www-2/src/components/ArticlePreview.astro new file mode 100644 index 0000000..3301ad2 --- /dev/null +++ b/www-2/src/components/ArticlePreview.astro @@ -0,0 +1,68 @@ +--- +interface Props { + title: string; + date: string; + url: string; + content: string; + headerElement?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "h7"; +} + +const { title, date, url, content, headerElement = "h2" } = Astro.props; +const H = headerElement; +--- + +<section class="article-preview"> + <span class="date">{date}</span> + <H class="title"><a href={url}>{title}</a></H> + <p class="content"> + {content} + </p> + <p>... <a class="mono-link" href="{{ .link }}">Read more</a></p> +</section> + +<style> + .article-preview { + font-size: 0.95em; + padding-inline: 0.5em; + padding-block: 0.5em; + + & > p { + font-size: 0.9em; + line-height: 1.4; + margin-inline-start: 0.3em; + margin-block: 0; + } + + & > .title { + margin-block-start: 0; + margin-block-end: 0.3em; + } + + & > .date { + font-size: small; + margin-top: 0.25em; + float: right; + color: hsl(0, 0%, 25%); + } + + & > .content { + overflow: hidden; + height: 3lh; + } + } + + html[data-theme="dark"] { + & .article-preview { + background-color: hsl(0, 0%, 3%); + + & > .date { + color: hsl(0, 0%, 75%); + } + } + } + + hr.article-preview-hr { + border: none; + border-top: 1.5px dashed currentColor; + } +</style> diff --git a/www-2/src/components/Friend.astro b/www-2/src/components/Friend.astro new file mode 100644 index 0000000..d0de0ab --- /dev/null +++ b/www-2/src/components/Friend.astro @@ -0,0 +1,49 @@ +--- +import githubIcon from "../assets/img/github.png"; + +interface Props { + name: string; + url?: string; + githubUrl: string; + avatarUrl: string; + tag?: string; +} + +const { name, githubUrl, url = githubUrl, avatarUrl, tag } = Astro.props; +--- + +<div class="friend"> + <a rel="noopener noreferrer" href={url}> + <img + class="friend-avatar" + alt={`Friend ${name}'s avatar`} + src={avatarUrl} + width="80" + height="80" + /><br />{name}</a + > + <a rel="noopener noreferrer" href={githubUrl}> + <img class="friend-github" src={githubIcon.src} /> + </a><br /> + {tag && <span class="friend-tag">{tag}</span>} +</div> + +<style> +.friend a { + font-family: unset; +} + +.friend-avatar { + object-fit: cover; +} + +.friend-github { + width: 1em; + vertical-align: middle; + margin-right: -0.5em; +} + +.friend-tag { + font-size: 0.8em; +} +</style>
\ No newline at end of file diff --git a/www-2/src/components/Nav.astro b/www-2/src/components/Nav.astro new file mode 100644 index 0000000..f62a9dc --- /dev/null +++ b/www-2/src/components/Nav.astro @@ -0,0 +1,23 @@ +--- + +let path = Astro.url.pathname +if (path.startsWith("/")) { path = path.slice(1)} +if (path.endsWith("/")) { path = path.slice(0, -1)} +const segments = path.split("/").slice(0, -1); +const sections: {name: string; link: string;}[] = [] +let current = "/" +for (const segment of segments) { + current += segment + "/"; + sections.push({ + name: segment, + link: current + }) +} + +--- +<nav class="mono"> + { sections.map(s => + <><a class="mono-link" href={s.link}>{s.name}</a> ></>) + } + this +</nav> diff --git a/www-2/src/content.config.ts b/www-2/src/content.config.ts new file mode 100644 index 0000000..f309aa5 --- /dev/null +++ b/www-2/src/content.config.ts @@ -0,0 +1,17 @@ +import { defineCollection } from "astro:content"; +import { glob } from "astro/loaders"; +import { z } from "astro/zod"; + +const blogs = defineCollection({ + loader: glob({ pattern: "**/*.md", base: "./content" }), + schema: z.object({ + title: z.string(), + description: z.string().optional(), + date: z.coerce.date(), + lastmod: z.coerce.date().optional(), + categories: z.string().optional(), + tags: z.array(z.string()).optional(), + }), +}); + +export const collections = { blogs }; diff --git a/www-2/src/layouts/ArticlePage.astro b/www-2/src/layouts/ArticlePage.astro new file mode 100644 index 0000000..b6ea5d0 --- /dev/null +++ b/www-2/src/layouts/ArticlePage.astro @@ -0,0 +1,50 @@ +--- +import PageBase from "./PageBase.astro"; +import Nav from "../components/Nav.astro"; + +interface Props { + id: string; + data: { + title: string; + date: Date; + lastmod?: Date; + }; +} + +const { + id, + data: { title, date, lastmod }, +} = Astro.props; +--- + +<PageBase> + <Nav /> + <h1 class="post-title">{title}</h1> + <hr /> + <p class="post-info"> + <span class="created">{date.toLocaleString()}</span> | + { + lastmod && ( + <span class="last-updated"> + Last updated: {lastmod.toLocaleString()} + </span> + ) + } + </p> + <slot /> +</PageBase> + +<style> + .post-info { + margin-block: 0; + font-family: monospace; + font-size: 0.95em; + display: flex; + flex-wrap: wrap; + gap: 1em; + + & > .created { + margin-inline-end: auto; + } + } +</style> diff --git a/www-2/src/layouts/PageBase.astro b/www-2/src/layouts/PageBase.astro new file mode 100644 index 0000000..e6e0e1e --- /dev/null +++ b/www-2/src/layouts/PageBase.astro @@ -0,0 +1,181 @@ +<!doctype html> +<html lang="en"> + <head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width" /> + <link rel="icon" href="/favicon.ico" /> + <meta name="generator" content={Astro.generator} /> + <title>Astro Basics</title> + </head> + <body> + <article id="main-article"> + <slot /> + <hr /> + <footer class="mono-link"> + <p id="license"> + <small + >This work is licensed under + <a + rel="license noopener noreferrer" + href="https://creativecommons.org/licenses/by-nc/4.0/" + target="_blank" + > + <span id="license-text">CC BY-NC 4.0</span> + <span id="license-img-container"> + <img + src="https://mirrors.creativecommons.org/presskit/icons/cc.svg" + /> + <img + src="https://mirrors.creativecommons.org/presskit/icons/by.svg" + /> + <img + src="https://mirrors.creativecommons.org/presskit/icons/nc.svg" + /> + </span> + </a> + </small> + </p> + </footer> + </article> + </body> +</html> + +<style is:global> +html { + width: 100%; + --body-fg-color: unset; + --body-bg-color: unset; + --table-border-color: black; + --toast-fg-color: white; + --toast-bg-color: black; + --code-fg-color: var(--body-fg-color); + --code-bg-color: #eff1f5; +} + +* { + box-sizing: border-box; +} + +body { + width: 100%; + margin: 0; + color: var(--body-fg-color); + background-color: var(--body-bg-color); +} + +/* https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/Heading_Elements#specifying_a_uniform_font_size_for_h1 */ +h1 { + margin-block: 0.67em; + font-size: 2em; +} + +.mono { + font-family: monospace; +} + +a.mono-link, +.mono-link a, +.mono-link .fake-link { + font-family: monospace; +} + +div.mono-container { + font-family: monospace; + margin-block: 1rem; +} + +table { + border-collapse: collapse; + + &, :is(td,th) { + padding: 0.2em 0.4em; + border: 1px solid var(--table-border-color); + } +} + +.toast { + font-size: large; + font-family: monospace; + color: var(--toast-fg-color); + background-color: var(--toast-bg-color); + padding: 0.5em 0.3em; + border-radius: 6px; + + position: fixed; + z-index: 1; + top: 4px; + left: 50vw; + transform: translateX(-50%); +} + +.chroma { + overflow-x: auto; + padding-left: 1px; + padding-right: 4px; + border-radius: 6px; +} + +nav { + font-size: large; +} + +#main-article { + position: relative; + left: 50%; + transform: translateX(-50%); + max-width: 880px; + padding: 0 1em; + margin-top: 1em; +} + +#license a { + font-family: initial; + text-decoration: none; +} + +#license-text { + font-family: monospace; + text-decoration: initial; +} + +#license-img-container img { + height: 1em; + vertical-align: middle; +} + +.link-group { + margin-block-end: 1em; + + > .link-group-title { + font-size: 1.1em; + margin-block-end: 5px; + } + + > .link-group-list { + border-inline-start: solid 1px hsl(0, 0%, 25%); + padding-inline-start: 8px; + + > .link-group-item::before { + content: "- "; + } + } +} + +html[data-theme="dark"] { + --body-fg-color: white; + --body-bg-color: black; + --table-border-color: hsl(0, 0%, 25%); + --toast-fg-color: var(--body-bg-color); + --toast-bg-color: var(--body-fg-color); + --code-bg-color: #1e1e2e; + + & a:link { + color:#34ffd9; + } + + & a:visited { + color:#abcac4; + } +} + +</style> diff --git a/www-2/src/pages/[...id].astro b/www-2/src/pages/[...id].astro new file mode 100644 index 0000000..b3c5b40 --- /dev/null +++ b/www-2/src/pages/[...id].astro @@ -0,0 +1,18 @@ +--- +import { getCollection, render } from "astro:content"; + +import ArticlePage from "../layouts/ArticlePage.astro"; + +export async function getStaticPaths() { + const posts = await getCollection("blogs"); + return posts.map((post) => ({ + params: { id: post.id }, + props: { post }, + })); +} + +const { post } = Astro.props; +const { Content } = await render(post); +--- + +<ArticlePage id={post.id} data={post.data}><Content /></ArticlePage> diff --git a/www-2/src/pages/index.astro b/www-2/src/pages/index.astro new file mode 100644 index 0000000..4007037 --- /dev/null +++ b/www-2/src/pages/index.astro @@ -0,0 +1,124 @@ +--- +import { getCollection, render } from "astro:content"; + +import PageBase from "../layouts/PageBase.astro"; +import Friend from "../components/Friend.astro"; +import ArticlePreview from "../components/ArticlePreview.astro"; + +const posts = ( + await getCollection("blogs", ({ id }) => id.startsWith("posts/")) +).slice(0, 3); +--- + +<PageBase> + <img id="avatar" src="/avatar.png" alt="My avatar" width="80" height="80" /> + <h1 id="title">Hello! This is <code>crupest</code> !</h1> + <hr /> + <section> + <p>Welcome to my home page! Nice to meet you here! 🥰</p> + <p> + Feel free to contact me via my email address <a + href="mailto:crupest@crupest.life">crupest@crupest.life</a + >, or just create an issue in any of my <a + rel="noopener noreferrer" + href="https://github.com/crupest">GitHub</a + > + repos. I love talking with people a lot. + </p> + <div id="links" class="mono-link"> + goto: + <ul> + <li><a href="/git/">git</a></li> + <li><a href="/notes/">notes</a></li> + <li><a href="/notes/hurd">hurd</a></li> + <li><a href="/notes/cheat-sheet">cheat-sheet</a></li> + </ul> + </div> + </section> + <hr /> + <section id="recent-posts"> + <h2>Recent Posts <a class="mono-link" href="/posts">(all)</a></h2> + { + posts.map((post) => ( + <ArticlePreview + title={post.data.title} + date={post.data.date.toLocaleString()} + url={"/posts/" + post.id} + content="" + /> + )) + } + </section> + <hr /> + <section> + <h2 id="friends"> + My Friends <small>(more links are being collected ...)</small> + </h2> + <div id="friends-container"> + <Friend + name="wsm" + avatarUrl="https://avatars.githubusercontent.com/u/74699943?v=4" + githubUrl="wushuming666" + /> + <Friend + name="hsz" + url="https://www.hszsoft.com" + avatarUrl="https://avatars.githubusercontent.com/u/63097618?v=4" + githubUrl="hszSoft" + tag="随性の程序员" + /> + </div> + </section> +</PageBase> + +<style> + #avatar { + float: right; + } + + #links { + font-family: monospace; + + margin-block-end: 1rem; + + > ul { + display: inline; + padding-inline-start: 0.5em; + > li { + display: inline; + + &::after { + content: " | "; + } + } + } + } + + #recent-posts { + margin-block-end: 1.5em; + } + + #friends-container { + display: flex; + gap: 1em; + } + + .friend { + flex-grow: 0; + text-align: center; + } + + .citation { + margin: auto; + } + + .citation figcaption { + text-align: right; + } + + html[data-theme="dark"] { + & .friend-github { + filter: invert(1); + } + } +</style> |
