feat(comments): 添加 Waline 评论组件,替换 Giscus 评论组件

This commit is contained in:
joyzhao
2026-01-12 09:46:29 +08:00
parent 1952f4de64
commit ca9e083399
6 changed files with 306 additions and 56 deletions

View File

@@ -0,0 +1,61 @@
import { useEffect, useRef } from 'react';
import type { WalineInstance, WalineInitOptions } from '@waline/client';
import { init } from '@waline/client';
import '@waline/client/style';
import type { Lang } from '@/types/i18n';
export type CommentsProps = Partial<Omit<WalineInitOptions, 'el' | 'serverURL'>> & { lang?: Lang };
export default function Comments({ lang = 'en', ...props }: CommentsProps) {
const walineInstanceRef = useRef<WalineInstance | null>(null);
const containerRef = useRef<HTMLDivElement>(null);
const walineLang = lang === 'zh' ? 'zh-CN' : 'en';
useEffect(() => {
if (!containerRef.current) return;
const getTheme = () => document.documentElement.classList.contains('dark') ? 'html.dark' : false;
const pathname = window.location.pathname;
const postsMatch = pathname.match(/\/posts\/([^/]+)/);
const path = postsMatch ? postsMatch[1] : pathname;
walineInstanceRef.current = init({
...props,
el: containerRef.current,
serverURL: import.meta.env.PUBLIC_WALINE_SERVER_URL,
lang: walineLang,
dark: getTheme(),
path,
});
return () => walineInstanceRef.current?.destroy();
}, []);
useEffect(() => {
const getTheme = () => document.documentElement.classList.contains('dark') ? 'html.dark' : false;
walineInstanceRef.current?.update({
...props,
lang: walineLang,
dark: getTheme(),
});
const handleThemeChange = () => {
walineInstanceRef.current?.update({
...props,
lang: walineLang,
dark: getTheme(),
});
};
const observer = new MutationObserver(handleThemeChange);
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
return () => observer.disconnect();
}, [lang, props, walineLang]);
return <div ref={containerRef} className="waline-container" />;
}