mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-13 23:16:47 +00:00
gitbook主题变量名调整
This commit is contained in:
@@ -11,6 +11,7 @@ import { useEffect, useRef } from 'react'
|
||||
export const ArticleLock = props => {
|
||||
const { validPassword } = props
|
||||
const { locale } = useGlobal()
|
||||
console.log('locale', locale)
|
||||
|
||||
const submitPassword = () => {
|
||||
const p = document.getElementById('password')
|
||||
@@ -29,25 +30,33 @@ export const ArticleLock = props => {
|
||||
passwordInputRef.current.focus()
|
||||
}, [])
|
||||
|
||||
return <div id='container' className='w-full flex justify-center items-center h-96 '>
|
||||
<div className='text-center space-y-3'>
|
||||
<div className='font-bold'>{locale.COMMON.ARTICLE_LOCK_TIPS}</div>
|
||||
<div className='flex mx-4'>
|
||||
<input id="password" type='password'
|
||||
onKeyDown={(e) => {
|
||||
return (
|
||||
<div
|
||||
id='container'
|
||||
className='w-full flex justify-center items-center h-96 '>
|
||||
<div className='text-center space-y-3'>
|
||||
<div className='font-bold'>{locale.COMMON.ARTICLE_LOCK_TIPS}</div>
|
||||
<div className='flex mx-4'>
|
||||
<input
|
||||
id='password'
|
||||
type='password'
|
||||
onKeyDown={e => {
|
||||
if (e.key === 'Enter') {
|
||||
submitPassword()
|
||||
}
|
||||
}}
|
||||
ref={passwordInputRef} // 绑定ref到passwordInputRef变量
|
||||
className='outline-none w-full text-sm pl-5 rounded-l transition focus:shadow-lg dark:text-gray-300 font-light leading-10 text-black bg-gray-100 dark:bg-gray-500'>
|
||||
</input>
|
||||
<div onClick={submitPassword} className="px-3 whitespace-nowrap cursor-pointer items-center justify-center py-2 bg-green-500 hover:bg-green-400 text-white rounded-r duration-300" >
|
||||
<i className={'duration-200 cursor-pointer fas fa-key'} > {locale.COMMON.SUBMIT}</i>
|
||||
className='outline-none w-full text-sm pl-5 rounded-l transition focus:shadow-lg dark:text-gray-300 font-light leading-10 text-black bg-gray-100 dark:bg-gray-500'></input>
|
||||
<div
|
||||
onClick={submitPassword}
|
||||
className='px-3 whitespace-nowrap cursor-pointer items-center justify-center py-2 bg-green-500 hover:bg-green-400 text-white rounded-r duration-300'>
|
||||
<i className={'duration-200 cursor-pointer fas fa-key'}>
|
||||
{locale.COMMON.SUBMIT}
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id='tips'>
|
||||
<div id='tips'></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
109
themes/gitbook/components/Header.js
Normal file
109
themes/gitbook/components/Header.js
Normal file
@@ -0,0 +1,109 @@
|
||||
import Collapse from '@/components/Collapse'
|
||||
import DarkModeButton from '@/components/DarkModeButton'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { useRef, useState } from 'react'
|
||||
import CONFIG from '../config'
|
||||
import LogoBar from './LogoBar'
|
||||
import { MenuBarMobile } from './MenuBarMobile'
|
||||
import { MenuItemDrop } from './MenuItemDrop'
|
||||
|
||||
/**
|
||||
* 页头:顶部导航栏 + 菜单
|
||||
* @param {} param0
|
||||
* @returns
|
||||
*/
|
||||
export default function Header(props) {
|
||||
const { className, customNav, customMenu } = props
|
||||
const [isOpen, changeShow] = useState(false)
|
||||
const collapseRef = useRef(null)
|
||||
|
||||
const { locale } = useGlobal()
|
||||
|
||||
const defaultLinks = [
|
||||
{
|
||||
icon: 'fas fa-th',
|
||||
name: locale.COMMON.CATEGORY,
|
||||
to: '/category',
|
||||
show: siteConfig('GITBOOK_MENU_CATEGORY', null, CONFIG)
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-tag',
|
||||
name: locale.COMMON.TAGS,
|
||||
to: '/tag',
|
||||
show: siteConfig('GITBOOK_BOOK_MENU_TAG', null, CONFIG)
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-archive',
|
||||
name: locale.NAV.ARCHIVE,
|
||||
to: '/archive',
|
||||
show: siteConfig('GITBOOK_MENU_ARCHIVE', null, CONFIG)
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-search',
|
||||
name: locale.NAV.SEARCH,
|
||||
to: '/search',
|
||||
show: siteConfig('GITBOOK_MENU_SEARCH', null, CONFIG)
|
||||
}
|
||||
]
|
||||
|
||||
let links = defaultLinks.concat(customNav)
|
||||
|
||||
const toggleMenuOpen = () => {
|
||||
changeShow(!isOpen)
|
||||
}
|
||||
|
||||
// 如果 开启自定义菜单,则覆盖Page生成的菜单
|
||||
if (siteConfig('CUSTOM_MENU')) {
|
||||
links = customMenu
|
||||
}
|
||||
|
||||
return (
|
||||
<div id='top-nav' className={'fixed top-0 w-full z-20 ' + className}>
|
||||
{/* 移动端折叠菜单 */}
|
||||
<Collapse
|
||||
type='vertical'
|
||||
collapseRef={collapseRef}
|
||||
isOpen={isOpen}
|
||||
className='md:hidden'>
|
||||
<div className='bg-white dark:bg-hexo-black-gray pt-1 py-2 lg:hidden '>
|
||||
<MenuBarMobile
|
||||
{...props}
|
||||
onHeightChange={param =>
|
||||
collapseRef.current?.updateCollapseHeight(param)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</Collapse>
|
||||
|
||||
{/* 导航栏菜单 */}
|
||||
<div className='flex w-full h-14 shadow glassmorphism bg-white dark:bg-hexo-black-gray px-7 items-between'>
|
||||
{/* 左侧图标Logo */}
|
||||
<LogoBar {...props} />
|
||||
|
||||
{/* 折叠按钮、仅移动端显示 */}
|
||||
<div className='mr-1 flex md:hidden justify-end items-center space-x-4 dark:text-gray-200'>
|
||||
<DarkModeButton className='flex text-md items-center h-full' />
|
||||
<div
|
||||
onClick={toggleMenuOpen}
|
||||
className='cursor-pointer text-lg hover:scale-110 duration-150'>
|
||||
{isOpen ? (
|
||||
<i className='fas fa-times' />
|
||||
) : (
|
||||
<i className='fa-solid fa-ellipsis-vertical' />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 桌面端顶部菜单 */}
|
||||
<div className='hidden md:flex'>
|
||||
{links &&
|
||||
links?.map((link, index) => (
|
||||
<MenuItemDrop key={index} link={link} />
|
||||
))}
|
||||
<DarkModeButton className='text-sm flex items-center h-full' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGitBookGlobal } from '@/themes/gitbook'
|
||||
import Link from 'next/link'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import CONFIG from '../config'
|
||||
|
||||
/**
|
||||
@@ -17,14 +17,25 @@ export default function LogoBar(props) {
|
||||
changePageNavVisible(!pageNavVisible)
|
||||
}
|
||||
return (
|
||||
<div id='top-wrapper' className='w-full flex items-center'>
|
||||
<div onClick={togglePageNavVisible} className='cursor-pointer md:hidden text-xl pr-3 hover:scale-110 duration-150'>
|
||||
<i className={`fa-solid ${pageNavVisible ? 'fa-align-justify' : 'fa-indent'}`}></i>
|
||||
</div>
|
||||
<Link href={`/${siteConfig('GITBOOK_INDEX_PAGE', '', CONFIG)}`} className='flex text-md md:text-xl dark:text-gray-200'>
|
||||
<LazyImage src={siteInfo?.icon} width={24} height={24} alt={siteConfig('AUTHOR')} className='mr-2 hidden md:block' />
|
||||
{siteConfig('TITLE')}
|
||||
</Link>
|
||||
</div>
|
||||
<div id='top-wrapper' className='w-full flex items-center'>
|
||||
<div
|
||||
onClick={togglePageNavVisible}
|
||||
className='cursor-pointer md:hidden text-xl pr-3 hover:scale-110 duration-150'>
|
||||
<i
|
||||
className={`fa-solid ${pageNavVisible ? 'fa-align-justify' : 'fa-indent'}`}></i>
|
||||
</div>
|
||||
<Link
|
||||
href={`/${siteConfig('GITBOOK_INDEX_PAGE', '', CONFIG)}`}
|
||||
className='flex text-md md:text-xl dark:text-gray-200'>
|
||||
<LazyImage
|
||||
src={siteInfo?.icon}
|
||||
width={24}
|
||||
height={24}
|
||||
alt={siteConfig('AUTHOR')}
|
||||
className='mr-2 hidden md:block'
|
||||
/>
|
||||
{siteInfo?.title || siteConfig('TITLE')}
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
import LogoBar from './LogoBar'
|
||||
import { useRef, useState } from 'react'
|
||||
import Collapse from '@/components/Collapse'
|
||||
import { MenuBarMobile } from './MenuBarMobile'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import CONFIG from '../config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { MenuItemDrop } from './MenuItemDrop'
|
||||
import DarkModeButton from '@/components/DarkModeButton'
|
||||
|
||||
/**
|
||||
* 顶部导航栏 + 菜单
|
||||
* @param {} param0
|
||||
* @returns
|
||||
*/
|
||||
export default function TopNavBar(props) {
|
||||
const { className, customNav, customMenu } = props
|
||||
const [isOpen, changeShow] = useState(false)
|
||||
const collapseRef = useRef(null)
|
||||
|
||||
const { locale } = useGlobal()
|
||||
|
||||
const defaultLinks = [
|
||||
{ icon: 'fas fa-th', name: locale.COMMON.CATEGORY, to: '/category', show: siteConfig('GITBOOK_MENU_CATEGORY', null, CONFIG) },
|
||||
{ icon: 'fas fa-tag', name: locale.COMMON.TAGS, to: '/tag', show: siteConfig('GITBOOK_BOOK_MENU_TAG', null, CONFIG) },
|
||||
{ icon: 'fas fa-archive', name: locale.NAV.ARCHIVE, to: '/archive', show: siteConfig('GITBOOK_MENU_ARCHIVE', null, CONFIG) },
|
||||
{ icon: 'fas fa-search', name: locale.NAV.SEARCH, to: '/search', show: siteConfig('GITBOOK_MENU_SEARCH', null, CONFIG) }
|
||||
]
|
||||
|
||||
let links = defaultLinks.concat(customNav)
|
||||
|
||||
const toggleMenuOpen = () => {
|
||||
changeShow(!isOpen)
|
||||
}
|
||||
|
||||
// 如果 开启自定义菜单,则覆盖Page生成的菜单
|
||||
if (siteConfig('CUSTOM_MENU')) {
|
||||
links = customMenu
|
||||
}
|
||||
|
||||
return (
|
||||
<div id='top-nav' className={'fixed top-0 w-full z-20 ' + className}>
|
||||
|
||||
{/* 移动端折叠菜单 */}
|
||||
<Collapse type='vertical' collapseRef={collapseRef} isOpen={isOpen} className='md:hidden'>
|
||||
<div className='bg-white dark:bg-hexo-black-gray pt-1 py-2 lg:hidden '>
|
||||
<MenuBarMobile {...props} onHeightChange={(param) => collapseRef.current?.updateCollapseHeight(param)} />
|
||||
</div>
|
||||
</Collapse>
|
||||
|
||||
{/* 导航栏菜单 */}
|
||||
<div className='flex w-full h-14 shadow glassmorphism bg-white dark:bg-hexo-black-gray px-7 items-between'>
|
||||
|
||||
{/* 左侧图标Logo */}
|
||||
<LogoBar {...props} />
|
||||
|
||||
{/* 折叠按钮、仅移动端显示 */}
|
||||
<div className='mr-1 flex md:hidden justify-end items-center space-x-4 dark:text-gray-200'>
|
||||
<DarkModeButton className='flex text-md items-center h-full' />
|
||||
<div onClick={toggleMenuOpen} className='cursor-pointer text-lg hover:scale-110 duration-150'>
|
||||
{isOpen ? <i className='fas fa-times' /> : <i className="fa-solid fa-ellipsis-vertical"/>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 桌面端顶部菜单 */}
|
||||
<div className='hidden md:flex'>
|
||||
{links && links?.map((link, index) => <MenuItemDrop key={index} link={link} />)}
|
||||
<DarkModeButton className='text-sm flex items-center h-full' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,41 +1,44 @@
|
||||
'use client'
|
||||
|
||||
import CONFIG from './config'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useEffect, useState, createContext, useContext, useRef } from 'react'
|
||||
import { isBrowser } from '@/lib/utils'
|
||||
import Footer from './components/Footer'
|
||||
import InfoCard from './components/InfoCard'
|
||||
import RevolverMaps from './components/RevolverMaps'
|
||||
import TopNavBar from './components/TopNavBar'
|
||||
import SearchInput from './components/SearchInput'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Live2D from '@/components/Live2D'
|
||||
import NavPostList from './components/NavPostList'
|
||||
import ArticleInfo from './components/ArticleInfo'
|
||||
import Catalog from './components/Catalog'
|
||||
import Announcement from './components/Announcement'
|
||||
import PageNavDrawer from './components/PageNavDrawer'
|
||||
import FloatTocButton from './components/FloatTocButton'
|
||||
import { AdSlot } from '@/components/GoogleAdsense'
|
||||
import JumpToTopButton from './components/JumpToTopButton'
|
||||
import ShareBar from '@/components/ShareBar'
|
||||
import CategoryItem from './components/CategoryItem'
|
||||
import TagItemMini from './components/TagItemMini'
|
||||
import ArticleAround from './components/ArticleAround'
|
||||
import Comment from '@/components/Comment'
|
||||
import TocDrawer from './components/TocDrawer'
|
||||
import NotionPage from '@/components/NotionPage'
|
||||
import { ArticleLock } from './components/ArticleLock'
|
||||
import { Transition } from '@headlessui/react'
|
||||
import { Style } from './style'
|
||||
import BlogArchiveItem from './components/BlogArchiveItem'
|
||||
import Link from 'next/link'
|
||||
import dynamic from 'next/dynamic'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { AdSlot } from '@/components/GoogleAdsense'
|
||||
import Live2D from '@/components/Live2D'
|
||||
import NotionIcon from '@/components/NotionIcon'
|
||||
import NotionPage from '@/components/NotionPage'
|
||||
import ShareBar from '@/components/ShareBar'
|
||||
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, useState } from 'react'
|
||||
import Announcement from './components/Announcement'
|
||||
import ArticleAround from './components/ArticleAround'
|
||||
import ArticleInfo from './components/ArticleInfo'
|
||||
import { ArticleLock } from './components/ArticleLock'
|
||||
import BlogArchiveItem from './components/BlogArchiveItem'
|
||||
import Catalog from './components/Catalog'
|
||||
import CategoryItem from './components/CategoryItem'
|
||||
import FloatTocButton from './components/FloatTocButton'
|
||||
import Footer from './components/Footer'
|
||||
import Header from './components/Header'
|
||||
import InfoCard from './components/InfoCard'
|
||||
import JumpToTopButton from './components/JumpToTopButton'
|
||||
import NavPostList from './components/NavPostList'
|
||||
import PageNavDrawer from './components/PageNavDrawer'
|
||||
import RevolverMaps from './components/RevolverMaps'
|
||||
import SearchInput from './components/SearchInput'
|
||||
import TagItemMini from './components/TagItemMini'
|
||||
import TocDrawer from './components/TocDrawer'
|
||||
import CONFIG from './config'
|
||||
import { Style } from './style'
|
||||
|
||||
const AlgoliaSearchModal = dynamic(() => import('@/components/AlgoliaSearchModal'), { ssr: false })
|
||||
const AlgoliaSearchModal = dynamic(
|
||||
() => import('@/components/AlgoliaSearchModal'),
|
||||
{ ssr: false }
|
||||
)
|
||||
const WWAds = dynamic(() => import('@/components/WWAds'), { ssr: false })
|
||||
|
||||
// 主题全局变量
|
||||
@@ -47,12 +50,14 @@ export const useGitBookGlobal = () => useContext(ThemeGlobalGitbook)
|
||||
*/
|
||||
function getNavPagesWithLatest(allNavPages, latestPosts, post) {
|
||||
// localStorage 保存id和上次阅读时间戳: posts_read_time = {"${post.id}":"Date()"}
|
||||
const postReadTime = JSON.parse(localStorage.getItem('post_read_time') || '{}');
|
||||
const postReadTime = JSON.parse(
|
||||
localStorage.getItem('post_read_time') || '{}'
|
||||
)
|
||||
if (post) {
|
||||
postReadTime[post.id] = new Date().getTime();
|
||||
postReadTime[post.id] = new Date().getTime()
|
||||
}
|
||||
// 更新
|
||||
localStorage.setItem('post_read_time', JSON.stringify(postReadTime));
|
||||
localStorage.setItem('post_read_time', JSON.stringify(postReadTime))
|
||||
|
||||
return allNavPages?.map(item => {
|
||||
const res = {
|
||||
@@ -67,12 +72,14 @@ function getNavPagesWithLatest(allNavPages, latestPosts, post) {
|
||||
lastEditedDate: item.lastEditedDate
|
||||
}
|
||||
// 属于最新文章通常6篇 && (无阅读记录 || 最近更新时间大于上次阅读时间)
|
||||
if (latestPosts.some(post => post.id === item.id) &&
|
||||
(!postReadTime[item.id] || postReadTime[item.id] < new Date(item.lastEditedDate).getTime())
|
||||
if (
|
||||
latestPosts.some(post => post.id === item.id) &&
|
||||
(!postReadTime[item.id] ||
|
||||
postReadTime[item.id] < new Date(item.lastEditedDate).getTime())
|
||||
) {
|
||||
return { ...res, isLatest: true };
|
||||
return { ...res, isLatest: true }
|
||||
} else {
|
||||
return res;
|
||||
return res
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -83,8 +90,16 @@ function getNavPagesWithLatest(allNavPages, latestPosts, post) {
|
||||
* @returns {JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
const LayoutBase = (props) => {
|
||||
const { children, post, allNavPages, latestPosts, slotLeft, slotRight, slotTop } = props
|
||||
const LayoutBase = props => {
|
||||
const {
|
||||
children,
|
||||
post,
|
||||
allNavPages,
|
||||
latestPosts,
|
||||
slotLeft,
|
||||
slotRight,
|
||||
slotTop
|
||||
} = props
|
||||
const { onLoading, fullWidth } = useGlobal()
|
||||
const router = useRouter()
|
||||
const [tocVisible, changeTocVisible] = useState(false)
|
||||
@@ -99,110 +114,140 @@ const LayoutBase = (props) => {
|
||||
}, [router])
|
||||
|
||||
return (
|
||||
<ThemeGlobalGitbook.Provider value={{ searchModal, tocVisible, changeTocVisible, filteredNavPages, setFilteredNavPages, allNavPages, pageNavVisible, changePageNavVisible }}>
|
||||
<Style/>
|
||||
<ThemeGlobalGitbook.Provider
|
||||
value={{
|
||||
searchModal,
|
||||
tocVisible,
|
||||
changeTocVisible,
|
||||
filteredNavPages,
|
||||
setFilteredNavPages,
|
||||
allNavPages,
|
||||
pageNavVisible,
|
||||
changePageNavVisible
|
||||
}}>
|
||||
<Style />
|
||||
|
||||
<div id='theme-gitbook' className={`${siteConfig('FONT_STYLE')} scroll-smooth bg-white dark:bg-hexo-black-gray w-full h-full min-h-screen justify-center dark:text-gray-300`}>
|
||||
<AlgoliaSearchModal cRef={searchModal} {...props}/>
|
||||
<div
|
||||
id='theme-gitbook'
|
||||
className={`${siteConfig('FONT_STYLE')} scroll-smooth bg-white dark:bg-hexo-black-gray w-full h-full min-h-screen justify-center dark:text-gray-300`}>
|
||||
<AlgoliaSearchModal cRef={searchModal} {...props} />
|
||||
|
||||
{/* 顶部导航栏 */}
|
||||
<TopNavBar {...props} />
|
||||
{/* 顶部导航栏 */}
|
||||
<Header {...props} />
|
||||
|
||||
<main id='wrapper' className={(JSON.parse(siteConfig('LAYOUT_SIDEBAR_REVERSE')) ? 'flex-row-reverse' : '') + 'relative flex justify-between w-full h-full mx-auto'}>
|
||||
|
||||
{/* 左侧推拉抽屉 */}
|
||||
{fullWidth
|
||||
? null
|
||||
: (<div className={'hidden md:block border-r dark:border-transparent relative z-10 dark:bg-hexo-black-gray'}>
|
||||
<div className='w-72 py-14 px-6 sticky top-0 overflow-y-scroll h-screen scroll-hidden'>
|
||||
{slotLeft}
|
||||
<SearchInput className='my-3 rounded-md' />
|
||||
<div className='mb-20'>
|
||||
{/* 所有文章列表 */}
|
||||
<NavPostList filteredNavPages={filteredNavPages} />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div className='w-72 fixed left-0 bottom-0 z-20 bg-white'>
|
||||
<Footer {...props} />
|
||||
</div>
|
||||
</div>) }
|
||||
|
||||
<div id='center-wrapper' className='flex flex-col justify-between w-full relative z-10 pt-14 min-h-screen dark:bg-black'>
|
||||
|
||||
<div id='container-inner' className={`w-full px-7 ${fullWidth ? 'px-10' : 'max-w-3xl'} justify-center mx-auto`}>
|
||||
{slotTop}
|
||||
<WWAds className='w-full' orientation='horizontal'/>
|
||||
|
||||
<Transition
|
||||
show={!onLoading}
|
||||
appear={true}
|
||||
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}
|
||||
>
|
||||
{children}
|
||||
</Transition>
|
||||
|
||||
{/* Google广告 */}
|
||||
<AdSlot type='in-article' />
|
||||
<WWAds className='w-full' orientation='horizontal'/>
|
||||
|
||||
{/* 回顶按钮 */}
|
||||
<JumpToTopButton />
|
||||
</div>
|
||||
|
||||
{/* 底部 */}
|
||||
<div className='md:hidden'>
|
||||
<Footer {...props} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 右侧侧推拉抽屉 */}
|
||||
{fullWidth
|
||||
? null
|
||||
: <div style={{ width: '20rem' }} className={'hidden xl:block dark:border-transparent flex-shrink-0 relative z-10 '}>
|
||||
<div className='py-14 px-6 sticky top-0'>
|
||||
<ArticleInfo post={props?.post ? props?.post : props.notice} />
|
||||
|
||||
<div className='py-4'>
|
||||
<Catalog {...props} />
|
||||
{slotRight}
|
||||
{router.route === '/' && <>
|
||||
<InfoCard {...props} />
|
||||
{siteConfig('GITBOOK_WIDGET_REVOLVER_MAPS', null, CONFIG) === 'true' && <RevolverMaps />}
|
||||
<Live2D />
|
||||
</>}
|
||||
{/* gitbook主题首页只显示公告 */}
|
||||
<Announcement {...props} />
|
||||
</div>
|
||||
|
||||
<AdSlot type='in-article' />
|
||||
<Live2D />
|
||||
|
||||
</div>
|
||||
</div>}
|
||||
|
||||
</main>
|
||||
|
||||
{/* 移动端悬浮目录按钮 */}
|
||||
{showTocButton && !tocVisible && <div className='md:hidden fixed right-0 bottom-52 z-30 bg-white border-l border-t border-b dark:border-gray-800 rounded'>
|
||||
<FloatTocButton {...props} />
|
||||
</div>}
|
||||
|
||||
{/* 移动端导航抽屉 */}
|
||||
<PageNavDrawer {...props} filteredNavPages={filteredNavPages} />
|
||||
|
||||
{/* 移动端底部导航栏 */}
|
||||
{/* <BottomMenuBar {...props} className='block md:hidden' /> */}
|
||||
<main
|
||||
id='wrapper'
|
||||
className={
|
||||
(JSON.parse(siteConfig('LAYOUT_SIDEBAR_REVERSE'))
|
||||
? 'flex-row-reverse'
|
||||
: '') + 'relative flex justify-between w-full h-full mx-auto'
|
||||
}>
|
||||
{/* 左侧推拉抽屉 */}
|
||||
{fullWidth ? null : (
|
||||
<div
|
||||
className={
|
||||
'hidden md:block border-r dark:border-transparent relative z-10 dark:bg-hexo-black-gray'
|
||||
}>
|
||||
<div className='w-72 py-14 px-6 sticky top-0 overflow-y-scroll h-screen scroll-hidden'>
|
||||
{slotLeft}
|
||||
<SearchInput className='my-3 rounded-md' />
|
||||
<div className='mb-20'>
|
||||
{/* 所有文章列表 */}
|
||||
<NavPostList filteredNavPages={filteredNavPages} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='w-72 fixed left-0 bottom-0 z-20 bg-white'>
|
||||
<Footer {...props} />
|
||||
</div>
|
||||
</div>
|
||||
</ThemeGlobalGitbook.Provider>
|
||||
)}
|
||||
|
||||
<div
|
||||
id='center-wrapper'
|
||||
className='flex flex-col justify-between w-full relative z-10 pt-14 min-h-screen dark:bg-black'>
|
||||
<div
|
||||
id='container-inner'
|
||||
className={`w-full px-7 ${fullWidth ? 'px-10' : 'max-w-3xl'} justify-center mx-auto`}>
|
||||
{slotTop}
|
||||
<WWAds className='w-full' orientation='horizontal' />
|
||||
|
||||
<Transition
|
||||
show={!onLoading}
|
||||
appear={true}
|
||||
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}>
|
||||
{children}
|
||||
</Transition>
|
||||
|
||||
{/* Google广告 */}
|
||||
<AdSlot type='in-article' />
|
||||
<WWAds className='w-full' orientation='horizontal' />
|
||||
|
||||
{/* 回顶按钮 */}
|
||||
<JumpToTopButton />
|
||||
</div>
|
||||
|
||||
{/* 底部 */}
|
||||
<div className='md:hidden'>
|
||||
<Footer {...props} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 右侧侧推拉抽屉 */}
|
||||
{fullWidth ? null : (
|
||||
<div
|
||||
style={{ width: '20rem' }}
|
||||
className={
|
||||
'hidden xl:block dark:border-transparent flex-shrink-0 relative z-10 '
|
||||
}>
|
||||
<div className='py-14 px-6 sticky top-0'>
|
||||
<ArticleInfo post={props?.post ? props?.post : props.notice} />
|
||||
|
||||
<div className='py-4'>
|
||||
<Catalog {...props} />
|
||||
{slotRight}
|
||||
{router.route === '/' && (
|
||||
<>
|
||||
<InfoCard {...props} />
|
||||
{siteConfig(
|
||||
'GITBOOK_WIDGET_REVOLVER_MAPS',
|
||||
null,
|
||||
CONFIG
|
||||
) === 'true' && <RevolverMaps />}
|
||||
<Live2D />
|
||||
</>
|
||||
)}
|
||||
{/* gitbook主题首页只显示公告 */}
|
||||
<Announcement {...props} />
|
||||
</div>
|
||||
|
||||
<AdSlot type='in-article' />
|
||||
<Live2D />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
|
||||
{/* 移动端悬浮目录按钮 */}
|
||||
{showTocButton && !tocVisible && (
|
||||
<div className='md:hidden fixed right-0 bottom-52 z-30 bg-white border-l border-t border-b dark:border-gray-800 rounded'>
|
||||
<FloatTocButton {...props} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 移动端导航抽屉 */}
|
||||
<PageNavDrawer {...props} filteredNavPages={filteredNavPages} />
|
||||
|
||||
{/* 移动端底部导航栏 */}
|
||||
{/* <BottomMenuBar {...props} className='block md:hidden' /> */}
|
||||
</div>
|
||||
</ThemeGlobalGitbook.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -212,7 +257,7 @@ const LayoutBase = (props) => {
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
const LayoutIndex = (props) => {
|
||||
const LayoutIndex = props => {
|
||||
const router = useRouter()
|
||||
useEffect(() => {
|
||||
router.push(siteConfig('GITBOOK_INDEX_PAGE', null, CONFIG)).then(() => {
|
||||
@@ -221,8 +266,13 @@ const LayoutIndex = (props) => {
|
||||
if (isBrowser) {
|
||||
const article = document.getElementById('notion-article')
|
||||
if (!article) {
|
||||
console.log('请检查您的Notion数据库中是否包含此slug页面: ', siteConfig('GITBOOK_INDEX_PAGE', null, CONFIG))
|
||||
const containerInner = document.querySelector('#theme-gitbook #container-inner')
|
||||
console.log(
|
||||
'请检查您的Notion数据库中是否包含此slug页面: ',
|
||||
siteConfig('GITBOOK_INDEX_PAGE', null, CONFIG)
|
||||
)
|
||||
const containerInner = document.querySelector(
|
||||
'#theme-gitbook #container-inner'
|
||||
)
|
||||
const newHTML = `<h1 class="text-3xl pt-12 dark:text-gray-300">配置有误</h1><blockquote class="notion-quote notion-block-ce76391f3f2842d386468ff1eb705b92"><div>请在您的notion中添加一个slug为${siteConfig('GITBOOK_INDEX_PAGE', null, CONFIG)}的文章</div></blockquote>`
|
||||
containerInner?.insertAdjacentHTML('afterbegin', newHTML)
|
||||
}
|
||||
@@ -240,7 +290,7 @@ const LayoutIndex = (props) => {
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
const LayoutPostList = (props) => {
|
||||
const LayoutPostList = props => {
|
||||
return <></>
|
||||
}
|
||||
|
||||
@@ -249,59 +299,76 @@ const LayoutPostList = (props) => {
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
const LayoutSlug = (props) => {
|
||||
const LayoutSlug = props => {
|
||||
const { post, prev, next, 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} />}
|
||||
<>
|
||||
{/* 文章锁 */}
|
||||
{lock && <ArticleLock validPassword={validPassword} />}
|
||||
|
||||
{!lock && <div id='container'>
|
||||
{!lock && (
|
||||
<div id='container'>
|
||||
{/* title */}
|
||||
<h1 className='text-3xl pt-12 dark:text-gray-300'>
|
||||
{siteConfig('POST_TITLE_ICON') && (
|
||||
<NotionIcon icon={post?.pageIcon} />
|
||||
)}
|
||||
{post?.title}
|
||||
</h1>
|
||||
|
||||
{/* title */}
|
||||
<h1 className="text-3xl pt-12 dark:text-gray-300">{siteConfig('POST_TITLE_ICON') && <NotionIcon icon={post?.pageIcon} />}{post?.title}</h1>
|
||||
{/* Notion文章主体 */}
|
||||
{post && (
|
||||
<section id='article-wrapper' className='px-1'>
|
||||
<NotionPage post={post} />
|
||||
|
||||
{/* Notion文章主体 */}
|
||||
{post && (<section id="article-wrapper" className="px-1">
|
||||
<NotionPage post={post} />
|
||||
{/* 分享 */}
|
||||
<ShareBar post={post} />
|
||||
{/* 文章分类和标签信息 */}
|
||||
<div className='flex justify-between'>
|
||||
{siteConfig('POST_DETAIL_CATEGORY', null, CONFIG) &&
|
||||
post?.category && <CategoryItem category={post.category} />}
|
||||
<div>
|
||||
{siteConfig('POST_DETAIL_TAG', null, CONFIG) &&
|
||||
post?.tagItems?.map(tag => (
|
||||
<TagItemMini key={tag.name} tag={tag} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 分享 */}
|
||||
<ShareBar post={post} />
|
||||
{/* 文章分类和标签信息 */}
|
||||
<div className='flex justify-between'>
|
||||
{siteConfig('POST_DETAIL_CATEGORY', null, CONFIG) && post?.category && <CategoryItem category={post.category} />}
|
||||
<div>
|
||||
{siteConfig('POST_DETAIL_TAG', null, CONFIG) && post?.tagItems?.map(tag => <TagItemMini key={tag.name} tag={tag} />)}
|
||||
</div>
|
||||
</div>
|
||||
{post?.type === 'Post' && (
|
||||
<ArticleAround prev={prev} next={next} />
|
||||
)}
|
||||
|
||||
{post?.type === 'Post' && <ArticleAround prev={prev} next={next} />}
|
||||
<AdSlot />
|
||||
<WWAds className='w-full' orientation='horizontal' />
|
||||
|
||||
<AdSlot />
|
||||
<WWAds className='w-full' orientation='horizontal'/>
|
||||
<Comment frontMatter={post} />
|
||||
</section>
|
||||
)}
|
||||
|
||||
<Comment frontMatter={post} />
|
||||
</section>)}
|
||||
|
||||
<TocDrawer {...props} />
|
||||
</div>}
|
||||
</>
|
||||
<TocDrawer {...props} />
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -311,7 +378,7 @@ const LayoutSlug = (props) => {
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
const LayoutSearch = (props) => {
|
||||
const LayoutSearch = props => {
|
||||
return <></>
|
||||
}
|
||||
|
||||
@@ -321,91 +388,111 @@ const LayoutSearch = (props) => {
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
const LayoutArchive = (props) => {
|
||||
const LayoutArchive = props => {
|
||||
const { archivePosts } = props
|
||||
|
||||
return <>
|
||||
<div className="mb-10 pb-20 md:py-12 py-3 min-h-full">
|
||||
{Object.keys(archivePosts)?.map(archiveTitle => <BlogArchiveItem key={archiveTitle} archiveTitle={archiveTitle} archivePosts={archivePosts} />)}
|
||||
</div>
|
||||
</>
|
||||
return (
|
||||
<>
|
||||
<div className='mb-10 pb-20 md:py-12 py-3 min-h-full'>
|
||||
{Object.keys(archivePosts)?.map(archiveTitle => (
|
||||
<BlogArchiveItem
|
||||
key={archiveTitle}
|
||||
archiveTitle={archiveTitle}
|
||||
archivePosts={archivePosts}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 404
|
||||
*/
|
||||
const Layout404 = props => {
|
||||
return <>
|
||||
<div className='w-full h-96 py-80 flex justify-center items-center'>404 Not found.</div>
|
||||
return (
|
||||
<>
|
||||
<div className='w-full h-96 py-80 flex justify-center items-center'>
|
||||
404 Not found.
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 分类列表
|
||||
*/
|
||||
const LayoutCategoryIndex = (props) => {
|
||||
const LayoutCategoryIndex = props => {
|
||||
const { categoryOptions } = props
|
||||
const { locale } = useGlobal()
|
||||
return <>
|
||||
<div className='bg-white dark:bg-gray-700 py-10'>
|
||||
<div className='dark:text-gray-200 mb-5'>
|
||||
<i className='mr-4 fas fa-th' />{locale.COMMON.CATEGORY}:
|
||||
return (
|
||||
<>
|
||||
<div className='bg-white dark:bg-gray-700 py-10'>
|
||||
<div className='dark:text-gray-200 mb-5'>
|
||||
<i className='mr-4 fas fa-th' />
|
||||
{locale.COMMON.CATEGORY}:
|
||||
</div>
|
||||
<div id='category-list' className='duration-200 flex flex-wrap'>
|
||||
{categoryOptions?.map(category => {
|
||||
return (
|
||||
<Link
|
||||
key={category.name}
|
||||
href={`/category/${category.name}`}
|
||||
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})
|
||||
</div>
|
||||
<div id='category-list' className='duration-200 flex flex-wrap'>
|
||||
{categoryOptions?.map(category => {
|
||||
return (
|
||||
<Link
|
||||
key={category.name}
|
||||
href={`/category/${category.name}`}
|
||||
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})
|
||||
</div>
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 标签列表
|
||||
*/
|
||||
const LayoutTagIndex = (props) => {
|
||||
const LayoutTagIndex = props => {
|
||||
const { tagOptions } = props
|
||||
const { locale } = useGlobal()
|
||||
|
||||
return <>
|
||||
<div className="bg-white dark:bg-gray-700 py-10">
|
||||
<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">
|
||||
{tagOptions?.map(tag => {
|
||||
return (
|
||||
<div key={tag.name} className="p-2">
|
||||
<TagItemMini key={tag.name} tag={tag} />
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
return (
|
||||
<>
|
||||
<div className='bg-white dark:bg-gray-700 py-10'>
|
||||
<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'>
|
||||
{tagOptions?.map(tag => {
|
||||
return (
|
||||
<div key={tag.name} className='p-2'>
|
||||
<TagItemMini key={tag.name} tag={tag} />
|
||||
</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