More customzation

This commit is contained in:
2025-11-28 15:29:39 +08:00
parent 985164f4c5
commit 9133d23a15
85 changed files with 4176 additions and 1439 deletions

View File

@@ -7,6 +7,7 @@ import SubpostsHeader from '@/components/SubpostsHeader.astro'
import SubpostsSidebar from '@/components/SubpostsSidebar.astro'
import TOCHeader from '@/components/TOCHeader.astro'
import TOCSidebar from '@/components/TOCSidebar.astro'
import NotionBlocks from '@/components/NotionBlocks.astro'
import { badgeVariants } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import Layout from '@/layouts/Layout.astro'
@@ -19,11 +20,14 @@ import {
getPostReadingTime,
getSubpostCount,
getTOCSections,
fetchRemotePostContent,
renderRemoteBlockMap,
hasSubposts,
isSubpost,
parseAuthors,
} from '@/lib/data-utils'
import { formatDate } from '@/lib/utils'
import type { TOCSection } from '@/lib/data-utils'
import { formatDate, readingTime } from '@/lib/utils'
import { Icon } from 'astro-icon/components'
import { Image } from 'astro:assets'
import { render } from 'astro:content'
@@ -38,7 +42,22 @@ export async function getStaticPaths() {
const post = Astro.props
const currentPostId = Astro.params.id
const { Content, headings } = await render(post)
const isRemotePost = post.body === ''
let Content: any = null
let headings
let remoteContent = null
if (isRemotePost) {
const remote = await fetchRemotePostContent(currentPostId)
remoteContent = remote ? renderRemoteBlockMap(remote.blockMap, remote.post.id) : null
headings = remoteContent?.headings ?? []
} else {
const rendered = await render(post)
Content = rendered.Content
headings = rendered.headings
}
const authors = await parseAuthors(post.data.authors ?? [])
const isCurrentSubpost = isSubpost(currentPostId)
@@ -49,13 +68,31 @@ const hasChildPosts = await hasSubposts(currentPostId)
const subpostCount = !isCurrentSubpost
? await getSubpostCount(currentPostId)
: 0
const postReadingTime = await getPostReadingTime(currentPostId)
const postReadingTime = remoteContent
? readingTime(remoteContent.wordCount)
: await getPostReadingTime(currentPostId)
const combinedReadingTime =
hasChildPosts && !isCurrentSubpost
!remoteContent && hasChildPosts && !isCurrentSubpost
? await getCombinedReadingTime(currentPostId)
: null
const tocSections = await getTOCSections(currentPostId)
const tocSections: TOCSection[] = remoteContent
? remoteContent.headings.length > 0
? [
{
type: 'parent',
title: 'Overview',
headings: remoteContent.headings,
},
]
: []
: await getTOCSections(currentPostId)
const heroImage =
post.data.banner && typeof post.data.banner === 'object' && 'src' in post.data.banner
? post.data.banner
: post.data.image && typeof post.data.image === 'object' && 'src' in post.data.image
? post.data.image
: null
---
<Layout>
@@ -109,9 +146,9 @@ const tocSections = await getTOCSections(currentPostId)
</div>
{
post.data.image && (
heroImage && (
<Image
src={post.data.image}
src={heroImage}
alt={post.data.title}
width={1200}
height={630}
@@ -224,9 +261,46 @@ const tocSections = await getTOCSections(currentPostId)
}
<article class="prose col-start-2 max-w-none">
<Content />
{
remoteContent ? (
remoteContent.blocks.length > 0 ? (
<NotionBlocks
blocks={remoteContent.blocks}
headings={remoteContent.headingBlocks}
/>
) : (
<p>Content unavailable.</p>
)
) : (
Content && <Content />
)
}
</article>
<div class="col-start-2">
<div id="tcomment"></div>
</div>
<script
is:inline
src="https://cdn.jsdelivr.net/npm/twikoo@1.6.44/dist/twikoo.min.js"
></script>
<script is:inline>
const mountTwikoo = () => {
if (!window.twikoo) return
window.twikoo.init({
envId: 'https://twikoo.hk.nvme0n1p.dev/',
el: '#tcomment',
})
}
if (document.readyState === 'complete') {
mountTwikoo()
} else {
addEventListener('astro:page-load', mountTwikoo)
addEventListener('DOMContentLoaded', mountTwikoo, { once: true })
}
</script>
{
(hasChildPosts || isCurrentSubpost) && (
<SubpostsSidebar