mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-18 23:16:49 +00:00
Merge branch 'main' into pr/jiashu1024/1622
This commit is contained in:
@@ -1,45 +1,47 @@
|
||||
'use strict'
|
||||
|
||||
import { useEffect } from 'react'
|
||||
import BLOG from '@/blog.config'
|
||||
import { loadExternalResource } from '@/lib/utils'
|
||||
import { useRouter } from 'next/router'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
const Ackee = () => {
|
||||
const router = useRouter()
|
||||
const server = siteConfig('ANALYTICS_ACKEE_DATA_SERVER')
|
||||
const domainId = siteConfig('ANALYTICS_ACKEE_DOMAIN_ID')
|
||||
|
||||
// 或者使用其他依赖数组,根据需要执行 handleAckee
|
||||
useEffect(() => {
|
||||
handleAckeeCallback()
|
||||
}, [router])
|
||||
|
||||
// handleAckee 函数
|
||||
const handleAckeeCallback = () => {
|
||||
handleAckee(
|
||||
router.asPath,
|
||||
{
|
||||
server: BLOG.ANALYTICS_ACKEE_DATA_SERVER,
|
||||
domainId: BLOG.ANALYTICS_ACKEE_DOMAIN_ID
|
||||
server: server,
|
||||
domainId: domainId
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Enable or disable tracking of personal data.
|
||||
* We recommend to ask the user for permission before turning this option on.
|
||||
*/
|
||||
* Enable or disable tracking of personal data.
|
||||
* We recommend to ask the user for permission before turning this option on.
|
||||
*/
|
||||
detailed: true,
|
||||
/*
|
||||
* Enable or disable tracking when on localhost.
|
||||
*/
|
||||
* Enable or disable tracking when on localhost.
|
||||
*/
|
||||
ignoreLocalhost: false,
|
||||
/*
|
||||
* Enable or disable the tracking of your own visits.
|
||||
* This is enabled by default, but should be turned off when using a wildcard Access-Control-Allow-Origin header.
|
||||
* Some browsers strictly block third-party cookies. The option won't have an impact when this is the case.
|
||||
*/
|
||||
* Enable or disable the tracking of your own visits.
|
||||
* This is enabled by default, but should be turned off when using a wildcard Access-Control-Allow-Origin header.
|
||||
* Some browsers strictly block third-party cookies. The option won't have an impact when this is the case.
|
||||
*/
|
||||
ignoreOwnVisits: false
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// 或者使用其他依赖数组,根据需要执行 handleAckee
|
||||
useEffect(() => {
|
||||
handleAckeeCallback()
|
||||
}, [router])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -53,8 +55,8 @@ export default Ackee
|
||||
* @param {Object} environment - Object containing the URL of the Ackee server and the domain id.
|
||||
* @param {?Object} options - Ackee options.
|
||||
*/
|
||||
const handleAckee = async function(pathname, environment, options = {}) {
|
||||
await loadExternalResource(BLOG.ANALYTICS_ACKEE_TRACKER, 'js')
|
||||
const handleAckee = async function (pathname, environment, options = {}) {
|
||||
await loadExternalResource(siteConfig('ANALYTICS_ACKEE_TRACKER'), 'js')
|
||||
const ackeeTracker = window.ackeeTracker
|
||||
|
||||
const instance = ackeeTracker?.create(environment.server, options)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useState, useImperativeHandle, useRef } from 'react'
|
||||
import BLOG from '@/blog.config'
|
||||
import algoliasearch from 'algoliasearch'
|
||||
import replaceSearchResult from '@/components/Mark'
|
||||
import Link from 'next/link'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import throttle from 'lodash/throttle'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
|
||||
/**
|
||||
* 结合 Algolia 实现的弹出式搜索框
|
||||
@@ -31,8 +31,8 @@ export default function AlgoliaSearchModal({ cRef }) {
|
||||
}
|
||||
})
|
||||
|
||||
const client = algoliasearch(BLOG.ALGOLIA_APP_ID, BLOG.ALGOLIA_SEARCH_ONLY_APP_KEY)
|
||||
const index = client.initIndex(BLOG.ALGOLIA_INDEX)
|
||||
const client = algoliasearch(siteConfig('ALGOLIA_APP_ID'), siteConfig('ALGOLIA_SEARCH_ONLY_APP_KEY'))
|
||||
const index = client.initIndex(siteConfig('ALGOLIA_INDEX'))
|
||||
|
||||
/**
|
||||
* 搜索
|
||||
@@ -97,7 +97,7 @@ export default function AlgoliaSearchModal({ cRef }) {
|
||||
setIsModalOpen(false)
|
||||
}
|
||||
|
||||
if (!BLOG.ALGOLIA_APP_ID) {
|
||||
if (!siteConfig('ALGOLIA_APP_ID')) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ export default function AlgoliaSearchModal({ cRef }) {
|
||||
<ul>
|
||||
{searchResults.map((result) => (
|
||||
<li key={result.objectID} className="replace my-2">
|
||||
<a href={`${BLOG.SUB_PATH}/${result.slug}`} className="font-bold hover:text-blue-600 text-black dark:text-gray-200">
|
||||
<a href={`${siteConfig('SUB_PATH')}/${result.slug}`} className="font-bold hover:text-blue-600 text-black dark:text-gray-200">
|
||||
{result.title}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { loadExternalResource } from '@/lib/utils'
|
||||
// import { loadExternalResource } from '@/lib/utils'
|
||||
import { useEffect } from 'react'
|
||||
@@ -11,17 +11,26 @@ import { useEffect } from 'react'
|
||||
*/
|
||||
|
||||
const Artalk = ({ siteInfo }) => {
|
||||
const artalkCss = siteConfig('COMMENT_ARTALK_CSS')
|
||||
const artalkServer = siteConfig('COMMENT_ARTALK_SERVER')
|
||||
const artalkLocale = siteConfig('LANG')
|
||||
const site = siteConfig('TITLE')
|
||||
|
||||
useEffect(() => {
|
||||
loadExternalResource(BLOG.COMMENT_ARTALK_CSS, 'css')
|
||||
initArtalk()
|
||||
}, [])
|
||||
|
||||
const initArtalk = async () => {
|
||||
await loadExternalResource(artalkCss, 'css')
|
||||
window?.Artalk?.init({
|
||||
server: BLOG.COMMENT_ARTALK_SERVER, // 后端地址
|
||||
server: artalkServer, // 后端地址
|
||||
el: '#artalk', // 容器元素
|
||||
locale: BLOG.LANG,
|
||||
locale: artalkLocale,
|
||||
// pageKey: '/post/1', // 固定链接 (留空自动获取)
|
||||
// pageTitle: '关于引入 Artalk 的这档子事', // 页面标题 (留空自动获取)
|
||||
site: siteInfo?.title // 你的站点名
|
||||
site: site // 你的站点名
|
||||
})
|
||||
}, [])
|
||||
}
|
||||
return (
|
||||
<div id="artalk"></div>
|
||||
)
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
|
||||
/**
|
||||
* 这是一个嵌入组件,可以在任意位置全屏显示您的chat-base对话框
|
||||
* 暂时没有页面引用
|
||||
* 因为您可以直接用内嵌网页的方式放入您的notion中 https://www.chatbase.co/chatbot-iframe/${BLOG.CHATBASE_ID}
|
||||
* 因为您可以直接用内嵌网页的方式放入您的notion中 https://www.chatbase.co/chatbot-iframe/${siteConfig('CHATBASE_ID')}
|
||||
*/
|
||||
export default function ChatBase() {
|
||||
if (!BLOG.CHATBASE_ID) {
|
||||
if (!siteConfig('CHATBASE_ID')) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
return <iframe
|
||||
src={`https://www.chatbase.co/chatbot-iframe/${BLOG.CHATBASE_ID}`}
|
||||
src={`https://www.chatbase.co/chatbot-iframe/${siteConfig('CHATBASE_ID')}`}
|
||||
width="100%"
|
||||
style={{ height: '100%', minHeight: '700px' }}
|
||||
frameborder="0"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import dynamic from 'next/dynamic'
|
||||
import Tabs from '@/components/Tabs'
|
||||
import { isBrowser } from '@/lib/utils'
|
||||
import { useRouter } from 'next/router'
|
||||
import Artalk from './Artalk'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
|
||||
const WalineComponent = dynamic(
|
||||
() => {
|
||||
@@ -55,13 +55,6 @@ const ValineComponent = dynamic(() => import('@/components/ValineComponent'), {
|
||||
ssr: false
|
||||
})
|
||||
|
||||
/**
|
||||
* 是否有评论
|
||||
*/
|
||||
export const commentEnable = BLOG.COMMENT_TWIKOO_ENV_ID || BLOG.COMMENT_WALINE_SERVER_URL || BLOG.COMMENT_VALINE_APP_ID ||
|
||||
BLOG.COMMENT_GISCUS_REPO || BLOG.COMMENT_CUSDIS_APP_ID || BLOG.COMMENT_UTTERRANCES_REPO ||
|
||||
BLOG.COMMENT_GITALK_CLIENT_ID || BLOG.COMMENT_WEBMENTION.ENABLE
|
||||
|
||||
/**
|
||||
* 评论组件
|
||||
* @param {*} param0
|
||||
@@ -70,6 +63,17 @@ BLOG.COMMENT_GISCUS_REPO || BLOG.COMMENT_CUSDIS_APP_ID || BLOG.COMMENT_UTTERRANC
|
||||
const Comment = ({ siteInfo, frontMatter, className }) => {
|
||||
const router = useRouter()
|
||||
|
||||
const COMMENT_ARTALK_SERVER = siteConfig('COMMENT_ARTALK_SERVER')
|
||||
const COMMENT_TWIKOO_ENV_ID = siteConfig('COMMENT_TWIKOO_ENV_ID')
|
||||
const COMMENT_WALINE_SERVER_URL = siteConfig('COMMENT_WALINE_SERVER_URL')
|
||||
const COMMENT_VALINE_APP_ID = siteConfig('COMMENT_VALINE_APP_ID')
|
||||
const COMMENT_GISCUS_REPO = siteConfig('COMMENT_GISCUS_REPO')
|
||||
const COMMENT_CUSDIS_APP_ID = siteConfig('COMMENT_CUSDIS_APP_ID')
|
||||
const COMMENT_UTTERRANCES_REPO = siteConfig('COMMENT_UTTERRANCES_REPO')
|
||||
const COMMENT_GITALK_CLIENT_ID = siteConfig('COMMENT_GITALK_CLIENT_ID')
|
||||
const COMMENT_WEBMENTION_ENABLE = siteConfig('COMMENT_WEBMENTION_ENABLE')
|
||||
|
||||
// 当连接中有特殊参数时跳转到评论区
|
||||
if (isBrowser && ('giscus' in router.query || router.query.target === 'comment')) {
|
||||
setTimeout(() => {
|
||||
const url = router.asPath.replace('?target=comment', '')
|
||||
@@ -83,47 +87,47 @@ const Comment = ({ siteInfo, frontMatter, className }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div key={frontMatter?.id} id='comment' className={`comment mt-5 text-gray-800 dark:text-gray-300 ${className || ''}`}>
|
||||
<Tabs>
|
||||
{BLOG.COMMENT_ARTALK_SERVER && (<div key='Artalk'>
|
||||
<Artalk siteInfo={siteInfo} />
|
||||
</div>)}
|
||||
<div key={frontMatter?.id} id='comment' className={`comment mt-5 text-gray-800 dark:text-gray-300 ${className || ''}`}>
|
||||
<Tabs>
|
||||
{COMMENT_ARTALK_SERVER && (<div key='Artalk'>
|
||||
<Artalk />
|
||||
</div>)}
|
||||
|
||||
{BLOG.COMMENT_TWIKOO_ENV_ID && (<div key='Twikoo'>
|
||||
<TwikooCompenent />
|
||||
</div>)}
|
||||
{COMMENT_TWIKOO_ENV_ID && (<div key='Twikoo'>
|
||||
<TwikooCompenent />
|
||||
</div>)}
|
||||
|
||||
{BLOG.COMMENT_WALINE_SERVER_URL && (<div key='Waline'>
|
||||
<WalineComponent />
|
||||
</div>)}
|
||||
{COMMENT_WALINE_SERVER_URL && (<div key='Waline'>
|
||||
<WalineComponent />
|
||||
</div>)}
|
||||
|
||||
{BLOG.COMMENT_VALINE_APP_ID && (<div key='Valine' name='reply'>
|
||||
<ValineComponent path={frontMatter.id} />
|
||||
</div>)}
|
||||
{COMMENT_VALINE_APP_ID && (<div key='Valine' name='reply'>
|
||||
<ValineComponent path={frontMatter.id} />
|
||||
</div>)}
|
||||
|
||||
{BLOG.COMMENT_GISCUS_REPO && (
|
||||
<div key="Giscus">
|
||||
<GiscusComponent className="px-2" />
|
||||
</div>
|
||||
)}
|
||||
{COMMENT_GISCUS_REPO && (
|
||||
<div key="Giscus">
|
||||
<GiscusComponent className="px-2" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{BLOG.COMMENT_CUSDIS_APP_ID && (<div key='Cusdis'>
|
||||
<CusdisComponent frontMatter={frontMatter} />
|
||||
</div>)}
|
||||
{COMMENT_CUSDIS_APP_ID && (<div key='Cusdis'>
|
||||
<CusdisComponent frontMatter={frontMatter} />
|
||||
</div>)}
|
||||
|
||||
{BLOG.COMMENT_UTTERRANCES_REPO && (<div key='Utterance'>
|
||||
<UtterancesComponent issueTerm={frontMatter.id} className='px-2' />
|
||||
</div>)}
|
||||
{COMMENT_UTTERRANCES_REPO && (<div key='Utterance'>
|
||||
<UtterancesComponent issueTerm={frontMatter.id} className='px-2' />
|
||||
</div>)}
|
||||
|
||||
{BLOG.COMMENT_GITALK_CLIENT_ID && (<div key='GitTalk'>
|
||||
<GitalkComponent frontMatter={frontMatter} />
|
||||
</div>)}
|
||||
{COMMENT_GITALK_CLIENT_ID && (<div key='GitTalk'>
|
||||
<GitalkComponent frontMatter={frontMatter} />
|
||||
</div>)}
|
||||
|
||||
{BLOG.COMMENT_WEBMENTION.ENABLE && (<div key='WebMention'>
|
||||
<WebMentionComponent frontMatter={frontMatter} className="px-2" />
|
||||
</div>)}
|
||||
</Tabs>
|
||||
</div>
|
||||
{COMMENT_WEBMENTION_ENABLE && (<div key='WebMention'>
|
||||
<WebMentionComponent frontMatter={frontMatter} className="px-2" />
|
||||
</div>)}
|
||||
</Tabs>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Head from 'next/head'
|
||||
|
||||
const CommonHead = ({ meta, children }) => {
|
||||
let url = BLOG?.PATH?.length ? `${BLOG.LINK}/${BLOG.SUB_PATH}` : BLOG.LINK
|
||||
let url = siteConfig('PATH')?.length ? `${siteConfig('LINK')}/${siteConfig('SUB_PATH', '')}` : siteConfig('LINK')
|
||||
let image
|
||||
if (meta) {
|
||||
url = `${url}/${meta.slug}`
|
||||
image = meta.image || '/bg_image.jpg'
|
||||
}
|
||||
const title = meta?.title || BLOG.TITLE
|
||||
const description = meta?.description || BLOG.DESCRIPTION
|
||||
const title = meta?.title || siteConfig('TITLE')
|
||||
const description = meta?.description || siteConfig('DESCRIPTION')
|
||||
const type = meta?.type || 'website'
|
||||
const keywords = meta?.tags || BLOG.KEYWORDS
|
||||
const lang = BLOG.LANG.replace('-', '_') // Facebook OpenGraph 要 zh_CN 這樣的格式才抓得到語言
|
||||
const category = meta?.category || BLOG.KEYWORDS || '軟體科技' // section 主要是像是 category 這樣的分類,Facebook 用這個來抓連結的分類
|
||||
const keywords = meta?.tags || siteConfig('KEYWORDS')
|
||||
const lang = siteConfig('LANG').replace('-', '_') // Facebook OpenGraph 要 zh_CN 這樣的格式才抓得到語言
|
||||
const category = meta?.category || siteConfig('KEYWORDS') // section 主要是像是 category 這樣的分類,Facebook 用這個來抓連結的分類
|
||||
|
||||
return (
|
||||
<Head>
|
||||
<title>{title}</title>
|
||||
<meta name="theme-color" content={BLOG.BACKGROUND_DARK} />
|
||||
<meta name="theme-color" content={siteConfig('BACKGROUND_DARK')} />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, minimum-scale=1.0" />
|
||||
<meta name="robots" content="follow, index" />
|
||||
<meta charSet="UTF-8" />
|
||||
{BLOG.SEO_GOOGLE_SITE_VERIFICATION && (
|
||||
{siteConfig('SEO_GOOGLE_SITE_VERIFICATION') && (
|
||||
<meta
|
||||
name="google-site-verification"
|
||||
content={BLOG.SEO_GOOGLE_SITE_VERIFICATION}
|
||||
content={siteConfig('SEO_GOOGLE_SITE_VERIFICATION')}
|
||||
/>
|
||||
)}
|
||||
{BLOG.SEO_BAIDU_SITE_VERIFICATION && (<meta name="baidu-site-verification" content={BLOG.SEO_BAIDU_SITE_VERIFICATION} />)}
|
||||
{siteConfig('SEO_BAIDU_SITE_VERIFICATION') && (<meta name="baidu-site-verification" content={siteConfig('SEO_BAIDU_SITE_VERIFICATION')} />)}
|
||||
<meta name="keywords" content={keywords} />
|
||||
<meta name="description" content={description} />
|
||||
<meta property="og:locale" content={lang} />
|
||||
@@ -36,33 +36,33 @@ const CommonHead = ({ meta, children }) => {
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:url" content={url} />
|
||||
<meta property="og:image" content={image} />
|
||||
<meta property="og:site_name" content={BLOG.TITLE} />
|
||||
<meta property="og:site_name" content={siteConfig('TITLE')} />
|
||||
<meta property="og:type" content={type} />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:description" content={description} />
|
||||
<meta name="twitter:title" content={title} />
|
||||
|
||||
{BLOG.COMMENT_WEBMENTION.ENABLE && (
|
||||
{siteConfig('COMMENT_WEBMENTION_ENABLE') && (
|
||||
<>
|
||||
<link rel="webmention" href={`https://webmention.io/${BLOG.COMMENT_WEBMENTION.HOSTNAME}/webmention`} />
|
||||
<link rel="pingback" href={`https://webmention.io/${BLOG.COMMENT_WEBMENTION.HOSTNAME}/xmlrpc`} />
|
||||
<link rel="webmention" href={`https://webmention.io/${siteConfig('COMMENT_WEBMENTION_HOSTNAME')}/webmention`} />
|
||||
<link rel="pingback" href={`https://webmention.io/${siteConfig('COMMENT_WEBMENTION_HOSTNAME')}/xmlrpc`} />
|
||||
</>
|
||||
)}
|
||||
|
||||
{BLOG.COMMENT_WEBMENTION.ENABLE && BLOG.COMMENT_WEBMENTION.AUTH !== '' && (
|
||||
<link href={BLOG.COMMENT_WEBMENTION.AUTH} rel="me" />
|
||||
{siteConfig('COMMENT_WEBMENTION_ENABLE') && siteConfig('COMMENT_WEBMENTION_AUTH') !== '' && (
|
||||
<link href={siteConfig('COMMENT_WEBMENTION_AUTH')} rel="me" />
|
||||
)}
|
||||
|
||||
{JSON.parse(BLOG.ANALYTICS_BUSUANZI_ENABLE) && <meta name="referrer" content="no-referrer-when-downgrade" />}
|
||||
{JSON.parse(siteConfig('ANALYTICS_BUSUANZI_ENABLE')) && <meta name="referrer" content="no-referrer-when-downgrade" />}
|
||||
{meta?.type === 'Post' && (
|
||||
<>
|
||||
<meta
|
||||
property="article:published_time"
|
||||
content={meta.publishDay}
|
||||
/>
|
||||
<meta property="article:author" content={BLOG.AUTHOR} />
|
||||
<meta property="article:author" content={siteConfig('AUTHOR')} />
|
||||
<meta property="article:section" content={category} />
|
||||
<meta property="article:publisher" content={BLOG.FACEBOOK_PAGE} />
|
||||
<meta property="article:publisher" content={siteConfig('FACEBOOK_PAGE')} />
|
||||
</>
|
||||
)}
|
||||
{children}
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
import BLOG from '@/blog.config'
|
||||
|
||||
/**
|
||||
* 第三方代码 统计脚本
|
||||
* @returns {JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
const CommonScript = () => {
|
||||
return (<>
|
||||
|
||||
{BLOG.CHATBASE_ID && (<>
|
||||
<script id={BLOG.CHATBASE_ID} src="https://www.chatbase.co/embed.min.js" defer/>
|
||||
<script async dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
window.chatbaseConfig = {
|
||||
chatbotId: "${BLOG.CHATBASE_ID}",
|
||||
}
|
||||
`
|
||||
}}/>
|
||||
</>)}
|
||||
|
||||
{BLOG.COMMENT_DAO_VOICE_ID && (<>
|
||||
{/* DaoVoice 反馈 */}
|
||||
<script async dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
(function(i,s,o,g,r,a,m){i["DaoVoiceObject"]=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;a.charset="utf-8";m.parentNode.insertBefore(a,m)})(window,document,"script",('https:' == document.location.protocol ? 'https:' : 'http:') + "//widget.daovoice.io/widget/daf1a94b.js","daovoice")
|
||||
`
|
||||
}}
|
||||
/>
|
||||
<script async dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
daovoice('init', {
|
||||
app_id: "${BLOG.COMMENT_DAO_VOICE_ID}"
|
||||
});
|
||||
daovoice('update');
|
||||
`
|
||||
}}
|
||||
/>
|
||||
</>)}
|
||||
|
||||
{BLOG.AD_WWADS_ID && <script type="text/javascript" charSet="UTF-8" src="https://cdn.wwads.cn/js/makemoney.js" async></script>}
|
||||
|
||||
{BLOG.COMMENT_CUSDIS_APP_ID && <script defer src={`https://cusdis.com/js/widget/lang/${BLOG.LANG.toLowerCase()}.js`} />}
|
||||
|
||||
{BLOG.COMMENT_TWIKOO_ENV_ID && <script defer src={BLOG.COMMENT_TWIKOO_CDN_URL}/> }
|
||||
|
||||
{BLOG.COMMENT_ARTALK_SERVER && <script defer src={BLOG.COMMENT_ARTALK_JS}/> }
|
||||
|
||||
{BLOG.COMMENT_TIDIO_ID && <script async src={`//code.tidio.co/${BLOG.COMMENT_TIDIO_ID}.js`} />}
|
||||
|
||||
{/* gitter聊天室 */}
|
||||
{BLOG.COMMENT_GITTER_ROOM && (<>
|
||||
<script src="https://sidecar.gitter.im/dist/sidecar.v1.js" async defer/>
|
||||
<script async dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
((window.gitter = {}).chat = {}).options = {
|
||||
room: '${BLOG.COMMENT_GITTER_ROOM}'
|
||||
};
|
||||
`
|
||||
}}/>
|
||||
</>)}
|
||||
|
||||
{/* 代码统计 */}
|
||||
{/* ackee统计脚本 */}
|
||||
{/* {BLOG.ANALYTICS_ACKEE_TRACKER && (
|
||||
<script async src={BLOG.ANALYTICS_ACKEE_TRACKER}
|
||||
data-ackee-server={BLOG.ANALYTICS_ACKEE_DATA_SERVER}
|
||||
data-ackee-domain-id={BLOG.ANALYTICS_ACKEE_DOMAIN_ID}
|
||||
/>
|
||||
)} */}
|
||||
|
||||
{/* 百度统计 */}
|
||||
{BLOG.ANALYTICS_BAIDU_ID && (
|
||||
<script async
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
var _hmt = _hmt || [];
|
||||
(function() {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?${BLOG.ANALYTICS_BAIDU_ID}";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
`
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 站长统计 */}
|
||||
{BLOG.ANALYTICS_CNZZ_ID && (
|
||||
<script async
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
document.write(unescape("%3Cspan style='display:none' id='cnzz_stat_icon_${BLOG.ANALYTICS_CNZZ_ID}'%3E%3C/span%3E%3Cscript src='https://s9.cnzz.com/z_stat.php%3Fid%3D${BLOG.ANALYTICS_CNZZ_ID}' type='text/javascript'%3E%3C/script%3E"));
|
||||
`
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Matomo 统计 */}
|
||||
{BLOG.MATOMO_HOST_URL && BLOG.MATOMO_SITE_ID && (
|
||||
<script async dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
var _paq = window._paq = window._paq || [];
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
(function() {
|
||||
var u="//${BLOG.MATOMO_HOST_URL}/";
|
||||
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
||||
_paq.push(['setSiteId', '${BLOG.MATOMO_SITE_ID}']);
|
||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
||||
})();
|
||||
`
|
||||
}}/>
|
||||
)}
|
||||
|
||||
{/* 谷歌统计 */}
|
||||
{BLOG.ANALYTICS_GOOGLE_ID && (<>
|
||||
<script async
|
||||
src={`https://www.googletagmanager.com/gtag/js?id=${BLOG.ANALYTICS_GOOGLE_ID}`}
|
||||
/>
|
||||
<script async
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', '${BLOG.ANALYTICS_GOOGLE_ID}', {
|
||||
page_path: window.location.pathname,
|
||||
});
|
||||
`
|
||||
}}
|
||||
/>
|
||||
</>)}
|
||||
|
||||
{/* 引入音乐播放 */}
|
||||
{JSON.parse(BLOG.MUSIC_PLAYER) && <script async src={BLOG.MUSIC_PLAYER_CDN_URL} />}
|
||||
{JSON.parse(BLOG.MUSIC_PLAYER) && JSON.parse(BLOG.MUSIC_PLAYER_METING) && <script async src="https://cdnjs.cloudflare.com/ajax/libs/meting/2.0.1/Meting.min.js" />}
|
||||
</>)
|
||||
}
|
||||
|
||||
export default CommonScript
|
||||
@@ -1,28 +1,34 @@
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import BLOG from '@/blog.config'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useEffect } from 'react'
|
||||
import { loadExternalResource } from '@/lib/utils'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
|
||||
const CusdisComponent = ({ frontMatter }) => {
|
||||
const { locale } = useGlobal()
|
||||
const router = useRouter()
|
||||
const { isDarkMode } = useGlobal()
|
||||
const { isDarkMode, lang } = useGlobal()
|
||||
const src = siteConfig('COMMENT_CUSDIS_SCRIPT_SRC')
|
||||
const i18nForCusdis = siteConfig('LANG').toLowerCase().indexOf('zh') === 0 ? siteConfig('LANG').toLowerCase() : siteConfig('LANG').toLowerCase().substring(0, 2)
|
||||
const langCDN = siteConfig('COMMENT_CUSDIS_LANG_SRC', `https://cusdis.com/js/widget/lang/${i18nForCusdis}.js`)
|
||||
|
||||
// 处理cusdis主题
|
||||
useEffect(() => {
|
||||
loadExternalResource(BLOG.COMMENT_CUSDIS_SCRIPT_SRC, 'js').then(url => {
|
||||
const CUSDIS = window.CUSDIS
|
||||
CUSDIS?.initial()
|
||||
})
|
||||
}, [isDarkMode])
|
||||
loadCusdis()
|
||||
}, [isDarkMode, lang])
|
||||
|
||||
const loadCusdis = async () => {
|
||||
await loadExternalResource(langCDN, 'js')
|
||||
await loadExternalResource(src, 'js')
|
||||
|
||||
window?.CUSDIS?.initial()
|
||||
}
|
||||
|
||||
return <div id="cusdis_thread"
|
||||
lang={locale.LOCALE.toLowerCase()}
|
||||
data-host={BLOG.COMMENT_CUSDIS_HOST}
|
||||
data-app-id={BLOG.COMMENT_CUSDIS_APP_ID}
|
||||
lang={lang.toLowerCase()}
|
||||
data-host={siteConfig('COMMENT_CUSDIS_HOST')}
|
||||
data-app-id={siteConfig('COMMENT_CUSDIS_APP_ID')}
|
||||
data-page-id={frontMatter.id}
|
||||
data-page-url={BLOG.LINK + router.asPath}
|
||||
data-page-url={siteConfig('LINK') + router.asPath}
|
||||
data-page-title={frontMatter.title}
|
||||
data-theme={isDarkMode ? 'dark' : 'light'}
|
||||
></div>
|
||||
|
||||
@@ -3,8 +3,8 @@ import { useRouter } from 'next/router'
|
||||
import { useEffect, useState, useRef, useLayoutEffect } from 'react'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { saveDarkModeToCookies, THEMES } from '@/themes/theme'
|
||||
import BLOG from '@/blog.config'
|
||||
import useWindowSize from '@/hooks/useWindowSize'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
|
||||
/**
|
||||
* 自定义右键菜单
|
||||
@@ -28,7 +28,7 @@ export default function CustomContextMenu(props) {
|
||||
function handleJumpToRandomPost() {
|
||||
const randomIndex = Math.floor(Math.random() * latestPosts.length)
|
||||
const randomPost = latestPosts[randomIndex]
|
||||
router.push(`${BLOG.SUB_PATH}/${randomPost?.slug}`)
|
||||
router.push(`${siteConfig('SUB_PATH', '')}/${randomPost?.slug}`)
|
||||
}
|
||||
|
||||
useLayoutEffect(() => {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { saveDarkModeToCookies } from '@/themes/theme'
|
||||
import { Moon, Sun } from './HeroIcons'
|
||||
import { useImperativeHandle } from 'react'
|
||||
|
||||
@@ -8,7 +7,7 @@ import { useImperativeHandle } from 'react'
|
||||
*/
|
||||
const DarkModeButton = (props) => {
|
||||
const { cRef, className } = props
|
||||
const { isDarkMode, updateDarkMode } = useGlobal()
|
||||
const { isDarkMode, toggleDarkMode } = useGlobal()
|
||||
|
||||
/**
|
||||
* 对外暴露方法
|
||||
@@ -16,22 +15,12 @@ const DarkModeButton = (props) => {
|
||||
useImperativeHandle(cRef, () => {
|
||||
return {
|
||||
handleChangeDarkMode: () => {
|
||||
handleChangeDarkMode()
|
||||
toggleDarkMode()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 用户手动设置主题
|
||||
const handleChangeDarkMode = () => {
|
||||
const newStatus = !isDarkMode
|
||||
saveDarkModeToCookies(newStatus)
|
||||
updateDarkMode(newStatus)
|
||||
const htmlElement = document.getElementsByTagName('html')[0]
|
||||
htmlElement.classList?.remove(newStatus ? 'light' : 'dark')
|
||||
htmlElement.classList?.add(newStatus ? 'dark' : 'light')
|
||||
}
|
||||
|
||||
return <div onClick={handleChangeDarkMode} className={`${className || ''} flex justify-center dark:text-gray-200 text-gray-800`}>
|
||||
return <div onClick={toggleDarkMode} className={`${className || ''} flex justify-center dark:text-gray-200 text-gray-800`}>
|
||||
<div id='darkModeButton' className=' hover:scale-110 cursor-pointer transform duration-200 w-5 h-5'> {isDarkMode ? <Sun /> : <Moon />}</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { useEffect, useState } from 'react'
|
||||
import Select from './Select'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { THEMES } from '@/themes/theme'
|
||||
import { useRouter } from 'next/router'
|
||||
import { siteConfigMap } from '@/lib/config'
|
||||
import { getQueryParam } from '@/lib/utils'
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -13,14 +14,14 @@ const DebugPanel = () => {
|
||||
const [show, setShow] = useState(false)
|
||||
const { theme, switchTheme, locale } = useGlobal()
|
||||
const router = useRouter()
|
||||
const currentTheme = getQueryParam(router.asPath, 'theme') || theme
|
||||
const [siteConfig, updateSiteConfig] = useState({})
|
||||
|
||||
// 主题下拉框
|
||||
const themeOptions = THEMES?.map(t => ({ value: t, text: t }))
|
||||
|
||||
useEffect(() => {
|
||||
updateSiteConfig(Object.assign({}, BLOG))
|
||||
// updateThemeConfig(Object.assign({}, ThemeMap[BLOG.THEME].THEME_CONFIG))
|
||||
updateSiteConfig(Object.assign({}, siteConfigMap()))
|
||||
}, [])
|
||||
|
||||
function toggleShow() {
|
||||
@@ -71,7 +72,7 @@ const DebugPanel = () => {
|
||||
<div className='flex'>
|
||||
<Select
|
||||
label={locale.COMMON.THEME_SWITCH}
|
||||
value={theme}
|
||||
value={currentTheme}
|
||||
options={themeOptions}
|
||||
onChange={handleUpdateDebugTheme}
|
||||
/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
/**
|
||||
@@ -6,7 +6,7 @@ import { useEffect } from 'react'
|
||||
*/
|
||||
export default function DisableCopy() {
|
||||
useEffect(() => {
|
||||
if (!JSON.parse(BLOG.CAN_COPY)) {
|
||||
if (!JSON.parse(siteConfig('CAN_COPY'))) {
|
||||
// 全栈添加禁止复制的样式
|
||||
document.getElementsByTagName('html')[0].classList.add('forbid-copy')
|
||||
// 监听复制事件
|
||||
|
||||
@@ -1,18 +1,7 @@
|
||||
import BLOG from 'blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import dynamic from 'next/dynamic'
|
||||
import WebWhiz from './Webwhiz'
|
||||
|
||||
// import TwikooCommentCounter from '@/components/TwikooCommentCounter'
|
||||
// import { DebugPanel } from '@/components/DebugPanel'
|
||||
// import { ThemeSwitch } from '@/components/ThemeSwitch'
|
||||
// import { Fireworks } from '@/components/Fireworks'
|
||||
// import { Nest } from '@/components/Nest'
|
||||
// import { FlutteringRibbon } from '@/components/FlutteringRibbon'
|
||||
// import { Ribbon } from '@/components/Ribbon'
|
||||
// import { Sakura } from '@/components/Sakura'
|
||||
// import { StarrySky } from '@/components/StarrySky'
|
||||
// import { Analytics } from '@vercel/analytics/react'
|
||||
|
||||
const TwikooCommentCounter = dynamic(() => import('@/components/TwikooCommentCounter'), { ssr: false })
|
||||
const DebugPanel = dynamic(() => import('@/components/DebugPanel'), { ssr: false })
|
||||
const ThemeSwitch = dynamic(() => import('@/components/ThemeSwitch'), { ssr: false })
|
||||
@@ -33,35 +22,152 @@ const VConsole = dynamic(() => import('@/components/VConsole'), { ssr: false })
|
||||
const CustomContextMenu = dynamic(() => import('@/components/CustomContextMenu'), { ssr: false })
|
||||
const DisableCopy = dynamic(() => import('@/components/DisableCopy'), { ssr: false })
|
||||
const AdBlockDetect = dynamic(() => import('@/components/AdBlockDetect'), { ssr: false })
|
||||
|
||||
/**
|
||||
* 各种第三方组件
|
||||
* 各种插件脚本
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
const ExternalPlugin = (props) => {
|
||||
return <>
|
||||
{JSON.parse(BLOG.THEME_SWITCH) && <ThemeSwitch />}
|
||||
{JSON.parse(BLOG.DEBUG) && <DebugPanel />}
|
||||
{BLOG.ANALYTICS_ACKEE_TRACKER && <Ackee />}
|
||||
{BLOG.ANALYTICS_GOOGLE_ID && <Gtag />}
|
||||
{BLOG.ANALYTICS_VERCEL && <Analytics />}
|
||||
{JSON.parse(BLOG.ANALYTICS_BUSUANZI_ENABLE) && <Busuanzi />}
|
||||
{BLOG.ADSENSE_GOOGLE_ID && <GoogleAdsense />}
|
||||
{BLOG.FACEBOOK_APP_ID && BLOG.FACEBOOK_PAGE_ID && <Messenger />}
|
||||
{JSON.parse(BLOG.FIREWORKS) && <Fireworks />}
|
||||
{JSON.parse(BLOG.SAKURA) && <Sakura />}
|
||||
{JSON.parse(BLOG.STARRY_SKY) && <StarrySky />}
|
||||
{JSON.parse(BLOG.MUSIC_PLAYER) && <MusicPlayer />}
|
||||
{JSON.parse(BLOG.NEST) && <Nest />}
|
||||
{JSON.parse(BLOG.FLUTTERINGRIBBON) && <FlutteringRibbon />}
|
||||
{JSON.parse(BLOG.COMMENT_TWIKOO_COUNT_ENABLE) && <TwikooCommentCounter {...props}/>}
|
||||
{JSON.parse(BLOG.RIBBON) && <Ribbon />}
|
||||
{JSON.parse(BLOG.CUSTOM_RIGHT_CLICK_CONTEXT_MENU) && <CustomContextMenu {...props} />}
|
||||
{!JSON.parse(BLOG.CAN_COPY) && <DisableCopy/>}
|
||||
{JSON.parse(BLOG.WEB_WHIZ_ENABLED) && <WebWhiz/>}
|
||||
{JSON.parse(BLOG.AD_WWADS_BLOCK_DETECT) && <AdBlockDetect/>}
|
||||
<VConsole/>
|
||||
</>
|
||||
{JSON.parse(siteConfig('THEME_SWITCH')) && <ThemeSwitch />}
|
||||
{JSON.parse(siteConfig('DEBUG')) && <DebugPanel />}
|
||||
{siteConfig('ANALYTICS_ACKEE_TRACKER') && <Ackee />}
|
||||
{siteConfig('ANALYTICS_GOOGLE_ID') && <Gtag />}
|
||||
{siteConfig('ANALYTICS_VERCEL') && <Analytics />}
|
||||
{JSON.parse(siteConfig('ANALYTICS_BUSUANZI_ENABLE')) && <Busuanzi />}
|
||||
{siteConfig('ADSENSE_GOOGLE_ID') && <GoogleAdsense />}
|
||||
{siteConfig('FACEBOOK_APP_ID') && siteConfig('FACEBOOK_PAGE_ID') && <Messenger />}
|
||||
{JSON.parse(siteConfig('FIREWORKS')) && <Fireworks />}
|
||||
{JSON.parse(siteConfig('SAKURA')) && <Sakura />}
|
||||
{JSON.parse(siteConfig('STARRY_SKY')) && <StarrySky />}
|
||||
{JSON.parse(siteConfig('MUSIC_PLAYER')) && <MusicPlayer />}
|
||||
{JSON.parse(siteConfig('NEST')) && <Nest />}
|
||||
{JSON.parse(siteConfig('FLUTTERINGRIBBON')) && <FlutteringRibbon />}
|
||||
{JSON.parse(siteConfig('COMMENT_TWIKOO_COUNT_ENABLE')) && <TwikooCommentCounter {...props} />}
|
||||
{JSON.parse(siteConfig('RIBBON')) && <Ribbon />}
|
||||
{JSON.parse(siteConfig('CUSTOM_RIGHT_CLICK_CONTEXT_MENU')) && <CustomContextMenu {...props} />}
|
||||
{!JSON.parse(siteConfig('CAN_COPY')) && <DisableCopy />}
|
||||
{JSON.parse(siteConfig('WEB_WHIZ_ENABLED')) && <WebWhiz />}
|
||||
{JSON.parse(siteConfig('AD_WWADS_BLOCK_DETECT')) && <AdBlockDetect />}
|
||||
<VConsole />
|
||||
|
||||
{siteConfig('CHATBASE_ID') && (<>
|
||||
<script id={siteConfig('CHATBASE_ID')} src="https://www.chatbase.co/embed.min.js" defer />
|
||||
<script async dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
window.chatbaseConfig = {
|
||||
chatbotId: "${siteConfig('CHATBASE_ID')}",
|
||||
}
|
||||
`
|
||||
}} />
|
||||
</>)}
|
||||
|
||||
{siteConfig('COMMENT_DAO_VOICE_ID') && (<>
|
||||
{/* DaoVoice 反馈 */}
|
||||
<script async dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
(function(i,s,o,g,r,a,m){i["DaoVoiceObject"]=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;a.charset="utf-8";m.parentNode.insertBefore(a,m)})(window,document,"script",('https:' == document.location.protocol ? 'https:' : 'http:') + "//widget.daovoice.io/widget/daf1a94b.js","daovoice")
|
||||
`
|
||||
}}
|
||||
/>
|
||||
<script async dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
daovoice('init', {
|
||||
app_id: "${siteConfig('COMMENT_DAO_VOICE_ID')}"
|
||||
});
|
||||
daovoice('update');
|
||||
`
|
||||
}}
|
||||
/>
|
||||
</>)}
|
||||
|
||||
{siteConfig('AD_WWADS_ID') && <script type="text/javascript" charSet="UTF-8" src="https://cdn.wwads.cn/js/makemoney.js" async></script>}
|
||||
|
||||
{siteConfig('COMMENT_TWIKOO_ENV_ID') && <script defer src={siteConfig('COMMENT_TWIKOO_CDN_URL')} />}
|
||||
|
||||
{siteConfig('COMMENT_ARTALK_SERVER') && <script defer src={siteConfig('COMMENT_ARTALK_JS')} />}
|
||||
|
||||
{siteConfig('COMMENT_TIDIO_ID') && <script async src={`//code.tidio.co/${siteConfig('COMMENT_TIDIO_ID')}.js`} />}
|
||||
|
||||
{/* gitter聊天室 */}
|
||||
{siteConfig('COMMENT_GITTER_ROOM') && (<>
|
||||
<script src="https://sidecar.gitter.im/dist/sidecar.v1.js" async defer />
|
||||
<script async dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
((window.gitter = {}).chat = {}).options = {
|
||||
room: '${siteConfig('COMMENT_GITTER_ROOM')}'
|
||||
};
|
||||
`
|
||||
}} />
|
||||
</>)}
|
||||
|
||||
{/* 百度统计 */}
|
||||
{siteConfig('ANALYTICS_BAIDU_ID') && (
|
||||
<script async
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
var _hmt = _hmt || [];
|
||||
(function() {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?${siteConfig('ANALYTICS_BAIDU_ID')}";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
`
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 站长统计 */}
|
||||
{siteConfig('ANALYTICS_CNZZ_ID') && (
|
||||
<script async
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
document.write(unescape("%3Cspan style='display:none' id='cnzz_stat_icon_${siteConfig('ANALYTICS_CNZZ_ID')}'%3E%3C/span%3E%3Cscript src='https://s9.cnzz.com/z_stat.php%3Fid%3D${siteConfig('ANALYTICS_CNZZ_ID')}' type='text/javascript'%3E%3C/script%3E"));
|
||||
`
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 谷歌统计 */}
|
||||
{siteConfig('ANALYTICS_GOOGLE_ID') && (<>
|
||||
<script async
|
||||
src={`https://www.googletagmanager.com/gtag/js?id=${siteConfig('ANALYTICS_GOOGLE_ID')}`}
|
||||
/>
|
||||
<script async
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', '${siteConfig('ANALYTICS_GOOGLE_ID')}', {
|
||||
page_path: window.location.pathname,
|
||||
});
|
||||
`
|
||||
}}
|
||||
/>
|
||||
</>)}
|
||||
|
||||
{/* Matomo 统计 */}
|
||||
{siteConfig('MATOMO_HOST_URL') && siteConfig('MATOMO_SITE_ID') && (
|
||||
<script async dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
var _paq = window._paq = window._paq || [];
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
(function() {
|
||||
var u="//${siteConfig('MATOMO_HOST_URL')}/";
|
||||
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
||||
_paq.push(['setSiteId', '${siteConfig('MATOMO_SITE_ID')}']);
|
||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
||||
})();
|
||||
`
|
||||
}}/>
|
||||
)}
|
||||
|
||||
</>
|
||||
}
|
||||
|
||||
export default ExternalPlugin
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
|
||||
export default function Messenger() {
|
||||
return <MessengerCustomerChat
|
||||
pageId={BLOG.FACEBOOK_PAGE_ID}
|
||||
appId={BLOG.FACEBOOK_APP_ID}
|
||||
language={BLOG.LANG.replace('-', '_')}
|
||||
pageId={siteConfig('FACEBOOK_PAGE_ID')}
|
||||
appId={siteConfig('FACEBOOK_APP_ID')}
|
||||
language={siteConfig('LANG').replace('-', '_')}
|
||||
shouldShowDialog={true}
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { FacebookProvider, Page } from 'react-facebook'
|
||||
import { FacebookIcon } from 'react-share'
|
||||
|
||||
@@ -7,27 +7,27 @@ import { FacebookIcon } from 'react-share'
|
||||
* @returns
|
||||
*/
|
||||
const FacebookPage = () => {
|
||||
if (!BLOG.FACEBOOK_APP_ID || !BLOG.FACEBOOK_PAGE) {
|
||||
if (!siteConfig('FACEBOOK_APP_ID') || !siteConfig('FACEBOOK_PAGE')) {
|
||||
return <></>
|
||||
}
|
||||
return <div className="shadow-md hover:shadow-xl dark:text-gray-300 border dark:border-black rounded-xl px-2 py-4 bg-white dark:bg-hexo-black-gray lg:duration-100 justify-center">
|
||||
{BLOG.FACEBOOK_PAGE && (
|
||||
{siteConfig('FACEBOOK_PAGE') && (
|
||||
<div className="flex items-center pb-2">
|
||||
<a
|
||||
href={BLOG.FACEBOOK_PAGE}
|
||||
href={siteConfig('FACEBOOK_PAGE')}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="p-1 pr-2 pt-0"
|
||||
>
|
||||
<FacebookIcon size={28} round />
|
||||
</a>
|
||||
<a href={BLOG.FACEBOOK_PAGE} rel="noopener noreferrer" target="_blank">
|
||||
{BLOG.FACEBOOK_PAGE_TITLE}
|
||||
<a href={siteConfig('FACEBOOK_PAGE')} rel="noopener noreferrer" target="_blank">
|
||||
{siteConfig('FACEBOOK_PAGE_TITLE')}
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
{BLOG.FACEBOOK_APP_ID && <FacebookProvider appId={BLOG.FACEBOOK_APP_ID}>
|
||||
<Page href={BLOG.FACEBOOK_PAGE} tabs="timeline" />
|
||||
{siteConfig('FACEBOOK_APP_ID') && <FacebookProvider appId={siteConfig('FACEBOOK_APP_ID')}>
|
||||
<Page href={siteConfig('FACEBOOK_PAGE')} tabs="timeline" />
|
||||
</FacebookProvider>}
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -4,11 +4,17 @@
|
||||
*/
|
||||
import { useEffect } from 'react'
|
||||
import anime from 'animejs'
|
||||
import BLOG from 'blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
|
||||
/**
|
||||
* 鼠标点击烟花特效
|
||||
* @returns
|
||||
*/
|
||||
const Fireworks = () => {
|
||||
const fireworksColor = siteConfig('FIREWORKS_COLOR')
|
||||
|
||||
useEffect(() => {
|
||||
createFireworks({})
|
||||
createFireworks({ colors: fireworksColor })
|
||||
}, [])
|
||||
return <canvas id='fireworks' className='fireworks'></canvas>
|
||||
}
|
||||
@@ -20,7 +26,7 @@ export default Fireworks
|
||||
*/
|
||||
function createFireworks(config) {
|
||||
const defaultConfig = {
|
||||
colors: BLOG.FIREWORKS_COLOR,
|
||||
colors: config?.colors,
|
||||
numberOfParticules: 20,
|
||||
orbitRadius: {
|
||||
min: 50,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Giscus from '@giscus/react'
|
||||
|
||||
@@ -15,17 +15,17 @@ const GiscusComponent = () => {
|
||||
|
||||
return (
|
||||
<Giscus
|
||||
repo={BLOG.COMMENT_GISCUS_REPO}
|
||||
repoId={BLOG.COMMENT_GISCUS_REPO_ID}
|
||||
categoryId={BLOG.COMMENT_GISCUS_CATEGORY_ID}
|
||||
mapping={BLOG.COMMENT_GISCUS_MAPPING}
|
||||
reactionsEnabled={BLOG.COMMENT_GISCUS_REACTIONS_ENABLED}
|
||||
emitMetadata={BLOG.COMMENT_GISCUS_EMIT_METADATA}
|
||||
repo={siteConfig('COMMENT_GISCUS_REPO')}
|
||||
repoId={siteConfig('COMMENT_GISCUS_REPO_ID')}
|
||||
categoryId={siteConfig('COMMENT_GISCUS_CATEGORY_ID')}
|
||||
mapping={siteConfig('COMMENT_GISCUS_MAPPING')}
|
||||
reactionsEnabled={siteConfig('COMMENT_GISCUS_REACTIONS_ENABLED')}
|
||||
emitMetadata={siteConfig('COMMENT_GISCUS_EMIT_METADATA')}
|
||||
theme={theme}
|
||||
inputPosition={BLOG.COMMENT_GISCUS_INPUT_POSITION}
|
||||
lang={BLOG.COMMENT_GISCUS_LANG}
|
||||
loading={BLOG.COMMENT_GISCUS_LOADING}
|
||||
crossorigin={BLOG.COMMENT_GISCUS_CROSSORIGIN}
|
||||
inputPosition={siteConfig('COMMENT_GISCUS_INPUT_POSITION')}
|
||||
lang={siteConfig('COMMENT_GISCUS_LANG')}
|
||||
loading={siteConfig('COMMENT_GISCUS_LOADING')}
|
||||
crossorigin={siteConfig('COMMENT_GISCUS_CROSSORIGIN')}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,37 +1,39 @@
|
||||
// import 'gitalk/dist/gitalk.css'
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { loadExternalResource } from '@/lib/utils'
|
||||
import { useEffect } from 'react'
|
||||
// import GitalkComponent from 'gitalk/dist/gitalk-component'
|
||||
|
||||
/**
|
||||
* gitalk评论插件
|
||||
* @param {*} param0
|
||||
* @returns
|
||||
*/
|
||||
const Gitalk = ({ frontMatter }) => {
|
||||
// return <GitalkComponent options={{
|
||||
// id: frontMatter.id,
|
||||
// title: frontMatter.title,
|
||||
// clientID: BLOG.COMMENT_GITALK_CLIENT_ID,
|
||||
// clientSecret: BLOG.COMMENT_GITALK_CLIENT_SECRET,
|
||||
// repo: BLOG.COMMENT_GITALK_REPO,
|
||||
// owner: BLOG.COMMENT_GITALK_OWNER,
|
||||
// admin: BLOG.COMMENT_GITALK_ADMIN.split(','),
|
||||
// distractionFreeMode: JSON.parse(BLOG.COMMENT_GITALK_DISTRACTION_FREE_MODE)
|
||||
// }} />
|
||||
const loadGitalk = async() => {
|
||||
await loadExternalResource(BLOG.COMMENT_GITALK_CSS_CDN_URL, 'css')
|
||||
await loadExternalResource(BLOG.COMMENT_GITALK_JS_CDN_URL, 'js')
|
||||
const Gitalk = window.Gitalk
|
||||
const gitalkCSSCDN = siteConfig('COMMENT_GITALK_CSS_CDN_URL')
|
||||
const gitalkJSCDN = siteConfig('COMMENT_GITALK_JS_CDN_URL')
|
||||
const clientId = siteConfig('COMMENT_GITALK_CLIENT_ID')
|
||||
const clientSecret = siteConfig('COMMENT_GITALK_CLIENT_SECRET')
|
||||
const repo = siteConfig('COMMENT_GITALK_REPO')
|
||||
const owner = siteConfig('COMMENT_GITALK_OWNER')
|
||||
const admin = siteConfig('COMMENT_GITALK_ADMIN').split(',')
|
||||
const distractionFreeMode = siteConfig('COMMENT_GITALK_DISTRACTION_FREE_MODE')
|
||||
|
||||
const loadGitalk = async() => {
|
||||
await loadExternalResource(gitalkCSSCDN, 'css')
|
||||
await loadExternalResource(gitalkJSCDN, 'js')
|
||||
const Gitalk = window.Gitalk
|
||||
const gitalk = new Gitalk({
|
||||
clientID: BLOG.COMMENT_GITALK_CLIENT_ID,
|
||||
clientSecret: BLOG.COMMENT_GITALK_CLIENT_SECRET,
|
||||
repo: BLOG.COMMENT_GITALK_REPO,
|
||||
owner: BLOG.COMMENT_GITALK_OWNER,
|
||||
admin: BLOG.COMMENT_GITALK_ADMIN.split(','),
|
||||
clientID: clientId,
|
||||
clientSecret: clientSecret,
|
||||
repo: repo,
|
||||
owner: owner,
|
||||
admin: admin,
|
||||
id: frontMatter.id, // Ensure uniqueness and length less than 50
|
||||
distractionFreeMode: JSON.parse(BLOG.COMMENT_GITALK_DISTRACTION_FREE_MODE) // Facebook-like distraction free mode
|
||||
distractionFreeMode: distractionFreeMode // Facebook-like distraction free mode
|
||||
})
|
||||
|
||||
gitalk.render('gitalk-container')
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
loadGitalk()
|
||||
}, [])
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { loadExternalResource } from '@/lib/utils'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useEffect } from 'react'
|
||||
@@ -9,7 +9,7 @@ import { useEffect } from 'react'
|
||||
*/
|
||||
export default function GoogleAdsense() {
|
||||
const initGoogleAdsense = () => {
|
||||
loadExternalResource(`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${BLOG.ADSENSE_GOOGLE_ID}`, 'js').then(url => {
|
||||
loadExternalResource(`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${siteConfig('ADSENSE_GOOGLE_ID')}`, 'js').then(url => {
|
||||
setTimeout(() => {
|
||||
const ads = document.getElementsByClassName('adsbygoogle')
|
||||
const adsbygoogle = window.adsbygoogle
|
||||
@@ -44,7 +44,7 @@ export default function GoogleAdsense() {
|
||||
* 添加 可以在本地调试
|
||||
*/
|
||||
const AdSlot = ({ type = 'show' }) => {
|
||||
if (!BLOG.ADSENSE_GOOGLE_ID) {
|
||||
if (!siteConfig('ADSENSE_GOOGLE_ID')) {
|
||||
return null
|
||||
}
|
||||
// 文章内嵌广告
|
||||
@@ -53,9 +53,9 @@ const AdSlot = ({ type = 'show' }) => {
|
||||
style={{ display: 'block', textAlign: 'center' }}
|
||||
data-ad-layout="in-article"
|
||||
data-ad-format="fluid"
|
||||
data-adtest={BLOG.ADSENSE_GOOGLE_TEST ? 'on' : 'off'}
|
||||
data-ad-client={BLOG.ADSENSE_GOOGLE_ID}
|
||||
data-ad-slot={BLOG.ADSENSE_GOOGLE_SLOT_IN_ARTICLE}></ins>
|
||||
data-adtest={siteConfig('ADSENSE_GOOGLE_TEST') ? 'on' : 'off'}
|
||||
data-ad-client={siteConfig('ADSENSE_GOOGLE_ID')}
|
||||
data-ad-slot={siteConfig('ADSENSE_GOOGLE_SLOT_IN_ARTICLE')}></ins>
|
||||
}
|
||||
|
||||
// 信息流广告
|
||||
@@ -64,9 +64,9 @@ const AdSlot = ({ type = 'show' }) => {
|
||||
data-ad-format="fluid"
|
||||
data-ad-layout-key="-5j+cz+30-f7+bf"
|
||||
style={{ display: 'block' }}
|
||||
data-adtest={BLOG.ADSENSE_GOOGLE_TEST ? 'on' : 'off'}
|
||||
data-ad-client={BLOG.ADSENSE_GOOGLE_ID}
|
||||
data-ad-slot={BLOG.ADSENSE_GOOGLE_SLOT_FLOW}></ins>
|
||||
data-adtest={siteConfig('ADSENSE_GOOGLE_TEST') ? 'on' : 'off'}
|
||||
data-ad-client={siteConfig('ADSENSE_GOOGLE_ID')}
|
||||
data-ad-slot={siteConfig('ADSENSE_GOOGLE_SLOT_FLOW')}></ins>
|
||||
}
|
||||
|
||||
// 原生广告
|
||||
@@ -74,17 +74,17 @@ const AdSlot = ({ type = 'show' }) => {
|
||||
return <ins className="adsbygoogle"
|
||||
style={{ display: 'block', textAlign: 'center' }}
|
||||
data-ad-format="autorelaxed"
|
||||
data-adtest={BLOG.ADSENSE_GOOGLE_TEST ? 'on' : 'off'}
|
||||
data-ad-client={BLOG.ADSENSE_GOOGLE_ID}
|
||||
data-ad-slot={BLOG.ADSENSE_GOOGLE_SLOT_NATIVE}></ins>
|
||||
data-adtest={siteConfig('ADSENSE_GOOGLE_TEST') ? 'on' : 'off'}
|
||||
data-ad-client={siteConfig('ADSENSE_GOOGLE_ID')}
|
||||
data-ad-slot={siteConfig('ADSENSE_GOOGLE_SLOT_NATIVE')}></ins>
|
||||
}
|
||||
|
||||
// 展示广告
|
||||
return <ins className="adsbygoogle"
|
||||
style={{ display: 'block' }}
|
||||
data-ad-client={BLOG.ADSENSE_GOOGLE_ID}
|
||||
data-adtest={BLOG.ADSENSE_GOOGLE_TEST ? 'on' : 'off'}
|
||||
data-ad-slot={BLOG.ADSENSE_GOOGLE_SLOT_AUTO}
|
||||
data-ad-client={siteConfig('ADSENSE_GOOGLE_ID')}
|
||||
data-adtest={siteConfig('ADSENSE_GOOGLE_TEST') ? 'on' : 'off'}
|
||||
data-ad-slot={siteConfig('ADSENSE_GOOGLE_SLOT_AUTO')}
|
||||
data-ad-format="auto"
|
||||
data-full-width-responsive="true"></ins>
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Head from 'next/head'
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
|
||||
@@ -12,7 +12,7 @@ export default function LazyImage({
|
||||
id,
|
||||
src,
|
||||
alt,
|
||||
placeholderSrc = BLOG.IMG_LAZY_LOAD_PLACEHOLDER,
|
||||
placeholderSrc,
|
||||
className,
|
||||
width,
|
||||
height,
|
||||
@@ -22,6 +22,9 @@ export default function LazyImage({
|
||||
}) {
|
||||
const imageRef = useRef(null)
|
||||
const [imageLoaded, setImageLoaded] = useState(false)
|
||||
if (!placeholderSrc) {
|
||||
placeholderSrc = siteConfig('IMG_LAZY_LOAD_PLACEHOLDER')
|
||||
}
|
||||
|
||||
const handleImageLoad = () => {
|
||||
setImageLoaded(true)
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
/* eslint-disable no-undef */
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { loadExternalResource } from '@/lib/utils'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
export default function Live2D() {
|
||||
const { theme, switchTheme } = useGlobal()
|
||||
const showPet = JSON.parse(BLOG.WIDGET_PET)
|
||||
const showPet = JSON.parse(siteConfig('WIDGET_PET'))
|
||||
const petLink = siteConfig('WIDGET_PET_LINK')
|
||||
|
||||
useEffect(() => {
|
||||
if (showPet) {
|
||||
@@ -16,7 +17,7 @@ export default function Live2D() {
|
||||
if (typeof window?.loadlive2d !== 'undefined') {
|
||||
// https://github.com/xiazeyu/live2d-widget-models
|
||||
try {
|
||||
loadlive2d('live2d', BLOG.WIDGET_PET_LINK)
|
||||
loadlive2d('live2d', petLink)
|
||||
} catch (error) {
|
||||
console.error('读取PET模型', error)
|
||||
}
|
||||
@@ -26,7 +27,7 @@ export default function Live2D() {
|
||||
}, [theme])
|
||||
|
||||
function handleClick() {
|
||||
if (JSON.parse(BLOG.WIDGET_PET_SWITCH_THEME)) {
|
||||
if (JSON.parse(siteConfig('WIDGET_PET_SWITCH_THEME'))) {
|
||||
switchTheme()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,10 @@ import mediumZoom from '@fisch0920/medium-zoom'
|
||||
import React, { useEffect, useRef } from 'react'
|
||||
// import { Code } from 'react-notion-x/build/third-party/code'
|
||||
import TweetEmbed from 'react-tweet-embed'
|
||||
|
||||
import BLOG from '@/blog.config'
|
||||
import 'katex/dist/katex.min.css'
|
||||
import { mapImgUrl } from '@/lib/notion/mapImage'
|
||||
import { isBrowser } from '@/lib/utils'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
|
||||
const Code = dynamic(() =>
|
||||
import('react-notion-x/build/third-party/code').then(async (m) => {
|
||||
@@ -63,7 +62,7 @@ const NotionPage = ({ post, className }) => {
|
||||
|
||||
useEffect(() => {
|
||||
// 将相册gallery下的图片加入放大功能
|
||||
if (JSON.parse(BLOG.POST_DISABLE_GALLERY_CLICK)) {
|
||||
if (siteConfig('POST_DISABLE_GALLERY_CLICK')) {
|
||||
setTimeout(() => {
|
||||
if (isBrowser) {
|
||||
const imgList = document?.querySelectorAll('.notion-collection-card-cover img')
|
||||
|
||||
@@ -1,27 +1,54 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { loadExternalResource } from '@/lib/utils'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
|
||||
/**
|
||||
* 音乐播放器
|
||||
* @returns
|
||||
*/
|
||||
const Player = () => {
|
||||
const [player, setPlayer] = useState()
|
||||
const ref = useRef(null)
|
||||
const lrcType = JSON.parse(siteConfig('MUSIC_PLAYER_LRC_TYPE'))
|
||||
const playerVisible = JSON.parse(siteConfig('MUSIC_PLAYER_VISIBLE'))
|
||||
const autoPlay = JSON.parse(siteConfig('MUSIC_PLAYER_AUTO_PLAY'))
|
||||
const meting = JSON.parse(siteConfig('MUSIC_PLAYER_METING'))
|
||||
const order = siteConfig('MUSIC_PLAYER_ORDER')
|
||||
const audio = siteConfig('MUSIC_PLAYER_AUDIO_LIST')
|
||||
|
||||
const lrcType = JSON.parse(BLOG.MUSIC_PLAYER_LRC_TYPE)
|
||||
const playerVisible = JSON.parse(BLOG.MUSIC_PLAYER_VISIBLE)
|
||||
const autoPlay = JSON.parse(BLOG.MUSIC_PLAYER_AUTO_PLAY)
|
||||
const musicPlayerEnable = siteConfig('MUSIC_PLAYER')
|
||||
const musicPlayerCDN = siteConfig('MUSIC_PLAYER_CDN_URL')
|
||||
const musicMetingEnable = siteConfig('MUSIC_PLAYER_METING')
|
||||
const musicMetingCDNUrl = siteConfig('MUSIC_PLAYER_METING_CDN_URL', 'https://cdnjs.cloudflare.com/ajax/libs/meting/2.0.1/Meting.min.js')
|
||||
|
||||
const meting = JSON.parse(BLOG.MUSIC_PLAYER_METING)
|
||||
const initMusicPlayer = async () => {
|
||||
if (!musicPlayerEnable) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
await loadExternalResource(musicPlayerCDN, 'js')
|
||||
} catch (error) {
|
||||
console.error('音乐组件异常', error)
|
||||
}
|
||||
|
||||
if (musicMetingEnable) {
|
||||
await loadExternalResource(musicMetingCDNUrl, 'js')
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!meting && window.APlayer) {
|
||||
setPlayer(new window.APlayer({
|
||||
container: ref.current,
|
||||
fixed: true,
|
||||
lrcType: lrcType,
|
||||
autoplay: autoPlay,
|
||||
order: BLOG.MUSIC_PLAYER_ORDER,
|
||||
audio: BLOG.MUSIC_PLAYER_AUDIO_LIST
|
||||
order: order,
|
||||
audio: audio
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
initMusicPlayer()
|
||||
return () => {
|
||||
setPlayer(undefined)
|
||||
}
|
||||
@@ -39,11 +66,11 @@ const Player = () => {
|
||||
fixed="true"
|
||||
type="playlist"
|
||||
preload="auto"
|
||||
lrc-type={BLOG.MUSIC_PLAYER_METING_LRC_TYPE}
|
||||
lrc-type={siteConfig('MUSIC_PLAYER_METING_LRC_TYPE')}
|
||||
autoplay={autoPlay}
|
||||
order={BLOG.MUSIC_PLAYER_ORDER}
|
||||
server={BLOG.MUSIC_PLAYER_METING_SERVER}
|
||||
id={BLOG.MUSIC_PLAYER_METING_ID}
|
||||
order={siteConfig('MUSIC_PLAYER_ORDER')}
|
||||
server={siteConfig('MUSIC_PLAYER_METING_SERVER')}
|
||||
id={siteConfig('MUSIC_PLAYER_METING_ID')}
|
||||
/>
|
||||
: <div ref={ref} data-player={player} />
|
||||
}
|
||||
|
||||
@@ -10,10 +10,10 @@ import 'prismjs/plugins/line-numbers/prism-line-numbers'
|
||||
import 'prismjs/plugins/line-numbers/prism-line-numbers.css'
|
||||
|
||||
// mermaid图
|
||||
import BLOG from '@/blog.config'
|
||||
import { loadExternalResource } from '@/lib/utils'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
|
||||
/**
|
||||
* 代码美化相关
|
||||
@@ -23,22 +23,36 @@ import { useGlobal } from '@/lib/global'
|
||||
const PrismMac = () => {
|
||||
const router = useRouter()
|
||||
const { isDarkMode } = useGlobal()
|
||||
const codeMacBar = siteConfig('CODE_MAC_BAR')
|
||||
const prismjsAutoLoader = siteConfig('PRISM_JS_AUTO_LOADER')
|
||||
const prismjsPath = siteConfig('PRISM_JS_PATH')
|
||||
|
||||
const prismThemeSwitch = siteConfig('PRISM_THEME_SWITCH')
|
||||
const prismThemeDarkPath = siteConfig('PRISM_THEME_DARK_PATH')
|
||||
const prismThemeLightPath = siteConfig('PRISM_THEME_LIGHT_PATH')
|
||||
const prismThemePrefixPath = siteConfig('PRISM_THEME_PREFIX_PATH')
|
||||
|
||||
const mermaidCDN = siteConfig('MERMAID_CDN')
|
||||
const codeLineNumbers = siteConfig('CODE_LINE_NUMBERS')
|
||||
|
||||
const codeCollapse = siteConfig('CODE_COLLAPSE')
|
||||
const codeCollapseExpandDefault = siteConfig('CODE_COLLAPSE_EXPAND_DEFAULT')
|
||||
|
||||
useEffect(() => {
|
||||
if (JSON.parse(BLOG.CODE_MAC_BAR)) {
|
||||
if (codeMacBar) {
|
||||
loadExternalResource('/css/prism-mac-style.css', 'css')
|
||||
}
|
||||
// 加载prism样式
|
||||
loadPrismThemeCSS(isDarkMode)
|
||||
loadPrismThemeCSS(isDarkMode, prismThemeSwitch, prismThemeDarkPath, prismThemeLightPath, prismThemePrefixPath)
|
||||
// 折叠代码
|
||||
loadExternalResource(BLOG.PRISM_JS_AUTO_LOADER, 'js').then((url) => {
|
||||
loadExternalResource(prismjsAutoLoader, 'js').then((url) => {
|
||||
if (window?.Prism?.plugins?.autoloader) {
|
||||
window.Prism.plugins.autoloader.languages_path = BLOG.PRISM_JS_PATH
|
||||
window.Prism.plugins.autoloader.languages_path = prismjsPath
|
||||
}
|
||||
|
||||
renderPrismMac()
|
||||
renderMermaid()
|
||||
renderCollapseCode()
|
||||
renderPrismMac(codeLineNumbers)
|
||||
renderMermaid(mermaidCDN)
|
||||
renderCollapseCode(codeCollapse, codeCollapseExpandDefault)
|
||||
})
|
||||
}, [router, isDarkMode])
|
||||
|
||||
@@ -46,18 +60,18 @@ const PrismMac = () => {
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载样式
|
||||
* 加载Prism主题样式
|
||||
*/
|
||||
const loadPrismThemeCSS = (isDarkMode) => {
|
||||
const loadPrismThemeCSS = (isDarkMode, prismThemeSwitch, prismThemeDarkPath, prismThemeLightPath, prismThemePrefixPath) => {
|
||||
let PRISM_THEME
|
||||
let PRISM_PREVIOUS
|
||||
if (JSON.parse(BLOG.PRISM_THEME_SWITCH)) {
|
||||
if (prismThemeSwitch) {
|
||||
if (isDarkMode) {
|
||||
PRISM_THEME = BLOG.PRISM_THEME_DARK_PATH
|
||||
PRISM_PREVIOUS = BLOG.PRISM_THEME_LIGHT_PATH
|
||||
PRISM_THEME = prismThemeDarkPath
|
||||
PRISM_PREVIOUS = prismThemeLightPath
|
||||
} else {
|
||||
PRISM_THEME = BLOG.PRISM_THEME_LIGHT_PATH
|
||||
PRISM_PREVIOUS = BLOG.PRISM_THEME_DARK_PATH
|
||||
PRISM_THEME = prismThemeLightPath
|
||||
PRISM_PREVIOUS = prismThemeDarkPath
|
||||
}
|
||||
const previousTheme = document.querySelector(`link[href="${PRISM_PREVIOUS}"]`)
|
||||
if (previousTheme) {
|
||||
@@ -65,15 +79,15 @@ const loadPrismThemeCSS = (isDarkMode) => {
|
||||
}
|
||||
loadExternalResource(PRISM_THEME, 'css')
|
||||
} else {
|
||||
loadExternalResource(BLOG.PRISM_THEME_PREFIX_PATH, 'css')
|
||||
loadExternalResource(prismThemePrefixPath, 'css')
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 将代码块转为可折叠对象
|
||||
*/
|
||||
const renderCollapseCode = () => {
|
||||
if (!JSON.parse(BLOG.CODE_COLLAPSE)) {
|
||||
const renderCollapseCode = (codeCollapse, codeCollapseExpandDefault) => {
|
||||
if (!codeCollapse) {
|
||||
return
|
||||
}
|
||||
const codeBlocks = document.querySelectorAll('.code-toolbar')
|
||||
@@ -116,7 +130,7 @@ const renderCollapseCode = () => {
|
||||
// 点击后折叠展开代码
|
||||
header.addEventListener('click', collapseCode)
|
||||
// 是否自动展开
|
||||
if (JSON.parse(BLOG.CODE_COLLAPSE_EXPAND_DEFAULT)) {
|
||||
if (codeCollapseExpandDefault) {
|
||||
header.click()
|
||||
}
|
||||
}
|
||||
@@ -125,7 +139,7 @@ const renderCollapseCode = () => {
|
||||
/**
|
||||
* 将mermaid语言 渲染成图片
|
||||
*/
|
||||
const renderMermaid = async() => {
|
||||
const renderMermaid = async(mermaidCDN) => {
|
||||
const observer = new MutationObserver(async mutationsList => {
|
||||
for (const m of mutationsList) {
|
||||
if (m.target.className === 'notion-code language-mermaid') {
|
||||
@@ -146,7 +160,7 @@ const renderMermaid = async() => {
|
||||
}
|
||||
}
|
||||
if (needLoad) {
|
||||
loadExternalResource(BLOG.MERMAID_CDN, 'js').then(url => {
|
||||
loadExternalResource(mermaidCDN, 'js').then(url => {
|
||||
setTimeout(() => {
|
||||
const mermaid = window.mermaid
|
||||
mermaid?.contentLoaded()
|
||||
@@ -162,11 +176,11 @@ const renderMermaid = async() => {
|
||||
}
|
||||
}
|
||||
|
||||
function renderPrismMac() {
|
||||
function renderPrismMac(codeLineNumbers) {
|
||||
const container = document?.getElementById('notion-article')
|
||||
|
||||
// Add line numbers
|
||||
if (JSON.parse(BLOG.CODE_LINE_NUMBERS)) {
|
||||
if (codeLineNumbers) {
|
||||
const codeBlocks = container?.getElementsByTagName('pre')
|
||||
if (codeBlocks) {
|
||||
Array.from(codeBlocks).forEach(item => {
|
||||
@@ -200,7 +214,7 @@ function renderPrismMac() {
|
||||
}
|
||||
|
||||
// 折叠代码行号bug
|
||||
if (JSON.parse(BLOG.CODE_LINE_NUMBERS)) {
|
||||
if (codeLineNumbers) {
|
||||
fixCodeLineStyle()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { loadExternalResource } from '@/lib/utils'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
@@ -6,22 +6,26 @@ import { useEffect } from 'react'
|
||||
* 二维码生成
|
||||
*/
|
||||
export default function QrCode({ value }) {
|
||||
const qrCodeCDN = siteConfig('QR_CODE_CDN')
|
||||
|
||||
useEffect(() => {
|
||||
let qrcode
|
||||
if (!value) {
|
||||
return
|
||||
}
|
||||
loadExternalResource(BLOG.QR_CODE_CDN, 'js').then(url => {
|
||||
const QRCode = window.QRCode
|
||||
qrcode = new QRCode(document.getElementById('qrcode'), {
|
||||
text: value,
|
||||
width: 256,
|
||||
height: 256,
|
||||
colorDark: '#000000',
|
||||
colorLight: '#ffffff',
|
||||
correctLevel: QRCode.CorrectLevel.H
|
||||
})
|
||||
// console.log('二维码', qrcode, value)
|
||||
loadExternalResource(qrCodeCDN, 'js').then(url => {
|
||||
const QRCode = window?.QRCode
|
||||
if (typeof QRCode !== 'undefined') {
|
||||
qrcode = new QRCode(document.getElementById('qrcode'), {
|
||||
text: value,
|
||||
width: 256,
|
||||
height: 256,
|
||||
colorDark: '#000000',
|
||||
colorLight: '#ffffff',
|
||||
correctLevel: QRCode.CorrectLevel.H
|
||||
})
|
||||
// console.log('二维码', qrcode, value)
|
||||
}
|
||||
})
|
||||
return () => {
|
||||
if (qrcode) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useRouter } from 'next/router'
|
||||
import React from 'react'
|
||||
import ShareButtons from './ShareButtons'
|
||||
@@ -6,18 +6,18 @@ import ShareButtons from './ShareButtons'
|
||||
const ShareBar = ({ post }) => {
|
||||
const router = useRouter()
|
||||
|
||||
if (!JSON.parse(BLOG.POST_SHARE_BAR_ENABLE) || !post || post?.type !== 'Post') {
|
||||
if (!JSON.parse(siteConfig('POST_SHARE_BAR_ENABLE')) || !post || post?.type !== 'Post') {
|
||||
return <></>
|
||||
}
|
||||
|
||||
const shareUrl = BLOG.LINK + router.asPath
|
||||
const shareUrl = siteConfig('LINK') + router.asPath
|
||||
|
||||
return <div className='m-1 overflow-x-auto'>
|
||||
<div className='flex w-full md:justify-end'>
|
||||
<ShareButtons shareUrl={shareUrl} title={post.title} image={post.pageCover} body={
|
||||
post?.title +
|
||||
' | ' +
|
||||
BLOG.TITLE +
|
||||
siteConfig('TITLE') +
|
||||
' ' +
|
||||
shareUrl +
|
||||
' ' +
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import copy from 'copy-to-clipboard'
|
||||
import dynamic from 'next/dynamic'
|
||||
@@ -57,8 +57,8 @@ const QrCode = dynamic(() => import('@/components/QrCode'), { ssr: false })
|
||||
* @returns
|
||||
*/
|
||||
const ShareButtons = ({ shareUrl, title, body, image }) => {
|
||||
const services = BLOG.POSTS_SHARE_SERVICES.split(',')
|
||||
const titleWithSiteInfo = title + ' | ' + BLOG.TITLE
|
||||
const services = siteConfig('POSTS_SHARE_SERVICES').split(',')
|
||||
const titleWithSiteInfo = title + ' | ' + siteConfig('TITLE')
|
||||
const { locale } = useGlobal()
|
||||
const [qrCodeShow, setQrCodeShow] = useState(false)
|
||||
|
||||
@@ -93,7 +93,7 @@ const ShareButtons = ({ shareUrl, title, body, image }) => {
|
||||
<FacebookMessengerShareButton
|
||||
key={singleService}
|
||||
url={shareUrl}
|
||||
appId={BLOG.FACEBOOK_APP_ID}
|
||||
appId={siteConfig('FACEBOOK_APP_ID')}
|
||||
className="mx-1"
|
||||
>
|
||||
<FacebookMessengerIcon size={32} round />
|
||||
|
||||
@@ -12,7 +12,7 @@ const Tabs = ({ className, children }) => {
|
||||
return <></>
|
||||
}
|
||||
|
||||
children = children.filter(c => c !== '')
|
||||
children = children.filter(c => c && c !== '')
|
||||
|
||||
let count = 0
|
||||
children.forEach(e => {
|
||||
|
||||
@@ -1,21 +1,25 @@
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import React, { useState } from 'react'
|
||||
import { useState } from 'react'
|
||||
import { Draggable } from './Draggable'
|
||||
import { THEMES } from '@/themes/theme'
|
||||
import { useRouter } from 'next/router'
|
||||
import DarkModeButton from './DarkModeButton'
|
||||
import { getQueryParam } from '@/lib/utils'
|
||||
import LANGS from '@/lib/lang'
|
||||
/**
|
||||
*
|
||||
* @returns 主题切换
|
||||
*/
|
||||
const ThemeSwitch = () => {
|
||||
const { theme } = useGlobal()
|
||||
const { theme, lang, changeLang, locale, isDarkMode, toggleDarkMode } = useGlobal()
|
||||
const router = useRouter()
|
||||
const currentTheme = getQueryParam(router.asPath, 'theme') || theme
|
||||
// const currentLang = getQueryParam(router.asPath, 'lang') || lang
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
|
||||
// 修改当前路径url中的 theme 参数
|
||||
// 例如 http://localhost?theme=hexo 跳转到 http://localhost?theme=newTheme
|
||||
const onSelectChange = (e) => {
|
||||
const onThemeSelectChange = (e) => {
|
||||
setIsLoading(true)
|
||||
const newTheme = e.target.value
|
||||
const query = router.query
|
||||
@@ -25,27 +29,52 @@ const ThemeSwitch = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const onLangSelectChange = (e) => {
|
||||
const newLang = e.target.value
|
||||
changeLang(newLang)
|
||||
}
|
||||
|
||||
return (<>
|
||||
<Draggable>
|
||||
<div id="draggableBox" style={{ left: '10px', top: '80vh' }} className="fixed z-50 dark:text-white bg-gray-50 dark:bg-black rounded-2xl drop-shadow-lg">
|
||||
<div className="p-3 w-full flex items-center text-sm group duration-200 transition-all">
|
||||
<DarkModeButton className='mr-2' />
|
||||
<div className='w-0 group-hover:w-20 transition-all duration-200 overflow-hidden'>
|
||||
<select value={theme} onChange={onSelectChange} name="themes" className='appearance-none outline-none dark:text-white bg-gray-50 dark:bg-black uppercase cursor-pointer'>
|
||||
<div id="draggableBox" style={{ left: '0px', top: '80vh' }} className="fixed group space-y-2 overflow-hidden z-50 p-3 flex flex-col items-start dark:text-white bg-gray-50 dark:bg-black rounded-xl shadow-lg border dark:border-gray-800">
|
||||
{/* 深色按钮 */}
|
||||
<div className="text-sm flex items-center w-0 group-hover:w-32 transition-all duration-200">
|
||||
<DarkModeButton />
|
||||
<div onClick={toggleDarkMode} className='cursor-pointer w-0 group-hover:w-24 transition-all duration-200 overflow-hidden whitespace-nowrap pl-1 h-auto'>{isDarkMode ? locale.MENU.DARK_MODE : locale.MENU.LIGHT_MODE}</div>
|
||||
</div>
|
||||
|
||||
{/* 翻译按钮 */}
|
||||
<div className="text-sm flex items-center group-hover:w-32 transition-all duration-200">
|
||||
<i className="fa-solid fa-language w-5" />
|
||||
<div className='w-0 group-hover:w-24 transition-all duration-200 overflow-hidden'>
|
||||
<select value={lang} onChange={onLangSelectChange} name="themes" className='pl-1 bg-gray-50 dark:bg-black appearance-none outline-none dark:text-white uppercase cursor-pointer'>
|
||||
{Object.keys(LANGS)?.map(t => {
|
||||
return <option key={t} value={t}>{LANGS[t].LOCALE}</option>
|
||||
})}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 主题切换按钮 */}
|
||||
<div className="text-sm flex items-center group-hover:w-32 transition-all duration-200">
|
||||
<i className="fa-solid fa-palette w-5" />
|
||||
<div className='w-0 group-hover:w-24 transition-all duration-200 overflow-hidden'>
|
||||
<select value={currentTheme} onChange={onThemeSelectChange} name="themes" className='pl-1 bg-gray-50 dark:bg-black appearance-none outline-none dark:text-white uppercase cursor-pointer'>
|
||||
{THEMES?.map(t => {
|
||||
return <option key={t} value={t}>{t}</option>
|
||||
})}
|
||||
</select>
|
||||
</div>
|
||||
<i className="fa-solid fa-palette pl-2"></i>
|
||||
</div>
|
||||
</div>
|
||||
{/* 切换主题加载时的全屏遮罩 */}
|
||||
<div className={`${isLoading ? 'opacity-50 ' : 'opacity-0'} w-screen h-screen bg-black text-white shadow-text flex justify-center items-center
|
||||
transition-all fixed top-0 left-0 pointer-events-none duration-1000 z-50 shadow-inner`}>
|
||||
<i className='text-3xl mr-5 fas fa-spinner animate-spin' />
|
||||
</div>
|
||||
</Draggable>
|
||||
|
||||
{/* 切换主题加载时的全屏遮罩 */}
|
||||
<div className={`${isLoading ? 'opacity-50 ' : 'opacity-0'}
|
||||
w-screen h-screen bg-black text-white shadow-text flex justify-center items-center
|
||||
transition-all fixed top-0 left-0 pointer-events-none duration-1000 z-50 shadow-inner`}>
|
||||
<i className='text-3xl mr-5 fas fa-spinner animate-spin' />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
// import { loadExternalResource } from '@/lib/utils'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
@@ -10,14 +10,21 @@ import { useEffect } from 'react'
|
||||
*/
|
||||
|
||||
const Twikoo = ({ isDarkMode }) => {
|
||||
const envId = siteConfig('COMMENT_TWIKOO_ENV_ID')
|
||||
const el = siteConfig('COMMENT_TWIKOO_ELEMENT_ID', '#twikoo')
|
||||
|
||||
const lang = siteConfig('LANG')
|
||||
useEffect(() => {
|
||||
window?.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,需传此参数
|
||||
})
|
||||
const twikoo = window?.twikoo
|
||||
if (typeof twikoo !== 'undefined' && twikoo && typeof twikoo.init === 'function') {
|
||||
twikoo.init({
|
||||
envId: envId, // 腾讯云环境填 envId;Vercel 环境填地址(https://xxx.vercel.app)
|
||||
el: el, // 容器元素
|
||||
lang: 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,需传此参数
|
||||
})
|
||||
}
|
||||
}, [isDarkMode])
|
||||
return (
|
||||
<div id="twikoo"></div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
// import twikoo from 'twikoo'
|
||||
|
||||
/**
|
||||
@@ -8,7 +8,7 @@ import BLOG from '@/blog.config'
|
||||
*/
|
||||
|
||||
const TwikooCommentCount = ({ post, className }) => {
|
||||
if (!JSON.parse(BLOG.COMMENT_TWIKOO_COUNT_ENABLE)) {
|
||||
if (!JSON.parse(siteConfig('COMMENT_TWIKOO_COUNT_ENABLE'))) {
|
||||
return null
|
||||
}
|
||||
return <a href={`${post.slug}?target=comment`} className={`mx-1 hidden comment-count-wrapper-${post.id} ${className || ''}`}>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { loadExternalResource } from '@/lib/utils'
|
||||
import { useRouter } from 'next/router'
|
||||
@@ -13,16 +13,37 @@ import { useEffect } from 'react'
|
||||
const TwikooCommentCounter = (props) => {
|
||||
let commentsData = []
|
||||
const { theme } = useGlobal()
|
||||
const router = useRouter()
|
||||
|
||||
useEffect(() => {
|
||||
// console.log('路由触发评论计数')
|
||||
if (props?.posts && props?.posts?.length > 0) {
|
||||
fetchTwikooData(props.posts)
|
||||
}
|
||||
}, [router.events])
|
||||
|
||||
// 监控主题变化时的的评论数
|
||||
useEffect(() => {
|
||||
// console.log('主题触发评论计数', commentsData)
|
||||
updateCommentCount()
|
||||
}, [theme])
|
||||
|
||||
const twikooCDNURL = siteConfig('COMMENT_TWIKOO_CDN_URL')
|
||||
const twikooENVID = siteConfig('COMMENT_TWIKOO_ENV_ID')
|
||||
|
||||
/**
|
||||
* 加载外部twikoojs
|
||||
* @param {*} posts
|
||||
*/
|
||||
const fetchTwikooData = async (posts) => {
|
||||
posts.forEach(post => {
|
||||
post.slug = post.slug.startsWith('/') ? post.slug : `/${post.slug}`
|
||||
})
|
||||
try {
|
||||
await loadExternalResource(BLOG.COMMENT_TWIKOO_CDN_URL, 'js')
|
||||
await loadExternalResource(twikooCDNURL, 'js')
|
||||
const twikoo = window.twikoo
|
||||
twikoo.getCommentsCount({
|
||||
envId: BLOG.COMMENT_TWIKOO_ENV_ID, // 环境 ID
|
||||
envId: twikooENVID, // 环境 ID
|
||||
// region: 'ap-guangzhou', // 环境地域,默认为 ap-shanghai,如果您的环境地域不是上海,需传此参数
|
||||
urls: posts?.map(post => post.slug), // 不包含协议、域名、参数的文章路径列表,必传参数
|
||||
includeReply: true // 评论数是否包括回复,默认:false
|
||||
@@ -58,20 +79,7 @@ const TwikooCommentCounter = (props) => {
|
||||
}
|
||||
})
|
||||
}
|
||||
const router = useRouter()
|
||||
|
||||
useEffect(() => {
|
||||
// console.log('路由触发评论计数')
|
||||
if (props?.posts && props?.posts?.length > 0) {
|
||||
fetchTwikooData(props.posts)
|
||||
}
|
||||
}, [router.events])
|
||||
|
||||
// 监控主题变化时的的评论数
|
||||
useEffect(() => {
|
||||
// console.log('主题触发评论计数', commentsData)
|
||||
updateCommentCount()
|
||||
}, [theme])
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
/**
|
||||
@@ -11,9 +11,9 @@ import { useEffect } from 'react'
|
||||
const Utterances = ({ issueTerm, layout }) => {
|
||||
useEffect(() => {
|
||||
const theme =
|
||||
BLOG.APPEARANCE === 'auto'
|
||||
siteConfig('APPEARANCE') === 'auto'
|
||||
? 'preferred-color-scheme'
|
||||
: BLOG.APPEARANCE === 'light'
|
||||
: siteConfig('APPEARANCE') === 'light'
|
||||
? 'github-light'
|
||||
: 'github-dark'
|
||||
const script = document.createElement('script')
|
||||
@@ -21,7 +21,7 @@ const Utterances = ({ issueTerm, layout }) => {
|
||||
script.setAttribute('src', 'https://utteranc.es/client.js')
|
||||
script.setAttribute('crossorigin', 'anonymous')
|
||||
script.setAttribute('async', true)
|
||||
script.setAttribute('repo', BLOG.COMMENT_UTTERRANCES_REPO)
|
||||
script.setAttribute('repo', siteConfig('COMMENT_UTTERRANCES_REPO'))
|
||||
script.setAttribute('issue-term', 'title')
|
||||
script.setAttribute('theme', theme)
|
||||
anchor.appendChild(script)
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { loadExternalResource } from '@/lib/utils'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
const ValineComponent = ({ path }) => {
|
||||
const loadValine = async () => {
|
||||
try {
|
||||
await loadExternalResource(BLOG.COMMENT_VALINE_CDN, 'js')
|
||||
await loadExternalResource(siteConfig('COMMENT_VALINE_CDN'), 'js')
|
||||
const Valine = window.Valine
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const valine = new Valine({
|
||||
el: '#valine', // 容器元素
|
||||
lang: BLOG.LANG, // 用于手动设定评论区语言,支持的语言列表 https://github.com/imaegoo/twikoo/blob/main/src/client/utils/i18n/index.js
|
||||
appId: BLOG.COMMENT_VALINE_APP_ID,
|
||||
appKey: BLOG.COMMENT_VALINE_APP_KEY,
|
||||
lang: siteConfig('LANG'), // 用于手动设定评论区语言,支持的语言列表 https://github.com/imaegoo/twikoo/blob/main/src/client/utils/i18n/index.js
|
||||
appId: siteConfig('COMMENT_VALINE_APP_ID'),
|
||||
appKey: siteConfig('COMMENT_VALINE_APP_KEY'),
|
||||
avatar: '',
|
||||
path,
|
||||
recordIP: true,
|
||||
placeholder: BLOG.COMMENT_VALINE_PLACEHOLDER,
|
||||
serverURLs: BLOG.COMMENT_VALINE_SERVER_URLS,
|
||||
placeholder: siteConfig('COMMENT_VALINE_PLACEHOLDER'),
|
||||
serverURLs: siteConfig('COMMENT_VALINE_SERVER_URLS'),
|
||||
visitor: true
|
||||
})
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react'
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
|
||||
/**
|
||||
* 万维广告插件
|
||||
@@ -8,11 +7,13 @@ import BLOG from '@/blog.config'
|
||||
* @returns {JSX.Element | null} - 返回渲染的 JSX 元素或 null
|
||||
*/
|
||||
export default function WWAds({ orientation = 'vertical', sticky = false, className }) {
|
||||
if (!JSON.parse(BLOG.AD_WWADS_ID)) {
|
||||
const adWWADSId = siteConfig('AD_WWADS_ID')
|
||||
|
||||
if (!adWWADSId) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`wwads-cn ${orientation === 'vertical' ? 'wwads-vertical' : 'wwads-horizontal'} ${sticky ? 'wwads-sticky' : ''} z-10 ${className || ''}`} data-id={BLOG.AD_WWADS_ID}></div>
|
||||
)
|
||||
return <div data-id={adWWADSId} className={`wwads-cn
|
||||
${orientation === 'vertical' ? 'wwads-vertical' : 'wwads-horizontal'}
|
||||
${sticky ? 'wwads-sticky' : ''} z-10 ${className || ''}`} />
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React from 'react'
|
||||
import React, { createRef } from 'react'
|
||||
import { init } from '@waline/client'
|
||||
import BLOG from '@/blog.config'
|
||||
import { useRouter } from 'next/router'
|
||||
import '@waline/client/dist/waline.css'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
|
||||
const path = ''
|
||||
let waline = null
|
||||
@@ -12,7 +12,7 @@ let waline = null
|
||||
* @returns
|
||||
*/
|
||||
const WalineComponent = (props) => {
|
||||
const containerRef = React.createRef()
|
||||
const containerRef = createRef()
|
||||
const router = useRouter()
|
||||
|
||||
const updateWaline = url => {
|
||||
@@ -26,8 +26,8 @@ const WalineComponent = (props) => {
|
||||
waline = init({
|
||||
...props,
|
||||
el: containerRef.current,
|
||||
serverURL: BLOG.COMMENT_WALINE_SERVER_URL,
|
||||
lang: BLOG.lang,
|
||||
serverURL: siteConfig('COMMENT_WALINE_SERVER_URL'),
|
||||
lang: siteConfig('LANG'),
|
||||
reaction: true,
|
||||
dark: 'html.dark',
|
||||
emoji: [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import Image from 'next/image'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
|
||||
/**
|
||||
* 评论插件
|
||||
@@ -78,7 +78,7 @@ const WebmentionReplies = ({ target }) => {
|
||||
const [mentions, setMentions] = useState([])
|
||||
const fetchMentions = async (target) =>
|
||||
fetch(
|
||||
`https://webmention.io/api/mentions.jf2?per-page=500&target=${encodeURIComponent(target)}&token=${BLOG.COMMENT_WEBMENTION.TOKEN}`
|
||||
`https://webmention.io/api/mentions.jf2?per-page=500&target=${encodeURIComponent(target)}&token=${siteConfig('COMMENT_WEBMENTION_TOKEN')}`
|
||||
).then((response) => (response.json ? response.json() : response))
|
||||
useEffect(() => {
|
||||
async function getMentions() {
|
||||
@@ -137,8 +137,8 @@ const WebmentionReplies = ({ target }) => {
|
||||
|
||||
const WebMentionBlock = ({ frontMatter }) => {
|
||||
const router = useRouter()
|
||||
const url = `https://${BLOG.COMMENT_WEBMENTION.HOSTNAME}${router.asPath}`
|
||||
const tweet = `${frontMatter.title} by @${BLOG.COMMENT_WEBMENTION.TWITTER_USERNAME} ${url}`
|
||||
const url = `https://${siteConfig('COMMENT_WEBMENTION_HOSTNAME')}${router.asPath}`
|
||||
const tweet = `${frontMatter.title} by @${siteConfig('COMMENT_WEBMENTION_TWITTER_USERNAME')} ${url}`
|
||||
|
||||
return (
|
||||
<div className='webmention-block'>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import ExternalScript from './ExternalScript'
|
||||
|
||||
/**
|
||||
@@ -10,8 +10,8 @@ export default function WebWhiz() {
|
||||
const props = {
|
||||
id: '__webwhizSdk__',
|
||||
src: 'https://www.unpkg.com/webwhiz@1.0.0/dist/sdk.js',
|
||||
baseUrl: BLOG.WEB_WHIZ_BASE_URL,
|
||||
chatbotId: BLOG.WEB_WHIZ_CHAT_BOT_ID
|
||||
baseUrl: siteConfig('WEB_WHIZ_BASE_URL'),
|
||||
chatbotId: siteConfig('WEB_WHIZ_CHAT_BOT_ID')
|
||||
}
|
||||
return <ExternalScript {...props}/>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user