mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-14 07:26:52 +00:00
fukasawa 一点微调
This commit is contained in:
@@ -1,22 +1,22 @@
|
||||
import Logo from './Logo'
|
||||
import GroupCategory from './GroupCategory'
|
||||
import { MenuList } from './MenuList'
|
||||
import GroupTag from './GroupTag'
|
||||
import SearchInput from './SearchInput'
|
||||
import SiteInfo from './SiteInfo'
|
||||
import Catalog from './Catalog'
|
||||
import Announcement from './Announcement'
|
||||
import { useRouter } from 'next/router'
|
||||
import DarkModeButton from '@/components/DarkModeButton'
|
||||
import SocialButton from './SocialButton'
|
||||
import CONFIG from '@/themes/fukasawa/config'
|
||||
import { AdSlot } from '@/components/GoogleAdsense'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import MailChimpForm from './MailChimpForm'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { isBrowser } from '@/lib/utils'
|
||||
import CONFIG from '@/themes/fukasawa/config'
|
||||
import { debounce } from 'lodash'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import Announcement from './Announcement'
|
||||
import Catalog from './Catalog'
|
||||
import GroupCategory from './GroupCategory'
|
||||
import GroupTag from './GroupTag'
|
||||
import Logo from './Logo'
|
||||
import MailChimpForm from './MailChimpForm'
|
||||
import { MenuList } from './MenuList'
|
||||
import SearchInput from './SearchInput'
|
||||
import SiteInfo from './SiteInfo'
|
||||
import SocialButton from './SocialButton'
|
||||
|
||||
/**
|
||||
* 侧边栏
|
||||
@@ -24,16 +24,41 @@ import { debounce } from 'lodash'
|
||||
* @returns
|
||||
*/
|
||||
function AsideLeft(props) {
|
||||
const { tagOptions, currentTag, categoryOptions, currentCategory, post, slot, notice } = props
|
||||
const {
|
||||
tagOptions,
|
||||
currentTag,
|
||||
categoryOptions,
|
||||
currentCategory,
|
||||
post,
|
||||
slot,
|
||||
notice
|
||||
} = props
|
||||
const router = useRouter()
|
||||
const { fullWidth } = useGlobal()
|
||||
|
||||
const FUKASAWA_SIDEBAR_COLLAPSE_SATUS_DEFAULT = fullWidth || siteConfig('FUKASAWA_SIDEBAR_COLLAPSE_SATUS_DEFAULT', null, CONFIG)
|
||||
const FUKASAWA_SIDEBAR_COLLAPSE_SATUS_DEFAULT =
|
||||
fullWidth ||
|
||||
siteConfig('FUKASAWA_SIDEBAR_COLLAPSE_SATUS_DEFAULT', null, CONFIG)
|
||||
|
||||
const FUKASAWA_SIDEBAR_COLLAPSE_ON_SCROLL = siteConfig(
|
||||
'FUKASAWA_SIDEBAR_COLLAPSE_ON_SCROLL',
|
||||
false,
|
||||
CONFIG
|
||||
)
|
||||
|
||||
const FUKASAWA_SIDEBAR_COLLAPSE_BUTTON = siteConfig(
|
||||
'FUKASAWA_SIDEBAR_COLLAPSE_BUTTON',
|
||||
null,
|
||||
CONFIG
|
||||
)
|
||||
|
||||
// 侧边栏折叠从 本地存储中获取 open 状态的初始值
|
||||
const [isCollapsed, setIsCollapse] = useState(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
return localStorage.getItem('fukasawa-sidebar-collapse') === 'true' || FUKASAWA_SIDEBAR_COLLAPSE_SATUS_DEFAULT
|
||||
return (
|
||||
localStorage.getItem('fukasawa-sidebar-collapse') === 'true' ||
|
||||
FUKASAWA_SIDEBAR_COLLAPSE_SATUS_DEFAULT
|
||||
)
|
||||
}
|
||||
return FUKASAWA_SIDEBAR_COLLAPSE_SATUS_DEFAULT
|
||||
})
|
||||
@@ -69,7 +94,7 @@ function AsideLeft(props) {
|
||||
|
||||
// 自动折叠侧边栏 onResize 窗口宽度小于1366 || 滚动条滚动至页面的300px时 ; 将open设置为false
|
||||
useEffect(() => {
|
||||
if (!siteConfig('FUKASAWA_SIDEBAR_COLLAPSE_ON_SCROLL', false, CONFIG)) {
|
||||
if (!FUKASAWA_SIDEBAR_COLLAPSE_ON_SCROLL) {
|
||||
return
|
||||
}
|
||||
const handleResize = debounce(() => {
|
||||
@@ -92,73 +117,89 @@ function AsideLeft(props) {
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
|
||||
return <div className={`sideLeft relative ${isCollapsed ? 'w-0' : 'w-80'} duration-300 transition-all bg-white dark:bg-hexo-black-gray min-h-screen hidden lg:block z-20`}>
|
||||
{/* 折叠按钮 */}
|
||||
{siteConfig('FUKASAWA_SIDEBAR_COLLAPSE_BUTTON', null, CONFIG) && <div className={`${position} hidden lg:block fixed top-0 cursor-pointer hover:scale-110 duration-300 px-3 py-2 dark:text-white`} onClick={toggleOpen}>
|
||||
{isCollapsed ? <i className="fa-solid fa-indent text-xl"></i> : <i className='fas fa-bars text-xl'></i>}
|
||||
</div>}
|
||||
|
||||
<div className={`h-full ${isCollapsed ? 'hidden' : 'p-8'}`}>
|
||||
|
||||
<Logo {...props} />
|
||||
|
||||
<section className='siteInfo flex flex-col dark:text-gray-300 pt-8'>
|
||||
{siteConfig('DESCRIPTION')}
|
||||
</section>
|
||||
|
||||
<section className='flex flex-col text-gray-600'>
|
||||
<div className='w-12 my-4' />
|
||||
<MenuList {...props} />
|
||||
</section>
|
||||
|
||||
<section className='flex flex-col text-gray-600'>
|
||||
<div className='w-12 my-4' />
|
||||
<SearchInput {...props} />
|
||||
</section>
|
||||
|
||||
<section className='flex flex-col dark:text-gray-300'>
|
||||
<div className='w-12 my-4' />
|
||||
<Announcement post={notice} />
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<MailChimpForm />
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<AdSlot type='in-article' />
|
||||
</section>
|
||||
|
||||
{router.asPath !== '/tag' && <section className='flex flex-col'>
|
||||
<div className='w-12 my-4' />
|
||||
<GroupTag tags={tagOptions} currentTag={currentTag} />
|
||||
</section>}
|
||||
|
||||
{router.asPath !== '/category' && <section className='flex flex-col'>
|
||||
<div className='w-12 my-4' />
|
||||
<GroupCategory categories={categoryOptions} currentCategory={currentCategory} />
|
||||
</section>}
|
||||
|
||||
<section className='flex flex-col'>
|
||||
<div className='w-12 my-4' />
|
||||
<SocialButton />
|
||||
<SiteInfo />
|
||||
</section>
|
||||
|
||||
<section className='flex justify-center dark:text-gray-200 pt-4'>
|
||||
<DarkModeButton />
|
||||
</section>
|
||||
|
||||
<section className='sticky top-0 pt-12 flex flex-col max-h-screen '>
|
||||
<Catalog toc={post?.toc} />
|
||||
<div className='flex justify-center'>
|
||||
<div>{slot}</div>
|
||||
</div>
|
||||
</section>
|
||||
return (
|
||||
<div
|
||||
className={`sideLeft relative ${isCollapsed ? 'w-0' : 'w-80'} duration-300 transition-all bg-white dark:bg-hexo-black-gray min-h-screen hidden lg:block z-20`}>
|
||||
{/* 悬浮的折叠按钮 */}
|
||||
{FUKASAWA_SIDEBAR_COLLAPSE_BUTTON && (
|
||||
<div
|
||||
className={`${position} hidden lg:block fixed top-0 cursor-pointer hover:scale-110 duration-300 px-3 py-2 dark:text-white`}
|
||||
onClick={toggleOpen}>
|
||||
{isCollapsed ? (
|
||||
<i className='fa-solid fa-indent text-xl'></i>
|
||||
) : (
|
||||
<i className='fas fa-bars text-xl'></i>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className={`h-full ${isCollapsed ? 'hidden' : 'p-8'}`}>
|
||||
<Logo {...props} />
|
||||
|
||||
<section className='siteInfo flex flex-col dark:text-gray-300 pt-8'>
|
||||
{siteConfig('DESCRIPTION')}
|
||||
</section>
|
||||
|
||||
<section className='flex flex-col text-gray-600'>
|
||||
<div className='w-12 my-4' />
|
||||
<MenuList {...props} />
|
||||
</section>
|
||||
|
||||
<section className='flex flex-col text-gray-600'>
|
||||
<div className='w-12 my-4' />
|
||||
<SearchInput {...props} />
|
||||
</section>
|
||||
|
||||
<section className='flex flex-col dark:text-gray-300'>
|
||||
<div className='w-12 my-4' />
|
||||
<Announcement post={notice} />
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<MailChimpForm />
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<AdSlot type='in-article' />
|
||||
</section>
|
||||
|
||||
{router.asPath !== '/tag' && (
|
||||
<section className='flex flex-col'>
|
||||
<div className='w-12 my-4' />
|
||||
<GroupTag tags={tagOptions} currentTag={currentTag} />
|
||||
</section>
|
||||
)}
|
||||
|
||||
{router.asPath !== '/category' && (
|
||||
<section className='flex flex-col'>
|
||||
<div className='w-12 my-4' />
|
||||
<GroupCategory
|
||||
categories={categoryOptions}
|
||||
currentCategory={currentCategory}
|
||||
/>
|
||||
</section>
|
||||
)}
|
||||
|
||||
<section className='flex flex-col'>
|
||||
<div className='w-12 my-4' />
|
||||
<SocialButton />
|
||||
<SiteInfo />
|
||||
</section>
|
||||
|
||||
<section className='flex justify-center dark:text-gray-200 pt-4'>
|
||||
<DarkModeButton />
|
||||
</section>
|
||||
|
||||
<section className='sticky top-0 pt-12 flex flex-col max-h-screen '>
|
||||
<Catalog toc={post?.toc} />
|
||||
<div className='flex justify-center'>
|
||||
<div>{slot}</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AsideLeft
|
||||
|
||||
64
themes/fukasawa/components/Header.js
Normal file
64
themes/fukasawa/components/Header.js
Normal file
@@ -0,0 +1,64 @@
|
||||
import Collapse from '@/components/Collapse'
|
||||
import { useRef, useState } from 'react'
|
||||
import Logo from './Logo'
|
||||
import { MenuList } from './MenuList'
|
||||
import SearchInput from './SearchInput'
|
||||
|
||||
/**
|
||||
* 顶部导航
|
||||
* @param {*} param0
|
||||
* @returns
|
||||
*/
|
||||
const Header = props => {
|
||||
const [isOpen, changeShow] = useState(false)
|
||||
const collapseRef = useRef(null)
|
||||
|
||||
const toggleMenuOpen = () => {
|
||||
changeShow(!isOpen)
|
||||
}
|
||||
|
||||
return (
|
||||
<div id='top-nav' className='z-40 block lg:hidden'>
|
||||
{/* 导航栏 */}
|
||||
<div
|
||||
id='sticky-nav'
|
||||
className={
|
||||
'relative w-full top-0 z-20 transform duration-500 bg-white dark:bg-black'
|
||||
}>
|
||||
<Collapse type='vertical' isOpen={isOpen} collapseRef={collapseRef}>
|
||||
<div className='py-1 px-5'>
|
||||
<MenuList
|
||||
{...props}
|
||||
onHeightChange={param =>
|
||||
collapseRef.current?.updateCollapseHeight(param)
|
||||
}
|
||||
/>
|
||||
<SearchInput {...props} />
|
||||
</div>
|
||||
</Collapse>
|
||||
<div className='w-full flex justify-between items-center p-4 '>
|
||||
{/* 左侧LOGO 标题 */}
|
||||
<div className='flex flex-none flex-grow-0'>
|
||||
<Logo {...props} />
|
||||
</div>
|
||||
<div className='flex'></div>
|
||||
|
||||
{/* 右侧功能 */}
|
||||
<div className='mr-1 flex justify-end items-center text-sm space-x-4 font-serif dark:text-gray-200'>
|
||||
<div
|
||||
onClick={toggleMenuOpen}
|
||||
className='cursor-pointer text-lg p-2'>
|
||||
{isOpen ? (
|
||||
<i className='fas fa-times' />
|
||||
) : (
|
||||
<i className='fas fa-bars' />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Header
|
||||
@@ -1,50 +0,0 @@
|
||||
import { useState, useRef } from 'react'
|
||||
import Collapse from '@/components/Collapse'
|
||||
import { MenuList } from './MenuList'
|
||||
import Logo from './Logo'
|
||||
import SearchInput from './SearchInput'
|
||||
|
||||
/**
|
||||
* 顶部导航
|
||||
* @param {*} param0
|
||||
* @returns
|
||||
*/
|
||||
const TopNav = props => {
|
||||
const [isOpen, changeShow] = useState(false)
|
||||
const collapseRef = useRef(null)
|
||||
|
||||
const toggleMenuOpen = () => {
|
||||
changeShow(!isOpen)
|
||||
}
|
||||
|
||||
return (<div id='top-nav' className='z-40 block lg:hidden'>
|
||||
|
||||
{/* 导航栏 */}
|
||||
<div id='sticky-nav' className={'relative w-full top-0 z-20 transform duration-500 bg-white dark:bg-black'}>
|
||||
<Collapse type='vertical' isOpen={isOpen} collapseRef={collapseRef}>
|
||||
<div className='py-1 px-5'>
|
||||
<MenuList {...props} onHeightChange={(param) => collapseRef.current?.updateCollapseHeight(param)} />
|
||||
<SearchInput {...props} />
|
||||
</div>
|
||||
</Collapse>
|
||||
<div className='w-full flex justify-between items-center p-4 '>
|
||||
{/* 左侧LOGO 标题 */}
|
||||
<div className='flex flex-none flex-grow-0'>
|
||||
<Logo {...props} />
|
||||
</div>
|
||||
<div className='flex'>
|
||||
</div>
|
||||
|
||||
{/* 右侧功能 */}
|
||||
<div className='mr-1 flex justify-end items-center text-sm space-x-4 font-serif dark:text-gray-200'>
|
||||
<div onClick={toggleMenuOpen} className='cursor-pointer text-lg p-2'>
|
||||
{isOpen ? <i className='fas fa-times' /> : <i className='fas fa-bars' />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>)
|
||||
}
|
||||
|
||||
export default TopNav
|
||||
@@ -1,27 +1,27 @@
|
||||
'use client'
|
||||
|
||||
import CONFIG from './config'
|
||||
import TopNav from './components/TopNav'
|
||||
import AsideLeft from './components/AsideLeft'
|
||||
import { isBrowser } from '@/lib/utils'
|
||||
import AlgoliaSearchModal from '@/components/AlgoliaSearchModal'
|
||||
import { AdSlot } from '@/components/GoogleAdsense'
|
||||
import replaceSearchResult from '@/components/Mark'
|
||||
import WWAds from '@/components/WWAds'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { isBrowser } from '@/lib/utils'
|
||||
import { Transition } from '@headlessui/react'
|
||||
import dynamic from 'next/dynamic'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import { createContext, useContext, useEffect, useRef } from 'react'
|
||||
import ArticleDetail from './components/ArticleDetail'
|
||||
import ArticleLock from './components/ArticleLock'
|
||||
import AsideLeft from './components/AsideLeft'
|
||||
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 Header from './components/Header'
|
||||
import TagItemMini from './components/TagItemMini'
|
||||
import { useRouter } from 'next/router'
|
||||
import { createContext, useContext, useEffect, useRef } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { Transition } from '@headlessui/react'
|
||||
import dynamic from 'next/dynamic'
|
||||
import { AdSlot } from '@/components/GoogleAdsense'
|
||||
import CONFIG from './config'
|
||||
import { Style } from './style'
|
||||
import replaceSearchResult from '@/components/Mark'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import WWAds from '@/components/WWAds'
|
||||
import AlgoliaSearchModal from '@/components/AlgoliaSearchModal'
|
||||
|
||||
const Live2D = dynamic(() => import('@/components/Live2D'))
|
||||
|
||||
@@ -43,51 +43,58 @@ export const useFukasawaGlobal = () => useContext(ThemeGlobalFukasawa)
|
||||
* @returns {JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
const LayoutBase = (props) => {
|
||||
const LayoutBase = props => {
|
||||
const { children, headerSlot } = props
|
||||
const leftAreaSlot = <Live2D />
|
||||
const { onLoading, fullWidth } = useGlobal()
|
||||
const searchModal = useRef(null)
|
||||
return (
|
||||
<ThemeGlobalFukasawa.Provider value={{ searchModal }}>
|
||||
<div id='theme-fukasawa' className={`${siteConfig('FONT_STYLE')} dark:bg-black scroll-smooth`}>
|
||||
<AlgoliaSearchModal cRef={searchModal} {...props} />
|
||||
<div
|
||||
id='theme-fukasawa'
|
||||
className={`${siteConfig('FONT_STYLE')} dark:bg-black scroll-smooth`}>
|
||||
<Style />
|
||||
{/* 页头导航,此主题只在移动端生效 */}
|
||||
<Header {...props} />
|
||||
|
||||
<TopNav {...props} />
|
||||
|
||||
<div className={(JSON.parse(siteConfig('LAYOUT_SIDEBAR_REVERSE')) ? 'flex-row-reverse' : '') + ' flex'}>
|
||||
<div
|
||||
className={
|
||||
(JSON.parse(siteConfig('LAYOUT_SIDEBAR_REVERSE'))
|
||||
? 'flex-row-reverse'
|
||||
: '') + ' flex'
|
||||
}>
|
||||
{/* 侧边抽屉 */}
|
||||
<AsideLeft {...props} slot={leftAreaSlot} />
|
||||
|
||||
<main id='wrapper' className='relative flex w-full py-8 justify-center bg-day dark:bg-night'>
|
||||
<div id='container-inner' className={`${fullWidth ? '' : '2xl:max-w-6xl md:max-w-4xl'} w-full relative z-10`}>
|
||||
<main
|
||||
id='wrapper'
|
||||
className='relative flex w-full py-8 justify-center bg-day dark:bg-night'>
|
||||
<div
|
||||
id='container-inner'
|
||||
className={`${fullWidth ? '' : '2xl:max-w-6xl md:max-w-4xl'} w-full relative z-10`}>
|
||||
<Transition
|
||||
show={!onLoading}
|
||||
appear={true}
|
||||
className="w-full"
|
||||
enter="transition ease-in-out duration-700 transform order-first"
|
||||
enterFrom="opacity-0 translate-y-16"
|
||||
enterTo="opacity-100"
|
||||
leave="transition ease-in-out duration-300 transform"
|
||||
leaveFrom="opacity-100 translate-y-0"
|
||||
leaveTo="opacity-0 -translate-y-16"
|
||||
unmount={false}
|
||||
>
|
||||
className='w-full'
|
||||
enter='transition ease-in-out duration-700 transform order-first'
|
||||
enterFrom='opacity-0 translate-y-16'
|
||||
enterTo='opacity-100'
|
||||
leave='transition ease-in-out duration-300 transform'
|
||||
leaveFrom='opacity-100 translate-y-0'
|
||||
leaveTo='opacity-0 -translate-y-16'
|
||||
unmount={false}>
|
||||
<div> {headerSlot} </div>
|
||||
<div> {children} </div>
|
||||
|
||||
</Transition>
|
||||
|
||||
<div className='mt-2'>
|
||||
<AdSlot type='native' />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<AlgoliaSearchModal cRef={searchModal} {...props} />
|
||||
</div>
|
||||
</ThemeGlobalFukasawa.Provider>
|
||||
)
|
||||
@@ -96,49 +103,64 @@ const LayoutBase = (props) => {
|
||||
/**
|
||||
* 首页
|
||||
* @param {*} props notion数据
|
||||
* @returns 首页就是一个博客列表
|
||||
*/
|
||||
const LayoutIndex = (props) => {
|
||||
* @returns 首页就是一个博客列表
|
||||
*/
|
||||
const LayoutIndex = props => {
|
||||
return <LayoutPostList {...props} />
|
||||
}
|
||||
|
||||
/**
|
||||
* 博客列表
|
||||
* @param {*} props
|
||||
*/
|
||||
const LayoutPostList = (props) => {
|
||||
return <>
|
||||
<div className='w-full p-2'><WWAds className='w-full' orientation='horizontal' /></div>
|
||||
{siteConfig('POST_LIST_STYLE') === 'page' ? <BlogListPage {...props} /> : <BlogListScroll {...props} />}
|
||||
</>
|
||||
*/
|
||||
const LayoutPostList = props => {
|
||||
return (
|
||||
<>
|
||||
<div className='w-full p-2'>
|
||||
<WWAds className='w-full' orientation='horizontal' />
|
||||
</div>
|
||||
{siteConfig('POST_LIST_STYLE') === 'page' ? (
|
||||
<BlogListPage {...props} />
|
||||
) : (
|
||||
<BlogListScroll {...props} />
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 文章详情
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
const LayoutSlug = (props) => {
|
||||
* @returns
|
||||
*/
|
||||
const LayoutSlug = props => {
|
||||
const { post, lock, validPassword } = props
|
||||
const router = useRouter()
|
||||
useEffect(() => {
|
||||
// 404
|
||||
if (!post) {
|
||||
setTimeout(() => {
|
||||
if (isBrowser) {
|
||||
const article = document.getElementById('notion-article')
|
||||
if (!article) {
|
||||
router.push('/404').then(() => {
|
||||
console.warn('找不到页面', router.asPath)
|
||||
})
|
||||
setTimeout(
|
||||
() => {
|
||||
if (isBrowser) {
|
||||
const article = document.getElementById('notion-article')
|
||||
if (!article) {
|
||||
router.push('/404').then(() => {
|
||||
console.warn('找不到页面', router.asPath)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}, siteConfig('POST_WAITING_TIME_FOR_404') * 1000)
|
||||
},
|
||||
siteConfig('POST_WAITING_TIME_FOR_404') * 1000
|
||||
)
|
||||
}
|
||||
}, [post])
|
||||
return (
|
||||
<>
|
||||
{lock ? <ArticleLock validPassword={validPassword} /> : <ArticleDetail {...props} />}
|
||||
{lock ? (
|
||||
<ArticleLock validPassword={validPassword} />
|
||||
) : (
|
||||
<ArticleDetail {...props} />
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -167,26 +189,28 @@ const LayoutSearch = props => {
|
||||
/**
|
||||
* 归档页面
|
||||
*/
|
||||
const LayoutArchive = (props) => {
|
||||
const LayoutArchive = props => {
|
||||
const { archivePosts } = props
|
||||
return <>
|
||||
<div className="mb-10 pb-20 bg-white md:p-12 p-3 dark:bg-gray-800 shadow-md min-h-full">
|
||||
{Object.keys(archivePosts).map(archiveTitle => (
|
||||
<BlogArchiveItem
|
||||
key={archiveTitle}
|
||||
posts={archivePosts[archiveTitle]}
|
||||
archiveTitle={archiveTitle}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
return (
|
||||
<>
|
||||
<div className='mb-10 pb-20 bg-white md:p-12 p-3 dark:bg-gray-800 shadow-md min-h-full'>
|
||||
{Object.keys(archivePosts).map(archiveTitle => (
|
||||
<BlogArchiveItem
|
||||
key={archiveTitle}
|
||||
posts={archivePosts[archiveTitle]}
|
||||
archiveTitle={archiveTitle}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 404
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
* @returns
|
||||
*/
|
||||
const Layout404 = props => {
|
||||
return <>404</>
|
||||
}
|
||||
@@ -194,16 +218,17 @@ const Layout404 = props => {
|
||||
/**
|
||||
* 分类列表
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
const LayoutCategoryIndex = (props) => {
|
||||
* @returns
|
||||
*/
|
||||
const LayoutCategoryIndex = props => {
|
||||
const { locale } = useGlobal()
|
||||
const { categoryOptions } = props
|
||||
return (
|
||||
<>
|
||||
<div className='bg-white dark:bg-gray-700 px-10 py-10 shadow'>
|
||||
<div className='dark:text-gray-200 mb-5'>
|
||||
<i className='mr-4 fas fa-th' />{locale.COMMON.CATEGORY}:
|
||||
<i className='mr-4 fas fa-th' />
|
||||
{locale.COMMON.CATEGORY}:
|
||||
</div>
|
||||
<div id='category-list' className='duration-200 flex flex-wrap'>
|
||||
{categoryOptions?.map(category => {
|
||||
@@ -214,8 +239,11 @@ const LayoutCategoryIndex = (props) => {
|
||||
passHref
|
||||
legacyBehavior>
|
||||
<div
|
||||
className={'hover:text-black dark:hover:text-white dark:text-gray-300 dark:hover:bg-gray-600 px-5 cursor-pointer py-2 hover:bg-gray-100'}>
|
||||
<i className='mr-4 fas fa-folder' />{category.name}({category.count})
|
||||
className={
|
||||
'hover:text-black dark:hover:text-white dark:text-gray-300 dark:hover:bg-gray-600 px-5 cursor-pointer py-2 hover:bg-gray-100'
|
||||
}>
|
||||
<i className='mr-4 fas fa-folder' />
|
||||
{category.name}({category.count})
|
||||
</div>
|
||||
</Link>
|
||||
)
|
||||
@@ -229,36 +257,41 @@ const LayoutCategoryIndex = (props) => {
|
||||
/**
|
||||
* 标签列表
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
const LayoutTagIndex = (props) => {
|
||||
* @returns
|
||||
*/
|
||||
const LayoutTagIndex = props => {
|
||||
const { locale } = useGlobal()
|
||||
const { tagOptions } = props
|
||||
return <>
|
||||
<div className='bg-white dark:bg-gray-700 px-10 py-10 shadow'>
|
||||
<div className='dark:text-gray-200 mb-5'><i className='mr-4 fas fa-tag' />{locale.COMMON.TAGS}:</div>
|
||||
<div id="tags-list" className="duration-200 flex flex-wrap ml-8">
|
||||
{tagOptions.map(tag => {
|
||||
return (
|
||||
<div key={tag.name} className="p-2">
|
||||
<TagItemMini key={tag.name} tag={tag} />
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
return (
|
||||
<>
|
||||
<div className='bg-white dark:bg-gray-700 px-10 py-10 shadow'>
|
||||
<div className='dark:text-gray-200 mb-5'>
|
||||
<i className='mr-4 fas fa-tag' />
|
||||
{locale.COMMON.TAGS}:
|
||||
</div>
|
||||
<div id='tags-list' className='duration-200 flex flex-wrap ml-8'>
|
||||
{tagOptions.map(tag => {
|
||||
return (
|
||||
<div key={tag.name} className='p-2'>
|
||||
<TagItemMini key={tag.name} tag={tag} />
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export {
|
||||
CONFIG as THEME_CONFIG,
|
||||
LayoutBase,
|
||||
LayoutIndex,
|
||||
LayoutSearch,
|
||||
LayoutArchive,
|
||||
LayoutSlug,
|
||||
Layout404,
|
||||
LayoutPostList,
|
||||
LayoutArchive,
|
||||
LayoutBase,
|
||||
LayoutCategoryIndex,
|
||||
LayoutTagIndex
|
||||
LayoutIndex,
|
||||
LayoutPostList,
|
||||
LayoutSearch,
|
||||
LayoutSlug,
|
||||
LayoutTagIndex,
|
||||
CONFIG as THEME_CONFIG
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user