Commit 556a314

HPCesia <me@hpcesia.com>
2025-03-11 14:20:53
refactor: draft handling
1 parent e29a570
Changed files (4)
src
src/components/aside/siteinfo/Stats.astro
@@ -1,10 +1,10 @@
 ---
-import { asideConfig, buildConfig, siteConfig } from '@/config';
+import { asideConfig, siteConfig } from '@/config';
 import I18nKey from '@i18n/I18nKey';
 import { i18n } from '@i18n/translation';
-import { getPostsCount } from '@utils/content-utils';
+import { getPosts, getPostsCount } from '@utils/content-utils';
 import { Icon } from 'astro-icon/components';
-import { getCollection, render } from 'astro:content';
+import { render } from 'astro:content';
 ---
 
 <div class="stats stats-vertical w-full">
@@ -46,14 +46,10 @@ import { getCollection, render } from 'astro:content';
               </div>
               <div class="stat-value text-base">
                 {(async () => {
-                  const posts = await getCollection('posts');
-                  const drafts = await getCollection('drafts');
-                  const onDev = import.meta.env.DEV;
-                  const entries =
-                    onDev && buildConfig.showDraftsOnDev ? [...posts, ...drafts] : posts;
+                  const posts = await getPosts();
                   const words = await Promise.all(
-                    entries.map(async (entry) => {
-                      const { remarkPluginFrontmatter } = await render(entry);
+                    posts.map(async (post) => {
+                      const { remarkPluginFrontmatter } = await render(post);
                       return remarkPluginFrontmatter.words as number;
                     })
                   );
src/pages/posts/[article].astro
@@ -1,5 +1,5 @@
 ---
-import { buildConfig, siteConfig } from '@/config';
+import { siteConfig } from '@/config';
 import License from '@components/misc/License.astro';
 import PostInfo from '@components/misc/PostInfo.astro';
 import ImageWrapper from '@components/utils/ImageWrapper.astro';
@@ -7,30 +7,21 @@ import Markdown from '@components/utils/Markdown.astro';
 import I18nKey from '@i18n/I18nKey';
 import { i18n } from '@i18n/translation';
 import PostPageLayout from '@layouts/PostPageLayout.astro';
+import { getPosts } from '@utils/content-utils';
 import { Icon } from 'astro-icon/components';
-import { getCollection, render } from 'astro:content';
-import dayjs from 'dayjs';
+import { render } from 'astro:content';
 import MarkdownIt from 'markdown-it';
 import path from 'path';
 
 export async function getStaticPaths() {
-  const posts = (await getCollection('posts')).map((post) => ({
-    article: post,
-    isDraft: false,
-  }));
-  const drafts = (await getCollection('drafts')).map((post) => ({
-    article: post,
-    isDraft: true,
-  }));
-  const onDev = import.meta.env.DEV;
-  const articles = onDev && buildConfig.showDraftsOnDev ? [...posts, ...drafts] : posts;
-  return articles.map((article) => ({
-    params: { article: article.article.data.slug },
-    props: { article: article.article, isDraft: article.isDraft },
+  const posts = await getPosts();
+  return posts.map((article) => ({
+    params: { article: article.data.slug },
+    props: { article },
   }));
 }
 
-const { article, isDraft } = Astro.props;
+const { article } = Astro.props;
 const { Content, headings, remarkPluginFrontmatter } = await render(article);
 const hasCover =
   article.data.cover !== '' && article.data.cover !== undefined && article.data.cover !== null;
@@ -40,10 +31,7 @@ const coverSrc = hasCover
     : article.data.cover
   : undefined;
 const description = article.data.description || remarkPluginFrontmatter.excerpt;
-const publishTime =
-  'published' in article.data
-    ? article.data.published
-    : dayjs(remarkPluginFrontmatter.createAt).toDate();
+const isDraft = article.data.draft === true;
 ---
 
 <PostPageLayout
@@ -57,7 +45,7 @@ const publishTime =
   <Fragment slot="header-content">
     <PostInfo
       title={article.data.title}
-      publishedAt={publishTime}
+      publishedAt={article.data.published}
       category={article.data.category}
       tags={article.data.tags}
       wordCount={remarkPluginFrontmatter.words}
@@ -85,5 +73,5 @@ const publishTime =
     }
     <Content />
   </Markdown>
-  <License time={publishTime} lang={article.data.lang} />
+  <License time={article.data.published} lang={article.data.lang} />
 </PostPageLayout>
src/utils/content-utils.ts
@@ -3,29 +3,29 @@ import type { BlogPostData } from '@/types/data';
 import type { BlogPost } from '@/types/data';
 import I18nKey from '@i18n/I18nKey';
 import { i18n } from '@i18n/translation';
-import { getCollection, render } from 'astro:content';
+import { type CollectionEntry, getCollection, render } from 'astro:content';
 import dayjs from 'dayjs';
 import path from 'path';
 
-export async function getSortedPosts(): Promise<BlogPost[]> {
-  let allBlogPosts;
-  const posts = (await getCollection('posts')) as unknown as BlogPost[];
+export async function getPosts() {
+  const posts = await getCollection('posts');
   const onDev = import.meta.env.DEV;
-
   if (onDev && buildConfig.showDraftsOnDev) {
-    const draftEntries = await getCollection('drafts');
-    const drafts = await Promise.all(
-      draftEntries.map(async (draft) => {
-        const { remarkPluginFrontmatter } = await render(draft);
-        const published = dayjs(remarkPluginFrontmatter.createAt as string).toDate();
-        const data = Object.assign(draft.data, { published });
-        return Object.assign(draft, { data }) as unknown as BlogPost;
-      })
-    );
-    allBlogPosts = [...posts, ...drafts];
-  } else {
-    allBlogPosts = posts;
+    const drafts = (await getCollection('drafts')) as unknown as CollectionEntry<'posts'>[];
+    drafts.forEach(async (draft) => {
+      if (draft.data.published !== undefined) return;
+      const { remarkPluginFrontmatter } = await render(draft);
+      const published = dayjs(remarkPluginFrontmatter.createAt as string).toDate();
+      draft.data.published = published;
+      draft.data.draft = true;
+    });
+    return [...posts, ...drafts];
   }
+  return posts;
+}
+
+export async function getSortedPosts(): Promise<BlogPost[]> {
+  const allBlogPosts = (await getPosts()) as unknown as BlogPost[];
   const sortedBlogPosts = allBlogPosts.sort(
     (a: { data: BlogPostData }, b: { data: BlogPostData }) => {
       const dateA = new Date(a.data.published);
src/content.config.ts
@@ -10,6 +10,7 @@ const postsCollection = defineCollection({
     title: z.string(),
     slug: z.string(),
     published: z.date(),
+    draft: z.boolean().optional().default(false),
     description: z.string().optional().default(''),
     cover: z.string().optional().default(''),
     tags: z.array(z.string()).optional().default([]),