diff --git a/components/Comment.js b/components/Comment.js
index 71c7bc09..45bb554f 100644
--- a/components/Comment.js
+++ b/components/Comment.js
@@ -26,6 +26,9 @@ const GiscusComponent = dynamic(
)
const Comment = ({ frontMatter }) => {
+ if (!frontMatter) {
+ return <>Loading...>
+ }
const router = useRouter()
const { locale, isDarkMode } = useGlobal()
return (
diff --git a/components/Live2D.js b/components/Live2D.js
index 3954decc..43578793 100644
--- a/components/Live2D.js
+++ b/components/Live2D.js
@@ -2,32 +2,28 @@
import BLOG from '@/blog.config'
import { useGlobal } from '@/lib/global'
import { loadExternalResource } from '@/lib/utils'
-import { useEffect, useState } from 'react'
+import { useEffect } from 'react'
-export default function Live2D () {
+export default function Live2D() {
if (!BLOG.WIDGET_PET) {
return <>>
}
- const [init, setInit] = useState()
const { switchTheme } = useGlobal()
- function handleClick () {
+ function handleClick() {
if (BLOG.WIDGET_PET_SWITCH_THEME) {
switchTheme()
}
}
useEffect(() => {
- if (!init) {
- initLive2D()
- setInit(true)
- }
- }, [init])
+ initLive2D()
+ }, [])
- return
+ return
}
-function initLive2D () {
+function initLive2D() {
// 加载 waifu.css live2d.min.js waifu-tips.js
if (screen.width >= 768) {
Promise.all([
diff --git a/components/NotionPage.js b/components/NotionPage.js
index c2fe6c3c..4295f224 100644
--- a/components/NotionPage.js
+++ b/components/NotionPage.js
@@ -11,6 +11,7 @@ import { NotionRenderer } from 'react-notion-x'
import mediumZoom from 'medium-zoom'
import { useEffect, useRef } from 'react'
import dynamic from 'next/dynamic'
+import { useRouter } from 'next/router'
const Code = dynamic(() =>
import('react-notion-x/build/third-party/code').then((m) => m.Code)
@@ -36,6 +37,10 @@ const Modal = dynamic(
}
)
const NotionPage = ({ post }) => {
+ if (!post || !post.blockMap) {
+ return <>{post?.summary || ''}>
+ }
+
const zoom = typeof window !== 'undefined' && mediumZoom({
container: '.notion-viewport',
background: 'rgba(0, 0, 0, 0.2)',
@@ -43,6 +48,8 @@ const NotionPage = ({ post }) => {
})
const zoomRef = useRef(zoom ? zoom.clone() : null)
+ const router = useRouter()
+
useEffect(() => {
// 将所有container下的所有图片添加medium-zoom
const container = document?.getElementById('container')
@@ -52,18 +59,20 @@ const NotionPage = ({ post }) => {
(zoomRef.current).attach(imgList[i])
}
}
- })
+ }, [router.events])
- return
+ return
+
+
}
const mapPageUrl = id => {
diff --git a/lib/cache/memory_cache.js b/lib/cache/memory_cache.js
index f0ff0eec..5bfee605 100644
--- a/lib/cache/memory_cache.js
+++ b/lib/cache/memory_cache.js
@@ -3,14 +3,14 @@ import BLOG from 'blog.config'
const cacheTime = BLOG.isProd ? 10 * 60 : 120 * 60 // 120 minutes for dev,10 minutes for prod
-export async function getCacheFromMemory (key, options) {
- return cache.get(key)
+export async function getCacheFromMemory(key, options) {
+ return await cache.get(key)
}
-export async function setCacheToMemory (key, data) {
+export async function setCacheToMemory(key, data) {
await cache.put(key, data, cacheTime * 1000)
}
-export async function delCacheFromMemory (key) {
+export async function delCacheFromMemory(key) {
await cache.del(key)
}
diff --git a/lib/global.js b/lib/global.js
index 10bfae28..ea93caff 100644
--- a/lib/global.js
+++ b/lib/global.js
@@ -6,7 +6,6 @@ import { initDarkMode, initTheme, saveThemeToCookies } from '@/lib/theme'
import { ALL_THEME } from '@/themes'
const GlobalContext = createContext()
-let hasInit = false
/**
* 全局变量Provider,包括语言本地化、样式主题、搜索词
@@ -14,7 +13,7 @@ let hasInit = false
* @returns {JSX.Element}
* @constructor
*/
-export function GlobalContextProvider ({ children }) {
+export function GlobalContextProvider({ children }) {
const [locale, updateLocale] = useState(generateLocaleDict('en-US'))
const [isDarkMode, updateDarkMode] = useState(false)
const [onLoading, changeLoadingState] = useState(false)
@@ -27,13 +26,13 @@ export function GlobalContextProvider ({ children }) {
changeLoadingState(false)
})
- function switchTheme () {
+ function switchTheme() {
const currentIndex = ALL_THEME.indexOf(theme)
const newIndex = currentIndex < ALL_THEME.length - 1 ? currentIndex + 1 : 0
changeTheme(ALL_THEME[newIndex])
}
- function changeTheme (theme) {
+ function changeTheme(theme) {
Router.query.theme = ''
if (ALL_THEME.indexOf(theme) > -1) {
setTheme(theme)
@@ -44,13 +43,10 @@ export function GlobalContextProvider ({ children }) {
}
useEffect(() => {
- if (!hasInit) {
- initLocale(locale, updateLocale)
- initDarkMode(isDarkMode, updateDarkMode)
- initTheme(theme, changeTheme)
- hasInit = true
- }
- })
+ initLocale(locale, updateLocale)
+ initDarkMode(isDarkMode, updateDarkMode)
+ initTheme(theme, changeTheme)
+ }, [])
return (
diff --git a/lib/notion/getNotionData.js b/lib/notion/getNotionData.js
index 68c10f7e..55a3d031 100644
--- a/lib/notion/getNotionData.js
+++ b/lib/notion/getNotionData.js
@@ -80,7 +80,7 @@ export async function getNotionPageData({ pageId, from }) {
const cacheKey = 'page_block_' + pageId
const data = await getDataFromCache(cacheKey)
if (data) {
- console.log('[请求缓存]:', `from:${from}`, `id:${pageId}`)
+ console.log('[请求缓存]:', `from:${from}`, `root-page-id:${pageId}`)
return data
}
const pageRecordMap = await getPageRecordMapByNotionAPI({ pageId, from })
diff --git a/lib/rss.js b/lib/rss.js
index 3d75d888..840045ad 100644
--- a/lib/rss.js
+++ b/lib/rss.js
@@ -41,7 +41,7 @@ export async function generateRss(posts) {
link: `${BLOG.LINK}/article/${post.slug}`,
description: post.summary,
content: await createFeedContent(post),
- date: new Date(post?.date?.start_date || post.createdTime)
+ date: new Date(post?.date?.start_date || post?.createdTime)
})
}
return feed.atom1()
diff --git a/lib/theme.js b/lib/theme.js
index 360dd7e2..4575bc9c 100644
--- a/lib/theme.js
+++ b/lib/theme.js
@@ -42,7 +42,7 @@ export const initTheme = (theme, changeTheme) => {
* 是否优先深色模式, 根据系统深色模式以及当前时间判断
* @returns {*}
*/
-export function isPreferDark () {
+export function isPreferDark() {
if (BLOG.APPEARANCE === 'dark') {
return true
}
diff --git a/lib/utils.js b/lib/utils.js
index a53b2f2d..be47e17f 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -6,7 +6,7 @@
* @param type js 或 css
* @returns {Promise}
*/
-export function loadExternalResource (url, type) {
+export function loadExternalResource(url, type) {
return new Promise((resolve, reject) => {
let tag
@@ -31,8 +31,8 @@ export function loadExternalResource (url, type) {
* @param {}} variable
* @returns
*/
-export function getQueryVariable (variable) {
- const query = window.location.search.substring(1)
+export function getQueryVariable(variable) {
+ const query = typeof window !== 'undefined' ? window.location.search.substring(1) : ''
const vars = query.split('&')
for (let i = 0; i < vars.length; i++) {
const pair = vars[i].split('=')
@@ -46,7 +46,7 @@ export function getQueryVariable (variable) {
* @param target
* @param sources
*/
-export function mergeDeep (target, ...sources) {
+export function mergeDeep(target, ...sources) {
if (!sources.length) return target
const source = sources.shift()
@@ -68,6 +68,6 @@ export function mergeDeep (target, ...sources) {
* @param item
* @returns {boolean}
*/
-export function isObject (item) {
+export function isObject(item) {
return (item && typeof item === 'object' && !Array.isArray(item))
}
diff --git a/package.json b/package.json
index be7d70c0..d47bdc78 100644
--- a/package.json
+++ b/package.json
@@ -32,8 +32,8 @@
"lodash.throttle": "^4.1.1",
"memory-cache": "^0.2.0",
"next": "^12.0.5",
- "notion-client": "6.5.0",
- "notion-utils": "6.5.0",
+ "notion-client": "6.10.0",
+ "notion-utils": "6.10.0",
"preact": "^10.5.15",
"qrcode.react": "^1.0.1",
"react": "17.0.2",
diff --git a/pages/[slug].js b/pages/[slug].js
index 99f49fed..cabde864 100644
--- a/pages/[slug].js
+++ b/pages/[slug].js
@@ -19,9 +19,9 @@ const Slug = props => {
}
// 文章锁🔐
- const [lock, setLock] = useState(true)
+ const [lock, setLock] = useState(post.password && post.password !== '')
useEffect(() => {
- if (post && post.password && post.password !== '') {
+ if (post.password && post.password !== '') {
setLock(true)
} else {
setLock(false)
diff --git a/pages/article/[slug].js b/pages/article/[slug].js
index aba79897..b190738d 100644
--- a/pages/article/[slug].js
+++ b/pages/article/[slug].js
@@ -24,20 +24,20 @@ const Slug = props => {
const article = document.getElementById('container')
if (!article) {
router.push('/404').then(() => {
- console.log('找不到页面', router.asPath)
+ console.warn('找不到页面', router.asPath)
})
}
}
}, 3000)
})
-
- return Redirecting...
+ const meta = { title: `${props?.siteInfo?.title} | loading` }
+ return
}
// 文章锁🔐
- const [lock, setLock] = useState(true)
+ const [lock, setLock] = useState(post.password && post.password !== '')
useEffect(() => {
- if (post && post.password && post.password !== '') {
+ if (post.password && post.password !== '') {
setLock(true)
} else {
setLock(false)
diff --git a/pages/search/[keyword].js b/pages/search/[keyword].js
index 1308726e..74591872 100644
--- a/pages/search/[keyword].js
+++ b/pages/search/[keyword].js
@@ -2,15 +2,14 @@ import { getGlobalNotionData } from '@/lib/notion/getNotionData'
import { useGlobal } from '@/lib/global'
import { getDataFromCache } from '@/lib/cache/cache_manager'
import * as ThemeMap from '@/themes'
+import BLOG from '@/blog.config'
const Index = props => {
const { keyword, siteInfo } = props
const { locale } = useGlobal()
const meta = {
- title: `${keyword || ''}${keyword ? ' | ' : ''}${locale.NAV.SEARCH} | ${
- siteInfo.title
- }`,
- description: siteInfo.title,
+ title: `${keyword || ''}${keyword ? ' | ' : ''}${locale.NAV.SEARCH} | ${siteInfo?.title}`,
+ description: siteInfo?.title,
slug: 'search/' + (keyword || ''),
type: 'website'
}
@@ -30,7 +29,7 @@ const Index = props => {
* @param {*} param0
* @returns
*/
-export async function getServerSideProps({ params: { keyword } }) {
+export async function getStaticProps({ params: { keyword } }) {
const props = await getGlobalNotionData({
from: 'search-props',
pageType: ['Post']
@@ -38,7 +37,15 @@ export async function getServerSideProps({ params: { keyword } }) {
props.posts = await filterByMemCache(props.allPosts, keyword)
props.keyword = keyword
return {
- props
+ props,
+ revalidate: 1
+ }
+}
+
+export async function getStaticPaths() {
+ return {
+ paths: [{ params: { keyword: BLOG.TITLE } }],
+ fallback: true
}
}
@@ -94,9 +101,11 @@ const isIterable = obj =>
*/
async function filterByMemCache(allPosts, keyword) {
const filterPosts = []
+ if (keyword) {
+ keyword = keyword.trim()
+ }
for (const post of allPosts) {
const cacheKey = 'page_block_' + post.id
- // const page = await getPostBlocks(post.id, 'search')
const page = await getDataFromCache(cacheKey)
const tagContent = post.tags ? post.tags.join(' ') : ''
const categoryContent = post.category ? post.category.join(' ') : ''
@@ -111,7 +120,7 @@ async function filterByMemCache(allPosts, keyword) {
indexContent = appendText(indexContent, properties, 'caption')
})
}
- // console.log('搜索是否命中缓存', page !== null, indexContent)
+ console.log('全文搜索缓存', cacheKey, page != null)
post.results = []
let hitCount = 0
for (const i in indexContent) {
@@ -119,7 +128,7 @@ async function filterByMemCache(allPosts, keyword) {
if (!c) {
continue
}
- const index = c.toLowerCase().indexOf(keyword.toLowerCase()) || -1
+ const index = c.toLowerCase().indexOf(keyword.toLowerCase())
if (index > -1) {
hit = true
hitCount += 1
diff --git a/themes/example/LayoutSlug.js b/themes/example/LayoutSlug.js
index 70482b5d..91b11d80 100644
--- a/themes/example/LayoutSlug.js
+++ b/themes/example/LayoutSlug.js
@@ -8,13 +8,18 @@ import formatDate from '@/lib/formatDate'
export const LayoutSlug = props => {
const { post, lock, validPassword } = props
+
+ if (!post) {
+ return
+ }
+
if (!lock && post?.blockMap?.block) {
post.content = Object.keys(post.blockMap.block)
post.toc = getPageTableOfContents(post, post.blockMap)
}
const { locale } = useGlobal()
- const date = formatDate(post?.date?.start_date || post.createdTime, locale.LOCALE)
+ const date = formatDate(post?.date?.start_date || post?.createdTime, locale.LOCALE)
return (
@@ -34,7 +39,7 @@ export const LayoutSlug = props => {
|
- {post.type[0] !== 'Page' && (<>
+ {post?.type[0] !== 'Page' && (<>
{
- {post.blockMap && }
+ {post && }
}
diff --git a/themes/fukasawa/components/ArticleDetail.js b/themes/fukasawa/components/ArticleDetail.js
index cbdfa0b7..77271f5f 100644
--- a/themes/fukasawa/components/ArticleDetail.js
+++ b/themes/fukasawa/components/ArticleDetail.js
@@ -10,11 +10,15 @@ import ArticleAround from './ArticleAround'
* @param {*} param0
* @returns
*/
-export default function ArticleDetail({ post, recommendPosts, prev, next }) {
+export default function ArticleDetail(props) {
+ const { post, prev, next } = props
+ if (!post) {
+ return <>>
+ }
const { locale } = useGlobal()
- const date = formatDate(post?.date?.start_date || post.createdTime, locale.LOCALE)
+ const date = formatDate(post?.date?.start_date || post?.createdTime, locale.LOCALE)
return (
- {post.type && !post.type.includes('Page') && post?.page_cover && (
+ {post?.type && !post?.type.includes('Page') && post?.page_cover && (
{/* eslint-disable-next-line @next/next/no-img-element */}

@@ -41,7 +45,7 @@ export default function ArticleDetail({ post, recommendPosts, prev, next }) {
|
- {post.type[0] !== 'Page' && (<>
+ {post?.type[0] !== 'Page' && (<>
- {post.blockMap &&
}
+ {post &&
}
diff --git a/themes/hexo/LayoutSlug.js b/themes/hexo/LayoutSlug.js
index e2fec724..ee3143cf 100644
--- a/themes/hexo/LayoutSlug.js
+++ b/themes/hexo/LayoutSlug.js
@@ -15,6 +15,15 @@ import ArticleRecommend from './components/ArticleRecommend'
export const LayoutSlug = props => {
const { post, lock, validPassword } = props
+ if (!post) {
+ return }
+ {...props}
+ showCategory={false}
+ showTag={false}
+ >
+ }
+
if (!lock && post?.blockMap?.block) {
post.content = Object.keys(post.blockMap.block)
post.toc = getPageTableOfContents(post, post.blockMap)
@@ -50,7 +59,7 @@ export const LayoutSlug = props => {
{/* Notion文章主体 */}
- {post.blockMap && }
+ {post && }
diff --git a/themes/hexo/components/BlogPostListPage.js b/themes/hexo/components/BlogPostListPage.js
index 038bb322..4964f024 100644
--- a/themes/hexo/components/BlogPostListPage.js
+++ b/themes/hexo/components/BlogPostListPage.js
@@ -13,7 +13,7 @@ import BlogPostListEmpty from './BlogPostListEmpty'
*/
const BlogPostListPage = ({ page = 1, posts = [], postCount }) => {
const totalPage = Math.ceil(postCount / BLOG.POSTS_PER_PAGE)
- const showPagination = posts.length === BLOG.POSTS_PER_PAGE
+ const showPagination = postCount >= BLOG.POSTS_PER_PAGE
if (!posts || posts.length === 0) {
return
@@ -26,7 +26,7 @@ const BlogPostListPage = ({ page = 1, posts = [], postCount }) => {
))}
- {showPagination &&
}
+ {showPagination &&
}
)
}
diff --git a/themes/hexo/components/HeaderArticle.js b/themes/hexo/components/HeaderArticle.js
index 3e91179d..bd0bea4a 100644
--- a/themes/hexo/components/HeaderArticle.js
+++ b/themes/hexo/components/HeaderArticle.js
@@ -4,12 +4,15 @@ import formatDate from '@/lib/formatDate'
import { useEffect } from 'react'
export default function HeaderArticle({ post, siteInfo }) {
+ if (!post) {
+ return <>loading...>
+ }
const headerImage = post?.page_cover ? `url("${post.page_cover}")` : `url("${siteInfo?.pageCover}")`
const { isDarkMode } = useGlobal()
const { locale } = useGlobal()
const date = formatDate(
- post?.date?.start_date || post.createdTime,
+ post?.date?.start_date || post?.createdTime,
locale.LOCALE
)
@@ -71,7 +74,7 @@ export default function HeaderArticle({ post, siteInfo }) {
>}
- {post.type[0] !== 'Page' && (
+ {post?.type[0] !== 'Page' && (
<>
{
const { post, lock, validPassword } = props
+ if (!post) {
+ return
+ }
if (!lock && post?.blockMap?.block) {
post.content = Object.keys(post.blockMap.block)
diff --git a/themes/medium/components/ArticleDetail.js b/themes/medium/components/ArticleDetail.js
index a0ed321e..ddaa9a76 100644
--- a/themes/medium/components/ArticleDetail.js
+++ b/themes/medium/components/ArticleDetail.js
@@ -15,7 +15,7 @@ export const ArticleDetail = props => {
const { locale } = useGlobal()
const date = formatDate(
- post?.date?.start_date || post.createdTime,
+ post?.date?.start_date || post?.createdTime,
locale.LOCALE
)
return
@@ -48,7 +48,7 @@ export const ArticleDetail = props => {
{/* Notion文章主体 */}
- {post.blockMap && ()}
+ {post && ()}
diff --git a/themes/medium/components/Progress.js b/themes/medium/components/Progress.js
index 3680e157..d9a13ad9 100644
--- a/themes/medium/components/Progress.js
+++ b/themes/medium/components/Progress.js
@@ -10,7 +10,6 @@ const Progress = ({ targetRef, showPercent = true }) => {
const [percent, changePercent] = useState(0)
const scrollListener = () => {
const target = currentRef || document.getElementById('container')
- console.log(target)
if (target) {
const clientHeight = target.clientHeight
const scrollY = window.pageYOffset
diff --git a/themes/next/LayoutSlug.js b/themes/next/LayoutSlug.js
index 097f457b..8e7ddd72 100644
--- a/themes/next/LayoutSlug.js
+++ b/themes/next/LayoutSlug.js
@@ -11,6 +11,14 @@ import { ArticleLock } from './components/ArticleLock'
export const LayoutSlug = (props) => {
const { post, latestPosts, lock, validPassword } = props
+ if (!post) {
+ return
+ }
+ />
+ }
if (!lock && post?.blockMap?.block) {
post.content = Object.keys(post.blockMap.block)
diff --git a/themes/next/components/ArticleDetail.js b/themes/next/components/ArticleDetail.js
index ba49b0a6..ab7f9608 100644
--- a/themes/next/components/ArticleDetail.js
+++ b/themes/next/components/ArticleDetail.js
@@ -21,15 +21,15 @@ export default function ArticleDetail(props) {
const { post, recommendPosts, prev, next, showArticleInfo } = props
const url = BLOG.LINK + useRouter().asPath
const { locale } = useGlobal()
- const date = formatDate(post?.date?.start_date || post.createdTime, locale.LOCALE)
+ const date = formatDate(post?.date?.start_date || post?.createdTime, locale.LOCALE)
return (