Merge branch 'main' into pr/noeFly/3223

This commit is contained in:
tangly1024
2025-04-11 18:18:17 +08:00
17 changed files with 243 additions and 106 deletions

View File

@@ -1,10 +1,10 @@
import { useEffect, useState } from 'react'
import Select from './Select'
import { siteConfigMap } from '@/lib/config'
import { useGlobal } from '@/lib/global'
import { getQueryParam } from '@/lib/utils'
import { THEMES } from '@/themes/theme'
import { useRouter } from 'next/router'
import { siteConfigMap } from '@/lib/config'
import { getQueryParam } from '@/lib/utils'
import { useEffect, useState } from 'react'
import Select from './Select'
/**
*
@@ -50,79 +50,83 @@ const DebugPanel = () => {
}
return (
<>
{/* 调试按钮 */}
<div>
<div
style={{ writingMode: 'vertical-lr' }}
className={`bg-black text-xs text-white shadow-2xl p-1.5 rounded-l-xl cursor-pointer ${show ? 'right-96' : 'right-0'} fixed bottom-72 duration-200 z-50`}
onClick={toggleShow}
>
{show
? <i className="fas fa-times">&nbsp;{locale.COMMON.DEBUG_CLOSE}</i>
: <i className="fas fa-tools">&nbsp;{locale.COMMON.DEBUG_OPEN}</i>}
</div>
</div>
<>
{/* 调试按钮 */}
<div>
<div
style={{ writingMode: 'vertical-lr' }}
className={`bg-black text-xs text-white shadow-2xl p-1.5 rounded-l-xl cursor-pointer ${show ? 'right-96' : 'right-0'} fixed bottom-72 duration-200 z-50`}
onClick={toggleShow}>
{show ? (
<i className='fas fa-times'>&nbsp;{locale.COMMON.DEBUG_CLOSE}</i>
) : (
<i className='fas fa-tools'>&nbsp;{locale.COMMON.DEBUG_OPEN}</i>
)}
</div>
</div>
{/* 调试侧拉抽屉 */}
{/* 调试侧拉抽屉 */}
<div
className={` ${show ? 'shadow-card w-96 right-0 ' : '-right-96 invisible w-0'} overflow-y-scroll h-full p-5 bg-white fixed bottom-0 z-50 duration-200`}>
<div className='flex justify-between space-x-1 my-5'>
<div className='flex-col px-5'>
<Select
label={locale.COMMON.THEME_SWITCH}
value={currentTheme}
options={themeOptions}
onChange={handleUpdateDebugTheme}
/>
<div
className={` ${show ? 'shadow-card w-96 right-0 ' : '-right-96 invisible w-0'} overflow-y-scroll h-full p-5 bg-white fixed bottom-0 z-50 duration-200`}
>
<div className="flex justify-between space-x-1 my-5">
<div className='flex'>
<Select
label={locale.COMMON.THEME_SWITCH}
value={currentTheme}
options={themeOptions}
onChange={handleUpdateDebugTheme}
/>
<div className="p-2 cursor-pointer" onClick={handleChangeDebugTheme}>
<i className="fas fa-sync" />
</div>
</div>
<div className='p-2'>
<i className='fas fa-times' onClick={toggleShow}/>
</div>
</div>
<div>
{/* <div>
<div className="font-bold w-18 border-b my-2">
主题配置{`config_${debugTheme}.js`}:
</div>
<div className="text-xs">
{Object.keys(themeConfig).map(k => (
<div key={k} className="justify-between flex py-1">
<span className="bg-indigo-500 p-0.5 rounded text-white mr-2">
{k}
</span>
<span className="whitespace-nowrap">
{filterResult(themeConfig[k] + '')}
</span>
</div>
))}
</div>
</div> */}
<div className="font-bold w-18 border-b my-2">
站点配置[blog.config.js]
</div>
<div className="text-xs">
{siteConfig && Object.keys(siteConfig).map(k => (
<div key={k} className="justify-between flex py-1">
<span className="bg-blue-500 p-0.5 rounded text-white mr-2">
{k}
</span>
<span className="whitespace-nowrap">
{filterResult(siteConfig[k] + '')}
</span>
</div>
))}
</div>
</div>
className='p-2 cursor-pointer'
onClick={handleChangeDebugTheme}>
<i className='fas fa-sync' />
</div>
</>
</div>
<div className='p-2'>
<i className='fas fa-times' onClick={toggleShow} />
</div>
</div>
<div className='flex-col px-5'>
{/*
<div>
<div className="font-bold w-18 border-b my-2">
主题配置{`config_${debugTheme}.js`}:
</div>
<div className="text-xs">
{Object.keys(themeConfig).map(k => (
<div key={k} className="justify-between flex py-1">
<span className="bg-indigo-500 p-0.5 rounded text-white mr-2">
{k}
</span>
<span className="whitespace-nowrap">
{filterResult(themeConfig[k] + '')}
</span>
</div>
))}
</div>
</div>
*/}
<div className='font-bold w-18 border-b my-2'>
站点配置[blog.config.js]
</div>
<div className='text-xs'>
{siteConfig &&
Object.keys(siteConfig).map(k => (
<div key={k} className='justify-between flex py-1'>
<span className='bg-blue-500 p-0.5 rounded text-white mr-2'>
{k}
</span>
<span className='whitespace-nowrap'>
{filterResult(siteConfig[k] + '')}
</span>
</div>
))}
</div>
</div>
</div>
</>
)
}
export default DebugPanel

