Tip

  • giscus 是一个用于博客评论的工具,原理是通过借用 github 中的 discussion 区域进行评论的发布和存储
  • 在 quartz 中需要进行 quartz插件的编写,支持深色模式自动切换,相关代码在下文已给出

自定义 Comments 组件代码如下所示:

// quartz/components/Comments.tsx
import commentsScript from "./scripts/comments.inline"
import { QuartzComponentConstructor, QuartzComponent, QuartzComponentProps } from "./types"
 
const Comment: QuartzComponent = ({ displayClass, cfg }: QuartzComponentProps) => {
 
  return (
    <script src="https://giscus.app/client.js"
      data-repo="odd256/odd256.github.io"
      data-repo-id="R_kgDOLX95UQ"
      data-category="Announcements"
      data-category-id="DIC_kwDOLX95Uc4CdlNe"
      data-mapping="pathname"
      data-strict="0"
      data-reactions-enabled="1"
      data-emit-metadata="0"
      data-input-position="top"
      data-theme="light"
      data-lang="zh-CN"
      data-loading="lazy"
      crossorigin="anonymous"
      async>
    </script>
  )
}
 
Comment.beforeDOMLoaded = commentsScript
export default (() => Comment) satisfies QuartzComponentConstructor
// quartz/components/scripts/comments.inline.ts
// 为了实现动态颜色切换,必须重构部分样式
function sendMessage(message: { setConfig: { theme: string } }) {
    const iframe = document.querySelector('iframe.giscus-frame') as HTMLIFrameElement;
    if (!iframe) return;
    iframe.contentWindow?.postMessage({ giscus: message }, 'https://giscus.app');
}
document.addEventListener("themechange", (e) => {
    const theme = e.detail.theme === 'light' ? 'light' : 'dark'
 
    sendMessage({
        setConfig: {
            theme: theme
        }
    });
})
 
// first-time loaded
document.addEventListener("DOMContentLoaded", () => {
    const userPref = window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark"
    const currentTheme = localStorage.getItem("theme") ?? userPref
    if (currentTheme === "dark") {return} // default is dark theme
  
    const theme = currentTheme === "light" ? "light_protanopia" : "dark_protanopia"
  
    const existingGiscusContainer = document.getElementById('giscus-container');
  
    if (existingGiscusContainer) {
      // Remove the existing Giscus instance
      existingGiscusContainer.innerHTML = '';
    }
  
    // Create a new container element for Giscus
    const newGiscusContainer = document.createElement('div');
    newGiscusContainer.id = 'giscus-container';
    document.body.appendChild(newGiscusContainer);
    
    // Create a new script element with the updated data-theme attribute
    const newScript = document.createElement('script');
    newScript.src = 'https://giscus.app/client.js';
    newScript.setAttribute('data-repo', 'odd256/odd256.github.io');
    newScript.setAttribute('data-repo-id', 'R_kgDOLX95UQ');
    newScript.setAttribute('data-category', 'Announcements');
    newScript.setAttribute('data-category-id', 'DIC_kwDOLX95Uc4CdlNe');
    newScript.setAttribute('data-mapping', 'pathname');
    newScript.setAttribute('data-strict', '0');
    newScript.setAttribute('data-reactions-enabled', '1');
    newScript.setAttribute('data-emit-metadata', '0');
    newScript.setAttribute('data-input-position', 'top');
    newScript.setAttribute('data-theme', theme);
    newScript.setAttribute('data-lang', 'zh-CN');
    newScript.setAttribute('data-loading', 'lazy');
    newScript.setAttribute('crossOrigin', 'anonymous');
    newScript.async = true;
  
    // Append the new script to the Giscus container
    newGiscusContainer.appendChild(newScript);
  })

最后在 quartz.layout.ts 文件中添加自定义的 Comments 组件即可