部分公共组件配置化

This commit is contained in:
tangly1024.com
2023-11-08 19:05:35 +08:00
parent f96aa2242f
commit b2759c6d5e
34 changed files with 301 additions and 239 deletions

View File

@@ -4,42 +4,45 @@ 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 +56,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)

View File

@@ -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>

View File

@@ -1,4 +1,3 @@
import BLOG from '@/blog.config'
import { siteConfig } from '@/lib/config'
import { loadExternalResource } from '@/lib/utils'
// import { loadExternalResource } from '@/lib/utils'
@@ -12,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: siteConfig('TITLE') // 你的站点名
site: site // 你的站点名
})
}, [])
}
return (
<div id="artalk"></div>
)

View File

@@ -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"

View File

@@ -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
@@ -85,41 +78,41 @@ 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'>
{siteConfig('COMMENT_ARTALK_SERVER') && (<div key='Artalk'>
<Artalk />
</div>)}
{BLOG.COMMENT_TWIKOO_ENV_ID && (<div key='Twikoo'>
{siteConfig('COMMENT_TWIKOO_ENV_ID') && (<div key='Twikoo'>
<TwikooCompenent />
</div>)}
{BLOG.COMMENT_WALINE_SERVER_URL && (<div key='Waline'>
{siteConfig('COMMENT_WALINE_SERVER_URL') && (<div key='Waline'>
<WalineComponent />
</div>)}
{BLOG.COMMENT_VALINE_APP_ID && (<div key='Valine' name='reply'>
{siteConfig('COMMENT_VALINE_APP_ID') && (<div key='Valine' name='reply'>
<ValineComponent path={frontMatter.id} />
</div>)}
{BLOG.COMMENT_GISCUS_REPO && (
{siteConfig('COMMENT_GISCUS_REPO') && (
<div key="Giscus">
<GiscusComponent className="px-2" />
</div>
)}
{BLOG.COMMENT_CUSDIS_APP_ID && (<div key='Cusdis'>
{siteConfig('COMMENT_CUSDIS_APP_ID') && (<div key='Cusdis'>
<CusdisComponent frontMatter={frontMatter} />
</div>)}
{BLOG.COMMENT_UTTERRANCES_REPO && (<div key='Utterance'>
{siteConfig('COMMENT_UTTERRANCES_REPO') && (<div key='Utterance'>
<UtterancesComponent issueTerm={frontMatter.id} className='px-2' />
</div>)}
{BLOG.COMMENT_GITALK_CLIENT_ID && (<div key='GitTalk'>
{siteConfig('COMMENT_GITALK_CLIENT_ID') && (<div key='GitTalk'>
<GitalkComponent frontMatter={frontMatter} />
</div>)}
{BLOG.COMMENT_WEBMENTION_ENABLE && (<div key='WebMention'>
{siteConfig('COMMENT_WEBMENTION_ENABLE') && (<div key='WebMention'>
<WebMentionComponent frontMatter={frontMatter} className="px-2" />
</div>)}
</Tabs>

View File

@@ -1,7 +1,7 @@
import BLOG from '@/blog.config'
/**
* 第三方代码 统计脚本
* 统计脚本
* @returns {JSX.Element}
* @constructor
*/
@@ -60,15 +60,6 @@ const CommonScript = () => {
}}/>
</>)}
{/* 代码统计 */}
{/* 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
@@ -116,9 +107,6 @@ const CommonScript = () => {
/>
</>)}
{/* 引入音乐播放 */}
{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" />}
</>)
}

View File

@@ -1,17 +1,18 @@
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 { lang } = useGlobal()
const router = useRouter()
const { isDarkMode } = useGlobal()
const src = siteConfig('COMMENT_CUSDIS_SCRIPT_SRC')
// 处理cusdis主题
useEffect(() => {
loadExternalResource(BLOG.COMMENT_CUSDIS_SCRIPT_SRC, 'js').then(url => {
loadExternalResource(src, 'js').then(url => {
const CUSDIS = window.CUSDIS
CUSDIS?.initial()
})
@@ -19,10 +20,10 @@ const CusdisComponent = ({ frontMatter }) => {
return <div id="cusdis_thread"
lang={lang.toLowerCase()}
data-host={BLOG.COMMENT_CUSDIS_HOST}
data-app-id={BLOG.COMMENT_CUSDIS_APP_ID}
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>

View File

@@ -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(() => {

View File

@@ -22,7 +22,6 @@ const DebugPanel = () => {
useEffect(() => {
updateSiteConfig(Object.assign({}, siteConfigMap()))
// updateThemeConfig(Object.assign({}, ThemeMap[BLOG.THEME].THEME_CONFIG))
}, [])
function toggleShow() {

View File

@@ -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}
/>
}

View File

@@ -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>
}

View File

@@ -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,

View File

@@ -1,4 +1,5 @@
import BLOG from '@/blog.config'
import { siteConfig } from '@/lib/config'
import { useGlobal } from '@/lib/global'
import Giscus from '@giscus/react'
@@ -15,17 +16,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')}
/>
)
}

View File

@@ -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()
}, [])

View File

@@ -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>
}

View File

@@ -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)

View File

@@ -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()
}
}

View File

@@ -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')

View File

@@ -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} />
}

View File

@@ -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()
}
}

View File

@@ -1,4 +1,4 @@
import BLOG from '@/blog.config'
import { siteConfig } from '@/lib/config'
import { loadExternalResource } from '@/lib/utils'
import { useEffect } from 'react'
@@ -6,12 +6,14 @@ 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 => {
loadExternalResource(qrCodeCDN, 'js').then(url => {
const QRCode = window.QRCode
qrcode = new QRCode(document.getElementById('qrcode'), {
text: value,

View File

@@ -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 +
' ' +

View File

@@ -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 />

View File

@@ -1,4 +1,4 @@
import BLOG from '@/blog.config'
import { siteConfig } from '@/lib/config'
// import { loadExternalResource } from '@/lib/utils'
import { useEffect } from 'react'
@@ -10,11 +10,15 @@ 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, // 腾讯云环境填 envIdVercel 环境填地址https://xxx.vercel.app
el: '#twikoo', // 容器元素
lang: BLOG.LANG // 用于手动设定评论区语言,支持的语言列表 https://github.com/imaegoo/twikoo/blob/main/src/client/utils/i18n/index.js
envId: envId, // 腾讯云环境填 envIdVercel 环境填地址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-guangzhouVercel 环境不填
// path: location.pathname, // 用于区分不同文章的自定义 js 路径,如果您的文章路径不是 location.pathname需传此参数
})

View File

@@ -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 || ''}`}>

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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) {

View File

@@ -1,5 +1,5 @@
import React from 'react'
import BLOG from '@/blog.config'
import { siteConfig } from '@/lib/config'
/**
* 万维广告插件
@@ -8,11 +8,11 @@ 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)) {
if (!JSON.parse(siteConfig('AD_WWADS_ID'))) {
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>
<div className={`wwads-cn ${orientation === 'vertical' ? 'wwads-vertical' : 'wwads-horizontal'} ${sticky ? 'wwads-sticky' : ''} z-10 ${className || ''}`} data-id={siteConfig('AD_WWADS_ID')}></div>
)
}

View File

@@ -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: [

View File

@@ -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'>

View File

@@ -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}/>
}

View File

@@ -5,7 +5,7 @@ import { useGlobal } from './global'
import { deepClone } from './utils'
/**
* 读取配置
* 读取配置顺序
* 1. 优先读取NotionConfig表
* 2. 其次读取环境变量
* 3. 再读取blog.config.js / 或各个主题的CONFIG文件

View File

@@ -21,7 +21,7 @@ import SearchNav from './components/SearchNav'
import BlogPostArchive from './components/BlogPostArchive'
import { ArticleLock } from './components/ArticleLock'
import PostHeader from './components/PostHeader'
import Comment, { commentEnable } from '@/components/Comment'
import Comment from '@/components/Comment'
import NotionPage from '@/components/NotionPage'
import ArticleAdjacent from './components/ArticleAdjacent'
import ArticleCopyright from './components/ArticleCopyright'
@@ -310,6 +310,9 @@ const LayoutSlug = props => {
<PostHeader {...props} />
</header>
)
const commentEnable = siteConfig('COMMENT_TWIKOO_ENV_ID') || siteConfig('COMMENT_WALINE_SERVER_URL') || siteConfig('COMMENT_VALINE_APP_ID') ||
siteConfig('COMMENT_GISCUS_REPO') || siteConfig('COMMENT_CUSDIS_APP_ID') || siteConfig('COMMENT_UTTERRANCES_REPO') ||
siteConfig('COMMENT_GITALK_CLIENT_ID') || siteConfig('COMMENT_WEBMENTION_ENABLE')
return (
<LayoutBase