diff --git a/astro.config.mjs b/astro.config.mjs
index 47fb2f9..11e45b2 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -27,7 +27,8 @@ export default defineConfig({
icon({
include: {
'material-symbols': ['*'],
- 'fa6-brands': ['*']
+ 'fa6-brands': ['*'],
+ 'fa6-regular': ['*']
}
})
],
diff --git a/package.json b/package.json
index fae23fb..2cb1150 100644
--- a/package.json
+++ b/package.json
@@ -30,6 +30,7 @@
"devDependencies": {
"@astrojs/ts-plugin": "^1.1.3",
"@iconify-json/fa6-brands": "^1.1.13",
+ "@iconify-json/fa6-regular": "^1.1.13",
"@iconify-json/material-symbols": "^1.1.59",
"@rollup/plugin-yaml": "^4.1.2",
"@tailwindcss/typography": "^0.5.10",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 062eeba..aa1832c 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -58,6 +58,9 @@ devDependencies:
'@iconify-json/fa6-brands':
specifier: ^1.1.13
version: 1.1.13
+ '@iconify-json/fa6-regular':
+ specifier: ^1.1.13
+ version: 1.1.13
'@iconify-json/material-symbols':
specifier: ^1.1.59
version: 1.1.59
@@ -981,6 +984,12 @@ packages:
'@iconify/types': 2.0.0
dev: true
+ /@iconify-json/fa6-regular@1.1.13:
+ resolution: {integrity: sha512-wY5nEeWwg+fdDzfPdzOHcbgiN7Qk2bTyO0BreJUQJb8NKPcXivyHAlkWPc+wA0kQwfqrmekVCwWnrLoD7B9T0g==}
+ dependencies:
+ '@iconify/types': 2.0.0
+ dev: true
+
/@iconify-json/material-symbols@1.1.59:
resolution: {integrity: sha512-azzJVyS2AKQ4cxIUUmeMHaTVlU9aWM6M98NEqf8luZ1RJpVWuDdSjExY+x58Y39wPFTf+6hgvS4pRwCJRdpohw==}
dependencies:
diff --git a/src/components/GlobalStyles.astro b/src/components/GlobalStyles.astro
index d62ab27..a135aa2 100644
--- a/src/components/GlobalStyles.astro
+++ b/src/components/GlobalStyles.astro
@@ -88,6 +88,8 @@ color_set({
--codeblock-selection: oklch(0.40 0.08 var(--hue))
--codeblock-bg: oklch(0.2 0.015 var(--hue)) oklch(0.17 0.015 var(--hue))
+ --license-block-bg: black(0.03) var(--codeblock-bg)
+
--link-hover: oklch(0.95 0.025 var(--hue)) oklch(0.40 0.08 var(--hue))
--link-active: oklch(0.90 0.05 var(--hue)) oklch(0.35 0.07 var(--hue))
diff --git a/src/components/misc/License.astro b/src/components/misc/License.astro
new file mode 100644
index 0000000..f5b93ef
--- /dev/null
+++ b/src/components/misc/License.astro
@@ -0,0 +1,47 @@
+---
+import {formatDateToYYYYMMDD} from "../../utils/date-utils";
+interface Props {
+ title: string;
+ slug: string;
+ pubDate: Date;
+ class: string;
+}
+
+const { title, slug, pubDate } = Astro.props;
+const className = Astro.props.class;
+
+import { Icon } from 'astro-icon/components';
+import {licenseConfig, profileConfig} from "../../config";
+import {getFullUrl, getPostUrlBySlug} from "../../utils/url-utils";
+import {i18n} from "../../i18n/translation";
+import I18nKey from "../../i18n/i18nKey";
+
+const profileConf = profileConfig;
+const licenseConf = licenseConfig;
+
+const postUrl = getFullUrl(getPostUrlBySlug(slug));
+
+---
+
+
+ {title}
+
+
+ {postUrl}
+
+
+
+
{i18n(I18nKey.author)}
+
{profileConf.name}
+
+
+
{i18n(I18nKey.publishedAt)}
+
{formatDateToYYYYMMDD(pubDate)}
+
+
+
+
+
\ No newline at end of file
diff --git a/src/config.ts b/src/config.ts
index 04134a3..43b6d96 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -1,10 +1,11 @@
-import type {NavBarConfig, ProfileConfig, SiteConfig} from "./types/config.ts";
+import type {LicenseConfig, NavBarConfig, ProfileConfig, SiteConfig} from "./types/config.ts";
import {LinkPreset} from "./types/config.ts";
export const siteConfig: SiteConfig = {
title: 'Fuwari',
subtitle: 'Demo Site',
- lang: 'en-US',
+ url: 'https://fuwari.vercel.app/',
+ lang: 'en',
themeHue: 250,
banner: {
enable: true,
@@ -44,4 +45,10 @@ export const profileConfig: ProfileConfig = {
url: 'https://github.com/saicaca/fuwari',
}
]
+}
+
+export const licenseConfig: LicenseConfig = {
+ enable: true,
+ name: 'CC BY-NC-SA 4.0',
+ url: 'https://creativecommons.org/licenses/by-nc-sa/4.0/',
}
\ No newline at end of file
diff --git a/src/i18n/i18nKey.ts b/src/i18n/i18nKey.ts
index 991c219..5dd4b60 100644
--- a/src/i18n/i18nKey.ts
+++ b/src/i18n/i18nKey.ts
@@ -23,6 +23,10 @@ enum I18nKey {
primaryColor = "primaryColor",
more = "more",
+
+ author = "author",
+ publishedAt = "publishedAt",
+ license = "license",
}
export default I18nKey;
\ No newline at end of file
diff --git a/src/i18n/languages/en.ts b/src/i18n/languages/en.ts
index c45f0b4..3061f59 100644
--- a/src/i18n/languages/en.ts
+++ b/src/i18n/languages/en.ts
@@ -26,4 +26,8 @@ export const en: Translation = {
[Key.primaryColor]: "Primary Color",
[Key.more]: "More",
+
+ [Key.author]: "Author",
+ [Key.publishedAt]: "Published at",
+ [Key.license]: "License",
};
diff --git a/src/i18n/languages/zh_CN.ts b/src/i18n/languages/zh_CN.ts
index 583111c..3d534dd 100644
--- a/src/i18n/languages/zh_CN.ts
+++ b/src/i18n/languages/zh_CN.ts
@@ -26,4 +26,8 @@ export const zh_CN: Translation = {
[Key.primaryColor]: "主题色",
[Key.more]: "更多",
+
+ [Key.author]: "作者",
+ [Key.publishedAt]: "发布于",
+ [Key.license]: "许可协议",
};
\ No newline at end of file
diff --git a/src/i18n/languages/zh_TW.ts b/src/i18n/languages/zh_TW.ts
index 4e9510b..a16c614 100644
--- a/src/i18n/languages/zh_TW.ts
+++ b/src/i18n/languages/zh_TW.ts
@@ -26,4 +26,8 @@ export const zh_TW: Translation = {
[Key.primaryColor]: "主題色",
[Key.more]: "更多",
+
+ [Key.author]: "作者",
+ [Key.publishedAt]: "發佈於",
+ [Key.license]: "許可協議",
};
diff --git a/src/pages/posts/[slug].astro b/src/pages/posts/[slug].astro
index a91197e..61bd6a9 100644
--- a/src/pages/posts/[slug].astro
+++ b/src/pages/posts/[slug].astro
@@ -8,7 +8,8 @@ import Button from "../../components/control/Button.astro";
import {i18n} from "../../i18n/translation";
import I18nKey from "../../i18n/i18nKey";
import {getPostUrlBySlug} from "../../utils/url-utils";
-import CommentLayout from "../../components/comment/CommentLayout.astro";
+import License from "../../components/misc/License.astro";
+import {licenseConfig} from "../../config";
export async function getStaticPaths() {
const blogEntries = await getCollection('posts');
@@ -25,7 +26,7 @@ const { remarkPluginFrontmatter } = await entry.render();
---
-
@@ -73,13 +74,15 @@ const { remarkPluginFrontmatter } = await entry.render();
{!entry.data.image &&
}
-
+ {licenseConfig.enable &&
}
+
@@ -183,7 +186,7 @@ const { remarkPluginFrontmatter } = await entry.render();
&:after
content: none
img
- border-radius: 8px
+ border-radius: 12px
hr
border-color: var(--line-divider)
border-style: dashed
diff --git a/src/types/config.ts b/src/types/config.ts
index 96c3061..18a2844 100644
--- a/src/types/config.ts
+++ b/src/types/config.ts
@@ -1,6 +1,7 @@
export type SiteConfig = {
title: string,
subtitle: string,
+ url: string,
lang: string,
@@ -36,4 +37,10 @@ export type ProfileConfig = {
url: string,
icon: string,
}[],
-};
\ No newline at end of file
+};
+
+export type LicenseConfig = {
+ enable: boolean;
+ name: string,
+ url: string,
+}
\ No newline at end of file
diff --git a/src/utils/url-utils.ts b/src/utils/url-utils.ts
index fdbbe3f..0404a93 100644
--- a/src/utils/url-utils.ts
+++ b/src/utils/url-utils.ts
@@ -1,9 +1,16 @@
+import {siteConfig} from "../config.ts";
+
export function pathsEqual(path1: string, path2: string) {
const normalizedPath1 = path1.replace(/^\/|\/$/g, '').toLowerCase();
const normalizedPath2 = path2.replace(/^\/|\/$/g, '').toLowerCase();
return normalizedPath1 === normalizedPath2;
}
+function joinUrl(...parts: string[]): string {
+ const joined = parts.join('/');
+ return joined.replace(/([^:]\/)\/+/g, '$1');
+}
+
export function getPostUrlBySlug(slug: string): string | null {
if (!slug)
return null;
@@ -16,3 +23,6 @@ export function getCategoryUrl(category: string): string | null {
return `/archive/category/${category}`;
}
+export function getFullUrl(path: string): string {
+ return joinUrl(siteConfig.url, path);
+}
\ No newline at end of file