Merge pull request #3419 from LooseLi/fix-eslint-errors

Fix eslint errors
This commit is contained in:
tangly1024
2025-06-05 12:43:48 +08:00
committed by GitHub
34 changed files with 240 additions and 188 deletions

View File

@@ -39,7 +39,7 @@ module.exports = {
'react/prop-types': 'off',
'space-before-function-paren': 0,
'react-hooks/rules-of-hooks': 'error', // Checks rules of Hooks
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], // 确保未使用的变量报错
'@typescript-eslint/no-unused-vars': 'off', // 关闭未使用的变量报错
'@typescript-eslint/explicit-function-return-type': 'off' // 关闭强制函数返回类型声明
},
overrides: [

View File

@@ -8,7 +8,7 @@ import { useEffect } from 'react'
* https://michalsnik.github.io/aos/
*/
export default function AOSAnimation() {
const initAOS = async () => {
const initAOS = () => {
Promise.all([
loadExternalResource('/js/aos.js', 'js'),
loadExternalResource('/css/aos.css', 'css')

View File

@@ -14,16 +14,19 @@ 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) {
document.readyState === 'complete' ||
document.readyState === 'interactive'
? setTimeout(t, 1)
? setTimeout(() => t(), 1)
: document.addEventListener('DOMContentLoaded', t)
}

View File

@@ -13,7 +13,6 @@ import WebWhiz from './Webwhiz'
import { useGlobal } from '@/lib/global'
import IconFont from './IconFont'
/**
* 各种插件脚本
* @param {*} props
@@ -22,7 +21,7 @@ import IconFont from './IconFont'
const ExternalPlugin = props => {
// 读取自Notion的配置
const { NOTION_CONFIG } = props
const {lang} = useGlobal()
const { lang } = useGlobal()
const DISABLE_PLUGIN = siteConfig('DISABLE_PLUGIN', null, NOTION_CONFIG)
const THEME_SWITCH = siteConfig('THEME_SWITCH', null, NOTION_CONFIG)
const DEBUG = siteConfig('DEBUG', null, NOTION_CONFIG)
@@ -172,7 +171,7 @@ const ExternalPlugin = props => {
setTimeout(() => {
// 映射url
convertInnerUrl({ allPages:props?.allNavPages, lang:lang })
convertInnerUrl({ allPages: props?.allNavPages, lang: lang })
}, 500)
}, [router])
@@ -474,7 +473,7 @@ const DifyChatbot = dynamic(() => import('@/components/DifyChatbot'), {
})
const Analytics = dynamic(
() =>
import('@vercel/analytics/react').then(async m => {
import('@vercel/analytics/react').then(m => {
return m.Analytics
}),
{ ssr: false }

View File

@@ -16,7 +16,7 @@ const Fireworks = () => {
useEffect(() => {
// 异步加载
async function loadFireworks() {
function loadFireworks() {
loadExternalResource(
'https://cdnjs.snrat.com/ajax/libs/animejs/3.2.1/anime.min.js',
'js'

View File

@@ -60,7 +60,7 @@ function getNodesWithAdsByGoogleClass(node) {
* 初始化谷歌广告
* @returns
*/
export const initGoogleAdsense = async ADSENSE_GOOGLE_ID => {
export const initGoogleAdsense = ADSENSE_GOOGLE_ID => {
console.log('Load Adsense')
loadExternalResource(
`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${ADSENSE_GOOGLE_ID}`,

View File

@@ -12,7 +12,9 @@ const Lenis = () => {
useEffect(() => {
// 异步加载
async function loadLenis() {
loadExternalResource('/js/lenis.js', 'js').then(() => {
try {
await loadExternalResource('/js/lenis.js', 'js')
// console.log('Lenis', window.Lenis)
if (!window.Lenis) {
console.error('Lenis not loaded')
@@ -23,14 +25,14 @@ const Lenis = () => {
// 创建 Lenis 实例
const lenis = new Lenis({
duration: 1.2,
easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), // https://www.desmos.com/calculator/brs54l4xou
easing: t => Math.min(1, 1.001 - Math.pow(2, -10 * t)), // https://www.desmos.com/calculator/brs54l4xou
direction: 'vertical', // vertical, horizontal
gestureDirection: 'vertical', // vertical, horizontal, both
smooth: true,
mouseMultiplier: 1,
smoothTouch: false,
touchMultiplier: 2,
infinite: false,
infinite: false
})
// 存储实例到 ref
@@ -48,7 +50,9 @@ const Lenis = () => {
}
requestAnimationFrame(raf)
})
} catch (error) {
console.error('Failed to load Lenis:', error)
}
}
loadLenis()

View File

@@ -228,7 +228,7 @@ function getMediumZoomMargin() {
// 代码
const Code = dynamic(
() =>
import('react-notion-x/build/third-party/code').then(async m => {
import('react-notion-x/build/third-party/code').then(m => {
return m.Code
}),
{ ssr: false }

View File

@@ -160,8 +160,8 @@ const renderCollapseCode = (codeCollapse, codeCollapseExpandDefault) => {
/**
* 将mermaid语言 渲染成图片
*/
const renderMermaid = async(mermaidCDN) => {
const observer = new MutationObserver(async mutationsList => {
const renderMermaid = mermaidCDN => {
const observer = new MutationObserver(mutationsList => {
for (const m of mutationsList) {
if (m.target.className === 'notion-code language-mermaid') {
const chart = m.target.querySelector('code').textContent

View File

@@ -4,21 +4,19 @@ import React from 'react'
* 下拉单选框
*/
class Select extends React.Component {
constructor (props) {
super(props)
this.handleChange = this.handleChange.bind(this)
}
handleChange (event) {
handleChange = event => {
const { onChange } = this.props
onChange(event.target.value)
}
render () {
render() {
return (
<div className='py-1 space-x-3'>
<label className='text-gray-500'>{this.props.label}</label>
<select value={this.props.value} onChange={this.handleChange} className='border p-1 rounded cursor-pointer'>
<select
value={this.props.value}
onChange={this.handleChange}
className='border p-1 rounded cursor-pointer'>
{this.props.options?.map(o => (
<option key={o.value} value={o.value}>
{o.text}

View File

@@ -6,10 +6,10 @@ const cacheInvalidSeconds = 1000000000 * 1000
// 文件名
const jsonFile = path.resolve('./data.json')
export async function getCache (key) {
const exist = await fs.existsSync(jsonFile)
export function getCache(key) {
const exist = fs.existsSync(jsonFile)
if (!exist) return null
const data = await fs.readFileSync(jsonFile)
const data = fs.readFileSync(jsonFile)
let json = null
if (!data) return null
try {
@@ -19,7 +19,9 @@ export async function getCache (key) {
return null
}
// 缓存超过有效期就作废
const cacheValidTime = new Date(parseInt(json[key + '_expire_time']) + cacheInvalidSeconds)
const cacheValidTime = new Date(
parseInt(json[key + '_expire_time']) + cacheInvalidSeconds
)
const currentTime = new Date()
if (!cacheValidTime || cacheValidTime < currentTime) {
return null
@@ -33,17 +35,17 @@ export async function getCache (key) {
* @param data
* @returns {Promise<null>}
*/
export async function setCache (key, data) {
const exist = await fs.existsSync(jsonFile)
const json = exist ? JSON.parse(await fs.readFileSync(jsonFile)) : {}
export function setCache(key, data) {
const exist = fs.existsSync(jsonFile)
const json = exist ? JSON.parse(fs.readFileSync(jsonFile)) : {}
json[key] = data
json[key + '_expire_time'] = new Date().getTime()
fs.writeFileSync(jsonFile, JSON.stringify(json))
}
export async function delCache (key) {
const exist = await fs.existsSync(jsonFile)
const json = exist ? JSON.parse(await fs.readFileSync(jsonFile)) : {}
export function delCache(key) {
const exist = fs.existsSync(jsonFile)
const json = exist ? JSON.parse(fs.readFileSync(jsonFile)) : {}
delete json.key
json[key + '_expire_time'] = new Date().getTime()
fs.writeFileSync(jsonFile, JSON.stringify(json))
@@ -52,7 +54,7 @@ export async function delCache (key) {
/**
* 清理缓存
*/
export async function cleanCache() {
export function cleanCache() {
const json = {}
fs.writeFileSync(jsonFile, JSON.stringify(json))
}

View File

@@ -13,7 +13,7 @@ export async function getCache(key) {
const data = await redisClient.get(key)
return data ? JSON.parse(data) : null
} catch (e) {
console.error('redisClient读取失败 ' + e)
console.error(`redisClient读取失败 ${String(e)}`)
}
}
@@ -26,7 +26,7 @@ export async function setCache(key, data, customCacheTime) {
customCacheTime || cacheTime
)
} catch (e) {
console.error('redisClient写入失败 ' + e)
console.error(`redisClient写入失败 ${String(e)}`)
}
}
@@ -34,7 +34,7 @@ export async function delCache(key) {
try {
await redisClient.del(key)
} catch (e) {
console.error('redisClient删除失败 ' + e)
console.error(`redisClient删除失败 ${String(e)}`)
}
}

View File

@@ -267,12 +267,13 @@ async function convertNotionToSiteDate(pageId, from, pageRecordMap) {
categoryOptions: getCategoryOptions(schema)
})
// 所有标签
const tagSchemaOptions = getTagOptions(schema)
const tagOptions =
getAllTags({
allPages,
tagOptions: getTagOptions(schema),
allPages: allPages ?? [],
tagOptions: tagSchemaOptions ?? [],
NOTION_CONFIG
}) || null
}) ?? null
// 旧的菜单
const customNav = getCustomNav({
allPages: collectionData.filter(
@@ -280,7 +281,7 @@ async function convertNotionToSiteDate(pageId, from, pageRecordMap) {
)
})
// 新的菜单
const customMenu = await getCustomMenu({ collectionData, NOTION_CONFIG })
const customMenu = getCustomMenu({ collectionData, NOTION_CONFIG })
const latestPosts = getLatestPosts({ allPages, from, latestPostCount: 6 })
const allNavPages = getNavPages({ allPages })

View File

@@ -40,7 +40,8 @@ export function GlobalContextProvider(props) {
// 登录验证相关
const enableClerk = process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY
const { isLoaded, isSignedIn, user } = enableClerk
? useUser()
? /* eslint-disable-next-line react-hooks/rules-of-hooks */
useUser()
: { isLoaded: true, isSignedIn: false, user: false }
// 是否全屏
@@ -99,9 +100,11 @@ export function GlobalContextProvider(props) {
useEffect(() => {
const handleStart = url => {
const { theme } = router.query
if (theme && !url.includes(`theme=${theme}`)) {
const newUrl = `${url}${url.includes('?') ? '&' : '?'}theme=${theme}`
const themeValue = router.query.theme
const themeStr = Array.isArray(themeValue) ? themeValue[0] : themeValue
if (themeStr && !url.includes(`theme=${themeStr}`)) {
const newUrl = `${url}${url.includes('?') ? '&' : '?'}theme=${themeStr}`
router.push(newUrl)
}
if (!onLoading) {

View File

@@ -1,16 +1,29 @@
const axios = require('axios')
import axios from 'axios'
// 定义内容项的接口
interface ContentItem {
type: string
content: string
}
// 定义Notion块的接口
interface NotionBlock {
object: string
type: string
[key: string]: unknown
}
// 发送 Notion API 请求
async function postNotion(
properties: any,
properties: Record<string, unknown>,
databaseId: string,
listContentMain: any[],
listContentMain: ContentItem[],
token: string
) {
): Promise<{ status: number; data: Record<string, unknown> }> {
const url = 'https://api.notion.com/v1/pages'
const children = listContentMain
.map(contentMain => {
.map((contentMain: ContentItem): NotionBlock | null => {
if (contentMain.type === 'paragraph') {
return {
object: 'block',
@@ -51,14 +64,21 @@ async function postNotion(
try {
const response = await axios.post(url, payload, { headers })
return response
} catch (error: any) {
} catch (error) {
console.error('写入Notion异常', error)
throw new Error(`Error posting to Notion: ${error.message}`)
const errorMessage = error instanceof Error ? error.message : String(error)
throw new Error(`Error posting to Notion: ${errorMessage}`)
}
}
// 定义响应结果的接口
interface NotionResponse {
status: number
data: Record<string, unknown>
}
// 处理响应结果
function responseResult(response: { status: number; data: any }) {
function responseResult(response: NotionResponse): void {
if (response.status === 200) {
console.log('成功...')
console.log(response.data)
@@ -68,15 +88,25 @@ function responseResult(response: { status: number; data: any }) {
}
}
// 定义用户属性的接口
interface UserProperties {
id: string
avatar: string
name: string
mail: string
lastLoginTime: string
token: string
}
// 准备属性字段
function notionProperty(
id: any,
avatar: any,
name: any,
mail: any,
lastLoginTime: any,
token: any
) {
id: string,
avatar: string,
name: string,
mail: string,
lastLoginTime: string,
token: string
): Record<string, unknown> {
return {
id: {
rich_text: [

View File

@@ -6,7 +6,7 @@ import algoliasearch from 'algoliasearch'
* 生成全文索引
* @param {*} allPages
*/
const generateAlgoliaSearch = async ({ allPages, force = false }) => {
const generateAlgoliaSearch = ({ allPages, force = false }) => {
allPages?.forEach(p => {
// 判断这篇文章是否需要重新创建索引
if (p && !p.password) {

View File

@@ -1,15 +1,19 @@
import BLOG from '@/blog.config'
/**
* 订阅邮件-服务端接口
* @param {*} email
* @returns
*/
export default function subscribeToMailchimpApi({ email, first_name = '', last_name = '' }) {
* 订阅邮件-服务端接口
* @param {*} email
* @returns
*/
export default function subscribeToMailchimpApi({
email,
first_name = '',
last_name = ''
}) {
const listId = BLOG.MAILCHIMP_LIST_ID // 替换为你的邮件列表 ID
const apiKey = BLOG.MAILCHIMP_API_KEY // 替换为你的 API KEY
if (!email || !listId || !apiKey) {
return {}
return Promise.resolve({})
}
const data = {
email_address: email,

View File

@@ -1,6 +1,6 @@
import fs from 'fs'
export async function generateRobotsTxt(props) {
export function generateRobotsTxt(props) {
const { siteInfo } = props
const LINK = siteInfo?.link
const content = `

View File

@@ -5,7 +5,7 @@ import { siteConfig } from './config'
* 生成站点地图
* @param {*} param0
*/
export async function generateSitemapXml({ allPages, NOTION_CONFIG }) {
export function generateSitemapXml({ allPages, NOTION_CONFIG }) {
let link = siteConfig('LINK', BLOG.LINK, NOTION_CONFIG)
// 确保链接不以斜杠结尾
if (link && link.endsWith('/')) {

View File

@@ -64,7 +64,7 @@ const noAuthMiddleware = async (req: NextRequest, ev: any) => {
* 鉴权中间件
*/
const authMiddleware = process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY
? clerkMiddleware(async (auth, req) => {
? clerkMiddleware((auth, req) => {
const { userId } = auth()
// 处理 /dashboard 路由的登录保护
if (isTenantRoute(req)) {

View File

@@ -117,7 +117,7 @@ const nextConfig = {
// 默认将feed重定向至 /public/rss/feed.xml
redirects: process.env.EXPORT
? undefined
: async () => {
: () => {
return [
{
source: '/feed',
@@ -129,7 +129,7 @@ const nextConfig = {
// 重写url
rewrites: process.env.EXPORT
? undefined
: async () => {
: () => {
// 处理多语言重定向
const langsRewrites = []
if (BLOG.NOTION_PAGE_ID.indexOf(',') > 0) {
@@ -176,7 +176,7 @@ const nextConfig = {
},
headers: process.env.EXPORT
? undefined
: async () => {
: () => {
return [
{
source: '/:path*{/}?',
@@ -217,7 +217,7 @@ const nextConfig = {
experimental: {
scrollRestoration: true
},
exportPathMap: async function (
exportPathMap: function (
defaultPathMap,
{ dev, dir, outDir, distDir, buildId }
) {

View File

@@ -62,7 +62,10 @@ export default async function handler(
}
// 这里将用户数据写入到Notion数据库
res.redirect(302, `/auth/result?${new URLSearchParams(redirectQuery)}`)
res.redirect(
302,
`/auth/result?${new URLSearchParams(redirectQuery).toString()}`
)
} else {
const redirectQuery = { msg: params?.statusText || '请求异常' }
res.redirect(

View File

@@ -71,7 +71,7 @@ export async function getStaticProps({ locale }) {
}
}
export const getStaticPaths = async () => {
export const getStaticPaths = () => {
return {
paths: [
{ params: { index: [] } }, // 对应首页路径

View File

@@ -51,7 +51,7 @@ export async function getStaticProps({ params: { keyword }, locale }) {
}
}
export async function getStaticPaths() {
export function getStaticPaths() {
return {
paths: [{ params: { keyword: 'NotionNext' } }],
fallback: true
@@ -128,7 +128,7 @@ async function filterByMemCache(allPosts, keyword) {
// console.log('全文搜索缓存', cacheKey, page != null)
post.results = []
let hitCount = 0
for (const i in indexContent) {
for (const i of indexContent) {
const c = indexContent[i]
if (!c) {
continue

View File

@@ -50,7 +50,7 @@ export async function getStaticProps({ params: { keyword, page }, locale }) {
}
}
export async function getStaticPaths() {
export function getStaticPaths() {
return {
paths: [{ params: { keyword: 'NotionNext', page: '1' } }],
fallback: true
@@ -135,7 +135,7 @@ async function filterByMemCache(allPosts, keyword) {
// console.log('全文搜索缓存', cacheKey, page != null)
post.results = []
let hitCount = 0
for (const i in indexContent) {
for (const i of indexContent) {
const c = indexContent[i]
if (!c) {
continue

View File

@@ -37,7 +37,7 @@ export async function getStaticProps(req) {
* catch-all route for clerk
* @returns
*/
export async function getStaticPaths() {
export function getStaticPaths() {
return {
paths: [
{ params: { index: [] } }, // 使 /sign-in 路径可访问

View File

@@ -36,7 +36,7 @@ export async function getStaticProps(req) {
* catch-all route for clerk
* @returns
*/
export async function getStaticPaths() {
export function getStaticPaths() {
return {
paths: [
{ params: { index: [] } }, // 使 /sign-up 路径可访问

View File

@@ -7,10 +7,12 @@ import Link from 'next/link'
* @returns
*/
export default function ArticleAround({ prev, next }) {
const { locale } = useGlobal()
if (!prev || !next) {
return <></>
}
const { locale } = useGlobal()
return (
<section className='text-gray-800 dark:text-gray-400 flex items-center justify-between gap-x-3 my-4'>
<Link

View File

@@ -256,26 +256,24 @@ const LayoutIndex = props => {
setHasRedirected(true) // 更新状态,防止多次执行
// 重定向到指定文章
router.push(index).then(() => {
setTimeout(() => {
const article = document.querySelector(
'#article-wrapper #notion-article'
)
if (!article) {
console.log(
'请检查您的Notion数据库中是否包含此slug页面 ',
index
)
await router.push(index)
// 显示错误信息
const containerInner = document.querySelector(
'#theme-gitbook #container-inner'
)
const newHTML = `<h1 class="text-3xl pt-12 dark:text-gray-300">配置有误</h1><blockquote class="notion-quote notion-block-ce76391f3f2842d386468ff1eb705b92"><div>请在您的notion中添加一个slug为${index}的文章</div></blockquote>`
containerInner?.insertAdjacentHTML('afterbegin', newHTML)
}
}, 2000)
})
// 使用setTimeout检查页面加载情况
setTimeout(() => {
const article = document.querySelector(
'#article-wrapper #notion-article'
)
if (!article) {
console.log('请检查您的Notion数据库中是否包含此slug页面 ', index)
// 显示错误信息
const containerInner = document.querySelector(
'#theme-gitbook #container-inner'
)
const newHTML = `<h1 class="text-3xl pt-12 dark:text-gray-300">配置有误</h1><blockquote class="notion-quote notion-block-ce76391f3f2842d386468ff1eb705b92"><div>请在您的notion中添加一个slug为${index}的文章</div></blockquote>`
containerInner?.insertAdjacentHTML('afterbegin', newHTML)
}
}, 2000)
}
}
@@ -320,21 +318,18 @@ const LayoutSlug = props => {
useEffect(() => {
// 404
if (!post) {
setTimeout(
() => {
if (isBrowser) {
const article = document.querySelector(
'#article-wrapper #notion-article'
)
if (!article) {
router.push('/404').then(() => {
console.warn('找不到页面', router.asPath)
})
}
setTimeout(() => {
if (isBrowser) {
const article = document.querySelector(
'#article-wrapper #notion-article'
)
if (!article) {
router.push('/404').then(() => {
console.warn('找不到页面', router.asPath)
})
}
},
waiting404
)
}
}, waiting404)
}
}, [post])
return (
@@ -451,16 +446,21 @@ const Layout404 = props => {
}, 3000)
}, [])
return <>
<div className='md:-mt-20 text-black w-full h-screen text-center justify-center content-center items-center flex flex-col'>
<div className='dark:text-gray-200'>
<h2 className='inline-block border-r-2 border-gray-600 mr-2 px-3 py-2 align-top'><i className='mr-2 fas fa-spinner animate-spin' />404</h2>
<div className='inline-block text-left h-32 leading-10 items-center'>
<h2 className='m-0 p-0'>{locale.NAV.PAGE_NOT_FOUND_REDIRECT}</h2>
</div>
</div>
return (
<>
<div className='md:-mt-20 text-black w-full h-screen text-center justify-center content-center items-center flex flex-col'>
<div className='dark:text-gray-200'>
<h2 className='inline-block border-r-2 border-gray-600 mr-2 px-3 py-2 align-top'>
<i className='mr-2 fas fa-spinner animate-spin' />
404
</h2>
<div className='inline-block text-left h-32 leading-10 items-center'>
<h2 className='m-0 p-0'>{locale.NAV.PAGE_NOT_FOUND_REDIRECT}</h2>
</div>
</div>
</div>
</>
)
}
/**
@@ -609,18 +609,17 @@ const LayoutDashboard = props => {
}
export {
Layout404,
LayoutArchive,
LayoutBase,
LayoutCategoryIndex,
LayoutDashboard,
LayoutIndex,
LayoutPostList,
LayoutSearch,
LayoutSignIn,
LayoutSignUp,
LayoutSlug,
LayoutTagIndex,
CONFIG as THEME_CONFIG
Layout404,
LayoutArchive,
LayoutBase,
LayoutCategoryIndex,
LayoutDashboard,
LayoutIndex,
LayoutPostList,
LayoutSearch,
LayoutSignIn,
LayoutSignUp,
LayoutSlug,
LayoutTagIndex,
CONFIG as THEME_CONFIG
}

View File

@@ -12,22 +12,24 @@ export const ArticleFooter = props => {
const router = useRouter()
const { locale } = useGlobal()
return <div className="flex justify-between font-medium text-gray-500 dark:text-gray-400">
<a>
<button
onClick={() => router.push('/')}
className="mt-2 cursor-pointer hover:text-black dark:hover:text-gray-100"
>
{locale.POST.BACK}
</button>
</a>
<a>
<button
onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}
className="mt-2 cursor-pointer hover:text-black dark:hover:text-gray-100"
>
{locale.POST.TOP}
</button>
</a>
</div>
return (
<div className='flex justify-between font-medium text-gray-500 dark:text-gray-400'>
<a>
<button
onClick={() => {
void router.push('/')
}}
className='mt-2 cursor-pointer hover:text-black dark:hover:text-gray-100'>
{locale.POST.BACK}
</button>
</a>
<a>
<button
onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}
className='mt-2 cursor-pointer hover:text-black dark:hover:text-gray-100'>
{locale.POST.TOP}
</button>
</a>
</div>
)
}

View File

@@ -13,22 +13,24 @@ export const ArticleFooter = props => {
const router = useRouter()
const { locale } = useGlobal()
return <div className="flex justify-between font-medium text-gray-500 dark:text-gray-400">
<a>
<button
onClick={() => router.push(siteConfig('path') || '/')}
className="mt-2 cursor-pointer hover:text-black dark:hover:text-gray-100"
>
{locale.POST.BACK}
</button>
</a>
<a>
<button
onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}
className="mt-2 cursor-pointer hover:text-black dark:hover:text-gray-100"
>
{locale.POST.TOP}
</button>
</a>
</div>
return (
<div className='flex justify-between font-medium text-gray-500 dark:text-gray-400'>
<a>
<button
onClick={() => {
void router.push(siteConfig('path') || '/')
}}
className='mt-2 cursor-pointer hover:text-black dark:hover:text-gray-100'>
{locale.POST.BACK}
</button>
</a>
<a>
<button
onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}
className='mt-2 cursor-pointer hover:text-black dark:hover:text-gray-100'>
{locale.POST.TOP}
</button>
</a>
</div>
)
}

View File

@@ -51,10 +51,6 @@ export const MenuList = props => {
links = customMenu
}
if (!links || links.length === 0) {
return null
}
const toggleMenu = () => {
setShowMenu(!showMenu) // 切换菜单状态
}
@@ -63,6 +59,10 @@ export const MenuList = props => {
setShowMenu(false)
}, [router])
if (!links || links.length === 0) {
return null
}
return (
<div>
{/* 移动端菜单切换按钮 */}

View File

@@ -51,10 +51,6 @@ export const MenuList = props => {
links = customMenu
}
if (!links || links.length === 0) {
return null
}
const toggleMenu = () => {
setShowMenu(!showMenu) // 切换菜单状态
}
@@ -63,6 +59,10 @@ export const MenuList = props => {
setShowMenu(false)
}, [router])
if (!links || links.length === 0) {
return null
}
return (
<div>
{/* 移动端菜单切换按钮 */}

View File

@@ -79,17 +79,17 @@ export const getBaseLayoutByTheme = theme => {
*/
export const DynamicLayout = props => {
const { theme, layoutName } = props
const SelectedLayout = getLayoutByTheme({ layoutName, theme })
const SelectedLayout = useLayoutByTheme({ layoutName, theme })
return <SelectedLayout {...props} />
}
/**
* 加载主题文件
* @param {*} router
* @param {*} layoutName
* @param {*} theme
* @returns
*/
export const getLayoutByTheme = ({ layoutName, theme }) => {
export const useLayoutByTheme = ({ layoutName, theme }) => {
// const layoutName = getLayoutNameByPath(router.pathname, router.asPath)
const LayoutComponents =
ThemeComponents[layoutName] || ThemeComponents.LayoutSlug