Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
43 changes: 43 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# 构建输出
.next/
out/
build/
dist/

# 依赖
node_modules/

# 日志
logs/
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# 缓存目录
.npm
.eslintcache
.vercel

# 特定项目文件
public/
.github/
lib/plugins/

# 包锁文件
package-lock.json
yarn.lock
pnpm-lock.yaml

# 静态资源
*.svg
*.ico
*.jpg
*.jpeg
*.png
*.gif
*.webp
*.pdf
*.ttf
*.woff
*.woff2
2 changes: 1 addition & 1 deletion .prettierrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
"printWidth": 80,
"bracketSpacing": true,
"jsxSingleQuote": true,
"jsxBracketSameLine": true
"bracketSameLine": true
}
3 changes: 2 additions & 1 deletion blog.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ const BLOG = {
KEYWORDS: process.env.NEXT_PUBLIC_KEYWORD || 'Notion, 博客', // 网站关键词 英文逗号隔开
BLOG_FAVICON: process.env.NEXT_PUBLIC_FAVICON || '/favicon.ico', // blog favicon 配置, 默认使用 /public/favicon.ico,支持在线图片,如 https://img.imesong.com/favicon.png
BEI_AN: process.env.NEXT_PUBLIC_BEI_AN || '', // 备案号 闽ICP备XXXXXX
BEI_AN_LINK: process.env.NEXT_PUBLIC_BEI_AN_LINK || 'https://beian.miit.gov.cn/', // 备案查询链接,如果用了萌备等备案请在这里填写
BEI_AN_LINK:
process.env.NEXT_PUBLIC_BEI_AN_LINK || 'https://beian.miit.gov.cn/', // 备案查询链接,如果用了萌备等备案请在这里填写

// RSS订阅
ENABLE_RSS: process.env.NEXT_PUBLIC_ENABLE_RSS || true, // 是否开启RSS订阅功能
Expand Down
12 changes: 7 additions & 5 deletions components/Ackee.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,18 @@ const handleAckee = async function (pathname, environment, options = {}) {
const instance = ackeeTracker?.create(environment.server, options)

if (instance == null) {
console.warn('Skipped record creation because useAckee has been called in a non-browser environment')
console.warn(
'Skipped record creation because useAckee has been called in a non-browser environment'
)
return
}

const hasPathname = (
pathname != null && pathname !== ''
)
const hasPathname = pathname != null && pathname !== ''

if (hasPathname === false) {
console.warn('Skipped record creation because useAckee has been called without pathname')
console.warn(
'Skipped record creation because useAckee has been called without pathname'
)
return
}

Expand Down
7 changes: 5 additions & 2 deletions components/AdBlockDetect.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ export default function AdBlockDetect() {
const wwadsCns = document.getElementsByClassName('wwads-cn')
if (wwadsCns && wwadsCns.length > 0) {
for (const wwadsCn of wwadsCns) {
wwadsCn.insertAdjacentHTML('beforeend', "<style>.wwads-horizontal,.wwads-vertical{background-color:#f4f8fa;padding:5px;min-height:120px;margin-top:20px;box-sizing:border-box;border-radius:3px;font-family:sans-serif;display:flex;min-width:150px;position:relative;overflow:hidden;}.wwads-horizontal{flex-wrap:wrap;justify-content:center}.wwads-vertical{flex-direction:column;align-items:center;padding-bottom:32px}.wwads-horizontal a,.wwads-vertical a{text-decoration:none}.wwads-horizontal .wwads-img,.wwads-vertical .wwads-img{margin:5px}.wwads-horizontal .wwads-content,.wwads-vertical .wwads-content{margin:5px}.wwads-horizontal .wwads-content{flex:130px}.wwads-vertical .wwads-content{margin-top:10px}.wwads-horizontal .wwads-text,.wwads-content .wwads-text{font-size:14px;line-height:1.4;color:#0e1011;-webkit-font-smoothing:antialiased}.wwads-horizontal .wwads-poweredby,.wwads-vertical .wwads-poweredby{display:block;font-size:11px;color:#a6b7bf;margin-top:1em}.wwads-vertical .wwads-poweredby{position:absolute;left:10px;bottom:10px}.wwads-horizontal .wwads-poweredby span,.wwads-vertical .wwads-poweredby span{transition:all 0.2s ease-in-out;margin-left:-1em}.wwads-horizontal .wwads-poweredby span:first-child,.wwads-vertical .wwads-poweredby span:first-child{opacity:0}.wwads-horizontal:hover .wwads-poweredby span,.wwads-vertical:hover .wwads-poweredby span{opacity:1;margin-left:0}.wwads-horizontal .wwads-hide,.wwads-vertical .wwads-hide{position:absolute;right:-23px;bottom:-23px;width:46px;height:46px;border-radius:23px;transition:all 0.3s ease-in-out;cursor:pointer;}.wwads-horizontal .wwads-hide:hover,.wwads-vertical .wwads-hide:hover{background:rgb(0 0 0 /0.05)}.wwads-horizontal .wwads-hide svg,.wwads-vertical .wwads-hide svg{position:absolute;left:10px;top:10px;fill:#a6b7bf}.wwads-horizontal .wwads-hide:hover svg,.wwads-vertical .wwads-hide:hover svg{fill:#3E4546}</style><a href='https://wwads.cn/page/whitelist-wwads' class='wwads-img' target='_blank' rel='nofollow'><img src='https://creatives-1301677708.file.myqcloud.com/images/placeholder/wwads-friendly-ads.png' width='130'></a><div class='wwads-content'><a href='https://wwads.cn/page/whitelist-wwads' class='wwads-text' target='_blank' rel='nofollow'>为了本站的长期运营,请将我们的网站加入广告拦截器的白名单,感谢您的支持!</a><a href='https://wwads.cn/page/end-user-privacy' class='wwads-poweredby' title='万维广告 ~ 让广告更优雅,且有用' target='_blank'><span>万维</span><span>广告</span></a></div><a class='wwads-hide' onclick='parentNode.remove()' title='隐藏广告'><svg xmlns='http://www.w3.org/2000/svg' width='6' height='7'><path d='M.879.672L3 2.793 5.121.672a.5.5 0 11.707.707L3.708 3.5l2.12 2.121a.5.5 0 11-.707.707l-2.12-2.12-2.122 2.12a.5.5 0 11-.707-.707l2.121-2.12L.172 1.378A.5.5 0 01.879.672z'></path></svg></a>")
wwadsCn.insertAdjacentHTML(
'beforeend',
"<style>.wwads-horizontal,.wwads-vertical{background-color:#f4f8fa;padding:5px;min-height:120px;margin-top:20px;box-sizing:border-box;border-radius:3px;font-family:sans-serif;display:flex;min-width:150px;position:relative;overflow:hidden;}.wwads-horizontal{flex-wrap:wrap;justify-content:center}.wwads-vertical{flex-direction:column;align-items:center;padding-bottom:32px}.wwads-horizontal a,.wwads-vertical a{text-decoration:none}.wwads-horizontal .wwads-img,.wwads-vertical .wwads-img{margin:5px}.wwads-horizontal .wwads-content,.wwads-vertical .wwads-content{margin:5px}.wwads-horizontal .wwads-content{flex:130px}.wwads-vertical .wwads-content{margin-top:10px}.wwads-horizontal .wwads-text,.wwads-content .wwads-text{font-size:14px;line-height:1.4;color:#0e1011;-webkit-font-smoothing:antialiased}.wwads-horizontal .wwads-poweredby,.wwads-vertical .wwads-poweredby{display:block;font-size:11px;color:#a6b7bf;margin-top:1em}.wwads-vertical .wwads-poweredby{position:absolute;left:10px;bottom:10px}.wwads-horizontal .wwads-poweredby span,.wwads-vertical .wwads-poweredby span{transition:all 0.2s ease-in-out;margin-left:-1em}.wwads-horizontal .wwads-poweredby span:first-child,.wwads-vertical .wwads-poweredby span:first-child{opacity:0}.wwads-horizontal:hover .wwads-poweredby span,.wwads-vertical:hover .wwads-poweredby span{opacity:1;margin-left:0}.wwads-horizontal .wwads-hide,.wwads-vertical .wwads-hide{position:absolute;right:-23px;bottom:-23px;width:46px;height:46px;border-radius:23px;transition:all 0.3s ease-in-out;cursor:pointer;}.wwads-horizontal .wwads-hide:hover,.wwads-vertical .wwads-hide:hover{background:rgb(0 0 0 /0.05)}.wwads-horizontal .wwads-hide svg,.wwads-vertical .wwads-hide svg{position:absolute;left:10px;top:10px;fill:#a6b7bf}.wwads-horizontal .wwads-hide:hover svg,.wwads-vertical .wwads-hide:hover svg{fill:#3E4546}</style><a href='https://wwads.cn/page/whitelist-wwads' class='wwads-img' target='_blank' rel='nofollow'><img src='https://creatives-1301677708.file.myqcloud.com/images/placeholder/wwads-friendly-ads.png' width='130'></a><div class='wwads-content'><a href='https://wwads.cn/page/whitelist-wwads' class='wwads-text' target='_blank' rel='nofollow'>为了本站的长期运营,请将我们的网站加入广告拦截器的白名单,感谢您的支持!</a><a href='https://wwads.cn/page/end-user-privacy' class='wwads-poweredby' title='万维广告 ~ 让广告更优雅,且有用' target='_blank'><span>万维</span><span>广告</span></a></div><a class='wwads-hide' onclick='parentNode.remove()' title='隐藏广告'><svg xmlns='http://www.w3.org/2000/svg' width='6' height='7'><path d='M.879.672L3 2.793 5.121.672a.5.5 0 11.707.707L3.708 3.5l2.12 2.121a.5.5 0 11-.707.707l-2.12-2.12-2.122 2.12a.5.5 0 11-.707-.707l2.121-2.12L.172 1.378A.5.5 0 01.879.672z'></path></svg></a>"
)
}
}
};
}

// check document ready
function docReady(t) {
Expand Down
6 changes: 3 additions & 3 deletions components/Artalk.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ const Artalk = ({ siteInfo }) => {
darkMode: document.documentElement.classList.contains('dark')
})

const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
if (mutation.attributeName === 'class') {
const isDark = document.documentElement.classList.contains('dark')
artalk?.setDarkMode(isDark)
Expand All @@ -45,7 +45,7 @@ const Artalk = ({ siteInfo }) => {
return () => observer.disconnect()
}

return <div id="artalk"></div>
return <div id='artalk'></div>
}

export default Artalk
15 changes: 9 additions & 6 deletions components/Badge.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
* 红点
*/
export default function Badge() {
return <>
{/* 红点 */}
<span class="absolute right-1 top-1 flex h-2 w-2">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-red-400 opacity-75"></span>
<span class="relative inline-flex rounded-full h-2 w-2 bg-red-500"></span>
</span></>
return (
<>
{/* 红点 */}
<span class='absolute right-1 top-1 flex h-2 w-2'>
<span class='animate-ping absolute inline-flex h-full w-full rounded-full bg-red-400 opacity-75'></span>
<span class='relative inline-flex rounded-full h-2 w-2 bg-red-500'></span>
</span>
</>
)
}
2 changes: 1 addition & 1 deletion components/Busuanzi.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useEffect } from 'react'

