From eecac656e19203850a5e90fb054dac9e6b4758d7 Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Sun, 7 May 2023 18:30:56 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=A8twikoo=E5=AE=9E=E7=8E=B0=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E8=AF=84=E8=AE=BA=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- blog.config.js | 4 +- components/PrismMac.js | 6 +- components/Twikoo.js | 56 ++++++++++++++---- components/TwikooCommenCount.js | 22 +++++++ components/TwikooCommentCounter.js | 61 ++++++++++++++++++++ package.json | 1 - pages/_app.js | 2 + themes/hexo/components/BlogPostCardInfo.js | 7 ++- themes/hexo/components/HexoRecentComments.js | 28 ++++----- 9 files changed, 156 insertions(+), 31 deletions(-) create mode 100644 components/TwikooCommenCount.js create mode 100644 components/TwikooCommentCounter.js diff --git a/blog.config.js b/blog.config.js index c51d97a2..94680611 100644 --- a/blog.config.js +++ b/blog.config.js @@ -185,7 +185,9 @@ const BLOG = { // ----> 评论互动 可同时开启多个支持 WALINE VALINE GISCUS CUSDIS UTTERRANCES GITALK // twikoo - COMMENT_TWIKOO_ENV_ID: process.env.NEXT_PUBLIC_COMMENT_ENV_ID || '', // TWIKOO地址 腾讯云环境填 envId;Vercel 环境域名地址(https://xxx.vercel.app) + COMMENT_TWIKOO_ENV_ID: process.env.NEXT_PUBLIC_COMMENT_ENV_ID || '', // TWIKOO后端地址 腾讯云环境填envId;Vercel环境填域名,教程:https://tangly1024.com/article/notionnext-twikoo + COMMENT_TWIKOO_COUNT_ENABLE: process.env.NEXT_PUBLIC_COMMENT_TWIKOO_COUNT_ENABLE || false, // 博客列表是否显示评论数 + COMMENT_TWIKOO_CDN_URL: process.env.NEXT_PUBLIC_COMMENT_TWIKOO_CDN_URL || 'https://cdn.staticfile.org/twikoo/1.6.16/twikoo.all.min.js', // twikoo客户端cdn // utterance COMMENT_UTTERRANCES_REPO: diff --git a/components/PrismMac.js b/components/PrismMac.js index 60cc0983..b2f9ce90 100644 --- a/components/PrismMac.js +++ b/components/PrismMac.js @@ -23,8 +23,10 @@ const PrismMac = () => { loadExternalResource('/css/prism-mac-style.css', 'css') } loadExternalResource(BLOG.PRISM_THEME_PATH, 'css') - loadExternalResource(BLOG.PRISM_JS_AUTO_LOADER, 'js').then((e) => { - Prism.plugins.autoloader.languages_path = BLOG.PRISM_JS_PATH + loadExternalResource(BLOG.PRISM_JS_AUTO_LOADER, 'js').then((url) => { + if (window?.Prism?.plugins?.autoloader) { + window.Prism.plugins.autoloader.languages_path = BLOG.PRISM_JS_PATH + } renderPrismMac() }) } diff --git a/components/Twikoo.js b/components/Twikoo.js index bc6baa06..0c489bd5 100644 --- a/components/Twikoo.js +++ b/components/Twikoo.js @@ -1,6 +1,7 @@ import BLOG from '@/blog.config' -import React from 'react' -import twikoo from 'twikoo' +import { loadExternalResource } from '@/lib/utils' +import { useEffect } from 'react' +// import twikoo from 'twikoo' /** * Giscus评论 @see https://giscus.app/zh-CN @@ -10,17 +11,48 @@ import twikoo from 'twikoo' */ const Twikoo = ({ isDarkMode }) => { - React.useEffect(() => { - twikoo({ - envId: BLOG.COMMENT_TWIKOO_ENV_ID, // 腾讯云环境填 envId;Vercel 环境填地址(https://xxx.vercel.app) - el: '#twikoo', // 容器元素 - lang: BLOG.LANG // 用于手动设定评论区语言,支持的语言列表 https://github.com/imaegoo/twikoo/blob/main/src/client/utils/i18n/index.js - // region: 'ap-guangzhou', // 环境地域,默认为 ap-shanghai,腾讯云环境填 ap-shanghai 或 ap-guangzhou;Vercel 环境不填 - // path: location.pathname, // 用于区分不同文章的自定义 js 路径,如果您的文章路径不是 location.pathname,需传此参数 - }) - }) + const loadTwikoo = async () => { + try { + const url = await loadExternalResource(BLOG.COMMENT_TWIKOO_CDN_URL, 'js') + console.log('twikoo 加载成功', url) + const twikoo = window.twikoo + twikoo.init({ + envId: BLOG.COMMENT_TWIKOO_ENV_ID, // 腾讯云环境填 envId;Vercel 环境填地址(https://xxx.vercel.app) + el: '#twikoo', // 容器元素 + lang: BLOG.LANG // 用于手动设定评论区语言,支持的语言列表 https://github.com/imaegoo/twikoo/blob/main/src/client/utils/i18n/index.js + // region: 'ap-guangzhou', // 环境地域,默认为 ap-shanghai,腾讯云环境填 ap-shanghai 或 ap-guangzhou;Vercel 环境不填 + // path: location.pathname, // 用于区分不同文章的自定义 js 路径,如果您的文章路径不是 location.pathname,需传此参数 + }) + + twikoo.getCommentsCount({ + envId: BLOG.COMMENT_TWIKOO_ENV_ID, // 环境 ID + // region: 'ap-guangzhou', // 环境地域,默认为 ap-shanghai,如果您的环境地域不是上海,需传此参数 + urls: [ // 不包含协议、域名、参数的文章路径列表,必传参数 + '/article/notion-next', + '/article/notion-next-guide' + ], + includeReply: false // 评论数是否包括回复,默认:false + }).then(function (res) { + console.log(res) + // 返回示例: [ + // { url: '/2020/10/post-1.html', count: 10 }, + // { url: '/2020/11/post-2.html', count: 0 }, + // { url: '/2020/12/post-3.html', count: 20 } + // ] + }).catch(function (err) { + // 发生错误 + console.error(err) + }) + } catch (error) { + console.error('twikoo 加载失败', error) + } + } + + useEffect(() => { + loadTwikoo() + }, []) return ( -
+
) } diff --git a/components/TwikooCommenCount.js b/components/TwikooCommenCount.js new file mode 100644 index 00000000..eb5cd605 --- /dev/null +++ b/components/TwikooCommenCount.js @@ -0,0 +1,22 @@ +import BLOG from '@/blog.config' +// import twikoo from 'twikoo' + +/** + * 获取博客的评论数,用与在列表中展示 + * @returns {JSX.Element} + * @constructor + */ + +const TwikooCommentCount = ({ post, className }) => { + if (!JSON.parse(BLOG.COMMENT_TWIKOO_COUNT_ENABLE)) { + return null + } + return +} + +export default TwikooCommentCount diff --git a/components/TwikooCommentCounter.js b/components/TwikooCommentCounter.js new file mode 100644 index 00000000..1020cb92 --- /dev/null +++ b/components/TwikooCommentCounter.js @@ -0,0 +1,61 @@ +import BLOG from '@/blog.config' +import { loadExternalResource } from '@/lib/utils' +import { useRouter } from 'next/router' +import { useEffect } from 'react' + +/** + * 获取博客的评论数,用与在列表中展示 + * @returns {JSX.Element} + * @constructor + */ + +const TwikooCommentCounter = (props) => { + const loadTwikoo = async (posts) => { + posts.forEach(post => { + post.slug = post.slug.startsWith('/') ? post.slug : `/${post.slug}` + }) + try { + await loadExternalResource(BLOG.COMMENT_TWIKOO_CDN_URL, 'js') + const twikoo = window.twikoo + twikoo.getCommentsCount({ + envId: BLOG.COMMENT_TWIKOO_ENV_ID, // 环境 ID + // region: 'ap-guangzhou', // 环境地域,默认为 ap-shanghai,如果您的环境地域不是上海,需传此参数 + urls: posts.map(post => post.slug), // 不包含协议、域名、参数的文章路径列表,必传参数 + includeReply: true // 评论数是否包括回复,默认:false + }).then(function (res) { + console.log(res) + posts.forEach(post => { + const matchingRes = res.find(r => r.url === post.slug) + if (matchingRes) { + // 修改评论数量div + const textElements = document.querySelectorAll(`.comment-count-text-${post.id}`) + textElements.forEach(element => { + element.innerHTML = matchingRes.count + }) + // 取消隐藏 + const wrapperElements = document.querySelectorAll(`.comment-count-wrapper-${post.id}`) + wrapperElements.forEach(element => { + element.classList.remove('hidden') + }) + } + }) + }).catch(function (err) { + // 发生错误 + console.error(err) + }) + } catch (error) { + console.error('twikoo 加载失败', error) + } + } + + const router = useRouter() + + useEffect(() => { + if (props?.posts && props?.posts?.length > 0) { + loadTwikoo(props.posts) + } + }, [router.events]) + return null +} + +export default TwikooCommentCounter diff --git a/package.json b/package.json index 3e855451..a84b827f 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,6 @@ "react-share": "^4.4.1", "react-tweet-embed": "~2.0.0", "smoothscroll-polyfill": "^0.4.4", - "twikoo": "^1.6.16", "typed.js": "^2.0.12", "use-ackee": "^3.0.0", "valine": "^1.4.18" diff --git a/pages/_app.js b/pages/_app.js index f8e2a8b9..e4895f82 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -26,6 +26,7 @@ import smoothscroll from 'smoothscroll-polyfill' import AOS from 'aos' import 'aos/dist/aos.css' // You can also use for styles import { isMobile } from '@/lib/utils' +import TwikooCommentCounter from '@/components/TwikooCommentCounter' const Ackee = dynamic(() => import('@/components/Ackee'), { ssr: false }) const Gtag = dynamic(() => import('@/components/Gtag'), { ssr: false }) @@ -53,6 +54,7 @@ const MyApp = ({ Component, pageProps }) => { {JSON.parse(BLOG.MUSIC_PLAYER) && } {JSON.parse(BLOG.NEST) && } {JSON.parse(BLOG.FLUTTERINGRIBBON) && } + {JSON.parse(BLOG.COMMENT_TWIKOO_COUNT_ENABLE) && } {JSON.parse(BLOG.RIBBON) && } diff --git a/themes/hexo/components/BlogPostCardInfo.js b/themes/hexo/components/BlogPostCardInfo.js index 7336b64a..fe27bee8 100644 --- a/themes/hexo/components/BlogPostCardInfo.js +++ b/themes/hexo/components/BlogPostCardInfo.js @@ -2,6 +2,7 @@ import BLOG from '@/blog.config' import NotionPage from '@/components/NotionPage' import Link from 'next/link' import TagItemMini from './TagItemMini' +import TwikooCommentCount from '@/components/TwikooCommenCount' /** * 博客列表的文字内容 @@ -26,17 +27,19 @@ export const BlogPostCardInfo = ({ post, showPreview, showPageCover, showSummary {/* 日期 */}
+ className="font-light cursor-pointer text-sm leading-4 mr-3 hover:text-indigo-700 dark:hover:text-indigo-400"> {post.date?.start_date || post.lastEditedTime} + +
{/* 摘要 */} diff --git a/themes/hexo/components/HexoRecentComments.js b/themes/hexo/components/HexoRecentComments.js index 9c2042e6..2ebf00c8 100644 --- a/themes/hexo/components/HexoRecentComments.js +++ b/themes/hexo/components/HexoRecentComments.js @@ -25,21 +25,23 @@ const HexoRecentComments = (props) => { }, []) return ( - -
- - {locale.COMMON.RECENT_COMMENTS} -
+ +
+ + {locale.COMMON.RECENT_COMMENTS} +
- {onLoading &&
Loading...
} - {!onLoading && comments && comments.length === 0 &&
No Comments
} - {!onLoading && comments && comments.length > 0 && comments.map((comment) =>
-
-
--{comment.nick}
-
)} + {onLoading &&
Loading...
} + {!onLoading && comments && comments.length === 0 &&
No Comments
} + {!onLoading && comments && comments.length > 0 && comments.map((comment) =>
+
+
+ --{comment.nick} +
+
)} - - ); + + ) } export default HexoRecentComments