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 */} {post.title} @@ -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 (
{showArticleInfo &&
- {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 */} {post.title} @@ -51,7 +51,7 @@ export default function ArticleDetail(props) { | } - {post.type[0] !== 'Page' && (<> + {post?.type[0] !== 'Page' && (<> - {post.blockMap && ()} + {post && ()}
diff --git a/themes/next/components/Footer.js b/themes/next/components/Footer.js index 8247f344..ac93dc0f 100644 --- a/themes/next/components/Footer.js +++ b/themes/next/components/Footer.js @@ -7,17 +7,17 @@ const Footer = ({ title }) => { const startYear = BLOG.SINCE && BLOG.SINCE !== currentYear && BLOG.SINCE + '-' return ( diff --git a/themes/next/components/Toc.js b/themes/next/components/Toc.js index ce83e41b..adc4f7f6 100644 --- a/themes/next/components/Toc.js +++ b/themes/next/components/Toc.js @@ -60,10 +60,10 @@ const Toc = ({ toc }) => { return
- +
-