diff --git a/pages/archive/index.js b/pages/archive/index.js
index 6d0ebe32..7a94f224 100644
--- a/pages/archive/index.js
+++ b/pages/archive/index.js
@@ -1,9 +1,10 @@
import { getGlobalNotionData } from '@/lib/notion/getNotionData'
-import React from 'react'
+import React, { useEffect } from 'react'
import { useGlobal } from '@/lib/global'
import BLOG from '@/blog.config'
import { useRouter } from 'next/router'
import { getLayoutByTheme } from '@/themes/theme'
+import { isBrowser } from '@/lib/utils'
const ArchiveIndex = props => {
const { siteInfo } = props
@@ -12,6 +13,20 @@ const ArchiveIndex = props => {
// 根据页面路径加载不同Layout文件
const Layout = getLayoutByTheme(useRouter())
+ useEffect(() => {
+ if (isBrowser()) {
+ const anchor = window.location.hash
+ if (anchor) {
+ setTimeout(() => {
+ const anchorElement = document.getElementById(anchor.substring(1))
+ if (anchorElement) {
+ anchorElement.scrollIntoView({ block: 'start', behavior: 'smooth' })
+ }
+ }, 300)
+ }
+ }
+ }, [])
+
const meta = {
title: `${locale.NAV.ARCHIVE} | ${siteInfo?.title}`,
description: siteInfo?.description,
diff --git a/themes/example/components/BlogListGroupByDate.js b/themes/example/components/BlogListGroupByDate.js
index 742c83fa..7759eaca 100644
--- a/themes/example/components/BlogListGroupByDate.js
+++ b/themes/example/components/BlogListGroupByDate.js
@@ -1,4 +1,5 @@
-import BLOG, { LINK } from '@/blog.config'
+import BLOG from '@/blog.config'
+import Link from 'next/link'
/**
* 按照日期将文章分组
@@ -20,17 +21,12 @@ export default function BlogListGroupByDate({ archiveTitle, archivePosts }) {
>
+ {/* 网页SEO信息 */}
{/* 页头 */}
@@ -97,6 +98,7 @@ const LayoutIndex = props => {
*/
const LayoutPostList = props => {
const { category, tag } = props
+ // 顶部如果是按照分类或标签查看文章列表,列表顶部嵌入一个横幅
let slotTop = null
if (category) {
slotTop =
{category}
diff --git a/themes/fukasawa/Layout404.js b/themes/fukasawa/Layout404.js
deleted file mode 100644
index 98ae689a..00000000
--- a/themes/fukasawa/Layout404.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import LayoutBase from './LayoutBase'
-
-export const Layout404 = props => {
- return
404
-}
-
-export default Layout404
diff --git a/themes/fukasawa/LayoutArchive.js b/themes/fukasawa/LayoutArchive.js
deleted file mode 100644
index f82f3e35..00000000
--- a/themes/fukasawa/LayoutArchive.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import { useEffect } from 'react'
-import BlogArchiveItem from './components/BlogPostArchive'
-import LayoutBase from './LayoutBase'
-
-export const LayoutArchive = (props) => {
- const { archivePosts } = props
-
- useEffect(() => {
- const anchor = window.location.hash
- if (anchor) {
- setTimeout(() => {
- const anchorElement = document.getElementById(anchor.substring(1))
- if (anchorElement) {
- anchorElement.scrollIntoView({ block: 'start', behavior: 'smooth' })
- }
- }, 300)
- }
- }, [])
- return
-
- {Object.keys(archivePosts).map(archiveTitle => (
-
- ))}
-
-
-}
-
-export default LayoutArchive
diff --git a/themes/fukasawa/LayoutBase.js b/themes/fukasawa/LayoutBase.js
deleted file mode 100644
index d000cfe0..00000000
--- a/themes/fukasawa/LayoutBase.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import CommonHead from '@/components/CommonHead'
-import TopNav from './components/TopNav'
-import AsideLeft from './components/AsideLeft'
-import Live2D from '@/components/Live2D'
-import BLOG from '@/blog.config'
-import { isBrowser, loadExternalResource } from '@/lib/utils'
-import { useGlobal } from '@/lib/global'
-
-/**
- * 基础布局 采用左右两侧布局,移动端使用顶部导航栏
- * @param children
- * @param layout
- * @param tags
- * @param meta
- * @param post
- * @param currentSearch
- * @param currentCategory
- * @param currentTag
- * @param categories
- * @returns {JSX.Element}
- * @constructor
- */
-const LayoutBase = (props) => {
- const { children, headerSlot, meta } = props
- const leftAreaSlot =
-
- if (isBrowser()) {
- loadExternalResource('/css/theme-fukasawa.css', 'css')
- }
-
- const { onLoading } = useGlobal()
-
- const LoadingCover =
-
- return (
-
-
-
-
-
-
-
-
-
{headerSlot}
-
{onLoading ? LoadingCover : children}
-
-
-
-
-
-
)
-}
-
-export default LayoutBase
diff --git a/themes/fukasawa/LayoutCategory.js b/themes/fukasawa/LayoutCategory.js
deleted file mode 100644
index c633a439..00000000
--- a/themes/fukasawa/LayoutCategory.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import BLOG from '@/blog.config'
-import BlogListPage from './components/BlogListPage'
-import BlogListScroll from './components/BlogListScroll'
-import LayoutBase from './LayoutBase'
-
-export const LayoutCategory = props => {
- return
- {BLOG.POST_LIST_STYLE === 'page' ? : }
-
-}
-
-export default LayoutCategory
diff --git a/themes/fukasawa/LayoutCategoryIndex.js b/themes/fukasawa/LayoutCategoryIndex.js
deleted file mode 100644
index 469ab973..00000000
--- a/themes/fukasawa/LayoutCategoryIndex.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import { useGlobal } from '@/lib/global'
-import Link from 'next/link'
-import LayoutBase from './LayoutBase'
-
-export const LayoutCategoryIndex = (props) => {
- const { locale } = useGlobal()
- const { categoryOptions } = props
- return (
-
-
-
- {locale.COMMON.CATEGORY}:
-
-
- {categoryOptions?.map(category => {
- return (
-
-
- {category.name}({category.count})
-
-
- )
- })}
-
-
-
- )
-}
-
-export default LayoutCategoryIndex
diff --git a/themes/fukasawa/LayoutIndex.js b/themes/fukasawa/LayoutIndex.js
deleted file mode 100644
index d4e7451b..00000000
--- a/themes/fukasawa/LayoutIndex.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import BLOG from '@/blog.config'
-import BlogListPage from './components/BlogListPage'
-import BlogListScroll from './components/BlogListScroll'
-import LayoutBase from './LayoutBase'
-
-export const LayoutIndex = (props) => {
- return
- {BLOG.POST_LIST_STYLE === 'page' ? : }
-
-}
-
-export default LayoutIndex
diff --git a/themes/fukasawa/LayoutPage.js b/themes/fukasawa/LayoutPage.js
deleted file mode 100644
index c3a85397..00000000
--- a/themes/fukasawa/LayoutPage.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import BlogListPage from './components/BlogListPage'
-import LayoutBase from './LayoutBase'
-
-export const LayoutPage = (props) => {
- return
-
-
-
-
-}
-
-export default LayoutPage
diff --git a/themes/fukasawa/LayoutSearch.js b/themes/fukasawa/LayoutSearch.js
deleted file mode 100644
index 9efb3160..00000000
--- a/themes/fukasawa/LayoutSearch.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import LayoutBase from './LayoutBase'
-import BLOG from '@/blog.config'
-import BlogListPage from './components/BlogListPage'
-import BlogListScroll from './components/BlogListScroll'
-import { useRouter } from 'next/router'
-import { useEffect } from 'react'
-import Mark from 'mark.js'
-import { isBrowser } from '@/lib/utils'
-
-export const LayoutSearch = (props) => {
- const { keyword } = props
- const router = useRouter()
- const currentSearch = keyword || router?.query?.s
- useEffect(() => {
- setTimeout(() => {
- const container = isBrowser() && document.getElementById('posts-wrapper')
- if (container && container.innerHTML) {
- const re = new RegExp(currentSearch, 'gim')
- const instance = new Mark(container)
- instance.markRegExp(re, {
- element: 'span',
- className: 'text-red-500 border-b border-dashed'
- })
- }
- }, 100)
- })
- return
- {BLOG.POST_LIST_STYLE === 'page' ? : }
-
-}
-
-export default LayoutSearch
diff --git a/themes/fukasawa/LayoutSlug.js b/themes/fukasawa/LayoutSlug.js
deleted file mode 100644
index 73e22a00..00000000
--- a/themes/fukasawa/LayoutSlug.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import ArticleDetail from './components/ArticleDetail'
-import LayoutBase from './LayoutBase'
-import { ArticleLock } from './components/ArticleLock'
-
-export const LayoutSlug = (props) => {
- const { lock, validPassword } = props
- return (
-
- {!lock && }
- {lock && }
-
- )
-}
-
-export default LayoutSlug
diff --git a/themes/fukasawa/LayoutTag.js b/themes/fukasawa/LayoutTag.js
deleted file mode 100644
index 104b6884..00000000
--- a/themes/fukasawa/LayoutTag.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import BLOG from '@/blog.config'
-import BlogListPage from './components/BlogListPage'
-import BlogListScroll from './components/BlogListScroll'
-import LayoutBase from './LayoutBase'
-
-export const LayoutTag = (props) => {
- return
- {BLOG.POST_LIST_STYLE === 'page' ? : }
-
-}
-
-export default LayoutTag
diff --git a/themes/fukasawa/LayoutTagIndex.js b/themes/fukasawa/LayoutTagIndex.js
deleted file mode 100644
index 30f602a6..00000000
--- a/themes/fukasawa/LayoutTagIndex.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import { useGlobal } from '@/lib/global'
-import TagItemMini from './components/TagItemMini'
-import LayoutBase from './LayoutBase'
-
-export const LayoutTagIndex = (props) => {
- const { locale } = useGlobal()
- const { tagOptions } = props
- return
-
-
{locale.COMMON.TAGS}:
-
-
-
-}
-
-export default LayoutTagIndex
diff --git a/themes/fukasawa/components/LoadingCover.js b/themes/fukasawa/components/LoadingCover.js
new file mode 100644
index 00000000..01a2036d
--- /dev/null
+++ b/themes/fukasawa/components/LoadingCover.js
@@ -0,0 +1,11 @@
+/**
+ * 加载过程的遮罩
+ * @returns
+ */
+export default function LoadingCover () {
+ return
+}
diff --git a/themes/fukasawa/index.js b/themes/fukasawa/index.js
index 8b5764e6..6874c850 100644
--- a/themes/fukasawa/index.js
+++ b/themes/fukasawa/index.js
@@ -1,14 +1,209 @@
+'use client'
+
import CONFIG_FUKA from './config_fuka'
-import LayoutIndex from './LayoutIndex'
-import LayoutSearch from './LayoutSearch'
-import LayoutArchive from './LayoutArchive'
-import LayoutSlug from './LayoutSlug'
-import Layout404 from './Layout404'
-import LayoutCategory from './LayoutCategory'
-import LayoutCategoryIndex from './LayoutCategoryIndex'
-import LayoutPage from './LayoutPage'
-import LayoutTag from './LayoutTag'
-import LayoutTagIndex from './LayoutTagIndex'
+import CommonHead from '@/components/CommonHead'
+import TopNav from './components/TopNav'
+import AsideLeft from './components/AsideLeft'
+import Live2D from '@/components/Live2D'
+import BLOG from '@/blog.config'
+import { isBrowser, loadExternalResource } from '@/lib/utils'
+import { useGlobal } from '@/lib/global'
+import LoadingCover from './components/LoadingCover'
+import BlogListPage from './components/BlogListPage'
+import BlogListScroll from './components/BlogListScroll'
+import BlogArchiveItem from './components/BlogPostArchive'
+import ArticleDetail from './components/ArticleDetail'
+import { ArticleLock } from './components/ArticleLock'
+import TagItemMini from './components/TagItemMini'
+import { useRouter } from 'next/router'
+import { useEffect } from 'react'
+import Mark from 'mark.js'
+import Link from 'next/link'
+
+/**
+ * 基础布局 采用左右两侧布局,移动端使用顶部导航栏
+ * @param children
+ * @param layout
+ * @param tags
+ * @param meta
+ * @param post
+ * @param currentSearch
+ * @param currentCategory
+ * @param currentTag
+ * @param categories
+ * @returns {JSX.Element}
+ * @constructor
+ */
+const LayoutBase = (props) => {
+ const { children, headerSlot, meta } = props
+ const leftAreaSlot =
+ const { onLoading } = useGlobal()
+
+ if (isBrowser()) {
+ loadExternalResource('/css/theme-fukasawa.css', 'css')
+ }
+
+ return (
+
+
+
+
+
+ {/* 侧边抽屉 */}
+
+
+
+
+
{headerSlot}
+
{onLoading ? : children}
+
+
+
+
+
+
)
+}
+
+/**
+ * 首页
+ * @param {*} props notion数据
+ * @returns 首页就是一个博客列表
+ */
+const LayoutIndex = (props) => {
+ return
+}
+
+/**
+ * 博客列表
+ * @param {*} props
+ */
+const LayoutPostList = (props) => {
+ return
+ {BLOG.POST_LIST_STYLE === 'page' ? : }
+
+}
+
+/**
+ * 文章详情
+ * @param {*} props
+ * @returns
+ */
+const LayoutSlug = (props) => {
+ const { lock, validPassword } = props
+ return (
+
+ {lock ? : }
+
+ )
+}
+
+/**
+ * 搜索页
+ */
+const LayoutSearch = (props) => {
+ const { keyword } = props
+ const router = useRouter()
+ useEffect(() => {
+ setTimeout(() => {
+ const container = isBrowser() && document.getElementById('posts-wrapper')
+ if (container && container.innerHTML) {
+ const re = new RegExp(keyword, 'gim')
+ const instance = new Mark(container)
+ instance.markRegExp(re, {
+ element: 'span',
+ className: 'text-red-500 border-b border-dashed'
+ })
+ }
+ }, 300)
+ }, [router])
+ return
+}
+
+/**
+ * 归档页面
+ */
+const LayoutArchive = (props) => {
+ const { archivePosts } = props
+ return
+
+ {Object.keys(archivePosts).map(archiveTitle => (
+
+ ))}
+
+
+}
+
+/**
+ * 404
+ * @param {*} props
+ * @returns
+ */
+const Layout404 = props => {
+ return
404
+}
+
+/**
+ * 分类列表
+ * @param {*} props
+ * @returns
+ */
+const LayoutCategoryIndex = (props) => {
+ const { locale } = useGlobal()
+ const { categoryOptions } = props
+ return (
+
+
+
+ {locale.COMMON.CATEGORY}:
+
+
+ {categoryOptions?.map(category => {
+ return (
+
+
+ {category.name}({category.count})
+
+
+ )
+ })}
+
+
+
+ )
+}
+
+/**
+ * 标签列表
+ * @param {*} props
+ * @returns
+ */
+const LayoutTagIndex = (props) => {
+ const { locale } = useGlobal()
+ const { tagOptions } = props
+ return
+
+
{locale.COMMON.TAGS}:
+
+
+
+}
export {
CONFIG_FUKA as THEME_CONFIG,
@@ -17,9 +212,7 @@ export {
LayoutArchive,
LayoutSlug,
Layout404,
- LayoutCategory,
+ LayoutPostList,
LayoutCategoryIndex,
- LayoutPage,
- LayoutTag,
LayoutTagIndex
}
diff --git a/themes/theme.js b/themes/theme.js
index 40507c22..468199d2 100644
--- a/themes/theme.js
+++ b/themes/theme.js
@@ -16,7 +16,7 @@ export const getLayoutByTheme = (router) => {
const themeQuery = getQueryParam(router.asPath, 'theme') || BLOG.THEME
const layout = getLayoutNameByPath(router.pathname)
if (themeQuery !== BLOG.THEME) {
- return dynamic(() => import(`@/themes/${themeQuery}/${layout}`), { ssr: true })
+ return dynamic(() => import(`@/themes/${themeQuery}`).then(m => m[layout]), { ssr: true })
} else {
return ThemeComponents[layout]
}