customize more

This commit is contained in:
2025-11-28 16:02:10 +08:00
parent 9133d23a15
commit 8b9feeeb10
13 changed files with 70 additions and 112 deletions

View File

@@ -9,6 +9,17 @@ import {
} from './blog-helpers'
const DEFAULT_AUTHOR_ID = 'libr'
type ContentCollection = 'blog' | 'authors' | 'projects'
async function getCollectionSafe<T extends ContentCollection>(
name: T,
): Promise<CollectionEntry<T>[]> {
try {
return await getCollection(name)
} catch {
return []
}
}
type NotionPost = {
id: string
@@ -56,14 +67,14 @@ export interface LinkEntry {
}
export async function getAllAuthors(): Promise<CollectionEntry<'authors'>[]> {
return await getCollection('authors')
return getCollectionSafe('authors')
}
export const POSTS_API_URL = 'https://notion-api.nvme0n1p.dev/v2/posts'
export async function getAllPosts(): Promise<CollectionEntry<'blog'>[]> {
const fallback = async () => {
const posts = await getCollection('blog')
const posts = await getCollectionSafe('blog')
return posts
.filter((post) => !post.data.draft && !isSubpost(post.id))
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
@@ -91,6 +102,7 @@ export async function getAllPosts(): Promise<CollectionEntry<'blog'>[]> {
const date = new Date(dateString)
const id = post.slug || post.id
const banner = (post as any).banner || null
const image = banner
return {
id,
@@ -103,6 +115,7 @@ export async function getAllPosts(): Promise<CollectionEntry<'blog'>[]> {
draft: !(post.Published ?? true),
authors: [DEFAULT_AUTHOR_ID],
banner,
image,
},
body: '',
}
@@ -125,7 +138,7 @@ export async function getAllPostsAndSubposts(): Promise<
}
export async function getAllProjects(): Promise<CollectionEntry<'projects'>[]> {
const projects = await getCollection('projects')
const projects = await getCollectionSafe('projects')
return projects.sort((a, b) => {
const dateA = a.data.startDate?.getTime() || 0
const dateB = b.data.startDate?.getTime() || 0
@@ -155,7 +168,7 @@ export async function getAdjacentPosts(currentId: string): Promise<{
const allPosts = await getAllPosts()
const parent = allPosts.find((post) => post.id === parentId) || null
const posts = await getCollection('blog')
const posts = await getCollectionSafe('blog')
const subposts = posts
.filter(
(post) =>
@@ -242,7 +255,7 @@ export function getParentId(subpostId: string): string {
export async function getSubpostsForParent(
parentId: string,
): Promise<CollectionEntry<'blog'>[]> {
const posts = await getCollection('blog')
const posts = await getCollectionSafe('blog')
return posts
.filter(
(post) =>
@@ -305,6 +318,12 @@ export async function fetchRemotePostContent(
if (!res.ok) throw new Error(`Failed to fetch post content: ${res.status}`)
const data = (await res.json()) as Partial<RemotePostPayload>
if (!data.post || !data.blockMap) return null
const post = data.post as any
if (post?.banner && !post?.image) {
post.image = post.banner
}
return data as RemotePostPayload
} catch (error) {
console.error(`fetchRemotePostContent error for slug "${slug}":`, error)

View File

@@ -1,5 +1,6 @@
import { type ClassValue, clsx } from 'clsx'
import { twMerge } from 'tailwind-merge'
import type { ImageMetadata } from 'astro:assets'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
@@ -35,3 +36,19 @@ export function getHeadingMargin(depth: number): string {
}
return margins[depth] || ''
}
export type ImageSource = string | ImageMetadata
export function normalizeImageSource(value: unknown): ImageSource | null {
if (!value) return null
if (typeof value === 'string') return value
if (
typeof value === 'object' &&
value !== null &&
'src' in value &&
typeof (value as ImageMetadata).src === 'string'
) {
return value as ImageMetadata
}
return null
}