let path = ''

export default function Busuanzi () {
export default function Busuanzi() {
const { theme } = useGlobal()
const router = useRouter()
router.events.on('routeChangeComplete', (url, option) => {
Expand Down
13 changes: 7 additions & 6 deletions components/ChatBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ export default function ChatBase() {
return <></>
}

return <iframe
src={`https://www.chatbase.co/chatbot-iframe/${siteConfig('CHATBASE_ID')}`}
width="100%"
style={{ height: '100%', minHeight: '700px' }}
frameborder="0"
></iframe>
return (
<iframe
src={`https://www.chatbase.co/chatbot-iframe/${siteConfig('CHATBASE_ID')}`}
width='100%'
style={{ height: '100%', minHeight: '700px' }}
frameborder='0'></iframe>
)
}
182 changes: 92 additions & 90 deletions components/CursorDot.js
Original file line number Diff line number Diff line change
@@ -1,107 +1,109 @@
import { useRouter } from 'next/router';
import { useEffect } from 'react';
import { useRouter } from 'next/router'
import { useEffect } from 'react'
/**
* 白点鼠标跟随
* @returns
* @returns
*/
const CursorDot = () => {
const router = useRouter();
useEffect(() => {
// 创建小白点元素
const dot = document.createElement('div');
dot.classList.add('cursor-dot');
document.body.appendChild(dot);
const router = useRouter()
useEffect(() => {
// 创建小白点元素
const dot = document.createElement('div')
dot.classList.add('cursor-dot')
document.body.appendChild(dot)

// 鼠标坐标和缓动目标坐标
let mouse = { x: -100, y: -100 }; // 初始位置在屏幕外
let dotPos = { x: mouse.x, y: mouse.y };
// 鼠标坐标和缓动目标坐标
let mouse = { x: -100, y: -100 } // 初始位置在屏幕外
let dotPos = { x: mouse.x, y: mouse.y }

// 监听鼠标移动
const handleMouseMove = (e) => {
mouse.x = e.clientX;
mouse.y = e.clientY;
};
document.addEventListener('mousemove', handleMouseMove);
// 监听鼠标移动
const handleMouseMove = e => {
mouse.x = e.clientX
mouse.y = e.clientY
}
document.addEventListener('mousemove', handleMouseMove)

// 监听鼠标悬停在可点击对象上的事件
const handleMouseEnter = () => {
dot.classList.add('cursor-dot-hover'); // 添加放大样式
};
const handleMouseLeave = () => {
dot.classList.remove('cursor-dot-hover'); // 移除放大样式
};
// 监听鼠标悬停在可点击对象上的事件
const handleMouseEnter = () => {
dot.classList.add('cursor-dot-hover') // 添加放大样式
}
const handleMouseLeave = () => {
dot.classList.remove('cursor-dot-hover') // 移除放大样式
}

// 为所有可点击元素和包含 hover 或 group-hover 类名的元素添加事件监听
setTimeout(() => {
const clickableElements = document.querySelectorAll(
'a, button, [role="button"], [onclick], [cursor="pointer"], [class*="hover"], [class*="group-hover"], [class*="cursor-pointer"]'
)
clickableElements.forEach(el => {
el.addEventListener('mouseenter', handleMouseEnter)
el.addEventListener('mouseleave', handleMouseLeave)
})
}, 200) // 延时 200ms 执行

// 为所有可点击元素和包含 hover 或 group-hover 类名的元素添加事件监听
setTimeout(() => {
const clickableElements = document.querySelectorAll(
'a, button, [role="button"], [onclick], [cursor="pointer"], [class*="hover"], [class*="group-hover"], [class*="cursor-pointer"]'
);
clickableElements.forEach((el) => {
el.addEventListener('mouseenter', handleMouseEnter);
el.addEventListener('mouseleave', handleMouseLeave);
});
}, 200); // 延时 200ms 执行
// 动画循环:延迟更新小白点位置
const updateDotPosition = () => {
const damping = 0.2 // 阻尼系数,值越小延迟越明显
dotPos.x += (mouse.x - dotPos.x) * damping
dotPos.y += (mouse.y - dotPos.y) * damping

// 动画循环:延迟更新小白点位置
const updateDotPosition = () => {
const damping = 0.2; // 阻尼系数,值越小延迟越明显
dotPos.x += (mouse.x - dotPos.x) * damping;
dotPos.y += (mouse.y - dotPos.y) * damping;
// 更新DOM
dot.style.left = `${dotPos.x}px`
dot.style.top = `${dotPos.y}px`

// 更新DOM
dot.style.left = `${dotPos.x}px`;
dot.style.top = `${dotPos.y}px`;
requestAnimationFrame(updateDotPosition)
}

requestAnimationFrame(updateDotPosition);
};
// 启动动画
updateDotPosition()

// 启动动画
updateDotPosition();
// 清理函数
return () => {
document.removeEventListener('mousemove', handleMouseMove)
const clickableElements = document.querySelectorAll(
'a, button, [role="button"], [onclick], [cursor="pointer"], [class*="hover"], [class*="group-hover"], [class*="cursor-pointer"]'
)
clickableElements.forEach(el => {
el.removeEventListener('mouseenter', handleMouseEnter)
el.removeEventListener('mouseleave', handleMouseLeave)
})
document.body.removeChild(dot)
}
}, [router])

// 清理函数
return () => {
document.removeEventListener('mousemove', handleMouseMove);
const clickableElements = document.querySelectorAll(
'a, button, [role="button"], [onclick], [cursor="pointer"], [class*="hover"], [class*="group-hover"], [class*="cursor-pointer"]'
);
clickableElements.forEach((el) => {
el.removeEventListener('mouseenter', handleMouseEnter);
el.removeEventListener('mouseleave', handleMouseLeave);
});
document.body.removeChild(dot);
};
}, [router]);
return (
<style jsx global>{`
.cursor-dot {
position: fixed;
width: 12px;
height: 12px;
background: white;
border-radius: 50%;
pointer-events: none;
transform: translate(-50%, -50%);
z-index: 9999;
transition:
transform 100ms ease-out,
width 200ms ease,
height 200ms ease; /* 添加尺寸平滑过渡 */
mix-blend-mode: difference; /* 可选:增强对比度 */
}

return (
<style jsx global>{`
.cursor-dot {
position: fixed;
width: 12px;
height: 12px;
background: white;
border-radius: 50%;
pointer-events: none;
transform: translate(-50%, -50%);
z-index: 9999;
transition: transform 100ms ease-out, width 200ms ease, height 200ms ease; /* 添加尺寸平滑过渡 */
mix-blend-mode: difference; /* 可选:增强对比度 */
}
.cursor-dot-hover {
border: 1px solid rgba(167, 167, 167, 0.14); /* 鼠标悬停时的深灰色边框,厚度为1px */
width: 60px; /* 放大 */
height: 60px; /* 放大 */
background: hsla(0, 0%, 100%, 0.04); /* 半透明背景 */
-webkit-backdrop-filter: blur(5px); /* 毛玻璃效果 */
backdrop-filter: blur(5px);
}

.cursor-dot-hover {
border: 1px solid rgba(167, 167, 167, 0.14); /* 鼠标悬停时的深灰色边框,厚度为1px */
width: 60px; /* 放大 */
height: 60px; /* 放大 */
background: hsla(0, 0%, 100%, 0.04); /* 半透明背景 */
-webkit-backdrop-filter: blur(5px); /* 毛玻璃效果 */
backdrop-filter: blur(5px);
}
.dark .cursor-dot-hover {
border: 1px solid rgba(66, 66, 66, 0.66); /* 鼠标悬停时的深灰色边框,厚度为1px */
}
`}</style>
)
}

.dark .cursor-dot-hover {
border: 1px solid rgba(66, 66, 66, 0.66); /* 鼠标悬停时的深灰色边框,厚度为1px */
}
`}</style>
);
};

export default CursorDot;
export default CursorDot
Loading