magzine基本组件

This commit is contained in:
tangly1024.com
2024-09-13 12:54:25 +08:00
parent 4ca437b93f
commit 625b08b787
31 changed files with 572 additions and 227 deletions

View File

@@ -1664,9 +1664,8 @@ code[class*='language-'] {
}
/* NOTION CSS OVERRIDE */
.notion {
@apply dark:text-gray-300;
@apply dark:text-gray-100;
overflow-wrap: break-word;
}
.notion,

View File

@@ -10,7 +10,7 @@ const Announcement = ({ post, className }) => {
<div className={className}>
<section
id='announcement-wrapper'
className='dark:text-gray-300 rounded-xl px-2 py-4'>
className='dark:text-gray-300 rounded-xl px-2'>
{/* <div><i className='mr-2 fas fa-bullhorn' />{locale.COMMON.ANNOUNCEMENT}</div> */}
{post && (
<div id='announcement-content'>

View File

@@ -5,7 +5,7 @@ import Link from 'next/link'
* @param {*} param0
* @returns
*/
export default function BlogArchiveItem({ archiveTitle, archivePosts }) {
export default function ArchiveItem({ archiveTitle, archivePosts }) {
return (
<div key={archiveTitle}>
<div id={archiveTitle} className='pt-16 pb-4 text-3xl dark:text-gray-300'>

View File

@@ -32,7 +32,7 @@ export default function ArticleInfo(props) {
<i className='far fa-calendar-check mr-2' />
{post?.lastEditedDay}
</span>
<div className='hidden busuanzi_container_page_pv font-light mr-2 whitespace-nowrap'>
<div className='hidden busuanzi_container_page_pv mr-2 whitespace-nowrap'>
<i className='mr-1 fas fa-eye' />
<span className='busuanzi_value_page_pv' />
</div>

View File

@@ -45,7 +45,7 @@ export const ArticleLock = props => {
}
}}
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>
className='outline-none w-full text-sm pl-5 rounded-l transition focus:shadow-lg dark:text-gray-300 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-gray-500 hover:bg-gray-400 text-white rounded-r duration-300'>

View File

@@ -1,14 +0,0 @@
import { useGlobal } from '@/lib/global'
/**
* 空白博客 列表
* @returns {JSX.Element}
* @constructor
*/
const BlogPostListEmpty = ({ currentSearch }) => {
const { locale } = useGlobal()
return <div className='flex w-full items-center justify-center min-h-screen mx-auto md:-mt-20'>
<p className='text-gray-500 dark:text-gray-300'>{locale.COMMON.NO_RESULTS_FOUND} {(currentSearch && <div>{currentSearch}</div>)}</p>
</div>
}
export default BlogPostListEmpty

View File

@@ -77,7 +77,7 @@ const Catalog = ({ toc }) => {
<a
key={id}
href={`#${id}`}
className={`notion-table-of-contents-item duration-300 transform font-light dark:text-gray-300
className={`notion-table-of-contents-item duration-300 transform dark:text-gray-300
notion-table-of-contents-item-indent-level-${tocItem.indentLevel} `}>
<span
style={{

View File

@@ -8,13 +8,13 @@ export default function CategoryItem({ selected, category, categoryCount }) {
className={
(selected
? ' bg-gray-600 text-white '
: 'dark:text-gray-400 text-gray-500 ') +
' flex text-sm items-center duration-300 cursor-pointer py-1 font-light px-2 whitespace-nowrap'
: 'dark:text-gray-400 text-gray-900 ') +
' hover:underline flex text-sm items-center duration-300 cursor-pointer py-1 whitespace-nowrap'
}>
<div>
<i
{/* <i
className={`mr-2 fas ${selected ? 'fa-folder-open' : 'fa-folder'}`}
/>
/> */}
{category} {categoryCount && `(${categoryCount})`}
</div>
</Link>

View File

@@ -1,28 +1,56 @@
import DarkModeButton from '@/components/DarkModeButton'
import { siteConfig } from '@/lib/config'
import SocialButton from './SocialButton'
const Footer = ({ title }) => {
const d = new Date()
const currentYear = d.getFullYear()
const since = siteConfig('SINCE')
const copyrightDate = parseInt(since) < currentYear ? since + '-' + currentYear : currentYear
const copyrightDate =
parseInt(since) < currentYear ? since + '-' + currentYear : currentYear
return (
<footer
className='z-10 dark:bg-hexo-black-gray flex-shrink-0 justify-center text-center m-auto w-full leading-6 text-sm p-6 relative'
>
<DarkModeButton/>
<i className='fas fa-copyright' /> {`${copyrightDate}`} <span><i className='mx-1 animate-pulse fas fa-heart'/> <a href={siteConfig('LINK')} className='underline font-bold text-gray-500 dark:text-gray-300 '>{siteConfig('AUTHOR')}</a>.<br/>
{siteConfig('BEI_AN') && <><i className='fas fa-shield-alt'/> <a href='https://beian.miit.gov.cn/' className='mr-2'>{siteConfig('BEI_AN')}</a><br/></>}
<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>
<br/>
<footer className='z-10 bg-black text-white flex-shrink-0 justify-center text-center m-auto w-full leading-6 text-sm p-6 relative'>
<DarkModeButton />
<i className='fas fa-copyright' /> {`${copyrightDate}`}{' '}
<span>
<i className='mx-1 animate-pulse fas fa-heart' />{' '}
<a
href={siteConfig('LINK')}
className='underline font-bold justify-start '>
{siteConfig('AUTHOR')}
</a>
.<br />
{siteConfig('BEI_AN') && (
<>
<i className='fas fa-shield-alt' />{' '}
<a href='https://beian.miit.gov.cn/' className='mr-2'>
{siteConfig('BEI_AN')}
</a>
<br />
</>
)}
<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>
<br />
<h1>{title}</h1>
<span className='text-xs font-serif'>Powered by <a href='https://github.com/tangly1024/NotionNext' className='underline text-gray-500 dark:text-gray-300'>NotionNext {siteConfig('VERSION')}</a>.</span></span>
<span className='text-xs font-serif'>
Powered by{' '}
<a
href='https://github.com/tangly1024/NotionNext'
className='underline justify-start text-white'>
NotionNext {siteConfig('VERSION')}
</a>
.
</span>
</span>
<SocialButton />
</footer>
)
}

View File

@@ -17,6 +17,7 @@ export default function Header(props) {
const { customNav, customMenu } = props
const [isOpen, changeShow] = useState(false)
const collapseRef = useRef(null)
const lastScrollY = useRef(0) // 用于存储上一次的滚动位置
const { locale } = useGlobal()
@@ -66,16 +67,39 @@ export default function Header(props) {
const scrollTrigger = throttle(() => {
const scrollS = window.scrollY
const nav = document.querySelector('#top-navbar')
if (scrollS === lastScrollY.current) return // 如果滚动位置没有变化,则不做任何操作
const narrowNav = scrollS > 50
const nav = document.querySelector('#top-navbar')
const narrowNav = scrollS > 60
if (narrowNav) {
nav && nav.classList.replace('h-20', 'h-14')
} else {
nav && nav.classList.replace('h-14', 'h-20')
}
lastScrollY.current = scrollS // 更新上一次的滚动位置
}, throttleMs)
const [showSearchInput, changeShowSearchInput] = useState(false)
// 展示搜索框
const toggleShowSearchInput = () => {
if (siteConfig('ALGOLIA_APP_ID')) {
searchModal.current.openSearch()
} else {
changeShowSearchInput(!showSearchInput)
}
}
const onKeyUp = e => {
if (e.keyCode === 13) {
const search = document.getElementById('simple-search').value
if (search) {
router.push({ pathname: '/search/' + search })
}
}
}
// 如果 开启自定义菜单则覆盖Page生成的菜单
if (siteConfig('CUSTOM_MENU')) {
links = customMenu
@@ -94,25 +118,61 @@ export default function Header(props) {
{/* 导航栏菜单内容 */}
<div
id='top-navbar'
className='px-4 flex w-full mx-auto max-w-screen-xl h-20 transition-all duration-200 items-between'>
{/* 左侧图标Logo */}
<LogoBar {...props} />
className='flex w-full mx-auto max-w-7xl h-20 transition-all duration-200 items-center justify-between'>
{/* 搜索栏 */}
{showSearchInput && (
<input
autoFocus
id='simple-search'
onKeyUp={onKeyUp}
className='outline-none flex flex-row text-base relative w-full border-b py-2'
aria-label='Submit search'
type='search'
name='s'
autoComplete='off'
placeholder='Type then hit enter to search...'
/>
)}
{/* 移动端折叠按钮 */}
<div className='mr-1 flex md:hidden justify-end items-center text-lg space-x-4 font-serif dark:text-gray-200'>
<div onClick={toggleMenuOpen} className='cursor-pointer'>
{isOpen ? (
<i className='fas fa-times' />
) : (
<i className='fas fa-bars' />
)}
{/* 默认菜单 */}
{!showSearchInput && (
<>
{/* 左侧图标Logo */}
<div className='flex gap-x-8 h-full'>
<LogoBar {...props} />
{/* 桌面端顶部菜单 */}
<div className='hidden md:flex items-center gap-x-2'>
{links &&
links?.map(link => (
<MenuItemDrop key={link?.id} link={link} />
))}
</div>
</div>
</>
)}
{/* 右侧移动端折叠按钮 */}
<div className='flex items-center gap-x-2'>
<div className='mr-1 flex md:hidden justify-end items-center text-lg space-x-4 font-serif dark:text-gray-200'>
<div onClick={toggleMenuOpen} className='cursor-pointer'>
{isOpen ? (
<i className='fas fa-times' />
) : (
<i className='fas fa-bars' />
)}
</div>
</div>
</div>
{/* 桌面端顶部菜单 */}
<div className='hidden md:flex items-center'>
{links &&
links?.map(link => <MenuItemDrop key={link?.id} link={link} />)}
{/* 搜索按钮 */}
<div className='text-center items-center cursor-pointer'>
<i
className={
showSearchInput
? 'fa-regular fa-circle-xmark'
: 'fa-solid fa-magnifying-glass' + ' align-middle'
}
onClick={toggleShowSearchInput}></i>
</div>
</div>
</div>

View File

@@ -0,0 +1,62 @@
// import { useGlobal } from '@/lib/global'
import { siteConfig } from '@/lib/config'
import Link from 'next/link'
import PostItemCardTop from './PostItemCardTop'
import PostItemCardWide from './PostItemCardWide'
/**
* 首页主宣传
* @param {*} param0
* @returns
*/
const Hero = ({ posts }) => {
// 获取置顶文章与次要文章
const postTop = posts[0]
const post1 = posts[1]
const post2 = posts[2]
// 首屏信息栏按钮文字
const banner = siteConfig('MAGZINE_HOME_BANNER_ENABLE')
const button = siteConfig('MAGZINE_HOME_BUTTON')
const text = siteConfig('MAGZINE_HOME_BUTTON_TEXT')
const url = siteConfig('MAGZINE_HOME_BUTTON_URL')
const title = siteConfig('MAGZINE_HOME_TITLE')
const description = siteConfig('MAGZINE_HOME_DESCRIPTION')
const tips = siteConfig('MAGZINE_HOME_TIPS')
return (
<>
<div className='w-full mx-auto max-w-7xl xl:flex justify-between'>
{/* 左侧一篇主要置顶文章 */}
<div className='basis-1/2 mb-6'>
<PostItemCardTop post={postTop} />
</div>
{/* 右侧 */}
<div>
{/* 首屏介绍 */}
{banner && (
<div className='flex flex-col p-5 gap-y-5 dark items-center justify-between w-full bg-black text-white'>
{/* 首屏导航按钮 */}
<h2 className='text-2xl font-semibold'>{title}</h2>
<h3 className='text-sm'>{description}</h3>
{button && (
<div className='mt-2 text-center px-6 py-3 font-semibold rounded-3xl text-black bg-[#7BE986] hover:bg-[#62BA6B]'>
<Link href={url}>{text}</Link>
</div>
)}
<span className='text-xs'>{tips}</span>
</div>
)}
{/* 两篇次要文章 */}
<div className='py-4'>
<hr className='mb-8' />
<PostItemCardWide post={post1} />
<hr className='mb-8' />
<PostItemCardWide post={post2} />
</div>
</div>
</div>
</>
)
}
export default Hero

View File

@@ -1,7 +1,5 @@
import LazyImage from '@/components/LazyImage'
import { siteConfig } from '@/lib/config'
import Router from 'next/router'
import SocialButton from './SocialButton'
/**
* 用户信息卡
@@ -10,8 +8,9 @@ import SocialButton from './SocialButton'
*/
const InfoCard = props => {
const { siteInfo } = props
return (
<div id='info-card' className='py-4'>
<div id='info-card'>
<div className='items-center justify-start'>
<div
className='hover:scale-105 transform duration-200 cursor-pointer flex justify-start'
@@ -24,13 +23,12 @@ const InfoCard = props => {
alt={siteConfig('AUTHOR')}
/>
</div>
<div className='text-xl py-2 hover:scale-105 transform duration-200 flex justify-start dark:text-gray-300'>
<div className='text-xl py-2 hover:scale-105 transform duration-200 flex justify-start '>
{siteConfig('AUTHOR')}
</div>
<div className='font-light text-gray-600 mb-2 hover:scale-105 transform duration-200 flex justify-start dark:text-gray-400'>
<div className='text-gray-100 mb-2 hover:scale-105 transform duration-200 flex justify-start'>
{siteConfig('BIO')}
</div>
<SocialButton />
</div>
</div>
)

View File

@@ -1,5 +1,5 @@
import CONFIG from '../config'
import { siteConfig } from '@/lib/config'
import CONFIG from '../config'
/**
* 跳转到网页顶部
@@ -10,18 +10,23 @@ import { siteConfig } from '@/lib/config'
* @constructor
*/
const JumpToTopButton = ({ showPercent = false, percent, className }) => {
if (!siteConfig('MEDIUM_WIDGET_TO_TOP', null, CONFIG)) {
if (!siteConfig('MAGZINE_WIDGET_TO_TOP', null, CONFIG)) {
return <></>
}
return (
<div
id="jump-to-top"
data-aos="fade-up"
data-aos-duration="300"
data-aos-once="false"
data-aos-anchor-placement="top-center"
className='fixed xl:right-80 right-2 mr-10 bottom-24 z-20'>
<i className='fas fa-chevron-up cursor-pointer p-2 rounded-full border bg-white dark:bg-hexo-black-gray' onClick={() => { window.scrollTo({ top: 0, behavior: 'smooth' }) }} />
id='jump-to-top'
data-aos='fade-up'
data-aos-duration='300'
data-aos-once='false'
data-aos-anchor-placement='top-center'
className='fixed xl:right-80 right-2 mr-10 bottom-24 z-20'>
<i
className='fas fa-chevron-up cursor-pointer p-2 rounded-full border bg-white dark:bg-hexo-black-gray'
onClick={() => {
window.scrollTo({ top: 0, behavior: 'smooth' })
}}
/>
</div>
)
}

View File

@@ -5,7 +5,9 @@ export default function LogoBar(props) {
const { siteInfo } = props
return (
<div id='top-wrapper' className='w-full flex items-center '>
<Link href='/' className='flex text-md md:text-xl dark:text-gray-200'>
<Link
href='/'
className='flex text-md font-semibold md:text-xl hover:bg-black hover:text-white p-2 rounded-xl duration-200 dark:text-gray-200'>
{/* <LazyImage
src={siteInfo?.icon}
width={24}

View File

@@ -12,17 +12,17 @@ export const MenuBarMobile = props => {
{
name: locale.COMMON.CATEGORY,
href: '/category',
show: siteConfig('MEDIUM_MENU_CATEGORY', null, CONFIG)
show: siteConfig('MAGZINE_MENU_CATEGORY', null, CONFIG)
},
{
name: locale.COMMON.TAGS,
href: '/tag',
show: siteConfig('MEDIUM_MENU_TAG', null, CONFIG)
show: siteConfig('MAGZINE_MENU_TAG', null, CONFIG)
},
{
name: locale.NAV.ARCHIVE,
href: '/archive',
show: siteConfig('MEDIUM_MENU_ARCHIVE', null, CONFIG)
show: siteConfig('MAGZINE_MENU_ARCHIVE', null, CONFIG)
}
// { name: locale.NAV.SEARCH, href: '/search', show: siteConfig('MENU_SEARCH', null, CONFIG) }
]

View File

@@ -16,22 +16,22 @@ export const MenuItemDrop = ({ link }) => {
return (
<li
className='cursor-pointer list-none items-center flex mx-2'
className='cursor-pointer list-none items-center h-full'
onMouseOver={() => changeShow(true)}
onMouseOut={() => changeShow(false)}>
{hasSubMenu && (
<div
className={
'px-3 h-full whitespace-nowrap duration-300 text-sm justify-between dark:text-gray-300 cursor-pointer flex flex-nowrap items-center ' +
'h-full whitespace-nowrap duration-300 text-md justify-between dark:text-gray-300 cursor-pointer flex flex-nowrap items-center ' +
(selected
? 'bg-gray-600 text-white hover:text-white'
: 'hover:text-gray-600')
}>
<div>
<div className='items-center flex gap-x-1'>
{link?.icon && <i className={link?.icon} />} {link?.name}
{hasSubMenu && (
<i
className={`px-2 fas fa-chevron-down duration-500 transition-all ${show ? ' rotate-180' : ''}`}></i>
className={`px-1 fas fa-chevron-down duration-500 transition-all ${show ? ' rotate-180' : ''}`}></i>
)}
</div>
</div>
@@ -40,7 +40,7 @@ export const MenuItemDrop = ({ link }) => {
{!hasSubMenu && (
<div
className={
'px-3 h-full whitespace-nowrap duration-300 text-sm justify-between dark:text-gray-300 cursor-pointer flex flex-nowrap items-center ' +
'px-3 gap-x-1 h-full whitespace-nowrap duration-300 text-sm justify-between dark:text-gray-300 cursor-pointer flex flex-nowrap items-center ' +
(selected
? 'bg-gray-600 text-white hover:text-white'
: 'hover:text-gray-600')
@@ -54,14 +54,14 @@ export const MenuItemDrop = ({ link }) => {
{/* 子菜单 */}
{hasSubMenu && (
<ul
className={`${show ? 'visible opacity-100 top-12 ' : 'invisible opacity-0 top-10 '} border-gray-100 bg-white dark:bg-black dark:border-gray-800 transition-all duration-300 z-20 absolute block drop-shadow-lg `}>
className={`${show ? 'visible opacity-100 top-14 ' : 'invisible opacity-0 top-10 '} absolute border bg-white dark:bg-black dark:border-gray-800 transition-all duration-300 z-20 block rounded-lg drop-shadow-lg p-4 `}>
{link?.subMenus?.map(sLink => {
return (
<li
key={sLink.id}
className='not:last-child:border-b-0 border-b text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200 dark:border-gray-800 py-3 pr-6 pl-3'>
className='text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200 dark:border-gray-800 py-3 pr-6 pl-3'>
<Link href={sLink.href} target={link?.target}>
<span className='text-xs font-extralight'>
<span className='text-sm hover:underline'>
{link?.icon && <i className={sLink?.icon}> &nbsp; </i>}
{sLink.title}
</span>

View File

@@ -9,9 +9,9 @@ import CONFIG from '../config'
import CategoryItem from './CategoryItem'
import TagItemMini from './TagItemMini'
const BlogPostCard = ({ post, showSummary }) => {
const PostItemCard = ({ post, showSummary }) => {
const showPreview =
siteConfig('MEDIUM_POST_LIST_PREVIEW', null, CONFIG) && post.blockMap
siteConfig('MAGZINE_POST_LIST_PREVIEW', null, CONFIG) && post.blockMap
const { locale } = useGlobal()
return (
<div
@@ -29,7 +29,7 @@ const BlogPostCard = ({ post, showSummary }) => {
'cursor-pointer font-bold hover:underline text-3xl leading-tight text-gray-700 dark:text-gray-300 hover:text-gray-500 dark:hover:text-gray-400'
}>
<h2>
{siteConfig('MEDIUM_POST_LIST_COVER', null, CONFIG) && (
{siteConfig('MAGZINE_POST_LIST_COVER', null, CONFIG) && (
<div className='w-full max-h-96 object-cover overflow-hidden mb-2'>
<LazyImage
src={post.pageCoverThumbnail}
@@ -50,10 +50,10 @@ const BlogPostCard = ({ post, showSummary }) => {
'flex mt-2 items-center justify-start flex-wrap space-x-3 text-gray-400'
}>
<div className='text-sm py-1'>{post.date?.start_date}</div>
{siteConfig('MEDIUM_POST_LIST_CATEGORY', null, CONFIG) && (
{siteConfig('MAGZINE_POST_LIST_CATEGORY', null, CONFIG) && (
<CategoryItem category={post.category} />
)}
{siteConfig('MEDIUM_POST_LIST_TAG', null, CONFIG) &&
{siteConfig('MAGZINE_POST_LIST_TAG', null, CONFIG) &&
post?.tagItems?.map(tag => (
<TagItemMini key={tag.name} tag={tag} />
))}
@@ -63,7 +63,7 @@ const BlogPostCard = ({ post, showSummary }) => {
<div className='flex'></div>
{(!showPreview || showSummary) && (
<main className='my-4 text-gray-700 dark:text-gray-300 text-sm font-light leading-7'>
<main className='my-4 text-gray-700 dark:text-gray-300 text-sm leading-7'>
{post.summary}
</main>
)}
@@ -89,4 +89,4 @@ const BlogPostCard = ({ post, showSummary }) => {
)
}
export default BlogPostCard
export default PostItemCard

View File

@@ -0,0 +1,45 @@
import NotionIcon from '@/components/NotionIcon'
import { siteConfig } from '@/lib/config'
import { useGlobal } from '@/lib/global'
import Link from 'next/link'
import CONFIG from '../config'
import CategoryItem from './CategoryItem'
/**
* 不带图片
* @param {*} param0
* @returns
*/
const PostItemCardSimple = ({ post, showSummary }) => {
const showPreview =
siteConfig('MAGZINE_POST_LIST_PREVIEW', null, CONFIG) && post.blockMap
const { locale } = useGlobal()
return (
<div
key={post.id}
className='mb-6 max-w-7xl border-t mr-8 py-2 gap-y-4 flex flex-col dark:border-gray-800 '>
<div className='flex mr-2 items-center'>
{siteConfig('MAGZINE_POST_LIST_CATEGORY', null, CONFIG) && (
<CategoryItem category={post.category} />
)}
</div>
{/* 文章标题 */}
<Link
href={post?.href}
passHref
className={
'cursor-pointer hover:underline text-lg leading-tight dark:text-gray-300 dark:hover:text-gray-400'
}>
<h2>
{siteConfig('POST_TITLE_ICON') && <NotionIcon icon={post.pageIcon} />}
{post.title}
</h2>
</Link>
<div className='text-sm py-2 text-gray-700'>{post.date?.start_date}</div>
</div>
)
}
export default PostItemCardSimple

View File

@@ -13,9 +13,9 @@ import TagItemMini from './TagItemMini'
* @param {*} param0
* @returns
*/
const BlogPostCardTop = ({ post, showSummary }) => {
const PostItemCardTop = ({ post, showSummary }) => {
const showPreview =
siteConfig('MEDIUM_POST_LIST_PREVIEW', null, CONFIG) && post.blockMap
siteConfig('MAGZINE_POST_LIST_PREVIEW', null, CONFIG) && post.blockMap
const { locale } = useGlobal()
return (
<div
@@ -26,12 +26,12 @@ const BlogPostCardTop = ({ post, showSummary }) => {
data-aos-anchor-placement='top-bottom'
className='mb-6 max-w-7xl '>
<div className='flex flex-col w-full'>
{siteConfig('MEDIUM_POST_LIST_COVER', null, CONFIG) && (
{siteConfig('MAGZINE_POST_LIST_COVER', null, CONFIG) && (
<Link
href={post?.href}
passHref
className={
'cursor-pointer hover:underline font-bold text-3xl leading-tight dark:text-gray-300 dark:hover:text-gray-400'
'cursor-pointer hover:underline text-4xl leading-tight dark:text-gray-300 dark:hover:text-gray-400'
}>
<div className='w-full max-h-80 object-cover overflow-hidden mb-2'>
<LazyImage
@@ -43,15 +43,15 @@ const BlogPostCardTop = ({ post, showSummary }) => {
</Link>
)}
<div className='flex py-2 items-center'>
{siteConfig('MEDIUM_POST_LIST_CATEGORY', null, CONFIG) && (
<div className='flex py-2 mr-2 items-center'>
{siteConfig('MAGZINE_POST_LIST_CATEGORY', null, CONFIG) && (
<CategoryItem category={post.category} />
)}
<div
className={
'flex items-center justify-start flex-wrap space-x-3 text-gray-400'
}>
{siteConfig('MEDIUM_POST_LIST_TAG', null, CONFIG) &&
{siteConfig('MAGZINE_POST_LIST_TAG', null, CONFIG) &&
post?.tagItems?.map(tag => (
<TagItemMini key={tag.name} tag={tag} />
))}
@@ -62,9 +62,9 @@ const BlogPostCardTop = ({ post, showSummary }) => {
href={post?.href}
passHref
className={
'cursor-pointer hover:underline font-bold text-3xl leading-tight dark:text-gray-300 dark:hover:text-gray-400'
'cursor-pointer hover:underline leading-tight dark:text-gray-300 dark:hover:text-gray-400'
}>
<h2 className='text-2xl'>
<h2 className='text-4xl'>
{siteConfig('POST_TITLE_ICON') && (
<NotionIcon icon={post.pageIcon} />
)}
@@ -75,7 +75,7 @@ const BlogPostCardTop = ({ post, showSummary }) => {
<div className='flex'></div>
{(!showPreview || showSummary) && (
<main className='my-4 text-gray-700 dark:text-gray-300 text-sm font-light leading-7'>
<main className='my-4 text-gray-900 dark:text-gray-300 text-lg leading-7'>
{post.summary}
</main>
)}
@@ -103,4 +103,4 @@ const BlogPostCardTop = ({ post, showSummary }) => {
)
}
export default BlogPostCardTop
export default PostItemCardTop

View File

@@ -8,21 +8,24 @@ import CONFIG from '../config'
import CategoryItem from './CategoryItem'
import TagItemMini from './TagItemMini'
const BlogPostCardHorizontal = ({ post, showSummary }) => {
/**
* 水平左右布局的博客卡片
* @param {*} param0
* @returns
*/
const PostItemCardWide = ({ post, showSummary }) => {
const showPreview =
siteConfig('MEDIUM_POST_LIST_PREVIEW', null, CONFIG) && post.blockMap
siteConfig('MAGZINE_POST_LIST_PREVIEW', null, CONFIG) && post.blockMap
const { locale } = useGlobal()
return (
<div
key={post.id}
className='flex justify-between space-x-6 mb-6 border-top border-gray-200'>
<div key={post.id} className='flex justify-between space-x-6 mb-6 '>
{/* 卡牌左侧 */}
<div className='h-40 w-96'>
<Link
href={post?.href}
passHref
className={
' cursor-pointer font-bold hover:underline text-xl leading-tight text-gray-700 dark:text-gray-300 hover:text-gray-500 dark:hover:text-gray-400'
' cursor-pointer font-semibold hover:underline text-xl leading-tight dark:text-gray-300 dark:hover:text-gray-400'
}>
<h3 className='max-w-80 break-words'>
{siteConfig('POST_TITLE_ICON') && (
@@ -32,22 +35,8 @@ const BlogPostCardHorizontal = ({ post, showSummary }) => {
</h3>
</Link>
<div
className={
'flex mt-2 items-center justify-start flex-wrap space-x-3 text-gray-400'
}>
<div className='text-sm py-1'>{post.date?.start_date}</div>
{siteConfig('MEDIUM_POST_LIST_CATEGORY', null, CONFIG) && (
<CategoryItem category={post.category} />
)}
{siteConfig('MEDIUM_POST_LIST_TAG', null, CONFIG) &&
post?.tagItems?.map(tag => (
<TagItemMini key={tag.name} tag={tag} />
))}
</div>
{(!showPreview || showSummary) && (
<main className='my-4 line-clamp-2 text-gray-700 dark:text-gray-300 text-sm font-light leading-7'>
<main className='my-4 line-clamp-2 text-gray-900 dark:text-gray-300 text-sm'>
{post.summary}
</main>
)}
@@ -68,6 +57,20 @@ const BlogPostCardHorizontal = ({ post, showSummary }) => {
</div>
</div>
)}
<div
className={
'flex mt-2 items-center justify-start flex-wrap space-x-3 text-gray-400'
}>
{siteConfig('MAGZINE_POST_LIST_CATEGORY', null, CONFIG) && (
<CategoryItem category={post.category} />
)}
{siteConfig('MAGZINE_POST_LIST_TAG', null, CONFIG) &&
post?.tagItems?.map(tag => (
<TagItemMini key={tag.name} tag={tag} />
))}
<div className='text-sm py-1'>{post.date?.start_date}</div>
</div>
</div>
{/* 卡牌右侧图片 */}
@@ -82,4 +85,4 @@ const BlogPostCardHorizontal = ({ post, showSummary }) => {
)
}
export default BlogPostCardHorizontal
export default PostItemCardWide

View File

@@ -0,0 +1,19 @@
import { useGlobal } from '@/lib/global'
/**
* 空白博客 列表
* @returns {JSX.Element}
* @constructor
*/
const PostListEmpty = ({ currentSearch }) => {
const { locale } = useGlobal()
return (
<div className='flex w-full items-center justify-center min-h-screen mx-auto md:-mt-20'>
<p className='text-gray-500 dark:text-gray-300'>
{locale.COMMON.NO_RESULTS_FOUND}{' '}
{currentSearch && <div>{currentSearch}</div>}
</p>
</div>
)
}
export default PostListEmpty

View File

@@ -0,0 +1,38 @@
import Link from 'next/link'
import PostItemCardSimple from './PostItemCardSimple'
import PostListEmpty from './PostListEmpty'
/**
* 博文水平列表
* 含封面
* @returns {JSX.Element}
* @constructor
*/
const PostListHorizontal = ({ title, href, posts }) => {
if (!posts || posts.length === 0) {
return <PostListEmpty />
}
return (
<div className='w-full py-10 bg-[#F6F6F1]'>
<div className='max-w-7xl w-full mx-auto'>
{/* 标题 */}
<div className='flex justify-between items-center py-6'>
<h3 className='text-2xl'>{title}</h3>
<Link className='text-lg underline' href={href}>
<span>查看全部</span>
<i className='ml-2 fas fa-arrow-right' />
</Link>
</div>
{/* 列表 */}
<ul className='flex'>
{posts?.map(p => {
return <PostItemCardSimple key={p.id} post={p} />
})}
</ul>
</div>
</div>
)
}
export default PostListHorizontal

View File

@@ -1,8 +1,8 @@
import { siteConfig } from '@/lib/config'
import { useGlobal } from '@/lib/global'
import BlogPostCard from './BlogPostCard'
import BlogPostListEmpty from './BlogPostListEmpty'
import PaginationSimple from './PaginationSimple'
import PostItemCard from './PostItemCard'
import PostListEmpty from './PostListEmpty'
/**
* 文章列表分页表格
@@ -12,13 +12,13 @@ import PaginationSimple from './PaginationSimple'
* @returns {JSX.Element}
* @constructor
*/
const BlogPostListPage = ({ page = 1, posts = [], postCount }) => {
const PostListPage = ({ page = 1, posts = [], postCount }) => {
const { NOTION_CONFIG } = useGlobal()
const POSTS_PER_PAGE = siteConfig('POSTS_PER_PAGE', null, NOTION_CONFIG)
const totalPage = Math.ceil(postCount / POSTS_PER_PAGE)
if (!posts || posts.length === 0) {
return <BlogPostListEmpty />
return <PostListEmpty />
}
return (
@@ -26,7 +26,7 @@ const BlogPostListPage = ({ page = 1, posts = [], postCount }) => {
<div id='posts-wrapper'>
{/* 文章列表 */}
{posts?.map(post => (
<BlogPostCard key={post.id} post={post} />
<PostItemCard key={post.id} post={post} />
))}
</div>
<PaginationSimple page={page} totalPage={totalPage} />
@@ -34,4 +34,4 @@ const BlogPostListPage = ({ page = 1, posts = [], postCount }) => {
)
}
export default BlogPostListPage
export default PostListPage

View File

@@ -3,8 +3,8 @@ import { useGlobal } from '@/lib/global'
import throttle from 'lodash.throttle'
import { useRouter } from 'next/router'
import { useCallback, useEffect, useRef, useState } from 'react'
import BlogPostCard from './BlogPostCard'
import BlogPostListEmpty from './BlogPostListEmpty'
import PostItemCard from './PostItemCard'
import PostListEmpty from './PostListEmpty'
/**
* 博客列表滚动分页
@@ -13,7 +13,7 @@ import BlogPostListEmpty from './BlogPostListEmpty'
* @returns {JSX.Element}
* @constructor
*/
const BlogPostListScroll = ({ posts = [], currentSearch }) => {
const PostListScroll = ({ posts = [], currentSearch }) => {
const { NOTION_CONFIG } = useGlobal()
const POSTS_PER_PAGE = siteConfig('POSTS_PER_PAGE', null, NOTION_CONFIG)
const [page, updatePage] = useState(1)
@@ -67,14 +67,14 @@ const BlogPostListScroll = ({ posts = [], currentSearch }) => {
const { locale } = useGlobal()
if (!postsToShow || postsToShow.length === 0) {
return <BlogPostListEmpty currentSearch={currentSearch} />
return <PostListEmpty currentSearch={currentSearch} />
} else {
return (
<div id='posts-wrapper' ref={targetRef} className='w-full'>
{/* 文章列表 */}
<div className='space-y-1 lg:space-y-4'>
{postsToShow?.map(post => (
<BlogPostCard key={post.id} post={post} showSummary={true} />
<PostItemCard key={post.id} post={post} showSummary={true} />
))}
</div>
@@ -104,4 +104,4 @@ const getPostByPage = function (page, totalPosts, POSTS_PER_PAGE) {
return totalPosts.slice(0, POSTS_PER_PAGE * page)
}
export default BlogPostListScroll
export default PostListScroll

View File

@@ -0,0 +1,37 @@
import Link from 'next/link'
import PostItemCardSimple from './PostItemCardSimple'
import PostListEmpty from './PostListEmpty'
/**
* 博文水平列表;不带封面图
* @returns {JSX.Element}
* @constructor
*/
const PostSimpleListHorizontal = ({ title, href, posts }) => {
if (!posts || posts.length === 0) {
return <PostListEmpty />
}
return (
<div className='w-full py-10 bg-[#F6F6F1]'>
<div className='max-w-7xl w-full mx-auto'>
{/* 标题 */}
<div className='flex justify-between items-center py-6'>
<h3 className='text-2xl'>{title}</h3>
<Link className='text-lg underline' href={href}>
<span>查看全部</span>
<i className='ml-2 fas fa-arrow-right' />
</Link>
</div>
{/* 列表 */}
<ul className='flex'>
{posts?.map(p => {
return <PostItemCardSimple key={p.id} post={p} />
})}
</ul>
</div>
</div>
)
}
export default PostSimpleListHorizontal

View File

@@ -5,7 +5,7 @@ import { useGlobal } from '@/lib/global'
* @param {*} props
* @returns
*/
export default function BlogPostBar(props) {
export default function PostListSlotBar(props) {
const { tag, category } = props
const { locale } = useGlobal()

View File

@@ -21,14 +21,15 @@ const SearchInput = ({ currentTag, currentSearch, cRef, className }) => {
setLoadingState(true)
location.href = '/search/' + key
} else {
router.push({ pathname: '/' }).then(r => {
})
router.push({ pathname: '/' }).then(r => {})
}
}
const handleKeyUp = (e) => {
if (e.keyCode === 13) { // 回车
const handleKeyUp = e => {
if (e.keyCode === 13) {
// 回车
handleSearch(searchInputRef.current.value)
} else if (e.keyCode === 27) { // ESC
} else if (e.keyCode === 27) {
// ESC
cleanSearch()
}
}
@@ -37,7 +38,7 @@ const SearchInput = ({ currentTag, currentSearch, cRef, className }) => {
}
const [showClean, setShowClean] = useState(false)
const updateSearchKey = (val) => {
const updateSearchKey = val => {
if (lock) {
return
}
@@ -49,38 +50,48 @@ const SearchInput = ({ currentTag, currentSearch, cRef, className }) => {
setShowClean(false)
}
}
function lockSearchInput () {
function lockSearchInput() {
lock = true
}
function unLockSearchInput () {
function unLockSearchInput() {
lock = false
}
return <div className={'flex w-full bg-gray-100 ' + className}>
<input
ref={searchInputRef}
type='text'
className={'outline-none w-full text-sm pl-2 transition focus:shadow-lg font-light leading-10 text-black bg-gray-100 dark:bg-gray-900 dark:text-white'}
onKeyUp={handleKeyUp}
onCompositionStart={lockSearchInput}
onCompositionUpdate={lockSearchInput}
onCompositionEnd={unLockSearchInput}
onChange={e => updateSearchKey(e.target.value)}
defaultValue={currentSearch}
/>
return (
<div className={'flex w-full bg-gray-100 ' + className}>
<input
ref={searchInputRef}
type='text'
className={
'outline-none w-full text-sm pl-2 transition focus:shadow-lg leading-10 text-black bg-gray-100 dark:bg-gray-900 dark:text-white'
}
onKeyUp={handleKeyUp}
onCompositionStart={lockSearchInput}
onCompositionUpdate={lockSearchInput}
onCompositionEnd={unLockSearchInput}
onChange={e => updateSearchKey(e.target.value)}
defaultValue={currentSearch}
/>
<div className='-ml-8 cursor-pointer float-right items-center justify-center py-2'
onClick={handleSearch}>
<i className={`hover:text-black transform duration-200 text-gray-500 dark:hover:text-gray-300 cursor-pointer fas ${onLoading ? 'fa-spinner animate-spin' : 'fa-search'} `} />
</div>
{(showClean &&
<div className='-ml-12 cursor-pointer float-right items-center justify-center py-2'>
<i className='fas fa-times hover:text-black transform duration-200 text-gray-400 cursor-pointer dark:hover:text-gray-300' onClick={cleanSearch} />
<div
className='-ml-8 cursor-pointer float-right items-center justify-center py-2'
onClick={handleSearch}>
<i
className={`hover:text-black transform duration-200 text-gray-500 dark:hover:text-gray-300 cursor-pointer fas ${onLoading ? 'fa-spinner animate-spin' : 'fa-search'} `}
/>
</div>
{showClean && (
<div className='-ml-12 cursor-pointer float-right items-center justify-center py-2'>
<i
className='fas fa-times hover:text-black transform duration-200 text-gray-400 cursor-pointer dark:hover:text-gray-300'
onClick={cleanSearch}
/>
</div>
)}
</div>
</div>
)
}
export default SearchInput

View File

@@ -8,12 +8,15 @@ const TagItemMini = ({ tag, selected = false }) => {
passHref
className={`cursor-pointer inline-block rounded hover:bg-gray-500 hover:text-white duration-200
mr-2 py-1 px-2 text-xs whitespace-nowrap dark:hover:text-white
${selected
? 'text-white dark:text-gray-300 bg-black dark:bg-black dark:hover:bg-gray-900'
: `text-gray-600 hover:shadow-xl dark:border-gray-400 notion-${tag.color}_background dark:bg-gray-800`}` }>
<div className='font-light dark:text-gray-400'>{selected && <i className='mr-1 fas fa-tag'/>} {tag.name + (tag.count ? `(${tag.count})` : '')} </div>
${
selected
? 'text-white dark:text-gray-300 dark:hover:bg-gray-900'
: `text-gray-900 hover:shadow-xl dark:border-gray-400 dark:bg-gray-800`
}`}>
<div className=' dark:text-gray-400'>
{/* {selected && <i className='mr-1 fas fa-tag'/>} */}#
{tag.name + (tag.count ? `(${tag.count})` : '')}{' '}
</div>
</Link>
)
}

View File

@@ -24,25 +24,25 @@ export default function TopNavBar(props) {
icon: 'fas fa-th',
name: locale.COMMON.CATEGORY,
href: '/category',
show: siteConfig('MEDIUM_MENU_CATEGORY', null, CONFIG)
show: siteConfig('MAGZINE_MENU_CATEGORY', null, CONFIG)
},
{
icon: 'fas fa-tag',
name: locale.COMMON.TAGS,
href: '/tag',
show: siteConfig('MEDIUM_MENU_TAG', null, CONFIG)
show: siteConfig('MAGZINE_MENU_TAG', null, CONFIG)
},
{
icon: 'fas fa-archive',
name: locale.NAV.ARCHIVE,
href: '/archive',
show: siteConfig('MEDIUM_MENU_ARCHIVE', null, CONFIG)
show: siteConfig('MAGZINE_MENU_ARCHIVE', null, CONFIG)
},
{
icon: 'fas fa-search',
name: locale.NAV.SEARCH,
href: '/search',
show: siteConfig('MEDIUM_MENU_SEARCH', null, CONFIG)
show: siteConfig('MAGZINE_MENU_SEARCH', null, CONFIG)
}
]

View File

@@ -1,24 +1,35 @@
const CONFIG = {
// 首屏信息栏按钮文字
MAGZINE_HOME_BANNER_ENABLE: true, // 首屏右上角的宣传位
MAGZINE_HOME_BUTTON: true,
MAGZINE_HOME_BUTTON_URL: '/about',
MAGZINE_HOME_BUTTON_TEXT: '了解更多',
MAGZINE_HOME_TITLE: '立即开创您的在线业务。完全免费。',
MAGZINE_HOME_DESCRIPTION:
'借助NotionNext获得助您开创、经营和扩展业务所需的全部工具和帮助。',
MAGZINE_HOME_TIPS: 'AI时代来临这是属于超级个体的狂欢盛宴',
// Style
MEDIUM_RIGHT_PANEL_DARK: process.env.NEXT_PUBLIC_MEDIUM_RIGHT_DARK || false, // 右侧面板深色模式
MAGZINE_RIGHT_PANEL_DARK: process.env.NEXT_PUBLIC_MAGZINE_RIGHT_DARK || false, // 右侧面板深色模式
MEDIUM_POST_LIST_COVER: true, // 文章列表显示图片封面
MEDIUM_POST_LIST_PREVIEW: true, // 列表显示文章预览
MEDIUM_POST_LIST_CATEGORY: true, // 列表显示文章分类
MEDIUM_POST_LIST_TAG: true, // 列表显示文章标签
MAGZINE_POST_LIST_COVER: true, // 文章列表显示图片封面
MAGZINE_POST_LIST_PREVIEW: true, // 列表显示文章预览
MAGZINE_POST_LIST_CATEGORY: true, // 列表显示文章分类
MAGZINE_POST_LIST_TAG: true, // 列表显示文章标签
MEDIUM_POST_DETAIL_CATEGORY: true, // 文章显示分类
MEDIUM_POST_DETAIL_TAG: true, // 文章显示标签
MAGZINE_POST_DETAIL_CATEGORY: true, // 文章显示分类
MAGZINE_POST_DETAIL_TAG: true, // 文章显示标签
// 菜单
MEDIUM_MENU_CATEGORY: true, // 显示分类
MEDIUM_MENU_TAG: true, // 显示标签
MEDIUM_MENU_ARCHIVE: true, // 显示归档
MEDIUM_MENU_SEARCH: true, // 显示搜索
MAGZINE_MENU_CATEGORY: true, // 显示分类
MAGZINE_MENU_TAG: true, // 显示标签
MAGZINE_MENU_ARCHIVE: true, // 显示归档
MAGZINE_MENU_SEARCH: true, // 显示搜索
// Widget
MEDIUM_WIDGET_REVOLVER_MAPS: process.env.NEXT_PUBLIC_WIDGET_REVOLVER_MAPS || 'false', // 地图插件
MEDIUM_WIDGET_TO_TOP: true // 跳回顶部
MAGZINE_WIDGET_REVOLVER_MAPS:
process.env.NEXT_PUBLIC_WIDGET_REVOLVER_MAPS || 'false', // 地图插件
MAGZINE_WIDGET_TO_TOP: true // 跳回顶部
}
export default CONFIG

View File

@@ -8,21 +8,20 @@ import { isBrowser } from '@/lib/utils'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { createContext, useContext, useEffect, useState } from 'react'
import Announcement from './components/Announcement'
import ArchiveItem from './components/ArchiveItem'
import ArticleAround from './components/ArticleAround'
import ArticleInfo from './components/ArticleInfo'
import { ArticleLock } from './components/ArticleLock'
import BlogArchiveItem from './components/BlogArchiveItem'
import BlogPostCardHorizontal from './components/BlogPostCardHorizontal'
import BlogPostCardTop from './components/BlogPostCardTop'
import BlogPostListPage from './components/BlogPostListPage'
import BlogPostListScroll from './components/BlogPostListScroll'
import Catalog from './components/Catalog'
import CategoryGroup from './components/CategoryGroup'
import CategoryItem from './components/CategoryItem'
import Footer from './components/Footer'
import Header from './components/Header'
import InfoCard from './components/InfoCard'
import Hero from './components/Hero'
import PostListHorizontal from './components/PostListHorizontal'
import PostListPage from './components/PostListPage'
import PostListScroll from './components/PostListScroll'
import PostSimpleListHorizontal from './components/PostListSimpleHorizontal'
import SearchInput from './components/SearchInput'
import TagGroups from './components/TagGroups'
import TagItemMini from './components/TagItemMini'
@@ -81,33 +80,72 @@ const LayoutBase = props => {
* @returns
*/
const LayoutIndex = props => {
const { posts, notice } = props
const top = posts[0]
const post1 = posts[1]
const post2 = posts[2]
return (
<div className='container mx-auto max-w-7xl'>
{/* 首屏文章 */}
const { posts, allNavPages } = props
// 最新文章 从第4个元素开始截取出4个
const newPosts = posts.slice(3, 7)
<div className='md:flex justify-between py-10 md:py-16'>
<div className='basis-1/2 mb-6'>
<BlogPostCardTop post={top} />
</div>
<div className='px-10'>
<div className='flex justify-between px-4 w-full'>
<InfoCard {...props} />
<Announcement post={notice} />
</div>
{/* 两篇主要文章 */}
<div>
<BlogPostCardHorizontal post={post1} />
<BlogPostCardHorizontal post={post2} />
</div>
</div>
</div>
// 按分类将文章分组成文件夹
const categoryFolders = groupArticles(allNavPages.slice(8))
return (
<div className='py-10 md:py-18'>
{/* 首屏宣传区块 */}
<Hero posts={posts} />
{/* 最新文章区块 */}
<PostSimpleListHorizontal
title='最新文章'
href='/archive'
posts={newPosts}
/>
{/* 不同的分类文章列表 */}
{categoryFolders?.map((categoryGroup, index) => {
if (
!categoryGroup ||
!categoryGroup.items ||
categoryGroup.items.length < 1
) {
return null
}
return (
<PostListHorizontal
title={categoryGroup?.category}
href={`/category/${categoryGroup?.category}`}
posts={categoryGroup?.items}
/>
)
})}
</div>
)
}
// 按照分类将文章分组成文件夹
function groupArticles(allPosts) {
if (!allPosts) {
return []
}
const groups = []
for (let i = 0; i < allPosts.length; i++) {
const item = allPosts[i]
const categoryName = item?.category ? item?.category : '' // 将 category 转换为字符串
let existingGroup = groups.find(group => group.category === categoryName) // 搜索同名的最后一个分组
if (existingGroup && existingGroup.category === categoryName) {
// 如果分组已存在并且该分组中的文章数量小于4添加文章
if (existingGroup.items.length < 4) {
existingGroup.items.push(item)
}
} else {
// 新建分组,并添加当前文章
groups.push({ category: categoryName, items: [item] })
}
}
return groups
}
/**
* 博客列表
@@ -117,9 +155,9 @@ const LayoutPostList = props => {
return (
<>
{siteConfig('POST_LIST_STYLE') === 'page' ? (
<BlogPostListPage {...props} />
<PostListPage {...props} />
) : (
<BlogPostListScroll {...props} />
<PostListScroll {...props} />
)}
</>
)
@@ -180,10 +218,10 @@ const LayoutSlug = props => {
<ShareBar post={post} />
{/* 文章分类和标签信息 */}
<div className='flex justify-between'>
{siteConfig('MEDIUM_POST_DETAIL_CATEGORY', null, CONFIG) &&
{siteConfig('MAGZINE_POST_DETAIL_CATEGORY', null, CONFIG) &&
post?.category && <CategoryItem category={post?.category} />}
<div>
{siteConfig('MEDIUM_POST_DETAIL_TAG', null, CONFIG) &&
{siteConfig('MAGZINE_POST_DETAIL_TAG', null, CONFIG) &&
post?.tagItems?.map(tag => (
<TagItemMini key={tag.name} tag={tag} />
))}
@@ -245,9 +283,9 @@ const LayoutSearch = props => {
{currentSearch && (
<div>
{siteConfig('POST_LIST_STYLE') === 'page' ? (
<BlogPostListPage {...props} />
<PostListPage {...props} />
) : (
<BlogPostListScroll {...props} />
<PostListScroll {...props} />
)}
</div>
)}
@@ -266,7 +304,7 @@ const LayoutArchive = props => {
<>
<div className='mb-10 pb-20 md:py-12 py-3 min-h-full'>
{Object.keys(archivePosts)?.map(archiveTitle => (
<BlogArchiveItem
<ArchiveItem
key={archiveTitle}
archiveTitle={archiveTitle}
archivePosts={archivePosts}