更换到Astro #9

Merged
biss merged 30 commits from switch-to-astro into master 2026-06-19 13:23:31 +08:00
6 changed files with 368 additions and 7 deletions
Showing only changes of commit ce4a201508 - Show all commits

No files matched your search

+47 -3
View File
@@ -7,6 +7,11 @@ type TocItem = {
id: string;
};
type TocSection = {
heading: TocItem;
children: TocItem[];
};
interface Props {
post: BlogPost;
toc: TocItem[];
@@ -15,6 +20,16 @@ interface Props {
const { post, toc, relatedPosts } = Astro.props;
const avatar = 'https://free.picui.cn/free/2025/08/10/689845496a283.png';
const topDepth = toc.length > 0 ? Math.min(...toc.map((item) => item.depth)) : 1;
const tocSections = toc.reduce<TocSection[]>((sections, item) => {
if (item.depth <= topDepth || sections.length === 0) {
sections.push({ heading: item, children: [] });
} else {
sections[sections.length - 1].children.push(item);
}
return sections;
}, []);
---
<aside class="article-sidebar" aria-label="文章侧边栏">
@@ -27,6 +42,21 @@ const avatar = 'https://free.picui.cn/free/2025/08/10/689845496a283.png';
</div>
</section>
{post.tags.length > 0 && (
<section class="sidebar-card article-tags-card">
<h2>
<span aria-hidden="true">#</span>
文章标签
<em>{post.tags.length}</em>
</h2>
<div class="article-tag-list" aria-label="文章标签">
{post.tags.map((tag) => (
<a href={`/tags/${encodeURIComponent(tag)}/`}>#{tag}</a>
))}
</div>
</section>
)}
{toc.length > 0 && (
<section class="sidebar-card toc-card">
<h2>
@@ -34,9 +64,23 @@ const avatar = 'https://free.picui.cn/free/2025/08/10/689845496a283.png';
文章目录
<em>{toc.length}</em>
</h2>
<nav class="toc-list" aria-label="文章目录">
{toc.map((item) => (
<a class={`toc-depth-${item.depth}`} href={`#${item.id}`}>{item.text}</a>
<nav class="toc-list toc-tree" aria-label="文章目录" data-toc-tree>
{tocSections.map((section, index) => (
<div class:list={['toc-group', index === 0 && 'is-open']} data-toc-group data-heading-id={section.heading.id}>
<a class="toc-link toc-link-main" href={`#${section.heading.id}`} data-toc-link data-toc-top>
<span class="toc-marker" aria-hidden="true"></span>
<span>{section.heading.text}</span>
</a>
{section.children.length > 0 && (
<div class="toc-children" data-toc-children>
{section.children.map((item) => (
<a class={`toc-link toc-link-child toc-depth-${item.depth}`} href={`#${item.id}`} data-toc-link>
<span>{item.text}</span>
</a>
))}
</div>
)}
</div>
))}
</nav>
</section>
+72
View File
@@ -0,0 +1,72 @@
---
interface Props {
envId: string;
path: string;
title: string;
region?: string;
}
const { envId, path, title, region = '' } = Astro.props;
---
<section
id="post-comment"
class="twikoo-comments"
aria-label="Comments"
data-env-id={envId}
data-region={region}
data-path={path}
>
<div class="twikoo-comments-head">
<span class="twikoo-comments-icon" aria-hidden="true">
<svg viewBox="0 0 24 24">
<path d="M21 12a8 8 0 0 1-8 8H7l-4 3v-5a8 8 0 1 1 18-6Z" />
</svg>
</span>
<div>
<h2>Comments</h2>
<p>{title}</p>
</div>
</div>
<div id="twikoo-wrap" class="twikoo-wrap"></div>
</section>
<script is:inline>
(() => {
const root = document.getElementById('post-comment');
const wrap = document.getElementById('twikoo-wrap');
if (!root || !wrap || root.dataset.twikooLoaded === 'true') return;
const envId = root.dataset.envId;
const path = root.dataset.path || window.location.pathname;
const region = root.dataset.region || undefined;
if (!envId) return;
root.dataset.twikooLoaded = 'true';
const initTwikoo = () => {
if (!window.twikoo || typeof window.twikoo.init !== 'function') return;
window.twikoo.init({
el: wrap,
envId,
region,
path,
});
};
if (window.twikoo) {
initTwikoo();
return;
}
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/twikoo@1.7.7/dist/twikoo.min.js';
script.defer = true;
script.onload = initTwikoo;
script.onerror = () => {
root.dataset.twikooLoaded = 'false';
};
document.head.appendChild(script);
})();
</script>
+11
View File
@@ -19,6 +19,7 @@ const currentYear = new Date().getFullYear();
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content={description} />
<link rel="icon" href="/images/Bi.ico" />
<link rel="stylesheet" href="https://cdn.jsdmirror.com/npm/instantsearch.css/themes/reset-min.css" />
<title>{pageTitle}</title>
</head>
<body>
@@ -31,6 +32,13 @@ const currentYear = new Date().getFullYear();
<a href="/tags/">标签</a>
<a href="/about/">关于</a>
<a href="/link/">友链</a>
<button class="nav-search search-typesense-trigger" type="button" aria-label="搜索" title="搜索">
<svg aria-hidden="true" viewBox="0 0 24 24">
<path d="m21 21-4.3-4.3" />
<circle cx="11" cy="11" r="7" />
</svg>
<span>搜索</span>
</button>
</div>
</nav>
</header>
@@ -92,6 +100,9 @@ const currentYear = new Date().getFullYear();
</section>
</div>
</footer>
<script is:inline src="https://cdn.jsdmirror.com/npm/instantsearch.js@4.56.0"></script>
<script is:inline src="https://cdn.jsdmirror.com/npm/typesense-instantsearch-adapter@2.7.0/dist/typesense-instantsearch-adapter.min.js"></script>
<script is:inline src="/js/search/typesense-search.js"></script>
<script is:inline>
(() => {
const runtime = document.getElementById('site-runtime');
Loaded 3 of 6 files, more files were not shown because too many files have changed in this diff. Show more