From 79f5fcf9476e216627dc202876b74db07c62335e Mon Sep 17 00:00:00 2001 From: grassblock Date: Sun, 4 May 2025 12:19:54 +0800 Subject: [PATCH 1/4] chore: remove sample posts --- src/pages/post/[...slug].astro | 52 ++-------------------------------- 1 file changed, 3 insertions(+), 49 deletions(-) diff --git a/src/pages/post/[...slug].astro b/src/pages/post/[...slug].astro index 2826d2d..60f2b7c 100644 --- a/src/pages/post/[...slug].astro +++ b/src/pages/post/[...slug].astro @@ -12,66 +12,20 @@ export async function getStaticPaths() { const { entry } = Astro.props; const { Content } = await entry.render(); -// Sample content for demo purposes if no actual content collection is set up -const samplePosts = { - 'terminal-setup': { - title: 'My Terminal Setup', - date: '2025-06-08', - content: ` -

Here's my current terminal setup:

- -

I've been using this setup for about a year now and it's been working great for me.

- ` - }, - 'minimalism': { - title: 'The Art of Minimalism', - date: '2025-06-05', - content: ` -

Minimalism isn't just about having less, it's about making room for what matters.

-

In code, this means writing clean, maintainable code that does exactly what it needs to do, nothing more, nothing less.

-

This terminal blog is an exercise in digital minimalism - stripping away the unnecessary to focus on what's important: the content.

- ` - }, - 'first-post': { - title: 'First Post', - date: '2025-06-01', - content: ` -

Hello world! This is the first post on my new terminal blog.

-

I built this blog using Astro and vanilla CSS/JS to create a terminal-like experience.

-

More posts coming soon...

- ` - } -}; - const slug = Astro.params.slug; --- - {entry ? ( - <>

{entry.data.title}

- - ) : ( - <> -

{samplePosts[slug]?.title}

- -
- - )} - -
+ +
← Back to posts
\ No newline at end of file From 17f095239ce56a28dd42c5521bef13f866b81bc4 Mon Sep 17 00:00:00 2001 From: grassblock Date: Sun, 4 May 2025 12:21:06 +0800 Subject: [PATCH 2/4] chore: remove sample index --- src/pages/index.astro | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/src/pages/index.astro b/src/pages/index.astro index f17335b..8055825 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,33 +1,14 @@ --- import Layout from '../layouts/Layout.astro'; + --- -

~/home

+

~/

-

A random grassblock do some some writing work.

-

Welcome to my terminal blog. Navigate using the links above.

- -
- ls -la -
-

drwxr-xr-x 3 user group 96 Jun 8 15:42 .

-

drwxr-xr-x 15 user group 480 Jun 8 14:22 ..

-

-rw-r--r-- 1 user group 283 Jun 8 15:42 about.md

-

-rw-r--r-- 1 user group 148 Jun 8 15:40 projects.md

-

-rw-r--r-- 1 user group 892 Jun 8 15:35 notes.md

-
-
- -
- cat about.md -
-

- I'm a developer who enjoys minimalist design and terminal aesthetics. - This blog is a collection of my thoughts, projects, and experiments. -

-
-
+ Not much here yet, but you can check out my blog posts here. +
+ If you are site owner, please edit src/pages/index.astro to customize this page.
\ No newline at end of file From c09bb95eaa964d6c7fd277925b5a9e1191ee498b Mon Sep 17 00:00:00 2001 From: grassblock Date: Wed, 7 May 2025 16:15:48 +0800 Subject: [PATCH 3/4] feat: add comments section --- src/components/Comments.astro | 48 ++++++++++++++++++++++++++++++++++ src/config.ts | 37 ++++++++++++++++++++++++++ src/pages/post/[...slug].astro | 6 ++++- 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 src/components/Comments.astro diff --git a/src/components/Comments.astro b/src/components/Comments.astro new file mode 100644 index 0000000..8977e72 --- /dev/null +++ b/src/components/Comments.astro @@ -0,0 +1,48 @@ +--- +import {siteConfig} from "../config"; +const method = siteConfig.comments.type +const ArtalkConfig = siteConfig.comments.artalk +const giscusConfig = siteConfig.comments.giscus +interface Props { + path?: string; +} + +const { path='/' } = Astro.props; +--- +{method === 'artalk' && +
+ + + + + + + +
+ +
+} +{method === 'giscus' && ( + +)} \ No newline at end of file diff --git a/src/config.ts b/src/config.ts index dcfe039..a0d1c00 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,4 +1,41 @@ export const siteConfig = { title: '/var/log/mercury', description: 'A blog about software development, technology, and life.', + comments: { + type: 'artalk', // 'artalk','giscus','fediverse','hatsu' + artalk: { + instanceDomain: '', // the domain of your artalk instance + }, + giscus: { + // get these params from giscus.app + repo:"[ENTER REPO HERE]", + repoId: "[ENTER REPO ID HERE]", + category:"[ENTER CATEGORY NAME HERE]", + categoryId:"[ENTER CATEGORY ID HERE]", + mapping:"pathname", + strict:"0", + reactionsEnabled:"1", + emitMetadata:"0", + inputPosition:"bottom", + theme:"preferred_color_scheme", + lang:"en" + }, + // WIP + fediverse: { + // use Mastodon (compatible) api to search posts and parse replies + // it will search for the post's link by default + instanceDomain: '', // the domain of the fediverse instance to search posts from + useV2api: false, // use /api/v2/search instead of /api/v1/search to search on instance using newer version of mastodon + token: process.env.MASTODON_API_TOKEN, // the token to use to authenticate with the fediverse instance, usually a read:search-only token + // or use a reverse proxy api to return posts on instance, useful if you publish the site in SSG mode. + // the instanceDomain and token will be ignored if useReverseProxy is true and reverseProxyUrl is used. + useReverseProxy: false, + reverseProxyUrl: '', // the url of the reverse proxy, usually a cloudflare worker proxying the search api + accountId: '' // the account id to search posts from, can be got from api like: https://{instance}/api/v1/accounts/{username without domain part} + }, + hatsu: { + // use hatsu.cli.rs to get replies from the fediverse + instanceDomain: '', + } + } } \ No newline at end of file diff --git a/src/pages/post/[...slug].astro b/src/pages/post/[...slug].astro index 60f2b7c..aa8a993 100644 --- a/src/pages/post/[...slug].astro +++ b/src/pages/post/[...slug].astro @@ -1,6 +1,7 @@ --- import Layout from '../../layouts/Layout.astro'; import { getCollection } from 'astro:content'; +import Comments from "../../components/Comments.astro"; export async function getStaticPaths() { const blogEntries = await getCollection('posts'); @@ -15,7 +16,7 @@ const { Content } = await entry.render(); const slug = Astro.params.slug; --- - @@ -26,6 +27,9 @@ const slug = Astro.params.slug;
+

Comments

+ ← Back to posts
+
\ No newline at end of file From f571670e13daa179f3644de2e61e907ca7e59230 Mon Sep 17 00:00:00 2001 From: grassblock Date: Wed, 7 May 2025 18:26:08 +0800 Subject: [PATCH 4/4] feat: implement Fediverse comments integration --- src/components/Comments.astro | 7 +- .../helper/comments/Fediverse.astro | 249 ++++++++++++++++++ src/config.ts | 22 +- 3 files changed, 268 insertions(+), 10 deletions(-) create mode 100644 src/components/helper/comments/Fediverse.astro diff --git a/src/components/Comments.astro b/src/components/Comments.astro index 8977e72..694dbea 100644 --- a/src/components/Comments.astro +++ b/src/components/Comments.astro @@ -1,5 +1,7 @@ --- import {siteConfig} from "../config"; +import FediverseComments from "./helper/comments/Fediverse.astro"; + const method = siteConfig.comments.type const ArtalkConfig = siteConfig.comments.artalk const giscusConfig = siteConfig.comments.giscus @@ -7,7 +9,7 @@ interface Props { path?: string; } -const { path='/' } = Astro.props; +let { path='/' } = Astro.props; --- {method === 'artalk' &&
@@ -45,4 +47,5 @@ const { path='/' } = Astro.props; crossorigin="anonymous" async > -)} \ No newline at end of file +)} +{method === 'fediverse' && } \ No newline at end of file diff --git a/src/components/helper/comments/Fediverse.astro b/src/components/helper/comments/Fediverse.astro new file mode 100644 index 0000000..9b1017c --- /dev/null +++ b/src/components/helper/comments/Fediverse.astro @@ -0,0 +1,249 @@ +--- + import { siteConfig } from "../../../config"; + + const fediverseConfig = siteConfig.comments.fediverse; + const { + instanceDomain, + useV2api, + token, + useReverseProxy, + reverseProxyUrl, + accountId + } = fediverseConfig; + + interface Props { + path: string; + } + + const { path } = Astro.props; + + // Create the full URL to search for + const fullSiteUrl = Astro.url.host; + const postUrl = `https://${fullSiteUrl}${path.startsWith('/') ? path : '/' + path}`; + + // Define the search API endpoint based on configuration + let searchEndpoint; + if (useReverseProxy && reverseProxyUrl) { + searchEndpoint = reverseProxyUrl; + } else { + const apiVersion = useV2api ? 'v2' : 'v1'; + searchEndpoint = `https://${instanceDomain}/api/${apiVersion}/search`; + } + --- + +
+
+
Loading comments from the Fediverse...
+ + +
+
+
+ + + + \ No newline at end of file diff --git a/src/config.ts b/src/config.ts index a0d1c00..0dbf2b0 100644 --- a/src/config.ts +++ b/src/config.ts @@ -2,7 +2,7 @@ export const siteConfig = { title: '/var/log/mercury', description: 'A blog about software development, technology, and life.', comments: { - type: 'artalk', // 'artalk','giscus','fediverse','hatsu' + type: 'fediverse', // 'artalk','giscus','fediverse','hatsu' artalk: { instanceDomain: '', // the domain of your artalk instance }, @@ -24,14 +24,20 @@ export const siteConfig = { fediverse: { // use Mastodon (compatible) api to search posts and parse replies // it will search for the post's link by default - instanceDomain: '', // the domain of the fediverse instance to search posts from - useV2api: false, // use /api/v2/search instead of /api/v1/search to search on instance using newer version of mastodon - token: process.env.MASTODON_API_TOKEN, // the token to use to authenticate with the fediverse instance, usually a read:search-only token - // or use a reverse proxy api to return posts on instance, useful if you publish the site in SSG mode. - // the instanceDomain and token will be ignored if useReverseProxy is true and reverseProxyUrl is used. - useReverseProxy: false, + // the comments are rendered at the client side (by now) + // a reverse proxy is required in pure client-side rendering mode to get the posts from the fediverse instance + useReverseProxy: true, reverseProxyUrl: '', // the url of the reverse proxy, usually a cloudflare worker proxying the search api - accountId: '' // the account id to search posts from, can be got from api like: https://{instance}/api/v1/accounts/{username without domain part} + // the reverse proxy should be able to handle the following request: + // GET /api/v1/search?q={query}&type=statuses&account_id=12345678 + // GET /api/v1/statuses/12345678/context + // response body should be returned from the origin fediverse instance as-is. + accountId: '', // the account id to search posts from, can be got from api like: https://{instance}/api/v1/accounts/{username without domain part} + // for development purpose only (by now): + // TODO: render the comments on the server-side when in server-side render/hybrid render mode + instanceDomain: '', // the domain of the fediverse instance to search posts from + useV2api: true, // use /api/v2/search instead of /api/v1/search to search on instance using newer version of mastodon/pleroma/akkoma + token: process.env.MASTODON_API_TOKEN, // the token to use to authenticate with the fediverse instance, usually a read:search-only token }, hatsu: { // use hatsu.cli.rs to get replies from the fediverse