import BLOG from '@/blog.config' import CONFIG from './config' import React, { createContext, useEffect, useState, useContext, useRef } from 'react' import Nav from './components/Nav' import { Footer } from './components/Footer' import JumpToTopButton from './components/JumpToTopButton' import Live2D from '@/components/Live2D' import { useGlobal } from '@/lib/global' import Announcement from './components/Announcement' import { BlogListPage } from './components/BlogListPage' import { BlogListScroll } from './components/BlogListScroll' import { deepClone, isBrowser } from '@/lib/utils' import SearchNavBar from './components/SearchNavBar' import BlogArchiveItem from './components/BlogArchiveItem' import { ArticleLock } from './components/ArticleLock' import NotionPage from '@/components/NotionPage' import { ArticleInfo } from './components/ArticleInfo' import Comment from '@/components/Comment' import { ArticleFooter } from './components/ArticleFooter' import ShareBar from '@/components/ShareBar' import Link from 'next/link' import BlogListBar from './components/BlogListBar' import { Transition } from '@headlessui/react' import { Style } from './style' import replaceSearchResult from '@/components/Mark' import CommonHead from '@/components/CommonHead' import AlgoliaSearchModal from '@/components/AlgoliaSearchModal' // 主题全局状态 const ThemeGlobalNobelium = createContext() export const useNobeliumGlobal = () => useContext(ThemeGlobalNobelium) /** * 基础布局 采用左右两侧布局,移动端使用顶部导航栏 * @returns {JSX.Element} * @constructor */ const LayoutBase = props => { const { children, post, topSlot, meta } = props const fullWidth = post?.fullWidth ?? false const { onLoading } = useGlobal() const searchModal = useRef(null) return ( {/* SEO相关 */} {/* SEO相关 */} {/* 顶部导航栏 */} {/* 主区 */} {/* 顶部插槽 */} {topSlot} {children} {/* 页脚 */} {/* 右下悬浮 */} {/* 左下悬浮 */} {/* 搜索框 */} ) } /** * 首页 * 首页是个博客列表,加上顶部嵌入一个公告 * @param {*} props * @returns */ const LayoutIndex = props => { return ( } /> ) } /** * 博客列表 * @param {*} props * @returns */ const LayoutPostList = props => { const { posts, topSlot } = props // 在列表中进行实时过滤 const [filterKey, setFilterKey] = useState('') let filteredBlogPosts = [] if (filterKey && posts) { filteredBlogPosts = posts.filter(post => { const tagContent = post?.tags ? post?.tags.join(' ') : '' const searchContent = post.title + post.summary + tagContent return searchContent.toLowerCase().includes(filterKey.toLowerCase()) }) } else { filteredBlogPosts = deepClone(posts) } return ( }> {topSlot} {BLOG.POST_LIST_STYLE === 'page' ? : } ) } /** * 搜索 * 页面是博客列表,上方嵌入一个搜索引导条 * @param {*} props * @returns */ const LayoutSearch = props => { const { keyword, posts } = props useEffect(() => { if (isBrowser) { replaceSearchResult({ doms: document.getElementById('posts-wrapper'), search: keyword, target: { element: 'span', className: 'text-red-500 border-b border-dashed' } }) } }, []) // 在列表中进行实时过滤 const [filterKey, setFilterKey] = useState('') let filteredBlogPosts = [] if (filterKey && posts) { filteredBlogPosts = posts.filter(post => { const tagContent = post?.tags ? post?.tags.join(' ') : '' const searchContent = post.title + post.summary + tagContent return searchContent.toLowerCase().includes(filterKey.toLowerCase()) }) } else { filteredBlogPosts = deepClone(posts) } console.log('posts', props, posts, filteredBlogPosts) return }> {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 return ( {lock && } {!lock && <> > } ) } /** * 404 页面 * @param {*} props * @returns */ const Layout404 = (props) => { return 404 Not found. } /** * 文章分类列表 * @param {*} props * @returns */ const LayoutCategoryIndex = (props) => { const { categoryOptions } = props return ( {categoryOptions?.map(category => { return ( {category.name}({category.count}) ) })} ) } /** * 文章标签列表 * @param {*} props * @returns */ const LayoutTagIndex = (props) => { const { tagOptions } = props return ( {tagOptions.map(tag => { return ( {tag.name + (tag.count ? `(${tag.count})` : '')} ) })} ) } export { CONFIG as THEME_CONFIG, LayoutIndex, LayoutSearch, LayoutArchive, LayoutSlug, Layout404, LayoutPostList, LayoutCategoryIndex, LayoutTagIndex }