diff --git a/.vscode/settings.json b/.vscode/settings.json index b101389..d8c3693 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -121,6 +121,7 @@ "tsconfigs", "ultrahtml", "unpic", + "unsharp", "upyun", "urlset", "varchar", diff --git a/astro.config.ts b/astro.config.ts index e5bff18..6f99fbb 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -13,6 +13,9 @@ export default defineConfig({ security: { checkOrigin: true, }, + image: { + domains: ['localhost', '127.0.0.1'], + }, experimental: { env: { schema: { diff --git a/options.ts b/options.ts index a4f5814..04b00b2 100644 --- a/options.ts +++ b/options.ts @@ -1,5 +1,7 @@ import { z } from 'astro/zod'; +const isProd = (): boolean => import.meta.env.MODE === 'production' || process.env.NODE_ENV === 'production'; + // The type of the options, use zod for better validation. const Options = z .object({ @@ -65,9 +67,12 @@ const Options = z admins: z.array(z.number()), }), }), + thumbnail: z + .function() + .args(z.object({ src: z.string().min(1), width: z.number(), height: z.number() })) + .returns(z.string()), }) .transform((opts) => { - const isProd = (): boolean => import.meta.env.MODE === 'production' || process.env.NODE_ENV === 'production'; const assetsPrefix = (): string => (isProd() ? opts.settings.assetPrefix : opts.local.website); return { ...opts, @@ -81,7 +86,7 @@ const Options = z }; }); -const options = { +const options: z.input = { local: { port: 4321, }, @@ -172,6 +177,15 @@ const options = { admins: [3], }, }, + thumbnail: ({ src, width, height }) => { + if (isProd()) { + // Add upyun thumbnail support. + return `${src}!upyun520/both/${width}x${height}/quality/100/unsharp/true/progressive/true`; + } + // See https://docs.astro.build/en/reference/image-service-reference/#local-services + // Remember to add the localhost to you image service settings. + return `http://localhost:4321/_image?href=${src}&w=${width}&h=${height}&f=webp&q=100`; + }, }; export default Options.parse(options); diff --git a/src/components/image/Image.astro b/src/components/image/Image.astro index 8d99168..af90ae1 100644 --- a/src/components/image/Image.astro +++ b/src/components/image/Image.astro @@ -1,5 +1,6 @@ --- import { blurStyle, type Image } from '@/helpers/images'; +import options from '@/options'; interface Props extends Image { alt: string; @@ -8,4 +9,11 @@ interface Props extends Image { const { alt, src, width, height } = Astro.props; --- - + diff --git a/src/components/page/category/PinnedCategories.astro b/src/components/page/category/PinnedCategories.astro deleted file mode 100644 index 929a877..0000000 --- a/src/components/page/category/PinnedCategories.astro +++ /dev/null @@ -1,14 +0,0 @@ ---- -import PinnedCategory from '@/components/page/category/PinnedCategory.astro'; -import { getCategory } from '@/helpers/schema'; -import options from '@/options'; - -const pinnedSlug = options.settings.post.category ?? []; -const pinnedCategories = pinnedSlug - .map((slug) => getCategory(undefined, slug)) - .flatMap((category) => (category !== undefined ? [category] : [])); ---- - -
- {pinnedCategories.map((category) => )} -
diff --git a/src/components/page/category/PinnedCategory.astro b/src/components/page/category/PinnedCategory.astro deleted file mode 100644 index eb9f117..0000000 --- a/src/components/page/category/PinnedCategory.astro +++ /dev/null @@ -1,35 +0,0 @@ ---- -import Image from '@/components/image/Image.astro'; -import type { Category } from '@/helpers/schema'; - -interface Props { - category: Category; -} - -const { category } = Astro.props; ---- - -
-
-
- - {category.name} - -
-
-
- - {category.name} - -
-
{category.description}
-
-
- -
-
-
diff --git a/src/components/page/post/FeaturePost.astro b/src/components/page/post/FeaturePost.astro index ceeacd6..3a5fb6b 100644 --- a/src/components/page/post/FeaturePost.astro +++ b/src/components/page/post/FeaturePost.astro @@ -12,7 +12,7 @@ const { post } = Astro.props;
diff --git a/src/components/page/post/PostCard.astro b/src/components/page/post/PostCard.astro index 39ae31c..8c433d9 100644 --- a/src/components/page/post/PostCard.astro +++ b/src/components/page/post/PostCard.astro @@ -15,7 +15,7 @@ const category = getCategory(post.category, undefined);
- {post.title} + {post.title}
diff --git a/src/components/page/post/PostCards.astro b/src/components/page/post/PostCards.astro index bd1cdbb..06815b7 100644 --- a/src/components/page/post/PostCards.astro +++ b/src/components/page/post/PostCards.astro @@ -1,12 +1,25 @@ --- -import PostCard from '@/components/page/post/PostCard.astro'; +import Pagination from '@/components/page/pagination/Pagination.astro'; +import { slicePosts } from '@/helpers/formatter'; import type { Post } from '@/helpers/schema'; +import options from '@/options'; +import PostCard from './PostCard.astro'; interface Props { posts: Post[]; + pageNum: number; } -const { posts } = Astro.props; +const { pageNum, posts } = Astro.props; +const results = slicePosts(posts, pageNum, options.settings.pagination.posts); +if (!results) { + return Astro.redirect('/404'); +} + +const { currentPosts, totalPage } = results; --- -
{posts.map((post) => )}
+
+
{currentPosts.map((post) => )}
+ +
diff --git a/src/components/page/post/PostCategory.astro b/src/components/page/post/PostCategory.astro new file mode 100644 index 0000000..40e395a --- /dev/null +++ b/src/components/page/post/PostCategory.astro @@ -0,0 +1,41 @@ +--- +import Image from '@/components/image/Image.astro'; +import { getCategory } from '@/helpers/schema'; +import options from '@/options'; + +const pinnedSlug = options.settings.post.category ?? []; +const pinnedCategories = pinnedSlug + .map((slug) => getCategory(undefined, slug)) + .flatMap((category) => (category !== undefined ? [category] : [])); +--- + +
+ { + pinnedCategories.map((category) => ( +
+
+ +
+
+ + {category.name} + +
+
{category.description}
+
+
+ +
+
+
+ )) + } +
diff --git a/src/components/page/post/PostPagination.astro b/src/components/page/post/PostPagination.astro deleted file mode 100644 index d0277d0..0000000 --- a/src/components/page/post/PostPagination.astro +++ /dev/null @@ -1,25 +0,0 @@ ---- -import Pagination from '@/components/page/pagination/Pagination.astro'; -import PostCards from '@/components/page/post/PostCards.astro'; -import { slicePosts } from '@/helpers/formatter'; -import type { Post } from '@/helpers/schema'; -import options from '@/options'; - -interface Props { - posts: Post[]; - pageNum: number; -} - -const { pageNum, posts } = Astro.props; -const results = slicePosts(posts, pageNum, options.settings.pagination.posts); -if (!results) { - return Astro.redirect('/404'); -} - -const { currentPosts, totalPage } = results; ---- - -
- - -
diff --git a/src/components/page/post/PostSquare.astro b/src/components/page/post/PostSquare.astro index 0471ed6..4355ae5 100644 --- a/src/components/page/post/PostSquare.astro +++ b/src/components/page/post/PostSquare.astro @@ -16,7 +16,7 @@ const { post, first } = Astro.props;
diff --git a/src/layouts/posts/PostsLayout.astro b/src/layouts/posts/PostsLayout.astro index b5c3cce..a4fa0c9 100644 --- a/src/layouts/posts/PostsLayout.astro +++ b/src/layouts/posts/PostsLayout.astro @@ -1,7 +1,7 @@ --- -import PinnedCategories from '@/components/page/category/PinnedCategories.astro'; import FeaturePosts from '@/components/page/post/FeaturePosts.astro'; -import PostPagination from '@/components/page/post/PostPagination.astro'; +import PostCards from '@/components/page/post/PostCards.astro'; +import PinnedCategories from '@/components/page/post/PostCategory.astro'; import Sidebar from '@/components/sidebar/Sidebar.astro'; import type { Post, Tag } from '@/helpers/schema'; @@ -27,7 +27,7 @@ if (pageNum < 1) {
- +