import CONFIG from './config' import CommonHead from '@/components/CommonHead' import { useEffect, useRef } from 'react' import Footer from './components/Footer' import SideRight from './components/SideRight' import TopNav from './components/TopNav' import { useGlobal } from '@/lib/global' import BLOG from '@/blog.config' import { isBrowser, loadExternalResource } from '@/lib/utils' import BlogPostListPage from './components/BlogPostListPage' import BlogPostListScroll from './components/BlogPostListScroll' import Hero from './components/Header' import { useRouter } from 'next/router' import Mark from 'mark.js' import Card from './components/Card' import RightFloatArea from './components/RightFloatArea' import SearchNav from './components/SearchNav' import BlogPostArchive from './components/BlogPostArchive' import { ArticleLock } from './components/ArticleLock' import HeaderArticle from './components/HeaderArticle' import JumpToCommentButton from './components/JumpToCommentButton' import TocDrawer from './components/TocDrawer' import TocDrawerButton from './components/TocDrawerButton' import Comment from '@/components/Comment' import NotionPage from '@/components/NotionPage' import ArticleAdjacent from './components/ArticleAdjacent' import ArticleCopyright from './components/ArticleCopyright' import ArticleRecommend from './components/ArticleRecommend' import ShareBar from '@/components/ShareBar' import TagItemMini from './components/TagItemMini' import Link from 'next/link' import SlotBar from './components/SlotBar' import { Transition } from '@headlessui/react' /** * 基础布局 采用左右两侧布局,移动端使用顶部导航栏 * @param props * @returns {JSX.Element} * @constructor */ const LayoutBase = props => { const { children, headerSlot, floatSlot, slotTop, meta, siteInfo, className } = props const { onLoading } = useGlobal() // 加载主题样式 if (isBrowser()) { loadExternalResource('/css/theme-hexo.css', 'css') } return (
{/* 网页SEO */} {/* 顶部导航 */} {/* 顶部嵌入 */} {headerSlot} {/* 主区块 */}
{/* 主区上部嵌入 */} {slotTop} {children}
{/* 右侧栏 */}
{/* 悬浮菜单 */} {/* 页脚 */}
) } /** * 首页 * 是一个博客列表,嵌入一个Hero大图 * @param {*} props * @returns */ const LayoutIndex = (props) => { const headerSlot = CONFIG.HOME_BANNER_ENABLE && return } /** * 博客列表 * @param {*} props * @returns */ const LayoutPostList = (props) => { return {BLOG.POST_LIST_STYLE === 'page' ? : } } /** * 搜索 * @param {*} props * @returns */ const LayoutSearch = props => { const { keyword } = props const router = useRouter() const currentSearch = keyword || router?.query?.s useEffect(() => { setTimeout(() => { if (currentSearch) { const targets = document.getElementsByClassName('replace') for (const container of targets) { 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 ( {!currentSearch ? :
{BLOG.POST_LIST_STYLE === 'page' ? : }
}
) } /** * 归档 * @param {*} props * @returns */ const LayoutArchive = (props) => { const { archivePosts } = props return
{Object.keys(archivePosts).map(archiveTitle => ( ))}
} /** * 文章详情 * @param {*} props * @returns */ const LayoutSlug = props => { const { post, lock, validPassword } = props const drawerRight = useRef(null) if (!post) { return } > } const targetRef = isBrowser() ? document.getElementById('article-wrapper') : null const floatSlot = <> {post?.toc?.length > 1 &&
{ drawerRight?.current?.handleSwitchVisible() }} />
} return ( } showCategory={false} showTag={false} floatSlot={floatSlot} >
{lock && } {!lock &&
{/* Notion文章主体 */}
{post && }
{/* 分享 */} {post.type === 'Post' && <> }
{/* 评论互动 */}
}
) } /** * 404 * @param {*} props * @returns */ const Layout404 = props => { const router = useRouter() useEffect(() => { // 延时3秒如果加载失败就返回首页 setTimeout(() => { if (isBrowser()) { const article = document.getElementById('notion-article') if (!article) { router.push('/').then(() => { // console.log('找不到页面', router.asPath) }) } } }, 3000) }) return (

404

页面未找到

) } /** * 分类列表 * @param {*} props * @returns */ const LayoutCategoryIndex = props => { const { categoryOptions } = props const { locale } = useGlobal() return (
{locale.COMMON.CATEGORY}:
{categoryOptions.map(category => { return (
{category.name}({category.count})
) })}
) } /** * 标签列表 * @param {*} props * @returns */ const LayoutTagIndex = props => { const { tagOptions } = props const { locale } = useGlobal() return (
{locale.COMMON.TAGS}:
{tagOptions.map(tag =>
)}
) } export { CONFIG as THEME_CONFIG, LayoutIndex, LayoutSearch, LayoutArchive, LayoutSlug, Layout404, LayoutCategoryIndex, LayoutPostList, LayoutTagIndex }