import CONFIG from './config' import CommonHead from '@/components/CommonHead' import { useState, createContext, useContext, useEffect } from 'react' import Footer from './components/Footer' import InfoCard from './components/InfoCard' import RevolverMaps from './components/RevolverMaps' import Tabs from '@/components/Tabs' import TopNavBar from './components/TopNavBar' import SearchInput from './components/SearchInput' import BottomMenuBar from './components/BottomMenuBar' import { useGlobal } from '@/lib/global' import { useRouter } from 'next/router' import Live2D from '@/components/Live2D' import BLOG from '@/blog.config' import Announcement from './components/Announcement' import JumpToTopButton from './components/JumpToTopButton' import BlogPostListPage from './components/BlogPostListPage' import BlogPostListScroll from './components/BlogPostListScroll' import Catalog from './components/Catalog' import { ArticleLock } from './components/ArticleLock' import TagGroups from './components/TagGroups' import CategoryGroup from './components/CategoryGroup' import { isBrowser } from '@/lib/utils' import Mark from 'mark.js' import BlogArchiveItem from './components/BlogArchiveItem' import BlogPostBar from './components/BlogPostBar' import NotionPage from '@/components/NotionPage' import Comment from '@/components/Comment' import ArticleAround from './components/ArticleAround' import TocDrawer from './components/TocDrawer' import CategoryItem from './components/CategoryItem' import TagItemMini from './components/TagItemMini' import ShareBar from '@/components/ShareBar' import Link from 'next/link' import { Transition } from '@headlessui/react' // 主题全局状态 const ThemeGlobalMedium = createContext() export const useMediumGlobal = () => useContext(ThemeGlobalMedium) /** * 基础布局 * 采用左右两侧布局,移动端使用顶部导航栏 * @returns {JSX.Element} * @constructor */ const LayoutBase = props => { const { children, meta, showInfoCard = true, slotRight, slotTop, siteInfo, notice } = props const { locale } = useGlobal() const router = useRouter() const [tocVisible, changeTocVisible] = useState(false) const { onLoading } = useGlobal() return (
{/* 桌面端左侧菜单 */} {/* */} {/* 主区 */}
{/* 顶部导航栏 */}
{slotTop} {children}
{/* 底部 */}
{/* 桌面端右侧 */}
{slotRight}
{router.pathname !== '/search' && } {showInfoCard && } {CONFIG.WIDGET_REVOLVER_MAPS === 'true' && }
{/* 移动端底部导航栏 */}
) } /** * 首页 * 首页就是一个博客列表 * @param {*} props * @returns */ const LayoutIndex = (props) => { return } /** * 博客列表 * @returns */ const LayoutPostList = (props) => { const slotTop = return {BLOG.POST_LIST_STYLE === 'page' ? : } } /** * 文章详情 * @param {*} props * @returns */ const LayoutSlug = props => { const { post, prev, next, lock, validPassword } = props const { locale } = useGlobal() const slotRight = post?.toc && post?.toc?.length >= 3 && (
) return ( {/* 文章锁 */} {lock && } {!lock &&
{/* Notion文章主体 */}
{post && ()}
{/* 文章底部区域 */}
{/* 分享 */} {/* 文章分类和标签信息 */}
{CONFIG.POST_DETAIL_CATEGORY && post?.category && }
{CONFIG.POST_DETAIL_TAG && post?.tagItems?.map(tag => )}
{/* 上一篇下一篇文章 */} {post.type === 'Post' && } {/* 评论区 */}
{/* 移动端目录 */}
}
) } /** * 搜索 * @param {*} props * @returns */ const LayoutSearch = (props) => { const { locale } = useGlobal() 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 {/* 搜索导航栏 */}
{locale.NAV.SEARCH}
{!currentSearch && <> }
{/* 文章列表 */} {currentSearch &&
{BLOG.POST_LIST_STYLE === 'page' ? : }
}
} /** * 归档 * @param {*} props * @returns */ const LayoutArchive = props => { const { archivePosts } = props return (
{Object.keys(archivePosts)?.map(archiveTitle => )}
) } /** * 404 * @param {*} props * @returns */ const Layout404 = props => { return
404 Not found.
} /** * 分类列表 * @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 => { return (
) })}
) } export { CONFIG as THEME_CONFIG, LayoutIndex, LayoutPostList, LayoutSearch, LayoutArchive, LayoutSlug, Layout404, LayoutCategoryIndex, LayoutTagIndex }