View File

@@ -11,6 +11,8 @@ import Head from 'next/head'
import ExternalScript from './ExternalScript'
import WebWhiz from './Webwhiz'
import { useGlobal } from '@/lib/global'
import IconFont from './IconFont'
/**
* 各种插件脚本
@@ -126,6 +128,8 @@ const ExternalPlugin = props => {
NOTION_CONFIG
)
const ENABLE_ICON_FONT = siteConfig('ENABLE_ICON_FONT', false)
// 自定义样式css和js引入
if (isBrowser) {
// 初始化AOS动画
@@ -186,6 +190,7 @@ const ExternalPlugin = props => {
<>
{/* 全局样式嵌入 */}
<GlobalStyle />
{ENABLE_ICON_FONT && <IconFont />}
{MOUSE_FOLLOW && <MouseFollow />}
{THEME_SWITCH && <ThemeSwitch />}
{DEBUG && <DebugPanel />}

54
components/IconFont.js Normal file
View File

@@ -0,0 +1,54 @@
import { siteConfig } from '@/lib/config'
import { loadExternalResource } from '@/lib/utils'
import { useRouter } from 'next/router'
import { useEffect } from 'react'
/**
* iconfont
*/
export default function IconFont() {
const router = useRouter()
useEffect(() => {
loadExternalResource('/webfonts/iconfont.js').then(u => {
console.log('iconfont loaded')
// 查找所有 <i> 标签且 class 包含 'icon-'
const iElements = document.querySelectorAll('i[class*="icon-"]');
iElements.forEach(element => {
const className = Array.from(element.classList).find(cls => cls.startsWith('icon-'));
if (className) {
// 创建新的 <svg> 元素
const svgElement = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svgElement.setAttribute('class', 'icon');
svgElement.setAttribute('aria-hidden', 'true');
const useElement = document.createElementNS('http://www.w3.org/2000/svg', 'use');
useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', `#${className}`);
svgElement.appendChild(useElement);
// 替换原来的 <i> 元素
element.replaceWith(svgElement);
console.log(`Replaced <i> with class "${className}" to <svg>`);
}
});
})
}, [router])
return <style jsx global>
{`
.icon {
width: 1.1em;
height: 1.1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
svg.icon {
display: inline;
}
`}</style>
}

View File

