style: prettier format

This commit is contained in:
HPCesia 2025-01-23 13:34:59 +08:00
parent 1564426c1d
commit 34805f9279
37 changed files with 127 additions and 106 deletions

View File

@ -7,7 +7,15 @@ module.exports = {
trailingComma: 'es5', trailingComma: 'es5',
useTabs: false, useTabs: false,
plugins: ['prettier-plugin-astro'], importOrderSeparation: false,
importOrderSortSpecifiers: true,
plugins: [
'prettier-plugin-astro',
'prettier-plugin-tailwindcss',
'@trivago/prettier-plugin-sort-imports',
'prettier-plugin-astro-organize-imports',
],
overrides: [{ files: '*.astro', options: { parser: 'astro' } }], overrides: [{ files: '*.astro', options: { parser: 'astro' } }],
}; };

4
.stylelintignore Normal file
View File

@ -0,0 +1,4 @@
dist
node_modules
.github
.changeset

View File

@ -1,8 +1,7 @@
// @ts-check // @ts-check
import { defineConfig } from 'astro/config';
import tailwind from '@astrojs/tailwind'; import tailwind from '@astrojs/tailwind';
import icon from 'astro-icon'; import icon from 'astro-icon';
import { defineConfig } from 'astro/config';
// https://astro.build/config // https://astro.build/config
export default defineConfig({ export default defineConfig({

View File

@ -1,9 +1,9 @@
import js from '@eslint/js';
import typescriptParser from '@typescript-eslint/parser';
import astroEslintParser from 'astro-eslint-parser'; import astroEslintParser from 'astro-eslint-parser';
import eslintPluginAstro from 'eslint-plugin-astro'; import eslintPluginAstro from 'eslint-plugin-astro';
import globals from 'globals'; import globals from 'globals';
import js from '@eslint/js';
import tseslint from 'typescript-eslint'; import tseslint from 'typescript-eslint';
import typescriptParser from '@typescript-eslint/parser';
export default [ export default [
js.configs.recommended, js.configs.recommended,

View File

@ -6,7 +6,8 @@
"dev": "astro dev", "dev": "astro dev",
"build": "astro check && astro build", "build": "astro check && astro build",
"preview": "astro preview", "preview": "astro preview",
"astro": "astro" "astro": "astro",
"lint": "prettier -w . && eslint . --fix && stylelint \"**/*.{css,scss}\" --fix && tsc --noEmit && astro check"
}, },
"dependencies": { "dependencies": {
"@astrojs/tailwind": "^5.1.4", "@astrojs/tailwind": "^5.1.4",
@ -24,6 +25,9 @@
"devDependencies": { "devDependencies": {
"@astrojs/check": "^0.9.4", "@astrojs/check": "^0.9.4",
"@astrojs/ts-plugin": "^1.10.4", "@astrojs/ts-plugin": "^1.10.4",
"@eslint/js": "^9.18.0",
"@trivago/prettier-plugin-sort-imports": "^5.2.1",
"@typescript-eslint/parser": "^8.21.0",
"astro-eslint-parser": "^1.1.0", "astro-eslint-parser": "^1.1.0",
"eslint": "^9.18.0", "eslint": "^9.18.0",
"eslint-plugin-astro": "^1.3.1", "eslint-plugin-astro": "^1.3.1",
@ -31,6 +35,8 @@
"postcss-html": "^1.8.0", "postcss-html": "^1.8.0",
"prettier": "^3.4.2", "prettier": "^3.4.2",
"prettier-plugin-astro": "^0.14.1", "prettier-plugin-astro": "^0.14.1",
"prettier-plugin-astro-organize-imports": "^0.4.11",
"prettier-plugin-tailwindcss": "^0.6.10",
"stylelint": "^16.13.2", "stylelint": "^16.13.2",
"stylelint-config-html": "^1.1.0", "stylelint-config-html": "^1.1.0",
"stylelint-config-standard-scss": "^14.0.0", "stylelint-config-standard-scss": "^14.0.0",

View File

@ -1,6 +1,6 @@
import postcssImport from 'postcss-import'; import postcssImport from 'postcss-import';
import postcssNesting from 'tailwindcss/nesting/index.js';
import tailwindcss from 'tailwindcss'; import tailwindcss from 'tailwindcss';
import postcssNesting from 'tailwindcss/nesting/index.js';
/** @type {import('postcss-load-config').Config} */ /** @type {import('postcss-load-config').Config} */
export default { export default {

View File

@ -1,7 +0,0 @@
---
---
<div id="aside-content">
{}
</div>

View File

@ -12,7 +12,7 @@ const { categories, currentCategory } = Astro.props;
<div <div
id="category-bar" id="category-bar"
class="theme-card-bg theme-border flex w-full rounded-xl px-2 py-3 border-2 mb-4" class="theme-card-bg theme-border mb-4 flex w-full rounded-xl border-2 px-2 py-3"
> >
<a href={`/`} class:list={[currentCategory ? '' : 'theme-card-bg-hl']}> <a href={`/`} class:list={[currentCategory ? '' : 'theme-card-bg-hl']}>
{i18n(I18nKey.recentPosts)} {i18n(I18nKey.recentPosts)}

View File

@ -1,10 +1,8 @@
--- ---
import { navbarConfig } from '@/config'; import { navbarConfig } from '@/config';
import { Icon } from 'astro-icon/components';
import Button from './widgets/Button.astro';
import { i18n } from '@i18n/translation'; import { i18n } from '@i18n/translation';
import { Icon } from 'astro-icon/components';
import Button from './widgets/Button.astro';
interface Props { interface Props {
title?: string; title?: string;
@ -17,14 +15,14 @@ if (!title) title = 'Astral Halo';
<div <div
id="navbar" id="navbar"
transition:persist transition:persist
class="flex fixed z-30 w-full h-16 items-center border-b-2 theme-border theme-card-bg" class="theme-border theme-card-bg fixed z-30 flex h-16 w-full items-center border-b-2"
> >
<div id="nav-left" class="flex mr-auto w-fit"> <div id="nav-left" class="mr-auto flex w-fit">
<Button id="site-name" href="/"> <Button id="site-name" href="/">
<span class="text-xl font-bold">{title}</span> <span class="text-xl font-bold">{title}</span>
</Button> </Button>
</div> </div>
<div id="nav-center" class="flex m-auto w-fit max-md:hidden"> <div id="nav-center" class="m-auto flex w-fit max-md:hidden">
{ {
navbarConfig.navbarCenterItems.map((item) => { navbarConfig.navbarCenterItems.map((item) => {
const text = i18n(item.text); const text = i18n(item.text);
@ -36,7 +34,7 @@ if (!title) title = 'Astral Halo';
}) })
} }
</div> </div>
<div id="nav-right" class="flex ml-auto w-fit"> <div id="nav-right" class="ml-auto flex w-fit">
<div class="flex max-md:hidden"> <div class="flex max-md:hidden">
{ {
navbarConfig.navbarRightItems.onlyWide.map((item) => { navbarConfig.navbarRightItems.onlyWide.map((item) => {

View File

@ -8,7 +8,7 @@ const currentYear = new Date().getFullYear();
<div id="footer-links"></div> <div id="footer-links"></div>
<div <div
id="footer-bar-wrapper" id="footer-bar-wrapper"
class="theme-card-bg theme-border border-t-2 w-full mt-4 overflow-hidden p-4" class="theme-card-bg theme-border mt-4 w-full overflow-hidden border-t-2 p-4"
> >
<div id="footer-bar" class="flex justify-between"> <div id="footer-bar" class="flex justify-between">
<div id="footer-left" class="text-center"> <div id="footer-left" class="text-center">
@ -17,7 +17,7 @@ const currentYear = new Date().getFullYear();
} By <a href="/about/">{profileConfig.name}</a> } By <a href="/about/">{profileConfig.name}</a>
</div> </div>
<div id="footer-right"> <div id="footer-right">
Powered by <a href="https://astro.build/" class="font-bold mr-4">Astro</a> Powered by <a href="https://astro.build/" class="mr-4 font-bold">Astro</a>
Theme <a href="https://github.com/HPCesia/astral-halo/" class="font-bold">Astro Halo</a> Theme <a href="https://github.com/HPCesia/astral-halo/" class="font-bold">Astro Halo</a>
</div> </div>
</div> </div>

View File

@ -1,8 +1,8 @@
--- ---
import type { BlogPostData } from '@/types/data';
import { siteConfig } from '@/config'; import { siteConfig } from '@/config';
import PostCard from './widgets/PostCard.astro'; import type { BlogPostData } from '@/types/data';
import Pagination from './widgets/Pagination.astro'; import Pagination from './widgets/Pagination.astro';
import PostCard from './widgets/PostCard.astro';
interface Props { interface Props {
posts: { posts: {

View File

@ -15,11 +15,11 @@ import DarkModeButton from './widgets/DarkModeButton.astro';
<Button id="stb-back-to-top" class="group"> <Button id="stb-back-to-top" class="group">
<span <span
id="stb-read-percentage" id="stb-read-percentage"
class="absolute opacity-0 duration-300 group-hover:opacity-0 text-sm"></span> class="absolute text-sm opacity-0 duration-300 group-hover:opacity-0"></span>
<Icon <Icon
id="stb-back-to-top-icon" id="stb-back-to-top-icon"
name="material-symbols:arrow-upward-rounded" name="material-symbols:arrow-upward-rounded"
class="opacity-0 group-hover:opacity-100 duration-300" class="opacity-0 duration-300 group-hover:opacity-100"
/> />
</Button> </Button>
</div> </div>

View File

@ -1,8 +1,6 @@
--- ---
import { navbarConfig } from '@/config'; import { navbarConfig } from '@/config';
import { Icon } from 'astro-icon/components'; import { Icon } from 'astro-icon/components';
import Button from './widgets/Button.astro'; import Button from './widgets/Button.astro';
import DarkModeButton from './widgets/DarkModeButton.astro'; import DarkModeButton from './widgets/DarkModeButton.astro';
--- ---
@ -10,17 +8,17 @@ import DarkModeButton from './widgets/DarkModeButton.astro';
<div id="sidebar" transition:persist> <div id="sidebar" transition:persist>
<div <div
id="sidebar-mask" id="sidebar-mask"
class="fixed z-40 opacity-0 pointer-events-none w-full h-full bg-black/10 backdrop-blur-md backdrop-saturate-100 duration-500 ease-in-out" class="pointer-events-none fixed z-40 h-full w-full bg-black/10 opacity-0 backdrop-blur-md backdrop-saturate-100 duration-500 ease-in-out"
> >
</div> </div>
<div <div
id="sidebar-menu" id="sidebar-menu"
class="fixed h-full z-50 -right-1/2 w-1/2 duration-500 ease-in-out border-l-2 theme-border theme-card-bg" class="theme-border theme-card-bg fixed -right-1/2 z-50 h-full w-1/2 border-l-2 duration-500 ease-in-out"
> >
<div id="sidebar-site-data"></div> <div id="sidebar-site-data"></div>
<DarkModeButton <DarkModeButton
showText={true} showText={true}
class="text-lg !w-[calc(100%-1rem)] border-2 theme-border" class="theme-border !w-[calc(100%-1rem)] border-2 text-lg"
/> />
<div id="sidebar-menu-text-items"> <div id="sidebar-menu-text-items">
{ {

View File

@ -1,6 +1,6 @@
--- ---
import { getTimeArchives } from '@utils/content-utils';
import PostCard from '@components/widgets/PostCard.astro'; import PostCard from '@components/widgets/PostCard.astro';
import { getTimeArchives } from '@utils/content-utils';
type AllTimeArchives = Awaited<ReturnType<typeof getTimeArchives>>; type AllTimeArchives = Awaited<ReturnType<typeof getTimeArchives>>;
type YearArchives = AllTimeArchives[number]; type YearArchives = AllTimeArchives[number];
@ -18,7 +18,7 @@ const { group } = Astro.props;
group.map((year) => <Astro.self group={year} />) group.map((year) => <Astro.self group={year} />)
) : 'year' in group ? ( ) : 'year' in group ? (
<Fragment> <Fragment>
<div class="text-2xl font-bold ml-2"> <div class="ml-2 text-2xl font-bold">
<a href={`/archives/${group.year}/`}>{group.year}</a> <a href={`/archives/${group.year}/`}>{group.year}</a>
</div> </div>
{group.months.map((month) => ( {group.months.map((month) => (
@ -27,7 +27,7 @@ const { group } = Astro.props;
</Fragment> </Fragment>
) : ( ) : (
<Fragment> <Fragment>
<div class="text-xl font-bold ml-3">{group.month}</div> <div class="ml-3 text-xl font-bold">{group.month}</div>
{group.posts.map((post) => { {group.posts.map((post) => {
const data = post.data; const data = post.data;
return ( return (

View File

@ -36,7 +36,7 @@ const Tag = (href ? 'a' : Fragment) as HTMLTag;
} }
&:active { &:active {
@apply brightness-75 scale-95; @apply scale-95 brightness-75;
} }
} }
</style> </style>

View File

@ -1,9 +1,9 @@
--- ---
import type { HTMLAttributes } from 'astro/types';
import Button from './Button.astro';
import { Icon } from 'astro-icon/components';
import I18nKey from '@i18n/I18nKey'; import I18nKey from '@i18n/I18nKey';
import { i18n } from '@i18n/translation'; import { i18n } from '@i18n/translation';
import { Icon } from 'astro-icon/components';
import type { HTMLAttributes } from 'astro/types';
import Button from './Button.astro';
interface Props extends Omit<HTMLAttributes<'button'>, 'onclick'> { interface Props extends Omit<HTMLAttributes<'button'>, 'onclick'> {
showText?: boolean; showText?: boolean;
@ -22,7 +22,7 @@ const { class: className, showText, ...rest } = Astro.props;
<Icon class="darkmode-icon-light" name="material-symbols:light-mode-rounded" /> <Icon class="darkmode-icon-light" name="material-symbols:light-mode-rounded" />
<Icon class="darkmode-icon-dark" name="material-symbols:dark-mode-rounded" /> <Icon class="darkmode-icon-dark" name="material-symbols:dark-mode-rounded" />
<Icon class="darkmode-icon-auto" name="material-symbols:night-sight-auto-rounded" /> <Icon class="darkmode-icon-auto" name="material-symbols:night-sight-auto-rounded" />
{showText && <span class="darkmode-text px-2 ml-auto mr-2" />} {showText && <span class="darkmode-text ml-auto mr-2 px-2" />}
</Button> </Button>
<script> <script>

View File

@ -1,6 +1,6 @@
--- ---
import type { ComponentProps } from 'astro/types';
import { Icon } from 'astro-icon/components'; import { Icon } from 'astro-icon/components';
import type { ComponentProps } from 'astro/types';
type Props = ComponentProps<typeof Icon>; type Props = ComponentProps<typeof Icon>;

View File

@ -48,20 +48,20 @@ else {
current > 1 && ( current > 1 && (
<Button <Button
id="prev-page-btn" id="prev-page-btn"
class="theme-bg theme-border border-2 !rounded-xl mr-auto" class="theme-bg theme-border mr-auto !rounded-xl border-2"
href={getPageUrl(current - 1)} href={getPageUrl(current - 1)}
> >
<Icon name="material-symbols:keyboard-double-arrow-left-rounded" class="my-1" /> <Icon name="material-symbols:keyboard-double-arrow-left-rounded" class="my-1" />
</Button> </Button>
) )
} }
<div class="flex justify-center items-center gap-2 mx-auto"> <div class="mx-auto flex items-center justify-center gap-2">
{ {
pages.map((p) => { pages.map((p) => {
return ( return (
<Button <Button
class:list={[ class:list={[
'theme-bg theme-border border-2 !rounded-xl', 'theme-bg theme-border !rounded-xl border-2',
current === p.page && 'theme-card-bg-hl', current === p.page && 'theme-card-bg-hl',
]} ]}
href={p.url} href={p.url}
@ -75,7 +75,7 @@ else {
total > 1 && ( total > 1 && (
<div <div
id="page-jumper" id="page-jumper"
class="flex flex-row items-center theme-card-bg theme-border mx-2 rounded-xl border-2" class="theme-card-bg theme-border mx-2 flex flex-row items-center rounded-xl border-2"
data-base-url={baseUrl} data-base-url={baseUrl}
data-special-pages={specialPages?.map((p) => `${p.page}:${p.url}`).join(',')} data-special-pages={specialPages?.map((p) => `${p.page}:${p.url}`).join(',')}
> >
@ -84,11 +84,11 @@ else {
type="number" type="number"
min="1" min="1"
max={total} max={total}
class="duration-300 theme-bg border-none !active:border-none pl-4" class="theme-bg !active:border-none border-none pl-4 duration-300"
/> />
<Button <Button
id="page-jumper-button" id="page-jumper-button"
class="theme-card-bg !rounded-xl !m-0 relative right-0 duration-300" class="theme-card-bg relative right-0 !m-0 !rounded-xl duration-300"
> >
<Icon name="material-symbols:keyboard-double-arrow-right-rounded" class="my-1" /> <Icon name="material-symbols:keyboard-double-arrow-right-rounded" class="my-1" />
</Button> </Button>
@ -100,7 +100,7 @@ else {
current < total && ( current < total && (
<Button <Button
id="next-page-btn" id="next-page-btn"
class="theme-bg theme-border border-2 !rounded-xl ml-auto" class="theme-bg theme-border ml-auto !rounded-xl border-2"
href={getPageUrl(current + 1)} href={getPageUrl(current + 1)}
> >
<Icon name="material-symbols:keyboard-double-arrow-right-rounded" class="my-1" /> <Icon name="material-symbols:keyboard-double-arrow-right-rounded" class="my-1" />

View File

@ -1,7 +1,7 @@
--- ---
import MetaIcon from './MetaIcon.astro'; import MetaIcon from './MetaIcon.astro';
import ReadMoreButton from './ReadMoreButton.astro';
import PostCardCover from './PostCardCover.astro'; import PostCardCover from './PostCardCover.astro';
import ReadMoreButton from './ReadMoreButton.astro';
interface Props { interface Props {
class?: string; class?: string;
@ -49,13 +49,13 @@ const metas: ({ icon: string; text: string; link?: string } | undefined)[] = [
<div <div
class:list={[ class:list={[
'theme-card-bg theme-border', 'theme-card-bg theme-border',
'border-2 rounded-xl p-4 flex max-md:flex-col-reverse w-full', 'flex w-full rounded-xl border-2 p-4 max-md:flex-col-reverse',
className, className,
]} ]}
> >
<div class="items-center px-12 py-7 w-full h-full mr-auto"> <div class="mr-auto h-full w-full items-center px-12 py-7">
<div class="text-2xl mb-5"><a href={url}>{title}</a></div> <div class="mb-5 text-2xl"><a href={url}>{title}</a></div>
<div class="flex flex-wrap items-center mb-3 gap-x-4 gap-y-2 theme-text-second"> <div class="theme-text-second mb-3 flex flex-wrap items-center gap-x-4 gap-y-2">
{ {
metas.map((meta) => { metas.map((meta) => {
return ( return (
@ -63,11 +63,11 @@ const metas: ({ icon: string; text: string; link?: string } | undefined)[] = [
<div class="flex items-center gap-1"> <div class="flex items-center gap-1">
<MetaIcon name={meta.icon} /> <MetaIcon name={meta.icon} />
{meta.link ? ( {meta.link ? (
<a href={meta.link} class="text-sm font-medium"> <a href={meta.link} class="meta-text" title={meta.text}>
{meta.text} {meta.text}
</a> </a>
) : ( ) : (
<span class="text-sm font-medium">{meta.text}</span> <span class="meta-text">{meta.text}</span>
)} )}
</div> </div>
) )
@ -84,3 +84,13 @@ const metas: ({ icon: string; text: string; link?: string } | undefined)[] = [
) )
} }
</div> </div>
<style>
.meta-text {
@apply text-sm font-medium;
}
a.meta-text {
@apply duration-100 hover:brightness-125;
}
</style>

View File

@ -20,21 +20,21 @@ const { url, title, cover } = Astro.props;
<style> <style>
a { a {
@apply min-h-48 w-full md:w-3/4 md:max-w-96 relative; @apply relative min-h-48 w-full md:w-3/4 md:max-w-96;
@apply active:brightness-75 active:scale-95 duration-100; @apply duration-100 active:scale-95 active:brightness-75;
} }
img { img {
@apply w-full h-full object-cover rounded-md; @apply h-full w-full rounded-md object-cover;
} }
div { div {
@apply absolute inset-0 w-full h-full bg-black/60; @apply absolute inset-0 h-full w-full bg-black/60;
@apply flex items-center justify-center; @apply flex items-center justify-center;
@apply opacity-0 group-hover:opacity-100 duration-300; @apply opacity-0 duration-300 group-hover:opacity-100;
} }
svg { svg {
@apply w-24 h-24 text-white; @apply h-24 w-24 text-white;
} }
</style> </style>

View File

@ -1,7 +1,7 @@
--- ---
import { profileConfig } from '@/config'; import { profileConfig } from '@/config';
import avatarImg from '@assets/img/avatar.jpg';
import { Image } from 'astro:assets'; import { Image } from 'astro:assets';
import avatarImg from '/src/assets/img/avatar.jpg';
const avaterAttr = profileConfig.avatar const avaterAttr = profileConfig.avatar
? { ? {
@ -17,15 +17,15 @@ const avaterAttr = profileConfig.avatar
<div <div
id="profile-card" id="profile-card"
transition:persist transition:persist
class="theme-card-bg theme-border rounded-xl border-2 flex flex-col items-center text-center" class="theme-card-bg theme-border flex flex-col items-center rounded-xl border-2 text-center"
> >
<div class="m-3 w-fit min-w-20"> <div class="m-3 w-fit min-w-20">
<a href="/about/"> <a href="/about/">
<Image class="rounded-full border-4 w-20 h-20 theme-border" {...avaterAttr} /> <Image class="theme-border h-20 w-20 rounded-full border-4" {...avaterAttr} />
</a> </a>
</div> </div>
<div class="mx-3 mb-5 flex flex-col w-full"> <div class="mx-3 mb-5 flex w-full flex-col">
<div class="text-lg mb-3"> <div class="mb-3 text-lg">
<a href="/about/" class="font-bold">{profileConfig.name}</a> <a href="/about/" class="font-bold">{profileConfig.name}</a>
</div> </div>
<div>{profileConfig.bio}</div> <div>{profileConfig.bio}</div>

View File

@ -1,8 +1,8 @@
--- ---
import type { ComponentProps } from 'astro/types';
import { Icon } from 'astro-icon/components';
import { i18n } from '@i18n/translation';
import I18nKey from '@i18n/I18nKey'; import I18nKey from '@i18n/I18nKey';
import { i18n } from '@i18n/translation';
import { Icon } from 'astro-icon/components';
import type { ComponentProps } from 'astro/types';
type Props = Omit<ComponentProps<typeof Icon>, 'name'>; type Props = Omit<ComponentProps<typeof Icon>, 'name'>;
@ -15,13 +15,13 @@ const { href, title, ...rest } = Astro.props;
<style> <style>
a { a {
@apply max-md:hidden duration-100; @apply duration-100 max-md:hidden;
@apply hover:brightness-125; @apply hover:brightness-125;
@apply active:brightness-75 active:scale-95; @apply active:scale-95 active:brightness-75;
} }
svg { svg {
@apply min-h-48 h-full w-12 rounded-md; @apply h-full min-h-48 w-12 rounded-md;
@apply text-[var(--theme-color-light-darken)] dark:text-[var(--theme-color-dark-lighten)]; @apply text-[var(--theme-color-light-darken)] dark:text-[var(--theme-color-dark-lighten)];
@apply bg-[var(--theme-color-light-transparent)] dark:bg-[var(--theme-color-dark-transparent)]; @apply bg-[var(--theme-color-light-transparent)] dark:bg-[var(--theme-color-dark-transparent)];
} }

View File

@ -11,7 +11,7 @@ const minDepth = Math.min(...headings.map((h) => h.depth));
const maxLevel = 3; const maxLevel = 3;
--- ---
<div class:list={['theme-card-bg theme-border border-2 rounded-xl p-2', className]}> <div class:list={['theme-card-bg theme-border rounded-xl border-2 p-2', className]}>
<div></div> <div></div>
{ {
headings headings

View File

@ -1,11 +1,10 @@
import type { import type {
LicenseConfig, LicenseConfig,
NavbarConfig,
ProfileConfig, ProfileConfig,
SiteConfig, SiteConfig,
NavbarConfig,
ToolBarConfig, ToolBarConfig,
} from './types/config'; } from './types/config';
import I18nKey from '@i18n/I18nKey'; import I18nKey from '@i18n/I18nKey';
export const siteConfig: SiteConfig = { export const siteConfig: SiteConfig = {

View File

@ -1,5 +1,5 @@
import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders'; import { glob } from 'astro/loaders';
import { defineCollection, z } from 'astro:content';
const postsCollection = defineCollection({ const postsCollection = defineCollection({
loader: glob({ loader: glob({

View File

@ -1,14 +1,13 @@
import { siteConfig } from '@/config';
import I18nKey from './I18nKey'; import I18nKey from './I18nKey';
import { en } from './langs/en';
import { zh_CN } from './langs/zh_CN';
import { zh_TW } from './langs/zh_TW';
import { siteConfig } from '@/config';
export type Translation = { export type Translation = {
[K in I18nKey]: string; [K in I18nKey]: string;
}; };
import { en } from './langs/en';
import { zh_CN } from './langs/zh_CN';
import { zh_TW } from './langs/zh_TW';
const defaultTranslation = en; const defaultTranslation = en;
const map: { [key: string]: Translation } = { const map: { [key: string]: Translation } = {

View File

@ -13,9 +13,9 @@ const { title, description, lang } = Astro.props;
<div id="main-content" class="my-4 w-full"> <div id="main-content" class="my-4 w-full">
<slot /> <slot />
</div> </div>
<div id="aside-content" class="max-xl:hidden my-4 w-96 flex flex-col gap-4"> <div id="aside-content" class="my-4 flex w-96 flex-col gap-4 max-xl:hidden">
<slot name="aside-fixed" slot="aside-fixed" /> <slot name="aside-fixed" slot="aside-fixed" />
<div class="sticky flex flex-col gap-4 top-20"> <div class="sticky top-20 flex flex-col gap-4">
<slot name="aside-sticky" slot="aside-sticky" /> <slot name="aside-sticky" slot="aside-sticky" />
</div> </div>
</div> </div>

View File

@ -1,9 +1,9 @@
--- ---
import Navbar from '@components/Navbar.astro'; import Navbar from '@components/Navbar.astro';
import PageFooter from '@components/PageFooter.astro';
import SideToolBar from '@components/SideToolBar.astro'; import SideToolBar from '@components/SideToolBar.astro';
import Sidebar from '@components/Sidebar.astro'; import Sidebar from '@components/Sidebar.astro';
import GlobalLayout from './GlobalLayout.astro'; import GlobalLayout from './GlobalLayout.astro';
import PageFooter from '@components/PageFooter.astro';
interface Props { interface Props {
title?: string; title?: string;
@ -18,9 +18,9 @@ const { title, description, lang } = Astro.props;
<Sidebar /> <Sidebar />
<SideToolBar /> <SideToolBar />
<Navbar /> <Navbar />
<div id="body-wrap" class="items-center w-full"> <div id="body-wrap" class="w-full items-center">
<!-- Main content --> <!-- Main content -->
<div id="content-wrapper" class="flex mx-auto gap-4 max-w-screen-xl"> <div id="content-wrapper" class="mx-auto flex max-w-screen-xl gap-4">
<slot /> <slot />
</div> </div>
</div> </div>

View File

@ -1,10 +1,10 @@
--- ---
import { getCategories, getSortedPosts } from '@utils/content-utils';
import { siteConfig } from '@/config'; import { siteConfig } from '@/config';
import CategoryBar from '@components/CategoryBar.astro'; import CategoryBar from '@components/CategoryBar.astro';
import PostPage from '@components/PostPage.astro'; import PostPage from '@components/PostPage.astro';
import GridLayout from '@layouts/GridLayout.astro';
import ProfileCard from '@components/widgets/ProfileCard.astro'; import ProfileCard from '@components/widgets/ProfileCard.astro';
import GridLayout from '@layouts/GridLayout.astro';
import { getCategories, getSortedPosts } from '@utils/content-utils';
export async function getStaticPaths() { export async function getStaticPaths() {
const articles = await getSortedPosts(); const articles = await getSortedPosts();

View File

@ -1,8 +1,7 @@
--- ---
import MainLayout from '@layouts/MainLayout.astro';
import I18nKey from '@i18n/I18nKey'; import I18nKey from '@i18n/I18nKey';
import { i18n } from '@i18n/translation'; import { i18n } from '@i18n/translation';
import MainLayout from '@layouts/MainLayout.astro';
--- ---
<MainLayout title={i18n(I18nKey.about)}> <MainLayout title={i18n(I18nKey.about)}>

View File

@ -1,11 +1,11 @@
--- ---
import { getCategories, getSortedPosts } from '@utils/content-utils';
import PostPage from '@components/PostPage.astro';
import { siteConfig } from '@/config'; import { siteConfig } from '@/config';
import CategoryBar from '@components/CategoryBar.astro';
import PostPage from '@components/PostPage.astro';
import ProfileCard from '@components/widgets/ProfileCard.astro';
import I18nKey from '@i18n/I18nKey'; import I18nKey from '@i18n/I18nKey';
import GridLayout from '@layouts/GridLayout.astro'; import GridLayout from '@layouts/GridLayout.astro';
import CategoryBar from '@components/CategoryBar.astro'; import { getCategories, getSortedPosts } from '@utils/content-utils';
import ProfileCard from '@components/widgets/ProfileCard.astro';
export async function getStaticPaths() { export async function getStaticPaths() {
const posts = await getSortedPosts(); const posts = await getSortedPosts();

View File

@ -1,10 +1,10 @@
--- ---
import { getSortedPosts } from '@utils/content-utils';
import PostPage from '@components/PostPage.astro';
import { siteConfig } from '@/config'; import { siteConfig } from '@/config';
import GridLayout from '@layouts/GridLayout.astro'; import PostPage from '@components/PostPage.astro';
import ProfileCard from '@components/widgets/ProfileCard.astro'; import ProfileCard from '@components/widgets/ProfileCard.astro';
import I18nKey from '@i18n/I18nKey'; import I18nKey from '@i18n/I18nKey';
import GridLayout from '@layouts/GridLayout.astro';
import { getSortedPosts } from '@utils/content-utils';
export async function getStaticPaths() { export async function getStaticPaths() {
const posts = await getSortedPosts(); const posts = await getSortedPosts();

View File

@ -1,9 +1,9 @@
--- ---
import { getCollection, render } from 'astro:content';
import GridLayout from '@layouts/GridLayout.astro';
import ProfileCard from '@components/widgets/ProfileCard.astro';
import '@/styles/article.scss'; import '@/styles/article.scss';
import ProfileCard from '@components/widgets/ProfileCard.astro';
import TOC from '@components/widgets/TOC.astro'; import TOC from '@components/widgets/TOC.astro';
import GridLayout from '@layouts/GridLayout.astro';
import { getCollection, render } from 'astro:content';
export async function getStaticPaths() { export async function getStaticPaths() {
const articles = await getCollection('posts'); const articles = await getCollection('posts');
@ -18,7 +18,7 @@ const { Content, headings } = await render(article);
--- ---
<GridLayout> <GridLayout>
<div class="theme-card-bg theme-border border-2 px-6 py-4 rounded-xl"> <div class="theme-card-bg theme-border rounded-xl border-2 px-6 py-4">
<article> <article>
<Content /> <Content />
</article> </article>

View File

@ -40,7 +40,7 @@ article {
} }
hr { hr {
@apply border-dashed border-2; @apply border-2 border-dashed;
@apply mx-2 my-4; @apply mx-2 my-4;
} }

View File

@ -1,7 +1,7 @@
import { getCollection } from 'astro:content';
import type { BlogPostData } from '@/types/data'; import type { BlogPostData } from '@/types/data';
import { i18n } from '@i18n/translation';
import I18nKey from '@i18n/I18nKey'; import I18nKey from '@i18n/I18nKey';
import { i18n } from '@i18n/translation';
import { getCollection } from 'astro:content';
export async function getSortedPosts(): Promise<{ body: string; data: BlogPostData }[]> { export async function getSortedPosts(): Promise<{ body: string; data: BlogPostData }[]> {
const allBlogPosts = (await getCollection('posts')) as unknown as { const allBlogPosts = (await getCollection('posts')) as unknown as {

View File

@ -1,3 +1,6 @@
import i18nKey from '@i18n/I18nKey';
import { i18n } from '@i18n/translation';
export function pathsEqual(path1: string, path2: string) { export function pathsEqual(path1: string, path2: string) {
const normalizedPath1 = path1.replace(/^\/|\/$/g, '').toLowerCase(); const normalizedPath1 = path1.replace(/^\/|\/$/g, '').toLowerCase();
const normalizedPath2 = path2.replace(/^\/|\/$/g, '').toLowerCase(); const normalizedPath2 = path2.replace(/^\/|\/$/g, '').toLowerCase();
@ -12,3 +15,8 @@ function joinUrl(...parts: string[]): string {
export function url(path: string) { export function url(path: string) {
return joinUrl('', import.meta.env.BASE_URL, path); return joinUrl('', import.meta.env.BASE_URL, path);
} }
export function getCategoryUrl(category: string): string {
if (category === i18n(i18nKey.uncategorized)) return url('/archives/category/uncategorized/');
return url(`/archives/categories/${category}/1/`);
}