更换到Astro #9
No files matched your search
@@ -7,6 +7,11 @@ type TocItem = {
|
|||||||
id: string;
|
id: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type TocSection = {
|
||||||
|
heading: TocItem;
|
||||||
|
children: TocItem[];
|
||||||
|
};
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
post: BlogPost;
|
post: BlogPost;
|
||||||
toc: TocItem[];
|
toc: TocItem[];
|
||||||
@@ -15,6 +20,16 @@ interface Props {
|
|||||||
|
|
||||||
const { post, toc, relatedPosts } = Astro.props;
|
const { post, toc, relatedPosts } = Astro.props;
|
||||||
const avatar = 'https://free.picui.cn/free/2025/08/10/689845496a283.png';
|
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="文章侧边栏">
|
<aside class="article-sidebar" aria-label="文章侧边栏">
|
||||||
@@ -27,6 +42,21 @@ const avatar = 'https://free.picui.cn/free/2025/08/10/689845496a283.png';
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</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 && (
|
{toc.length > 0 && (
|
||||||
<section class="sidebar-card toc-card">
|
<section class="sidebar-card toc-card">
|
||||||
<h2>
|
<h2>
|
||||||
@@ -34,9 +64,23 @@ const avatar = 'https://free.picui.cn/free/2025/08/10/689845496a283.png';
|
|||||||
文章目录
|
文章目录
|
||||||
<em>{toc.length}</em>
|
<em>{toc.length}</em>
|
||||||
</h2>
|
</h2>
|
||||||
<nav class="toc-list" aria-label="文章目录">
|
<nav class="toc-list toc-tree" aria-label="文章目录" data-toc-tree>
|
||||||
{toc.map((item) => (
|
{tocSections.map((section, index) => (
|
||||||
<a class={`toc-depth-${item.depth}`} href={`#${item.id}`}>{item.text}</a>
|
<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>
|
</nav>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -19,6 +19,7 @@ const currentYear = new Date().getFullYear();
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta name="description" content={description} />
|
<meta name="description" content={description} />
|
||||||
<link rel="icon" href="/images/Bi.ico" />
|
<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>
|
<title>{pageTitle}</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -31,6 +32,13 @@ const currentYear = new Date().getFullYear();
|
|||||||
<a href="/tags/">标签</a>
|
<a href="/tags/">标签</a>
|
||||||
<a href="/about/">关于</a>
|
<a href="/about/">关于</a>
|
||||||
<a href="/link/">友链</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>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
@@ -92,6 +100,9 @@ const currentYear = new Date().getFullYear();
|
|||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</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>
|
<script is:inline>
|
||||||
(() => {
|
(() => {
|
||||||
const runtime = document.getElementById('site-runtime');
|
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
Reference in new issue
Block a user