@@ -98,6 +98,22 @@ const NotionPage = ({ post, className }) => {
})
})
}
// 查找所有具有 'notion-collection-page-properties' 类的元素,删除notion自带的页面properties
const timer = setTimeout(() => {
// 查找所有具有 'notion-collection-page-properties' 类的元素
const elements = document.querySelectorAll(
'.notion-collection-page-properties'
)
// 遍历这些元素并将其从 DOM 中移除
elements?.forEach(element => {
element?.remove()
})
}, 1000) // 1000 毫秒 = 1 秒
// 清理定时器,防止组件卸载时执行
return () => clearTimeout(timer)
}, [post])
return (

View File

@@ -43,9 +43,15 @@ const PrismMac = () => {
loadExternalResource('/css/prism-mac-style.css', 'css')
}
// 加载prism样式
loadPrismThemeCSS(isDarkMode, prismThemeSwitch, prismThemeDarkPath, prismThemeLightPath, prismThemePrefixPath)
loadPrismThemeCSS(
isDarkMode,
prismThemeSwitch,
prismThemeDarkPath,
prismThemeLightPath,
prismThemePrefixPath
)
// 折叠代码
loadExternalResource(prismjsAutoLoader, 'js').then((url) => {
loadExternalResource(prismjsAutoLoader, 'js').then(url => {
if (window?.Prism?.plugins?.autoloader) {
window.Prism.plugins.autoloader.languages_path = prismjsPath
}
@@ -62,7 +68,13 @@ const PrismMac = () => {
/**
* 加载Prism主题样式
*/
const loadPrismThemeCSS = (isDarkMode, prismThemeSwitch, prismThemeDarkPath, prismThemeLightPath, prismThemePrefixPath) => {
const loadPrismThemeCSS = (
isDarkMode,
prismThemeSwitch,
prismThemeDarkPath,
prismThemeLightPath,
prismThemePrefixPath
) => {
let PRISM_THEME
let PRISM_PREVIOUS
if (prismThemeSwitch) {
@@ -73,8 +85,14 @@ const loadPrismThemeCSS = (isDarkMode, prismThemeSwitch, prismThemeDarkPath, pri
PRISM_THEME = prismThemeLightPath
PRISM_PREVIOUS = prismThemeDarkPath
}
const previousTheme = document.querySelector(`link[href="${PRISM_PREVIOUS}"]`)
if (previousTheme && previousTheme.parentNode && previousTheme.parentNode.contains(previousTheme)) {
const previousTheme = document.querySelector(
`link[href="${PRISM_PREVIOUS}"]`
)
if (
previousTheme &&
previousTheme.parentNode &&
previousTheme.parentNode.contains(previousTheme)
) {
previousTheme.parentNode.removeChild(previousTheme)
}
loadExternalResource(PRISM_THEME, 'css')
@@ -103,14 +121,17 @@ const renderCollapseCode = (codeCollapse, codeCollapseExpandDefault) => {
const collapseWrapper = document.createElement('div')
collapseWrapper.className = 'collapse-wrapper w-full py-2'
const panelWrapper = document.createElement('div')
panelWrapper.className = 'border dark:border-gray-600 rounded-md hover:border-indigo-500 duration-200 transition-colors'
panelWrapper.className =
'border dark:border-gray-600 rounded-md hover:border-indigo-500 duration-200 transition-colors'
const header = document.createElement('div')
header.className = 'flex justify-between items-center px-4 py-2 cursor-pointer select-none'
header.className =
'flex justify-between items-center px-4 py-2 cursor-pointer select-none'
header.innerHTML = `<h3 class="text-lg font-medium">${language}</h3><svg class="transition-all duration-200 w-5 h-5 transform rotate-0" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M6.293 6.293a1 1 0 0 1 1.414 0L10 8.586l2.293-2.293a1 1 0 0 1 1.414 1.414l-3 3a1 1 0 0 1-1.414 0l-3-3a1 1 0 0 1 0-1.414z" clip-rule="evenodd"/></svg>`
const panel = document.createElement('div')
panel.className = 'invisible h-0 transition-transform duration-200 border-t border-gray-300'
panel.className =
'invisible h-0 transition-transform duration-200 border-t border-gray-300'
panelWrapper.appendChild(header)
panelWrapper.appendChild(panel)
@@ -145,7 +166,7 @@ const renderMermaid = async(mermaidCDN) => {
if (m.target.className === 'notion-code language-mermaid') {
const chart = m.target.querySelector('code').textContent
if (chart && !m.target.querySelector('.mermaid')) {
const mermaidChart = document.createElement('div')
const mermaidChart = document.createElement('pre')
mermaidChart.className = 'mermaid'
mermaidChart.innerHTML = chart
m.target.appendChild(mermaidChart)
@@ -172,7 +193,10 @@ const renderMermaid = async(mermaidCDN) => {
}
})
if (document.querySelector('#notion-article')) {
observer.observe(document.querySelector('#notion-article'), { attributes: true, subtree: true })
observer.observe(document.querySelector('#notion-article'), {
attributes: true,
subtree: true
})
}
}
@@ -234,7 +258,10 @@ const fixCodeLineStyle = () => {
}
}
})
observer.observe(document.querySelector('#notion-article'), { attributes: true, subtree: true })
observer.observe(document.querySelector('#notion-article'), {
attributes: true,
subtree: true
})
setTimeout(() => {
const preCodes = document.querySelectorAll('pre.notion-code')
for (const preCode of preCodes) {

View File

@@ -247,7 +247,7 @@ const getSEOMeta = (props, router, locale) => {
}
case '/404':
return {
title: `${siteInfo?.title} | 页面找不到啦`,
title: `${siteInfo?.title} | ${locale.NAV.PAGE_NOT_FOUND}`,
image: `${siteInfo?.pageCover}`
}
case '/tag':