theme-heo-framework

This commit is contained in:
tangly1024
2023-07-11 22:37:23 +08:00
parent 1f4f050e76
commit beb4677145
19 changed files with 193 additions and 345 deletions

View File

@@ -14,17 +14,16 @@ const BlogPostCard = ({ index, post, showSummary, siteInfo }) => {
// const delay = (index % 2) * 200
return (
<div className={`${CONFIG.POST_LIST_COVER_HOVER_ENLARGE ? ' hover:scale-110 transition-all duration-150' : ''}`} >
<div
data-aos="fade-up"
data-aos-easing="ease-in-out"
data-aos-duration="800"
data-aos-once="false"
data-aos-anchor-placement="top-bottom"
// data-aos="fade-up"
// data-aos-easing="ease-in-out"
// data-aos-duration="800"
// data-aos-once="false"
// data-aos-anchor-placement="top-bottom"
id='blog-post-card'
key={post.id}
className={`md:h-56 w-full flex justify-between md:flex-row flex-col-reverse ${CONFIG.POST_LIST_IMG_CROSSOVER && index % 2 === 1 ? 'md:flex-row-reverse' : ''}
className={`w-full justify-between flex flex-col-reverse lg:h-96 ${CONFIG.POST_LIST_IMG_CROSSOVER && index % 2 === 1 ? '' : ''}
overflow-hidden border dark:border-black rounded-xl bg-white dark:bg-hexo-black-gray`}>
{/* 文字内容 */}
@@ -32,7 +31,7 @@ const BlogPostCard = ({ index, post, showSummary, siteInfo }) => {
{/* 图片封面 */}
{showPageCover && (
<div className="md:w-5/12 overflow-hidden">
<div className="md:w-5/12 lg:w-full overflow-hidden">
<Link href={`${BLOG.SUB_PATH}/${post.slug}`} passHref legacyBehavior>
<div className='h-56 bg-center bg-cover hover:scale-110 duration-200' style={{ backgroundImage: `url('${post?.pageCoverThumbnail}')` }} />
</Link>

View File

@@ -20,7 +20,7 @@ const BlogPostListPage = ({ page = 1, posts = [], postCount, siteInfo }) => {
return (
<div id="container" className='w-full'>
{/* 文章列表 */}
<div className="space-y-6 px-2">
<div className="lg:grid lg:grid-cols-2">
{posts?.map(post => (
<BlogPostCard index={posts.indexOf(post)} key={post.id} post={post} siteInfo={siteInfo}/>
))}

View File

@@ -0,0 +1,9 @@
/**
* 博客列表上方嵌入条
* @param {*} props
* @returns
*/
export default function CategoryBar(props) {
return <div id='category-list' className="h-24 w-full bg-pink-100"></div>
}

View File

@@ -1,11 +1,12 @@
import React from 'react'
import BLOG from '@/blog.config'
import SocialButton from './SocialButton'
// import DarkModeButton from '@/components/DarkModeButton'
const Footer = ({ title }) => {
const d = new Date()
const currentYear = d.getFullYear()
const copyrightDate = (function() {
const copyrightDate = (function () {
if (Number.isInteger(BLOG.SINCE) && BLOG.SINCE < currentYear) {
return BLOG.SINCE + '-' + currentYear
}
@@ -13,23 +14,36 @@ const Footer = ({ title }) => {
})()
return (
<footer
className='relative z-10 dark:bg-black flex-shrink-0 bg-hexo-light-gray justify-center text-center m-auto w-full leading-6 text-gray-600 dark:text-gray-100 text-sm p-6'
>
{/* <DarkModeButton/> */}
<footer
className='relative z-10 flex-shrink-0 bg-white justify-center text-center m-auto w-full leading-6 text-gray-600 dark:text-gray-100 text-sm'
>
<i className='fas fa-copyright' /> {`${copyrightDate}`} <span><i className='mx-1 animate-pulse fas fa-heart'/> <a href={BLOG.LINK} className='underline font-bold dark:text-gray-300 '>{BLOG.AUTHOR}</a>.<br/>
<div id='color-transition' className='h-32 bg-gradient-to-b from-[#f7f9fe] to-white '>
{BLOG.BEI_AN && <><i className='fas fa-shield-alt' /> <a href='https://beian.miit.gov.cn/' className='mr-2'>{BLOG.BEI_AN}</a><br/></>}
</div>
<div className='w-full h-24'>
<SocialButton />
</div>
<span className='hidden busuanzi_container_site_pv'>
<i className='fas fa-eye'/><span className='px-1 busuanzi_value_site_pv'> </span> </span>
<span className='pl-2 hidden busuanzi_container_site_uv'>
<i className='fas fa-users'/> <span className='px-1 busuanzi_value_site_uv'> </span> </span>
<h1 className='text-xs pt-4 text-light-400 dark:text-gray-400'>{title} | {BLOG.BIO}</h1>
<p className='text-xs pt-2 text-light-500 dark:text-gray-500'>Powered by <a href='https://github.com/tangly1024/NotionNext' className='dark:text-gray-300'>NotionNext {BLOG.VERSION}</a>.</p></span><br/>
<br />
</footer>
<div id='footer-bottom' className='w-full h-20 flex justify-between px-6 items-center bg-[#f1f3f7]'>
<div id='footer-bottom-left'>
<i className='fas fa-copyright' /> {`${copyrightDate}`} <i className='mx-1 animate-pulse fas fa-heart' /> <a href={BLOG.LINK} className='underline font-bold dark:text-gray-300 '>{BLOG.AUTHOR}</a>.
</div>
<div id='footer-bottom-right'>
{BLOG.BEI_AN && <><i className='fas fa-shield-alt' /> <a href='https://beian.miit.gov.cn/' className='mr-2'>{BLOG.BEI_AN}</a></>}
<span className='hidden busuanzi_container_site_pv'>
<i className='fas fa-eye' /><span className='px-1 busuanzi_value_site_pv'> </span> </span>
<span className='pl-2 hidden busuanzi_container_site_uv'>
<i className='fas fa-users' /> <span className='px-1 busuanzi_value_site_uv'> </span> </span>
<h1 className='text-xs text-light-400 dark:text-gray-400'>{title} | {BLOG.BIO}</h1>
</div>
</div>
</footer>
)
}

View File

@@ -1,82 +1,82 @@
// import Image from 'next/image'
import { useEffect, useState } from 'react'
import Typed from 'typed.js'
import CONFIG from '../config'
import NavButtonGroup from './NavButtonGroup'
import { useGlobal } from '@/lib/global'
import BLOG from '@/blog.config'
import { useCallback, useEffect, useRef, useState } from 'react'
import Logo from './Logo'
import SearchDrawer from './SearchDrawer'
let wrapperTop = 0
import { MenuListTop } from './MenuListTop'
import throttle from 'lodash.throttle'
import SideBar from './SideBar'
import SideBarDrawer from './SideBarDrawer'
/**
* 顶部全屏大图
* 顶部导航
* @param {*} param0
* @returns
*/
const Hero = props => {
const [typed, changeType] = useState()
const { siteInfo } = props
const { locale } = useGlobal()
const scrollToWrapper = () => {
window.scrollTo({ top: wrapperTop, behavior: 'smooth' })
const Header = props => {
const searchDrawer = useRef()
const [isOpen, changeShow] = useState(false)
const [headerBgShow, setHeaderBgShow] = useState(false)
const toggleMenuOpen = () => {
changeShow(!isOpen)
}
const toggleSideBarClose = () => {
changeShow(false)
}
// 监听滚动
useEffect(() => {
updateHeaderHeight()
if (!typed && window && document.getElementById('typed')) {
changeType(
new Typed('#typed', {
strings: BLOG.GREETING_WORDS.split(','),
typeSpeed: 200,
backSpeed: 100,
backDelay: 400,
showCursor: true,
smartBackspace: true
})
)
}
window.addEventListener('resize', updateHeaderHeight)
scrollTrigger()
window.addEventListener('scroll', scrollTrigger)
return () => {
window.removeEventListener('resize', updateHeaderHeight)
window.removeEventListener('scroll', scrollTrigger)
}
})
}, [])
function updateHeaderHeight() {
requestAnimationFrame(() => {
const wrapperElement = document.getElementById('wrapper')
wrapperTop = wrapperElement?.offsetTop
})
}
const throttleMs = 200
return (
<header
id="header" style={{ zIndex: 1 }}
className="w-full h-screen relative bg-black"
>
/**
* 根据滚动条,切换导航栏样式
*/
const scrollTrigger = useCallback(throttle(() => {
const scrollS = window.scrollY
const header = document.querySelector('#header')
<div className="text-white absolute bottom-0 flex flex-col h-full items-center justify-center w-full ">
{/* 站点标题 */}
<div className='font-black text-4xl md:text-5xl shadow-text'>{siteInfo?.title}</div>
{/* 站点欢迎语 */}
<div className='mt-2 h-12 items-center text-center font-medium shadow-text text-lg'>
<span id='typed' />
// 导航栏设置 白色背景
if (header && scrollS > 60) {
setHeaderBgShow(true)
} else {
setHeaderBgShow(false)
}
}, throttleMs))
return (<div id='header' className='z-40'>
<SearchDrawer cRef={searchDrawer} />
{/* 导航栏 */}
<div id='sticky-nav' className={`${headerBgShow ? 'bg-white border-b' : 'bg-none'} top-0 duration-300 transition-all fixed text-black w-full z-20 transform`}>
<div className='w-full max-w-7xl mx-auto flex justify-between items-center py-2 px-5'>
<div className='flex'>
<Logo {...props} />
</div>
{/* 首页导航大按钮 */}
{CONFIG.HOME_NAV_BUTTONS && <NavButtonGroup {...props} />}
{/* 滚动按钮 */}
<div onClick={scrollToWrapper} className="z-10 cursor-pointer w-full text-center py-4 text-3xl absolute bottom-10 text-white">
<div className="opacity-70 animate-bounce text-xs">{locale.COMMON.START_READING}</div>
<i className='opacity-70 animate-bounce fas fa-angle-down' />
{/* 右侧功能 */}
<div className='mr-1 justify-end items-center '>
<div className='hidden lg:flex'> <MenuListTop {...props} /></div>
<div onClick={toggleMenuOpen} className='w-8 justify-center items-center h-8 cursor-pointer flex lg:hidden'>
{isOpen ? <i className='fas fa-times' /> : <i className='fas fa-bars' />}
</div>
</div>
</div>
</div>
<div id='header-cover' style={{ backgroundImage: `url('${siteInfo?.pageCover}')` }}
className={`header-cover bg-center w-full h-screen bg-cover ${CONFIG.HOME_NAV_BACKGROUND_IMG_FIXED ? 'bg-fixed' : ''}`} />
</header>
)
{/* 折叠侧边栏 */}
<SideBarDrawer isOpen={isOpen} onClose={toggleSideBarClose}>
<SideBar {...props} />
</SideBarDrawer>
</div>)
}
export default Hero
export default Header

View File

@@ -0,0 +1,29 @@
// import Image from 'next/image'
/**
* 顶部全屏大图
* @returns
*/
const Hero = props => {
return (
<div className="mt-16">
<notice className="max-w-7xl w-full mx-auto flex h-20 px-5">
<div className="bg-indigo-100 w-full h-full"></div>
</notice>
<hero id="hero" style={{ zIndex: 1 }} className="max-w-7xl w-full mx-auto flex relative px-5" >
<div id='hero-left' className='flex flex-col flex-1 bg-red-200'>
<div className="h-60 bg-blue-200"></div>
<div className="h-24 bg-yellow-100"></div>
</div>
<div id='hero-right' className='flex flex-col flex-1 bg-green-200'>
</div>
</hero>
</div>
)
}
export default Hero

View File

@@ -6,8 +6,10 @@ const Logo = props => {
const { siteInfo } = props
return (
<Link href='/' passHref legacyBehavior>
<div className='flex flex-col justify-center items-center cursor-pointer space-y-3'>
<div className='font-medium text-lg p-1.5 rounded dark:border-white menu-link transform duration-200'> {siteInfo?.title || BLOG.TITLE}</div>
<div className='flex justify-center items-center cursor-pointer'>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src={siteInfo?.icon} width={24} height={24} alt={BLOG.AUTHOR} className='mr-2 hidden md:block' />
<div className='font-medium text-lg my-auto rounded dark:border-white transform duration-200'> {siteInfo?.title || BLOG.TITLE}</div>
</div>
</Link>
)

View File

@@ -4,7 +4,7 @@ import { useGlobal } from '@/lib/global'
import BLOG from '@/blog.config'
import NotionIcon from '@/components/NotionIcon'
export default function HeaderArticle({ post, siteInfo }) {
export default function PostHeader({ post, siteInfo }) {
const { locale } = useGlobal()
if (!post) {

View File

@@ -1,18 +1,11 @@
import Card from './Card'
import CategoryGroup from './CategoryGroup'
import LatestPostsGroup from './LatestPostsGroup'
import TagGroups from './TagGroups'
import Catalog from './Catalog'
import { InfoCard } from './InfoCard'
import { AnalyticsCard } from './AnalyticsCard'
import CONFIG from '../config'
import BLOG from '@/blog.config'
import dynamic from 'next/dynamic'
import Announcement from './Announcement'
import { useGlobal } from '@/lib/global'
import Live2D from '@/components/Live2D'
const HexoRecentComments = dynamic(() => import('./HexoRecentComments'))
const FaceBookPage = dynamic(
() => {
let facebook = <></>
@@ -33,50 +26,36 @@ const FaceBookPage = dynamic(
*/
export default function SideRight(props) {
const {
post, currentCategory, categories, latestPosts, tags,
currentTag, showCategory, showTag, rightAreaSlot, notice
post, tagOptions,
currentTag, rightAreaSlot, notice
} = props
const { locale } = useGlobal()
console.log('props', props)
return (
<div id='sideRight' className={'space-y-4 lg:w-80 lg:pt-0 px-2 pt-4'}>
<InfoCard {...props} />
{CONFIG.WIDGET_ANALYTICS && <AnalyticsCard {...props} />}
<div id='sideRight' className='w-72'>
{showCategory && (
<Card>
<div className='ml-2 mb-1 '>
<i className='fas fa-th' /> {locale.COMMON.CATEGORY}
</div>
<CategoryGroup
currentCategory={currentCategory}
categories={categories}
/>
</Card>
)}
{showTag && (
<Card>
<TagGroups tags={tags} currentTag={currentTag} />
</Card>
)}
{CONFIG.WIDGET_LATEST_POSTS && latestPosts && latestPosts.length > 0 && <Card>
<LatestPostsGroup {...props} />
</Card>}
<InfoCard {...props} className='w-72' />
<Announcement post={notice}/>
<Card>
<div>Join Us</div>
</Card>
{BLOG.COMMENT_WALINE_SERVER_URL && BLOG.COMMENT_WALINE_RECENT && <HexoRecentComments/>}
<Card>
<TagGroups tags={tagOptions} currentTag={currentTag} />
</Card>
<div className='sticky top-20'>
{post && post.toc && post.toc.length > 1 && <Card>
<Catalog toc={post.toc} />
</Card>}
<Announcement post={notice} />
{rightAreaSlot}
<FaceBookPage/>
<Live2D />
</div>
<div className='sticky top-20'>
{post && post.toc && post.toc.length > 1 && <Card>
<Catalog toc={post.toc} />
</Card>}
</div>
{rightAreaSlot}
<FaceBookPage />
<Live2D />
</div>
</div>
)
}

View File

@@ -1,24 +0,0 @@
import Link from 'next/link'
/**
* 博客列表上方嵌入条
* @param {*} props
* @returns
*/
export default function SlotBar(props) {
const { tag, category } = props
if (tag) {
return <div className="cursor-pointer px-3 py-2 mb-2 font-light hover:text-indigo-700 dark:hover:text-indigo-400 transform dark:text-white">
<Link key={tag} href={`/tag/${encodeURIComponent(tag.name)}`} passHref
className={'cursor-pointer inline-block rounded duration-200 mr-2 py-0.5 px-1 text-xl whitespace-nowrap '}>
<div className='font-light dark:text-gray-400 dark:hover:text-white'> #{tag.name + (tag.count ? `(${tag.count})` : '')} </div>
</Link>
</div>
} else if (category) {
return <div className="cursor-pointer text-lg px-5 py-1 mb-2 font-light hover:text-indigo-700 dark:hover:text-indigo-400 transform dark:text-white">
<i className="mr-1 far fa-folder-open" /> {category}
</div>
}
return <></>
}

View File

@@ -8,7 +8,7 @@ import React from 'react'
*/
const SocialButton = () => {
return <div className='w-full justify-center flex-wrap flex'>
<div className='space-x-3 text-xl text-gray-600 dark:text-gray-300 '>
<div className='space-x-12 text-3xl text-gray-600 dark:text-gray-300 '>
{BLOG.CONTACT_GITHUB && <a target='_blank' rel='noreferrer' title={'github'} href={BLOG.CONTACT_GITHUB} >
<i className='transform hover:scale-125 duration-150 fab fa-github dark:hover:text-indigo-400 hover:text-indigo-600'/>
</a>}

View File

@@ -1,159 +0,0 @@
import { useGlobal } from '@/lib/global'
import Link from 'next/link'
import { useCallback, useEffect, useRef, useState } from 'react'
import CategoryGroup from './CategoryGroup'
import Logo from './Logo'
import SearchDrawer from './SearchDrawer'
import TagGroups from './TagGroups'
import { MenuListTop } from './MenuListTop'
import { useRouter } from 'next/router'
import throttle from 'lodash.throttle'
import SideBar from './SideBar'
import SideBarDrawer from './SideBarDrawer'
let windowTop = 0
/**
* 顶部导航
* @param {*} param0
* @returns
*/
const TopNav = props => {
const searchDrawer = useRef()
const { tags, currentTag, categories, currentCategory } = props
const { locale } = useGlobal()
const { isDarkMode } = useGlobal()
const router = useRouter()
const [isOpen, changeShow] = useState(false)
const toggleMenuOpen = () => {
changeShow(!isOpen)
}
const toggleSideBarClose = () => {
changeShow(false)
}
// 监听滚动
useEffect(() => {
scrollTrigger()
window.addEventListener('scroll', scrollTrigger)
return () => {
window.removeEventListener('scroll', scrollTrigger)
}
}, [])
const throttleMs = 200
const scrollTrigger = useCallback(throttle(() => {
const scrollS = window.scrollY
const nav = document.querySelector('#sticky-nav')
const header = document.querySelector('#header')
// 是否将导航栏透明
const navTransparent = (scrollS < document.documentElement.clientHeight - 12 && router.route === '/') || scrollS < 300 // 透明导航条的条件
if (header && navTransparent) {
nav && nav.classList.replace('bg-white', 'bg-none')
nav && nav.classList.replace('text-black', 'text-white')
nav && nav.classList.replace('border', 'border-transparent')
nav && nav.classList.replace('drop-shadow-md', 'shadow-none')
nav && nav.classList.replace('dark:bg-hexo-black-gray', 'transparent')
} else {
nav && nav.classList.replace('bg-none', 'bg-white')
nav && nav.classList.replace('text-white', 'text-black')
nav && nav.classList.replace('border-transparent', 'border')
nav && nav.classList.replace('shadow-none', 'drop-shadow-md')
nav && nav.classList.replace('transparent', 'dark:bg-hexo-black-gray')
}
const showNav = scrollS <= windowTop || scrollS < 5 || (header && scrollS <= header.clientHeight)// 非首页无大图时影藏顶部 滚动条置顶时隐藏
if (!showNav) {
nav && nav.classList.replace('top-0', '-top-20')
windowTop = scrollS
} else {
nav && nav.classList.replace('-top-20', 'top-0')
windowTop = scrollS
}
navDarkMode()
}, throttleMs)
)
const navDarkMode = () => {
const nav = document.getElementById('sticky-nav')
const header = document.querySelector('#header')
if (!isDarkMode && nav && header) {
if (window.scrollY < header.clientHeight) {
nav?.classList?.add('dark')
} else {
nav?.classList?.remove('dark')
}
}
}
const searchDrawerSlot = <>
{categories && (
<section className='mt-8'>
<div className='text-sm flex flex-nowrap justify-between font-light px-2'>
<div className='text-gray-600 dark:text-gray-200'><i className='mr-2 fas fa-th-list' />{locale.COMMON.CATEGORY}</div>
<Link
href={'/category'}
passHref
className='mb-3 text-gray-400 hover:text-black dark:text-gray-400 dark:hover:text-white hover:underline cursor-pointer'>
{locale.COMMON.MORE} <i className='fas fa-angle-double-right' />
</Link>
</div>
<CategoryGroup currentCategory={currentCategory} categories={categories} />
</section>
)}
{tags && (
<section className='mt-4'>
<div className='text-sm py-2 px-2 flex flex-nowrap justify-between font-light dark:text-gray-200'>
<div className='text-gray-600 dark:text-gray-200'><i className='mr-2 fas fa-tag' />{locale.COMMON.TAGS}</div>
<Link
href={'/tag'}
passHref
className='text-gray-400 hover:text-black dark:hover:text-white hover:underline cursor-pointer'>
{locale.COMMON.MORE} <i className='fas fa-angle-double-right' />
</Link>
</div>
<div className='p-2'>
<TagGroups tags={tags} currentTag={currentTag} />
</div>
</section>
)}
</>
return (<div id='top-nav' className='z-40'>
<SearchDrawer cRef={searchDrawer} slot={searchDrawerSlot} />
{/* 导航栏 */}
<div id='sticky-nav' style={{ backdropFilter: 'blur(3px)' }} className={'top-0 duration-300 transition-all shadow-none fixed bg-none dark:bg-hexo-black-gray dark:text-gray-200 text-black w-full z-20 transform border-transparent dark:border-transparent'}>
<div className='w-full flex justify-between items-center px-4 py-2'>
<div className='flex'>
<Logo {...props} />
</div>
{/* 右侧功能 */}
<div className='mr-1 justify-end items-center '>
<div className='hidden lg:flex'> <MenuListTop {...props} /></div>
<div onClick={toggleMenuOpen} className='w-8 justify-center items-center h-8 cursor-pointer flex lg:hidden'>
{isOpen ? <i className='fas fa-times' /> : <i className='fas fa-bars' />}
</div>
</div>
</div>
</div>
{/* 折叠侧边栏 */}
<SideBarDrawer isOpen={isOpen} onClose={toggleSideBarClose}>
<SideBar {...props} />
</SideBarDrawer>
</div>)
}
export default TopNav

View File

@@ -4,21 +4,20 @@ import CommonHead from '@/components/CommonHead'
import { useEffect, useRef } from 'react'
import Footer from './components/Footer'
import SideRight from './components/SideRight'
import TopNav from './components/TopNav'
import Header from './components/Header'
import { useGlobal } from '@/lib/global'
import BLOG from '@/blog.config'
import { isBrowser, loadExternalResource } from '@/lib/utils'
import BlogPostListPage from './components/BlogPostListPage'
import BlogPostListScroll from './components/BlogPostListScroll'
import Hero from './components/Header'
import Hero from './components/Hero'
import { useRouter } from 'next/router'
import Mark from 'mark.js'
import Card from './components/Card'
import RightFloatArea from './components/RightFloatArea'
import SearchNav from './components/SearchNav'
import BlogPostArchive from './components/BlogPostArchive'
import { ArticleLock } from './components/ArticleLock'
import HeaderArticle from './components/HeaderArticle'
import PostHeader from './components/PostHeader'
import JumpToCommentButton from './components/JumpToCommentButton'
import TocDrawer from './components/TocDrawer'
import TocDrawerButton from './components/TocDrawerButton'
@@ -30,7 +29,7 @@ import ArticleRecommend from './components/ArticleRecommend'
import ShareBar from '@/components/ShareBar'
import TagItemMini from './components/TagItemMini'
import Link from 'next/link'
import SlotBar from './components/SlotBar'
import CategoryBar from './components/CategoryBar'
import { Transition } from '@headlessui/react'
/**
@@ -40,7 +39,7 @@ import { Transition } from '@headlessui/react'
* @constructor
*/
const LayoutBase = props => {
const { children, headerSlot, floatSlot, slotTop, meta, siteInfo, className } = props
const { children, headerSlot, slotTop, meta, siteInfo, className } = props
const { onLoading } = useGlobal()
// 加载主题样式
@@ -49,14 +48,14 @@ const LayoutBase = props => {
}
return (
<div id='theme-hexo'>
<div id='theme-heo' className='bg-[#f7f9fe]'>
{/* 网页SEO */}
<CommonHead meta={meta} siteInfo={siteInfo} />
{/* 顶部导航 */}
<TopNav {...props} />
<Header {...props} />
{/* 顶部嵌入 */}
{/* 顶部嵌入 首页放hero文章页放大图 */}
<Transition
show={!onLoading}
appear={true}
@@ -72,9 +71,9 @@ const LayoutBase = props => {
</Transition>
{/* 主区块 */}
<main id="wrapper" className={`${CONFIG.HOME_BANNER_ENABLE ? '' : 'pt-16'} bg-hexo-background-gray dark:bg-black w-full py-8 md:px-8 lg:px-24 min-h-screen relative`}>
<main id="wrapper-outer" className={'w-full max-w-7xl mx-auto min-h-screen relative px-5'}>
<div id="container-inner" className={(BLOG.LAYOUT_SIDEBAR_REVERSE ? 'flex-row-reverse' : '') + ' w-full mx-auto lg:flex lg:space-x-4 justify-center relative z-10'} >
<div className={`${className || ''} w-full max-w-4xl h-full `}>
<div className={`${className || ''} w-full h-full`}>
<Transition
show={!onLoading}
@@ -99,9 +98,6 @@ const LayoutBase = props => {
</div>
</main>
{/* 悬浮菜单 */}
<RightFloatArea floatSlot={floatSlot} />
{/* 页脚 */}
<Footer title={siteInfo?.title || BLOG.TITLE} />
</div>
@@ -116,7 +112,7 @@ const LayoutBase = props => {
*/
const LayoutIndex = (props) => {
const headerSlot = CONFIG.HOME_BANNER_ENABLE && <Hero {...props} />
return <LayoutPostList {...props} headerSlot={headerSlot} className='pt-8' />
return <LayoutPostList {...props} headerSlot={headerSlot}/>
}
/**
@@ -125,8 +121,8 @@ const LayoutIndex = (props) => {
* @returns
*/
const LayoutPostList = (props) => {
return <LayoutBase {...props} className='pt-8'>
<SlotBar {...props} />
return <LayoutBase {...props}>
<CategoryBar {...props} />
{BLOG.POST_LIST_STYLE === 'page' ? <BlogPostListPage {...props} /> : <BlogPostListScroll {...props} />}
</LayoutBase>
}
@@ -213,7 +209,7 @@ const LayoutSlug = props => {
</>
return (
<LayoutBase {...props} headerSlot={<HeaderArticle {...props} />} showCategory={false} showTag={false} floatSlot={floatSlot} >
<LayoutBase {...props} headerSlot={<PostHeader {...props} />} showCategory={false} showTag={false} floatSlot={floatSlot} >
<div className="w-full lg:hover:shadow lg:border rounded-t-xl lg:rounded-xl lg:px-2 lg:py-4 bg-white dark:bg-hexo-black-gray dark:border-black article">
{lock && <ArticleLock validPassword={validPassword} />}

View File

@@ -4,7 +4,7 @@ import { useGlobal } from '@/lib/global'
import BLOG from '@/blog.config'
import NotionIcon from '@/components/NotionIcon'
export default function HeaderArticle({ post, siteInfo }) {
export default function PostHeader({ post, siteInfo }) {
const { locale } = useGlobal()
if (!post) {

View File

@@ -10,7 +10,7 @@ import BLOG from '@/blog.config'
import { isBrowser, loadExternalResource } from '@/lib/utils'
import BlogPostListPage from './components/BlogPostListPage'
import BlogPostListScroll from './components/BlogPostListScroll'
import Hero from './components/Header'
import Hero from './components/Hero'
import { useRouter } from 'next/router'
import Mark from 'mark.js'
import Card from './components/Card'
@@ -18,7 +18,7 @@ import RightFloatArea from './components/RightFloatArea'
import SearchNav from './components/SearchNav'
import BlogPostArchive from './components/BlogPostArchive'
import { ArticleLock } from './components/ArticleLock'
import HeaderArticle from './components/HeaderArticle'
import PostHeader from './components/PostHeader'
import JumpToCommentButton from './components/JumpToCommentButton'
import TocDrawer from './components/TocDrawer'
import TocDrawerButton from './components/TocDrawerButton'
@@ -213,7 +213,7 @@ const LayoutSlug = props => {
</>
return (
<LayoutBase {...props} headerSlot={<HeaderArticle {...props} />} showCategory={false} showTag={false} floatSlot={floatSlot} >
<LayoutBase {...props} headerSlot={<PostHeader {...props} />} showCategory={false} showTag={false} floatSlot={floatSlot} >
<div className="w-full lg:hover:shadow lg:border rounded-t-xl lg:rounded-xl lg:px-2 lg:py-4 bg-white dark:bg-hexo-black-gray dark:border-black article">
{lock && <ArticleLock validPassword={validPassword} />}

View File

@@ -1,6 +1,9 @@
import Image from 'next/image'
export default function HeaderArticle({ post, siteInfo }) {
/**
* 文章背景图
*/
export default function PostHeader({ post, siteInfo }) {
const headerImage = post?.pageCoverThumbnail ? post?.pageCoverThumbnail : siteInfo?.pageCover
const title = post?.title
return (

View File

@@ -17,7 +17,7 @@ import Hero from './components/Hero'
import Announcement from './components/Announcement'
import CatalogWrapper from './components/CatalogWrapper'
import TagItemMiddle from './components/TagItemMiddle'
import HeaderArticle from './components/HeaderArticle'
import PostHeader from './components/PostHeader'
import Link from 'next/link'
import ArticleAdjacent from './components/ArticleAdjacent'
import Comment from '@/components/Comment'
@@ -177,7 +177,7 @@ const LayoutSearch = props => {
*/
const LayoutArchive = (props) => {
const { archivePosts } = props
return <LayoutBase {...props} headerSlot={<HeaderArticle {...props} />} >
return <LayoutBase {...props} headerSlot={<PostHeader {...props} />} >
<Card className='w-full -mt-32'>
<div className="mb-10 pb-20 bg-white md:p-12 p-3 min-h-full dark:bg-hexo-black-gray">
{Object.keys(archivePosts).map(archiveTitle => (
@@ -200,7 +200,7 @@ const LayoutArchive = (props) => {
const LayoutSlug = props => {
const { post, lock, validPassword } = props
return (<LayoutBase {...props} headerSlot={<HeaderArticle {...props} />} showCategory={false} showTag={false} floatRightBottom={<JumpToCommentButton />}>
return (<LayoutBase {...props} headerSlot={<PostHeader {...props} />} showCategory={false} showTag={false} floatRightBottom={<JumpToCommentButton />}>
<div id='inner-wrapper' className={'w-full lg:max-w-3xl 2xl:max-w-4xl'} >
@@ -310,7 +310,7 @@ const LayoutCategoryIndex = props => {
const { categoryOptions } = props
return (
<LayoutBase {...props} headerSlot={<HeaderArticle {...props} />} >
<LayoutBase {...props} headerSlot={<PostHeader {...props} />} >
<div id='inner-wrapper' className='w-full'>
<div className="drop-shadow-xl -mt-32 rounded-md mx-3 px-5 lg:border lg:rounded-xl lg:px-2 lg:py-4 bg-white dark:bg-hexo-black-gray dark:border-black dark:text-gray-300">
@@ -340,7 +340,7 @@ const LayoutTagIndex = props => {
const { tagOptions } = props
const { locale } = useGlobal()
return (
<LayoutBase {...props} headerSlot={<HeaderArticle {...props} />} >
<LayoutBase {...props} headerSlot={<PostHeader {...props} />} >
<div id='inner-wrapper' className='w-full drop-shadow-xl'>
<div className="-mt-32 rounded-md mx-3 px-5 lg:border lg:rounded-xl lg:px-2 lg:py-4 bg-white dark:bg-hexo-black-gray dark:border-black">

View File

@@ -23,7 +23,7 @@ const BlogPost = ({ post }) => {
</article>
</Link>)
);
)
}
export default BlogPost