feat: add support for giscus, utterances, disqus
This commit is contained in:
parent
5cd4d89f98
commit
6b90542652
37
components/comments/Disqus.js
Normal file
37
components/comments/Disqus.js
Normal file
@ -0,0 +1,37 @@
|
||||
import React, { useState } from 'react'
|
||||
|
||||
import siteMetadata from '@/data/siteMetadata'
|
||||
|
||||
const Disqus = ({ frontMatter }) => {
|
||||
const [enableLoadComments, setEnabledLoadComments] = useState(true)
|
||||
|
||||
const COMMENTS_ID = 'disqus_thread'
|
||||
|
||||
function LoadComments() {
|
||||
setEnabledLoadComments(false)
|
||||
|
||||
window.disqus_config = function () {
|
||||
this.page.url = window.location.href
|
||||
this.page.identifier = frontMatter.slug
|
||||
}
|
||||
if (window.DISQUS === undefined) {
|
||||
const script = document.createElement('script')
|
||||
script.src = 'https://' + siteMetadata.comment.disqus.shortname + '.disqus.com/embed.js'
|
||||
script.setAttribute('data-timestamp', +new Date())
|
||||
script.setAttribute('crossorigin', 'anonymous')
|
||||
script.async = true
|
||||
document.body.appendChild(script)
|
||||
} else {
|
||||
window.DISQUS.reset({ reload: true })
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="pt-6 pb-6 text-center text-gray-700 dark:text-gray-300">
|
||||
{enableLoadComments && <button onClick={LoadComments}>Load Comments</button>}
|
||||
<div className="disqus-frame" id={COMMENTS_ID} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Disqus
|
49
components/comments/Giscus.js
Normal file
49
components/comments/Giscus.js
Normal file
@ -0,0 +1,49 @@
|
||||
import React, { useState } from 'react'
|
||||
|
||||
import siteMetadata from '@/data/siteMetadata'
|
||||
|
||||
const Giscus = ({ mapping }) => {
|
||||
const [enableLoadComments, setEnabledLoadComments] = useState(true)
|
||||
|
||||
const COMMENTS_ID = 'comments-container'
|
||||
|
||||
function LoadComments() {
|
||||
setEnabledLoadComments(false)
|
||||
const script = document.createElement('script')
|
||||
script.src = 'https://giscus.app/client.js'
|
||||
script.setAttribute('data-repo', siteMetadata.comment.giscusConfig.repo)
|
||||
script.setAttribute('data-repo-id', siteMetadata.comment.giscusConfig.repositoryId)
|
||||
script.setAttribute('data-category', siteMetadata.comment.giscusConfig.category)
|
||||
script.setAttribute('data-category-id', siteMetadata.comment.giscusConfig.categoryId)
|
||||
script.setAttribute('data-mapping', mapping)
|
||||
script.setAttribute('data-reactions-enabled', siteMetadata.comment.giscusConfig.reactions)
|
||||
script.setAttribute('data-emit-metadata', siteMetadata.comment.giscusConfig.metadata)
|
||||
script.setAttribute(
|
||||
'data-theme',
|
||||
`${
|
||||
siteMetadata.comment.giscusConfig.themeURL === ''
|
||||
? siteMetadata.comment.giscusConfig.theme
|
||||
: siteMetadata.comment.giscusConfig.themeURL
|
||||
}`
|
||||
)
|
||||
script.setAttribute('crossorigin', 'anonymous')
|
||||
script.async = true
|
||||
|
||||
const comments = document.getElementById(COMMENTS_ID)
|
||||
if (comments) comments.appendChild(script)
|
||||
|
||||
return () => {
|
||||
const comments = document.getElementById(COMMENTS_ID)
|
||||
if (comments) comments.innerHTML = ''
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="pt-6 pb-6 text-center text-gray-700 dark:text-gray-300">
|
||||
{enableLoadComments && <button onClick={LoadComments}>Load Comments</button>}
|
||||
<div className="giscus-frame" id={COMMENTS_ID} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Giscus
|
39
components/comments/Utterances.js
Normal file
39
components/comments/Utterances.js
Normal file
@ -0,0 +1,39 @@
|
||||
import React, { useState } from 'react'
|
||||
|
||||
import siteMetadata from '@/data/siteMetadata'
|
||||
|
||||
const Utterances = ({ issueTerm }) => {
|
||||
const [enableLoadComments, setEnabledLoadComments] = useState(true)
|
||||
|
||||
const COMMENTS_ID = 'comments-container'
|
||||
|
||||
function LoadComments() {
|
||||
setEnabledLoadComments(false)
|
||||
const script = document.createElement('script')
|
||||
script.src = 'https://utteranc.es/client.js'
|
||||
script.setAttribute('repo', siteMetadata.comment.utterancesConfig.repo)
|
||||
script.setAttribute('issue-term', issueTerm)
|
||||
script.setAttribute('label', siteMetadata.comment.utterancesConfig.label)
|
||||
script.setAttribute('theme', siteMetadata.comment.utterancesConfig.theme)
|
||||
script.setAttribute('crossorigin', 'anonymous')
|
||||
script.async = true
|
||||
|
||||
const comments = document.getElementById(COMMENTS_ID)
|
||||
if (comments) comments.appendChild(script)
|
||||
|
||||
return () => {
|
||||
const comments = document.getElementById(COMMENTS_ID)
|
||||
if (comments) comments.innerHTML = ''
|
||||
}
|
||||
}
|
||||
|
||||
// Added `relative` to fix a weird bug with `utterances-frame` position
|
||||
return (
|
||||
<div className="pt-6 pb-6 text-center text-gray-700 dark:text-gray-300">
|
||||
{enableLoadComments && <button onClick={LoadComments}>Load Comments</button>}
|
||||
<div className="utterances-frame relative" id={COMMENTS_ID} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Utterances
|
54
components/comments/index.js
Normal file
54
components/comments/index.js
Normal file
@ -0,0 +1,54 @@
|
||||
import siteMetadata from '@/data/siteMetadata'
|
||||
import dynamic from 'next/dynamic'
|
||||
|
||||
const UtterancesComponent = dynamic(
|
||||
() => {
|
||||
return import('@/components/comments/Utterances')
|
||||
},
|
||||
{ ssr: false }
|
||||
)
|
||||
const GiscusComponent = dynamic(
|
||||
() => {
|
||||
return import('@/components/comments/Giscus')
|
||||
},
|
||||
{ ssr: false }
|
||||
)
|
||||
const DisqusComponent = dynamic(
|
||||
() => {
|
||||
return import('@/components/comments/Disqus')
|
||||
},
|
||||
{ ssr: false }
|
||||
)
|
||||
|
||||
const Comments = ({ frontMatter }) => {
|
||||
let term
|
||||
switch (
|
||||
siteMetadata.comment.giscusConfig.mapping ||
|
||||
siteMetadata.comment.utterancesConfig.issueTerm
|
||||
) {
|
||||
case 'pathname':
|
||||
term = frontMatter.slug
|
||||
break
|
||||
case 'url':
|
||||
term = window.location.href
|
||||
break
|
||||
case 'title':
|
||||
term = frontMatter.title
|
||||
break
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{siteMetadata.comment && siteMetadata.comment.provider === 'giscus' && (
|
||||
<GiscusComponent mapping={term} />
|
||||
)}
|
||||
{siteMetadata.comment && siteMetadata.comment.provider === 'utterances' && (
|
||||
<UtterancesComponent issueTerm={term} />
|
||||
)}
|
||||
{siteMetadata.comment && siteMetadata.comment.provider === 'disqus' && (
|
||||
<DisqusComponent frontMatter={frontMatter} />
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Comments
|
@ -16,6 +16,40 @@ const siteMetadata = {
|
||||
youtube: 'https://youtube.com',
|
||||
linkedin: 'https://www.linkedin.com',
|
||||
locale: 'en-US',
|
||||
comment: {
|
||||
provider: '', // supported providers: giscus, utterances, disqus
|
||||
giscusConfig: {
|
||||
repo: '', // username/repoName
|
||||
// Visit the link below and copy/paste the 'repositoryId', 'category' and 'categoryId'
|
||||
// https://giscus.app/api/discussions/categories?repo={username}%2F{repoName}
|
||||
repositoryId: '',
|
||||
category: '',
|
||||
categoryId: '',
|
||||
mapping: '', // supported options: pathname, url, title
|
||||
reactions: '', // Emoji reactions: 1 = enable / 0 = disable
|
||||
// Send discussion metadata periodically to the parent window: 1 = enable / 0 = disable
|
||||
metadata: '',
|
||||
// theme example: light, dark, dark_dimmed, dark_high_contrast
|
||||
// transparent_dark, preferred_color_scheme, custom
|
||||
theme: '',
|
||||
// If the theme option above is set to 'custom`
|
||||
// please provide a link below to your custom theme css file.
|
||||
// example: https://giscus.app/themes/custom_example.css
|
||||
themeURL: '',
|
||||
},
|
||||
utterancesConfig: {
|
||||
repo: '', // username/repoName
|
||||
issueTerm: '', // supported options: pathname, url, title
|
||||
label: '', // label (optional): Comment 💬
|
||||
// theme example: github-light, github-dark, preferred-color-scheme
|
||||
// github-dark-orange, icy-dark, dark-blue, photon-dark, boxy-light
|
||||
theme: '',
|
||||
},
|
||||
disqus: {
|
||||
// https://help.disqus.com/en/articles/1717111-what-s-a-shortname
|
||||
shortname: '',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = siteMetadata
|
||||
|
@ -5,6 +5,7 @@ import { BlogSeo } from '@/components/SEO'
|
||||
import Image from '@/components/Image'
|
||||
import Tag from '@/components/Tag'
|
||||
import siteMetadata from '@/data/siteMetadata'
|
||||
import Comments from '@/components/comments'
|
||||
|
||||
const editUrl = (fileName) => `${siteMetadata.siteRepo}/blob/master/data/blog/${fileName}`
|
||||
const discussUrl = (slug) =>
|
||||
@ -91,6 +92,7 @@ export default function PostLayout({ frontMatter, authorDetails, next, prev, chi
|
||||
{` • `}
|
||||
<Link href={editUrl(fileName)}>{'View on GitHub'}</Link>
|
||||
</div>
|
||||
<Comments frontMatter={frontMatter} />
|
||||
</div>
|
||||
<footer>
|
||||
<div className="text-sm font-medium leading-5 divide-gray-200 xl:divide-y dark:divide-gray-700 xl:col-start-1 xl:row-start-2">
|
||||
|
@ -4,6 +4,7 @@ import SectionContainer from '@/components/SectionContainer'
|
||||
import { BlogSeo } from '@/components/SEO'
|
||||
import siteMetadata from '@/data/siteMetadata'
|
||||
import formatDate from '@/lib/utils/formatDate'
|
||||
import Comments from '@/components/comments'
|
||||
|
||||
export default function PostLayout({ frontMatter, authorDetails, next, prev, children }) {
|
||||
const { date, title } = frontMatter
|
||||
@ -35,6 +36,7 @@ export default function PostLayout({ frontMatter, authorDetails, next, prev, chi
|
||||
<div className="divide-y divide-gray-200 dark:divide-gray-700 xl:pb-0 xl:col-span-3 xl:row-span-2">
|
||||
<div className="pt-10 pb-8 prose dark:prose-dark max-w-none">{children}</div>
|
||||
</div>
|
||||
<Comments frontMatter={frontMatter} />
|
||||
<footer>
|
||||
<div className="flex flex-col text-sm font-medium sm:flex-row sm:justify-between sm:text-base">
|
||||
{prev && (
|
||||
|
Loading…
x
Reference in New Issue
Block a user