feat: 添加并改用 commento 评论。
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Ivan Li 2022-10-07 22:04:38 +08:00
parent eee38148ee
commit ca5eb7cd5e
9 changed files with 130 additions and 2 deletions

View File

@ -6,6 +6,7 @@ NEXT_PUBLIC_UTTERANCES_REPO=
NEXT_PUBLIC_DISQUS_SHORTNAME= NEXT_PUBLIC_DISQUS_SHORTNAME=
NEXT_PUBLIC_CUSDIS_APPID= NEXT_PUBLIC_CUSDIS_APPID=
NEXT_PUBLIC_CUSDIS_HOST= NEXT_PUBLIC_CUSDIS_HOST=
NEXT_PUBLIC_COMMENTO_URL=
MAILCHIMP_API_KEY= MAILCHIMP_API_KEY=

View File

@ -2,6 +2,7 @@
"cSpell.words": [ "cSpell.words": [
"alpn", "alpn",
"blackhole", "blackhole",
"Commento",
"Cusdis", "Cusdis",
"Disqus", "Disqus",
"dokodemo", "dokodemo",

View File

@ -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 (
<div className="my-2">
<ReactCommento url={siteMetadata.comment.commentoConfig.url} pageId={frontMatter.slug} />
</div>
)
}
export default Commento

View File

@ -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<HTMLDivElement>()
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 <div ref={container} id={containerId} />
}
export default ReactCommento

View File

@ -32,6 +32,12 @@ const CusdisComponent = dynamic(
}, },
{ ssr: false } { ssr: false }
) )
const CommentoComponent = dynamic(
() => {
return import('@/components/comments/Commento')
},
{ ssr: false }
)
const Comments = ({ frontMatter }: Props) => { const Comments = ({ frontMatter }: Props) => {
let term let term
@ -63,6 +69,9 @@ const Comments = ({ frontMatter }: Props) => {
{siteMetadata.comment && siteMetadata.comment.provider === 'cusdis' && ( {siteMetadata.comment && siteMetadata.comment.provider === 'cusdis' && (
<CusdisComponent frontMatter={frontMatter} /> <CusdisComponent frontMatter={frontMatter} />
)} )}
{siteMetadata.comment && siteMetadata.comment.provider === 'commento' && (
<CommentoComponent frontMatter={frontMatter} />
)}
</div> </div>
) )
} }

View File

@ -40,7 +40,7 @@ const siteMetadata = {
// content security policy in the `next.config.js` file. // content security policy in the `next.config.js` file.
// Select a provider and use the environment variables associated to it // Select a provider and use the environment variables associated to it
// https://vercel.com/docs/environment-variables // https://vercel.com/docs/environment-variables
provider: 'cusdis', // supported providers: giscus, utterances, disqus provider: 'commento', // supported providers: giscus, utterances, disqus
giscusConfig: { giscusConfig: {
// Visit the link below, and follow the steps in the 'configuration' section // Visit the link below, and follow the steps in the 'configuration' section
// https://giscus.app/ // https://giscus.app/
@ -82,6 +82,9 @@ const siteMetadata = {
appId: process.env.NEXT_PUBLIC_CUSDIS_APPID, appId: process.env.NEXT_PUBLIC_CUSDIS_APPID,
host: process.env.NEXT_PUBLIC_CUSDIS_HOST, host: process.env.NEXT_PUBLIC_CUSDIS_HOST,
}, },
commentoConfig: {
url: process.env.NEXT_PUBLIC_COMMENTO_URL,
},
}, },
} }

View File

@ -10,7 +10,7 @@ const ContentSecurityPolicy = `
img-src * blob: data:; img-src * blob: data:;
media-src 'none'; media-src 'none';
connect-src *; connect-src *;
font-src 'self'; font-src 'self' comment.ivanli.cc;
frame-src giscus.app comment.ivanli.cc frame-src giscus.app comment.ivanli.cc
` `

BIN
package-lock.json generated

Binary file not shown.

View File

@ -27,6 +27,7 @@
"postcss": "^8.4.17", "postcss": "^8.4.17",
"preact": "^10.11.1", "preact": "^10.11.1",
"react": "18.2.0", "react": "18.2.0",
"react-commento": "^1.0.0",
"react-cusdis": "^2.1.3", "react-cusdis": "^2.1.3",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"reading-time": "1.5.0", "reading-time": "1.5.0",