mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-06-05 07:26:46 +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 DarkModeButton from '@/components/DarkModeButton'
|
||||||
import SocialButton from './SocialButton'
|
|
||||||
import CONFIG from '@/themes/fukasawa/config'
|
|
||||||
import { AdSlot } from '@/components/GoogleAdsense'
|
import { AdSlot } from '@/components/GoogleAdsense'
|
||||||
import { siteConfig } from '@/lib/config'
|
import { siteConfig } from '@/lib/config'
|
||||||
import MailChimpForm from './MailChimpForm'
|
|
||||||
import { useGlobal } from '@/lib/global'
|
import { useGlobal } from '@/lib/global'
|
||||||
import { useEffect, useMemo, useState } from 'react'
|
|
||||||
import { isBrowser } from '@/lib/utils'
|
import { isBrowser } from '@/lib/utils'
|
||||||
|
import CONFIG from '@/themes/fukasawa/config'
|
||||||
import { debounce } from 'lodash'
|
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
|
* @returns
|
||||||
*/
|
*/
|
||||||
function AsideLeft(props) {
|
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 router = useRouter()
|
||||||
const { fullWidth } = useGlobal()
|
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 状态的初始值
|
// 侧边栏折叠从 本地存储中获取 open 状态的初始值
|
||||||
const [isCollapsed, setIsCollapse] = useState(() => {
|
const [isCollapsed, setIsCollapse] = useState(() => {
|
||||||
if (typeof window !== 'undefined') {
|
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
|
return FUKASAWA_SIDEBAR_COLLAPSE_SATUS_DEFAULT
|
||||||
})
|
})
|
||||||
@@ -69,7 +94,7 @@ function AsideLeft(props) {
|
|||||||
|
|
||||||
// 自动折叠侧边栏 onResize 窗口宽度小于1366 || 滚动条滚动至页面的300px时 ; 将open设置为false
|
// 自动折叠侧边栏 onResize 窗口宽度小于1366 || 滚动条滚动至页面的300px时 ; 将open设置为false
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!siteConfig('FUKASAWA_SIDEBAR_COLLAPSE_ON_SCROLL', false, CONFIG)) {
|
if (!FUKASAWA_SIDEBAR_COLLAPSE_ON_SCROLL) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const handleResize = debounce(() => {
|
const handleResize = debounce(() => {
|
||||||
@@ -93,72 +118,88 @@ function AsideLeft(props) {
|
|||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
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`}>
|
<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>}
|
{FUKASAWA_SIDEBAR_COLLAPSE_BUTTON && (
|
||||||
</div>}
|
<div
|
||||||
|
className={`${position} hidden lg:block fixed top-0 cursor-pointer hover:scale-110 duration-300 px-3 py-2 dark:text-white`}
|
||||||
<div className={`h-full ${isCollapsed ? 'hidden' : 'p-8'}`}>
|
onClick={toggleOpen}>
|
||||||
|
{isCollapsed ? (
|
||||||
<Logo {...props} />
|
<i className='fa-solid fa-indent text-xl'></i>
|
||||||
|
) : (
|
||||||
<section className='siteInfo flex flex-col dark:text-gray-300 pt-8'>
|
<i className='fas fa-bars text-xl'></i>
|
||||||
{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>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<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>
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AsideLeft
|
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'
|
'use client'
|
||||||
|
|
||||||
import CONFIG from './config'
|
import AlgoliaSearchModal from '@/components/AlgoliaSearchModal'
|
||||||
import TopNav from './components/TopNav'
|
import { AdSlot } from '@/components/GoogleAdsense'
|
||||||
import AsideLeft from './components/AsideLeft'
|
import replaceSearchResult from '@/components/Mark'
|
||||||
import { isBrowser } from '@/lib/utils'
|
import WWAds from '@/components/WWAds'
|
||||||
|
import { siteConfig } from '@/lib/config'
|
||||||
import { useGlobal } from '@/lib/global'
|
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 BlogListPage from './components/BlogListPage'
|
||||||
import BlogListScroll from './components/BlogListScroll'
|
import BlogListScroll from './components/BlogListScroll'
|
||||||
import BlogArchiveItem from './components/BlogPostArchive'
|
import BlogArchiveItem from './components/BlogPostArchive'
|
||||||
import ArticleDetail from './components/ArticleDetail'
|
import Header from './components/Header'
|
||||||
import ArticleLock from './components/ArticleLock'
|
|
||||||
import TagItemMini from './components/TagItemMini'
|
import TagItemMini from './components/TagItemMini'
|
||||||
import { useRouter } from 'next/router'
|
import CONFIG from './config'
|
||||||
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 { Style } from './style'
|
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'))
|
const Live2D = dynamic(() => import('@/components/Live2D'))
|
||||||
|
|
||||||
@@ -43,51 +43,58 @@ export const useFukasawaGlobal = () => useContext(ThemeGlobalFukasawa)
|
|||||||
* @returns {JSX.Element}
|
* @returns {JSX.Element}
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
const LayoutBase = (props) => {
|
const LayoutBase = props => {
|
||||||
const { children, headerSlot } = props
|
const { children, headerSlot } = props
|
||||||
const leftAreaSlot = <Live2D />
|
const leftAreaSlot = <Live2D />
|
||||||
const { onLoading, fullWidth } = useGlobal()
|
const { onLoading, fullWidth } = useGlobal()
|
||||||
const searchModal = useRef(null)
|
const searchModal = useRef(null)
|
||||||
return (
|
return (
|
||||||
<ThemeGlobalFukasawa.Provider value={{ searchModal }}>
|
<ThemeGlobalFukasawa.Provider value={{ searchModal }}>
|
||||||
<div id='theme-fukasawa' className={`${siteConfig('FONT_STYLE')} dark:bg-black scroll-smooth`}>
|
<div
|
||||||
<AlgoliaSearchModal cRef={searchModal} {...props} />
|
id='theme-fukasawa'
|
||||||
|
className={`${siteConfig('FONT_STYLE')} dark:bg-black scroll-smooth`}>
|
||||||
<Style />
|
<Style />
|
||||||
|
{/* 页头导航,此主题只在移动端生效 */}
|
||||||
|
<Header {...props} />
|
||||||
|
|
||||||
<TopNav {...props} />
|
<div
|
||||||
|
className={
|
||||||
<div className={(JSON.parse(siteConfig('LAYOUT_SIDEBAR_REVERSE')) ? 'flex-row-reverse' : '') + ' flex'}>
|
(JSON.parse(siteConfig('LAYOUT_SIDEBAR_REVERSE'))
|
||||||
|
? 'flex-row-reverse'
|
||||||
|
: '') + ' flex'
|
||||||
|
}>
|
||||||
{/* 侧边抽屉 */}
|
{/* 侧边抽屉 */}
|
||||||
<AsideLeft {...props} slot={leftAreaSlot} />
|
<AsideLeft {...props} slot={leftAreaSlot} />
|
||||||
|
|
||||||
<main id='wrapper' className='relative flex w-full py-8 justify-center bg-day dark:bg-night'>
|
<main
|
||||||
<div id='container-inner' className={`${fullWidth ? '' : '2xl:max-w-6xl md:max-w-4xl'} w-full relative z-10`}>
|
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
|
<Transition
|
||||||
show={!onLoading}
|
show={!onLoading}
|
||||||
appear={true}
|
appear={true}
|
||||||
className="w-full"
|
className='w-full'
|
||||||
enter="transition ease-in-out duration-700 transform order-first"
|
enter='transition ease-in-out duration-700 transform order-first'
|
||||||
enterFrom="opacity-0 translate-y-16"
|
enterFrom='opacity-0 translate-y-16'
|
||||||
enterTo="opacity-100"
|
enterTo='opacity-100'
|
||||||
leave="transition ease-in-out duration-300 transform"
|
leave='transition ease-in-out duration-300 transform'
|
||||||
leaveFrom="opacity-100 translate-y-0"
|
leaveFrom='opacity-100 translate-y-0'
|
||||||
leaveTo="opacity-0 -translate-y-16"
|
leaveTo='opacity-0 -translate-y-16'
|
||||||
unmount={false}
|
unmount={false}>
|
||||||
>
|
|
||||||
<div> {headerSlot} </div>
|
<div> {headerSlot} </div>
|
||||||
<div> {children} </div>
|
<div> {children} </div>
|
||||||
|
|
||||||
</Transition>
|
</Transition>
|
||||||
|
|
||||||
<div className='mt-2'>
|
<div className='mt-2'>
|
||||||
<AdSlot type='native' />
|
<AdSlot type='native' />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<AlgoliaSearchModal cRef={searchModal} {...props} />
|
||||||
</div>
|
</div>
|
||||||
</ThemeGlobalFukasawa.Provider>
|
</ThemeGlobalFukasawa.Provider>
|
||||||
)
|
)
|
||||||
@@ -96,49 +103,64 @@ const LayoutBase = (props) => {
|
|||||||
/**
|
/**
|
||||||
* 首页
|
* 首页
|
||||||
* @param {*} props notion数据
|
* @param {*} props notion数据
|
||||||
* @returns 首页就是一个博客列表
|
* @returns 首页就是一个博客列表
|
||||||
*/
|
*/
|
||||||
const LayoutIndex = (props) => {
|
const LayoutIndex = props => {
|
||||||
return <LayoutPostList {...props} />
|
return <LayoutPostList {...props} />
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 博客列表
|
* 博客列表
|
||||||
* @param {*} props
|
* @param {*} props
|
||||||
*/
|
*/
|
||||||
const LayoutPostList = (props) => {
|
const LayoutPostList = props => {
|
||||||
return <>
|
return (
|
||||||
<div className='w-full p-2'><WWAds className='w-full' orientation='horizontal' /></div>
|
<>
|
||||||
{siteConfig('POST_LIST_STYLE') === 'page' ? <BlogListPage {...props} /> : <BlogListScroll {...props} />}
|
<div className='w-full p-2'>
|
||||||
</>
|
<WWAds className='w-full' orientation='horizontal' />
|
||||||
|
</div>
|
||||||
|
{siteConfig('POST_LIST_STYLE') === 'page' ? (
|
||||||
|
<BlogListPage {...props} />
|
||||||
|
) : (
|
||||||
|
<BlogListScroll {...props} />
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文章详情
|
* 文章详情
|
||||||
* @param {*} props
|
* @param {*} props
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const LayoutSlug = (props) => {
|
const LayoutSlug = props => {
|
||||||
const { post, lock, validPassword } = props
|
const { post, lock, validPassword } = props
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 404
|
// 404
|
||||||
if (!post) {
|
if (!post) {
|
||||||
setTimeout(() => {
|
setTimeout(
|
||||||
if (isBrowser) {
|
() => {
|
||||||
const article = document.getElementById('notion-article')
|
if (isBrowser) {
|
||||||
if (!article) {
|
const article = document.getElementById('notion-article')
|
||||||
router.push('/404').then(() => {
|
if (!article) {
|
||||||
console.warn('找不到页面', router.asPath)
|
router.push('/404').then(() => {
|
||||||
})
|
console.warn('找不到页面', router.asPath)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}, siteConfig('POST_WAITING_TIME_FOR_404') * 1000)
|
siteConfig('POST_WAITING_TIME_FOR_404') * 1000
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}, [post])
|
}, [post])
|
||||||
return (
|
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
|
const { archivePosts } = props
|
||||||
return <>
|
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 => (
|
<div className='mb-10 pb-20 bg-white md:p-12 p-3 dark:bg-gray-800 shadow-md min-h-full'>
|
||||||
<BlogArchiveItem
|
{Object.keys(archivePosts).map(archiveTitle => (
|
||||||
key={archiveTitle}
|
<BlogArchiveItem
|
||||||
posts={archivePosts[archiveTitle]}
|
key={archiveTitle}
|
||||||
archiveTitle={archiveTitle}
|
posts={archivePosts[archiveTitle]}
|
||||||
/>
|
archiveTitle={archiveTitle}
|
||||||
))}
|
/>
|
||||||
</div>
|
))}
|
||||||
</>
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 404
|
* 404
|
||||||
* @param {*} props
|
* @param {*} props
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const Layout404 = props => {
|
const Layout404 = props => {
|
||||||
return <>404</>
|
return <>404</>
|
||||||
}
|
}
|
||||||
@@ -194,16 +218,17 @@ const Layout404 = props => {
|
|||||||
/**
|
/**
|
||||||
* 分类列表
|
* 分类列表
|
||||||
* @param {*} props
|
* @param {*} props
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const LayoutCategoryIndex = (props) => {
|
const LayoutCategoryIndex = props => {
|
||||||
const { locale } = useGlobal()
|
const { locale } = useGlobal()
|
||||||
const { categoryOptions } = props
|
const { categoryOptions } = props
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className='bg-white dark:bg-gray-700 px-10 py-10 shadow'>
|
<div className='bg-white dark:bg-gray-700 px-10 py-10 shadow'>
|
||||||
<div className='dark:text-gray-200 mb-5'>
|
<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>
|
||||||
<div id='category-list' className='duration-200 flex flex-wrap'>
|
<div id='category-list' className='duration-200 flex flex-wrap'>
|
||||||
{categoryOptions?.map(category => {
|
{categoryOptions?.map(category => {
|
||||||
@@ -214,8 +239,11 @@ const LayoutCategoryIndex = (props) => {
|
|||||||
passHref
|
passHref
|
||||||
legacyBehavior>
|
legacyBehavior>
|
||||||
<div
|
<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'}>
|
className={
|
||||||
<i className='mr-4 fas fa-folder' />{category.name}({category.count})
|
'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>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
)
|
)
|
||||||
@@ -229,36 +257,41 @@ const LayoutCategoryIndex = (props) => {
|
|||||||
/**
|
/**
|
||||||
* 标签列表
|
* 标签列表
|
||||||
* @param {*} props
|
* @param {*} props
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const LayoutTagIndex = (props) => {
|
const LayoutTagIndex = props => {
|
||||||
const { locale } = useGlobal()
|
const { locale } = useGlobal()
|
||||||
const { tagOptions } = props
|
const { tagOptions } = props
|
||||||
return <>
|
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 className='bg-white dark:bg-gray-700 px-10 py-10 shadow'>
|
||||||
<div id="tags-list" className="duration-200 flex flex-wrap ml-8">
|
<div className='dark:text-gray-200 mb-5'>
|
||||||
{tagOptions.map(tag => {
|
<i className='mr-4 fas fa-tag' />
|
||||||
return (
|
{locale.COMMON.TAGS}:
|
||||||
<div key={tag.name} className="p-2">
|
</div>
|
||||||
<TagItemMini key={tag.name} tag={tag} />
|
<div id='tags-list' className='duration-200 flex flex-wrap ml-8'>
|
||||||
</div>
|
{tagOptions.map(tag => {
|
||||||
)
|
return (
|
||||||
})}
|
<div key={tag.name} className='p-2'>
|
||||||
|
<TagItemMini key={tag.name} tag={tag} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
</>
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
CONFIG as THEME_CONFIG,
|
|
||||||
LayoutBase,
|
|
||||||
LayoutIndex,
|
|
||||||
LayoutSearch,
|
|
||||||
LayoutArchive,
|
|
||||||
LayoutSlug,
|
|
||||||
Layout404,
|
Layout404,
|
||||||
LayoutPostList,
|
LayoutArchive,
|
||||||
|
LayoutBase,
|
||||||
LayoutCategoryIndex,
|
LayoutCategoryIndex,
|
||||||
LayoutTagIndex
|
LayoutIndex,
|
||||||
|
LayoutPostList,
|
||||||
|
LayoutSearch,
|
||||||
|
LayoutSlug,
|
||||||
|
LayoutTagIndex,
|
||||||
|
CONFIG as THEME_CONFIG
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user