From ca5eb7cd5ea441233bd157100de359c201224849 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Fri, 7 Oct 2022 22:04:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=B9=B6=E6=94=B9?= =?UTF-8?q?=E7=94=A8=20commento=20=E8=AF=84=E8=AE=BA=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 1 + .vscode/settings.json | 1 + components/comments/Commento.tsx | 30 +++++++ .../comments/commento/ReactCommento.tsx | 83 ++++++++++++++++++ components/comments/index.tsx | 9 ++ data/siteMetadata.js | 5 +- next.config.js | 2 +- package-lock.json | Bin 912189 -> 913684 bytes package.json | 1 + 9 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 components/comments/Commento.tsx create mode 100644 components/comments/commento/ReactCommento.tsx diff --git a/.env.example b/.env.example index 97ce54d..ede613c 100644 --- a/.env.example +++ b/.env.example @@ -6,6 +6,7 @@ NEXT_PUBLIC_UTTERANCES_REPO= NEXT_PUBLIC_DISQUS_SHORTNAME= NEXT_PUBLIC_CUSDIS_APPID= NEXT_PUBLIC_CUSDIS_HOST= +NEXT_PUBLIC_COMMENTO_URL= MAILCHIMP_API_KEY= diff --git a/.vscode/settings.json b/.vscode/settings.json index bb6031b..83cf3ff 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,7 @@ "cSpell.words": [ "alpn", "blackhole", + "Commento", "Cusdis", "Disqus", "dokodemo", diff --git a/components/comments/Commento.tsx b/components/comments/Commento.tsx new file mode 100644 index 0000000..51ebbd9 --- /dev/null +++ b/components/comments/Commento.tsx @@ -0,0 +1,30 @@ +import React, { useMemo, useState } from 'react' + +import siteMetadata from '@/data/siteMetadata' +import { PostFrontMatter } from 'types/PostFrontMatter' +import { useTheme } from 'next-themes' +import ReactCommento from './commento/ReactCommento' + +interface Props { + frontMatter: PostFrontMatter +} + +const Commento = ({ frontMatter }: Props) => { + const { resolvedTheme } = useTheme() + const commentsTheme = useMemo(() => { + switch (resolvedTheme) { + case 'light': + case 'dark': + return resolvedTheme + default: + return 'auto' + } + }, [resolvedTheme]) + return ( +
+ +
+ ) +} + +export default Commento diff --git a/components/comments/commento/ReactCommento.tsx b/components/comments/commento/ReactCommento.tsx new file mode 100644 index 0000000..227bcf0 --- /dev/null +++ b/components/comments/commento/ReactCommento.tsx @@ -0,0 +1,83 @@ +import { createRef } from 'preact' +import React, { useLayoutEffect, useMemo, useRef } from 'react' + +interface DataAttributes { + [key: string]: string | boolean | undefined +} + +const insertScript = ( + src: string, + id: string, + dataAttributes: DataAttributes, + onload = () => {} +) => { + const script = window.document.createElement('script') + script.async = true + script.src = src + script.id = id + console.log(document.getElementById(id)) + if (document.getElementById(id)) { + return + } + script.addEventListener('load', onload, { capture: true, once: true }) + + Object.entries(dataAttributes).forEach(([key, value]) => { + if (value === undefined) { + return + } + script.setAttribute(`data-${key}`, value.toString()) + }) + + document.body.appendChild(script) + + return () => { + script.remove() + } +} + +const ReactCommento = ({ + url, + cssOverride, + autoInit, + noFonts, + hideDeleted, + pageId, +}: { + url: string + cssOverride?: string + autoInit?: boolean + noFonts?: boolean + hideDeleted?: boolean + pageId?: string +}) => { + const containerId = useMemo(() => `commento-${Math.random().toString().slice(2, 8)}`, []) + const container = createRef() + const initializing = useRef(false) + + useLayoutEffect(() => { + if (!window) { + return + } + + window['commento'] = container.current + + const removeScript = insertScript( + url, + `${containerId}-script`, + { + 'css-override': cssOverride, + 'auto-init': autoInit, + 'no-fonts': noFonts, + 'hide-deleted': hideDeleted, + 'page-id': pageId, + 'id-root': containerId, + }, + () => { + removeScript() + } + ) + }, [autoInit, cssOverride, hideDeleted, noFonts, pageId, url, containerId, container]) + + return
+} +export default ReactCommento diff --git a/components/comments/index.tsx b/components/comments/index.tsx index 9e30231..8d59051 100644 --- a/components/comments/index.tsx +++ b/components/comments/index.tsx @@ -32,6 +32,12 @@ const CusdisComponent = dynamic( }, { ssr: false } ) +const CommentoComponent = dynamic( + () => { + return import('@/components/comments/Commento') + }, + { ssr: false } +) const Comments = ({ frontMatter }: Props) => { let term @@ -63,6 +69,9 @@ const Comments = ({ frontMatter }: Props) => { {siteMetadata.comment && siteMetadata.comment.provider === 'cusdis' && ( )} + {siteMetadata.comment && siteMetadata.comment.provider === 'commento' && ( + + )}
) } diff --git a/data/siteMetadata.js b/data/siteMetadata.js index 6a7eb5e..9edd783 100644 --- a/data/siteMetadata.js +++ b/data/siteMetadata.js @@ -40,7 +40,7 @@ const siteMetadata = { // content security policy in the `next.config.js` file. // Select a provider and use the environment variables associated to it // https://vercel.com/docs/environment-variables - provider: 'cusdis', // supported providers: giscus, utterances, disqus + provider: 'commento', // supported providers: giscus, utterances, disqus giscusConfig: { // Visit the link below, and follow the steps in the 'configuration' section // https://giscus.app/ @@ -82,6 +82,9 @@ const siteMetadata = { appId: process.env.NEXT_PUBLIC_CUSDIS_APPID, host: process.env.NEXT_PUBLIC_CUSDIS_HOST, }, + commentoConfig: { + url: process.env.NEXT_PUBLIC_COMMENTO_URL, + }, }, } diff --git a/next.config.js b/next.config.js index 225c42a..cb1522a 100644 --- a/next.config.js +++ b/next.config.js @@ -10,7 +10,7 @@ const ContentSecurityPolicy = ` img-src * blob: data:; media-src 'none'; connect-src *; - font-src 'self'; + font-src 'self' comment.ivanli.cc; frame-src giscus.app comment.ivanli.cc ` diff --git a/package-lock.json b/package-lock.json index b56132e62cbf0026703630f6573c589addcd78cb..d987b0530e1aa9c6a0b7a248f90e60b50ee78069 100644 GIT binary patch delta 863 zcmdmc&3wuu^9`Sv*zGIJ`n$!FDva)UO*vV=XH9a7oNn-l@4xaq!7yh#HO+PHcCOrL^2b=ix4~N*z zrtk0MS+hM)lub&I4Pw#siw4{h(=TWP<>FP@SfzB6p$^d3)h|j-OfG>7OrJQLTO(9E zxXjfh(eJWDvU5&%=;V=`e!!27 zpBLF~{ptTz*tD3<^bDszoXcVYawKgi3(Co{#% zKiN1b)HS#~H`HRfV?L8QC?JKWXU*i{pYChG%RXKIG$+q=DG@e->D+l-LX2k9Cz>%D zL!#h=Ivd;ab~QGZ>8=_qQtex`*npTFh&h0m6NtHhn0xycEgnUw>4n}r!rOnl@SJv@ zo~OVmwjF3q0^gvDk&hCb%HSAbi!%fUyYcjehdA{>0vyv>PjX1Gf&@*bKg{DYM?{80 z7pG@60tkb7jF@s{G@HmI$^!b*Y WqT4;D^LQ|~FP_D-eeo>bSpfjauOJlw delta 174 zcmbR8$b9cL^9`Svn#Gvg#h4j^m+4#06h_I;%ZC|g+_MdtBR%T9x=@XpT_}fqEvH>wW z5OV-AClGT1G57XUx;*ky)0b8=DQy4d&U4Xux_$