mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-15 15:09:25 +00:00
Magzine主题基础版本
This commit is contained in:
@@ -63,7 +63,8 @@ const ExternalPlugin = props => {
|
||||
const MOUSE_FOLLOW = siteConfig('MOUSE_FOLLOW')
|
||||
const CUSTOM_EXTERNAL_CSS = siteConfig('CUSTOM_EXTERNAL_CSS')
|
||||
const CUSTOM_EXTERNAL_JS = siteConfig('CUSTOM_EXTERNAL_JS')
|
||||
const ENABLE_NPROGRSS = siteConfig('ENABLE_NPROGRSS', true)
|
||||
// 默认关闭NProgress
|
||||
const ENABLE_NPROGRSS = siteConfig('ENABLE_NPROGRSS', false)
|
||||
|
||||
// 自定义样式css和js引入
|
||||
if (isBrowser) {
|
||||
|
||||
@@ -73,8 +73,11 @@ const OpenWrite = () => {
|
||||
console.error('OpenWrite 加载异常', error)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.log('开发环境:屏蔽OpenWrite')
|
||||
return
|
||||
}
|
||||
if (isBrowser && blogId) {
|
||||
// Check if the element with id 'read-more-wrap' already exists
|
||||
const readMoreWrap = document.getElementById('read-more-wrap')
|
||||
|
||||
2
lib/cache/cache_manager.js
vendored
2
lib/cache/cache_manager.js
vendored
@@ -8,7 +8,7 @@ import MemoryCache from './memory_cache'
|
||||
* @returns
|
||||
*/
|
||||
export async function getDataFromCache(key, force) {
|
||||
if (JSON.parse(BLOG.ENABLE_CACHE) || force) {
|
||||
if (BLOG.ENABLE_CACHE || force) {
|
||||
const dataFromCache = await getApi().getCache(key)
|
||||
if (JSON.stringify(dataFromCache) === '[]') {
|
||||
return null
|
||||
|
||||
@@ -3,6 +3,9 @@ import dynamic from 'next/dynamic'
|
||||
|
||||
const NotionPage = dynamic(() => import('@/components/NotionPage'))
|
||||
|
||||
/**
|
||||
* Magzine主题的公告
|
||||
*/
|
||||
const Announcement = ({ post, className }) => {
|
||||
// const { locale } = useGlobal()
|
||||
if (post?.blockMap) {
|
||||
|
||||
@@ -2,6 +2,8 @@ import LazyImage from '@/components/LazyImage'
|
||||
import NotionIcon from '@/components/NotionIcon'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Link from 'next/link'
|
||||
import CategoryItem from './CategoryItem'
|
||||
import TagItemMini from './TagItemMini'
|
||||
|
||||
/**
|
||||
* 文章详情页介绍
|
||||
@@ -13,11 +15,42 @@ export default function ArticleInfo(props) {
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* title */}
|
||||
<h1 className='text-3xl pt-12 dark:text-gray-300'>
|
||||
{siteConfig('POST_TITLE_ICON') && <NotionIcon icon={post?.pageIcon} />}
|
||||
{post?.title}
|
||||
</h1>
|
||||
<div className='flex flex-col gap-y-8'>
|
||||
<div className='flex justify-center py-2 mr-2 items-center'>
|
||||
{siteConfig('MAGZINE_POST_LIST_CATEGORY') && (
|
||||
<CategoryItem category={post?.category} />
|
||||
)}
|
||||
<div
|
||||
className={
|
||||
'flex items-center justify-start flex-wrap space-x-3 text-gray-400'
|
||||
}>
|
||||
{siteConfig('MAGZINE_POST_LIST_TAG') &&
|
||||
post?.tagItems?.map(tag => (
|
||||
<TagItemMini key={tag.name} tag={tag} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* title */}
|
||||
<h2 className='text-5xl text-center dark:text-gray-300'>
|
||||
{siteConfig('POST_TITLE_ICON') && (
|
||||
<NotionIcon icon={post?.pageIcon} />
|
||||
)}
|
||||
{post?.title}
|
||||
</h2>
|
||||
|
||||
<div className='text-xl text-center'>{post?.summary}</div>
|
||||
</div>
|
||||
|
||||
{post?.type && !post?.type !== 'Page' && post?.pageCover && (
|
||||
<div className='w-full relative md:flex-shrink-0 overflow-hidden'>
|
||||
<LazyImage
|
||||
alt={post?.title}
|
||||
src={post?.pageCover}
|
||||
className='object-cover max-h-[60vh] w-full'
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* meta */}
|
||||
<section className='py-2 items-center text-sm px-1'>
|
||||
|
||||
@@ -1,56 +1,113 @@
|
||||
import DarkModeButton from '@/components/DarkModeButton'
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Link from 'next/link'
|
||||
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 { siteInfo } = useGlobal()
|
||||
const MAGZINE_FOOTER_LINKS = siteConfig('MAGZINE_FOOTER_LINKS', [])
|
||||
console.log('菜单', MAGZINE_FOOTER_LINKS)
|
||||
|
||||
return (
|
||||
<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')}
|
||||
<footer className='z-10 bg-black text-white justify-center m-auto w-full p-6 relative'>
|
||||
<div className='max-w-screen-2xl w-full mx-auto '>
|
||||
{/* 信息与链接区块 */}
|
||||
<div className='w-full flex justify-between py-16'>
|
||||
<div className='gap-x-2 flex items-center'>
|
||||
{/* 站长信息 */}
|
||||
<LazyImage
|
||||
src={siteInfo?.icon}
|
||||
className='rounded-full'
|
||||
width={40}
|
||||
alt={siteConfig('AUTHOR')}
|
||||
/>
|
||||
<div>
|
||||
<h1 className='text-lg'>{title}</h1>
|
||||
<i className='fas fa-copyright' />
|
||||
<a
|
||||
href={siteConfig('LINK')}
|
||||
className='underline font-bold justify-start '>
|
||||
{siteConfig('AUTHOR')}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 右侧链接区块 */}
|
||||
<div className='grid grid-cols-4 gap-16'>
|
||||
{MAGZINE_FOOTER_LINKS?.map((group, index) => {
|
||||
return (
|
||||
<div key={index}>
|
||||
<div className='font-bold text-lg text-white pb-8'>
|
||||
{group.name}
|
||||
</div>
|
||||
<div className='flex flex-col gap-y-2'>
|
||||
{group?.menus?.map((menu, index) => {
|
||||
return (
|
||||
<div key={index}>
|
||||
<Link href={menu.href} className='hover:underline'>
|
||||
{menu.title}
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 页脚 */}
|
||||
<div className='py-4 flex justify-between items-center border-t border-gray-400'>
|
||||
<span className='flex gap-x-2 items-center'>
|
||||
<DarkModeButton />
|
||||
{`${copyrightDate}`}
|
||||
{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>
|
||||
|
||||
<span className='text-sm font-serif'>
|
||||
Powered by{' '}
|
||||
<a
|
||||
href='https://github.com/tangly1024/NotionNext'
|
||||
className='underline justify-start text-white'>
|
||||
NotionNext {siteConfig('VERSION')}
|
||||
</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 justify-start text-white'>
|
||||
NotionNext {siteConfig('VERSION')}
|
||||
</a>
|
||||
.
|
||||
</span>
|
||||
</span>
|
||||
<SocialButton />
|
||||
.
|
||||
</span>
|
||||
<div className='flex items-center gap-x-2'>
|
||||
<span>
|
||||
<i className='mx-1 animate-pulse fas fa-heart' />{' '}
|
||||
<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>
|
||||
</span>
|
||||
<SocialButton />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ export default function Header(props) {
|
||||
{/* 导航栏菜单内容 */}
|
||||
<div
|
||||
id='top-navbar'
|
||||
className='flex w-full mx-auto max-w-7xl h-20 transition-all duration-200 items-center justify-between'>
|
||||
className='flex w-full mx-auto max-w-screen-2xl h-20 transition-all duration-200 items-center justify-between'>
|
||||
{/* 搜索栏 */}
|
||||
{showSearchInput && (
|
||||
<input
|
||||
|
||||
@@ -25,7 +25,7 @@ const Hero = ({ posts }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='w-full mx-auto max-w-7xl xl:flex justify-between'>
|
||||
<div className='w-full mx-auto max-w-screen-2xl xl:flex justify-between'>
|
||||
{/* 左侧一篇主要置顶文章 */}
|
||||
<div className='basis-1/2 mb-6'>
|
||||
<PostItemCardTop post={postTop} />
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import CONFIG from '../config'
|
||||
|
||||
/**
|
||||
* 跳转到网页顶部
|
||||
@@ -10,7 +9,7 @@ import CONFIG from '../config'
|
||||
* @constructor
|
||||
*/
|
||||
const JumpToTopButton = ({ showPercent = false, percent, className }) => {
|
||||
if (!siteConfig('MAGZINE_WIDGET_TO_TOP', null, CONFIG)) {
|
||||
if (!siteConfig('MAGZINE_WIDGET_TO_TOP')) {
|
||||
return <></>
|
||||
}
|
||||
return (
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
export default function LoadingCover() {
|
||||
return <div id='cover-loading' className={'z-50 opacity-50 pointer-events-none transition-all duration-300'}>
|
||||
<div className='w-full h-screen flex justify-center items-center'>
|
||||
<i className="fa-solid fa-spinner text-2xl text-black dark:text-white animate-spin"> </i>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import CONFIG from '../config'
|
||||
import { MenuItemCollapse } from './MenuItemCollapse'
|
||||
|
||||
export const MenuBarMobile = props => {
|
||||
@@ -12,19 +11,19 @@ export const MenuBarMobile = props => {
|
||||
{
|
||||
name: locale.COMMON.CATEGORY,
|
||||
href: '/category',
|
||||
show: siteConfig('MAGZINE_MENU_CATEGORY', null, CONFIG)
|
||||
show: siteConfig('MAGZINE_MENU_CATEGORY')
|
||||
},
|
||||
{
|
||||
name: locale.COMMON.TAGS,
|
||||
href: '/tag',
|
||||
show: siteConfig('MAGZINE_MENU_TAG', null, CONFIG)
|
||||
show: siteConfig('MAGZINE_MENU_TAG')
|
||||
},
|
||||
{
|
||||
name: locale.NAV.ARCHIVE,
|
||||
href: '/archive',
|
||||
show: siteConfig('MAGZINE_MENU_ARCHIVE', null, CONFIG)
|
||||
show: siteConfig('MAGZINE_MENU_ARCHIVE')
|
||||
}
|
||||
// { name: locale.NAV.SEARCH, href: '/search', show: siteConfig('MENU_SEARCH', null, CONFIG) }
|
||||
// { name: locale.NAV.SEARCH, href: '/search', show: siteConfig('MENU_SEARCH', ) }
|
||||
]
|
||||
|
||||
if (customNav) {
|
||||
|
||||
87
themes/magzine/components/PostBannerGroupByCategory.js
Normal file
87
themes/magzine/components/PostBannerGroupByCategory.js
Normal file
@@ -0,0 +1,87 @@
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import PostListHorizontal from './PostListHorizontal'
|
||||
|
||||
/**
|
||||
* 按文章类别分组的文章列表区块
|
||||
* @returns {JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
const PostBannerGroupByCategory = props => {
|
||||
const { posts, categoryOptions, allNavPages, latestPosts } = props
|
||||
if (!posts || posts.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 按分类将文章分组成文件夹
|
||||
const categoryFolders = groupArticles(categoryOptions, allNavPages.slice(8))
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* 不同的分类文章列表 */}
|
||||
{categoryFolders?.map((categoryGroup, index) => {
|
||||
if (
|
||||
!categoryGroup ||
|
||||
!categoryGroup.items ||
|
||||
categoryGroup.items.length < 1
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<PostListHorizontal
|
||||
key={index}
|
||||
hasBg={index % 2 === 1}
|
||||
title={categoryGroup?.category}
|
||||
href={`/category/${categoryGroup?.category}`}
|
||||
posts={categoryGroup?.items}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
// 按照分类将文章分组成文件夹
|
||||
function groupArticles(categoryOptions, 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] })
|
||||
}
|
||||
}
|
||||
const hiddenCategory = siteConfig('MAGZINE_HOME_HIDDEN_CATEGORY')
|
||||
// 按照 categoryOptions 的顺序排序 groups
|
||||
const sortedGroups = []
|
||||
for (let i = 0; i < categoryOptions.length; i++) {
|
||||
const option = categoryOptions[i]
|
||||
const matchingGroup = groups.find(group => group.category === option.name)
|
||||
|
||||
if (matchingGroup) {
|
||||
if (
|
||||
hiddenCategory &&
|
||||
hiddenCategory.indexOf(matchingGroup.category) >= 0
|
||||
) {
|
||||
continue
|
||||
}
|
||||
sortedGroups.push(matchingGroup)
|
||||
}
|
||||
}
|
||||
return sortedGroups
|
||||
}
|
||||
|
||||
export default PostBannerGroupByCategory
|
||||
@@ -1,43 +1,47 @@
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
import NotionIcon from '@/components/NotionIcon'
|
||||
import NotionPage from '@/components/NotionPage'
|
||||
import TwikooCommentCount from '@/components/TwikooCommentCount'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Link from 'next/link'
|
||||
import CONFIG from '../config'
|
||||
import CategoryItem from './CategoryItem'
|
||||
import TagItemMini from './TagItemMini'
|
||||
|
||||
/**
|
||||
* 普通的博客卡牌
|
||||
* 带封面图
|
||||
*/
|
||||
const PostItemCard = ({ post, showSummary }) => {
|
||||
const showPreview =
|
||||
siteConfig('MAGZINE_POST_LIST_PREVIEW', null, CONFIG) && post.blockMap
|
||||
const { locale } = useGlobal()
|
||||
const { siteInfo } = useGlobal()
|
||||
const cover = post?.pageCoverThumbnail || siteInfo?.pageCover
|
||||
return (
|
||||
<div
|
||||
key={post.id}
|
||||
data-aos='fade-up'
|
||||
data-aos-duration='300'
|
||||
data-aos-once='false'
|
||||
data-aos-anchor-placement='top-bottom'
|
||||
className='mb-6 max-w-7xl border-b dark:border-gray-800 '>
|
||||
<header className='lg:py-8 py-4 flex flex-col w-full'>
|
||||
<div key={post.id} className='mb-6 max-w-screen-2xl'>
|
||||
<div className='lg:py-8 py-4 flex flex-col w-full'>
|
||||
{siteConfig('MAGZINE_POST_LIST_COVER') && (
|
||||
<Link
|
||||
href={post?.href}
|
||||
passHref
|
||||
className={
|
||||
'cursor-pointer hover:underline leading-tight text-gray-700 dark:text-gray-300 hover:text-gray-500 dark:hover:text-gray-400'
|
||||
}>
|
||||
<div className='w-full h-40 aspect-video overflow-hidden mb-2'>
|
||||
<LazyImage
|
||||
src={cover}
|
||||
style={cover ? {} : { height: '0px' }}
|
||||
className='w-full h-40 aspect-video object-cover hover:scale-125 duration-150'
|
||||
/>
|
||||
</div>
|
||||
</Link>
|
||||
)}
|
||||
{siteConfig('MAGZINE_POST_LIST_CATEGORY') && (
|
||||
<CategoryItem category={post.category} />
|
||||
)}
|
||||
|
||||
<Link
|
||||
href={post?.href}
|
||||
passHref
|
||||
className={
|
||||
'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'
|
||||
'cursor-pointer hover:underline leading-tight text-gray-700 dark:text-gray-300 hover:text-gray-500 dark:hover:text-gray-400'
|
||||
}>
|
||||
<h2>
|
||||
{siteConfig('MAGZINE_POST_LIST_COVER', null, CONFIG) && (
|
||||
<div className='w-full max-h-96 object-cover overflow-hidden mb-2'>
|
||||
<LazyImage
|
||||
src={post.pageCoverThumbnail}
|
||||
style={post.pageCoverThumbnail ? {} : { height: '0px' }}
|
||||
className='w-full max-h-96 object-cover hover:scale-125 duration-150'
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{siteConfig('POST_TITLE_ICON') && (
|
||||
<NotionIcon icon={post.pageIcon} />
|
||||
)}
|
||||
@@ -45,46 +49,8 @@ const PostItemCard = ({ post, showSummary }) => {
|
||||
</h2>
|
||||
</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('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} />
|
||||
))}
|
||||
<TwikooCommentCount post={post} className='hover:underline' />
|
||||
</div>
|
||||
|
||||
<div className='flex'></div>
|
||||
|
||||
{(!showPreview || showSummary) && (
|
||||
<main className='my-4 text-gray-700 dark:text-gray-300 text-sm leading-7'>
|
||||
{post.summary}
|
||||
</main>
|
||||
)}
|
||||
|
||||
{showPreview && (
|
||||
<div className='overflow-ellipsis truncate'>
|
||||
<NotionPage post={post} />
|
||||
<div className='pointer-events-none border-t pt-8 border-dashed'>
|
||||
<div className='w-full justify-start flex'>
|
||||
<Link
|
||||
href={post?.href}
|
||||
passHref
|
||||
className='hover:bg-opacity-100 hover:scale-105 duration-200 pointer-events-auto transform font-bold text-gray-500 cursor-pointer'>
|
||||
{locale.COMMON.ARTICLE_DETAIL}
|
||||
<i className='ml-1 fas fa-angle-right' />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</header>
|
||||
<div className='text-sm py-1'>{post.date?.start_date}</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ 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'
|
||||
|
||||
/**
|
||||
@@ -11,15 +10,14 @@ import CategoryItem from './CategoryItem'
|
||||
* @returns
|
||||
*/
|
||||
const PostItemCardSimple = ({ post, showSummary }) => {
|
||||
const showPreview =
|
||||
siteConfig('MAGZINE_POST_LIST_PREVIEW', null, CONFIG) && post.blockMap
|
||||
const showPreview = siteConfig('MAGZINE_POST_LIST_PREVIEW') && 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 '>
|
||||
className='mb-6 max-w-screen-2xl 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) && (
|
||||
{siteConfig('MAGZINE_POST_LIST_CATEGORY') && (
|
||||
<CategoryItem category={post.category} />
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,6 @@ import NotionPage from '@/components/NotionPage'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Link from 'next/link'
|
||||
import CONFIG from '../config'
|
||||
import CategoryItem from './CategoryItem'
|
||||
import TagItemMini from './TagItemMini'
|
||||
|
||||
@@ -14,8 +13,7 @@ import TagItemMini from './TagItemMini'
|
||||
* @returns
|
||||
*/
|
||||
const PostItemCardTop = ({ post, showSummary }) => {
|
||||
const showPreview =
|
||||
siteConfig('MAGZINE_POST_LIST_PREVIEW', null, CONFIG) && post.blockMap
|
||||
const showPreview = siteConfig('MAGZINE_POST_LIST_PREVIEW') && post.blockMap
|
||||
const { locale } = useGlobal()
|
||||
return (
|
||||
<div
|
||||
@@ -24,9 +22,9 @@ const PostItemCardTop = ({ post, showSummary }) => {
|
||||
data-aos-duration='300'
|
||||
data-aos-once='false'
|
||||
data-aos-anchor-placement='top-bottom'
|
||||
className='mb-6 max-w-7xl '>
|
||||
className='mb-6 max-w-screen-2xl '>
|
||||
<div className='flex flex-col w-full'>
|
||||
{siteConfig('MAGZINE_POST_LIST_COVER', null, CONFIG) && (
|
||||
{siteConfig('MAGZINE_POST_LIST_COVER') && (
|
||||
<Link
|
||||
href={post?.href}
|
||||
passHref
|
||||
@@ -44,14 +42,14 @@ const PostItemCardTop = ({ post, showSummary }) => {
|
||||
)}
|
||||
|
||||
<div className='flex py-2 mr-2 items-center'>
|
||||
{siteConfig('MAGZINE_POST_LIST_CATEGORY', null, CONFIG) && (
|
||||
{siteConfig('MAGZINE_POST_LIST_CATEGORY') && (
|
||||
<CategoryItem category={post.category} />
|
||||
)}
|
||||
<div
|
||||
className={
|
||||
'flex items-center justify-start flex-wrap space-x-3 text-gray-400'
|
||||
}>
|
||||
{siteConfig('MAGZINE_POST_LIST_TAG', null, CONFIG) &&
|
||||
{siteConfig('MAGZINE_POST_LIST_TAG') &&
|
||||
post?.tagItems?.map(tag => (
|
||||
<TagItemMini key={tag.name} tag={tag} />
|
||||
))}
|
||||
|
||||
@@ -4,7 +4,6 @@ import NotionPage from '@/components/NotionPage'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Link from 'next/link'
|
||||
import CONFIG from '../config'
|
||||
import CategoryItem from './CategoryItem'
|
||||
import TagItemMini from './TagItemMini'
|
||||
|
||||
@@ -14,8 +13,7 @@ import TagItemMini from './TagItemMini'
|
||||
* @returns
|
||||
*/
|
||||
const PostItemCardWide = ({ post, showSummary }) => {
|
||||
const showPreview =
|
||||
siteConfig('MAGZINE_POST_LIST_PREVIEW', null, CONFIG) && post.blockMap
|
||||
const showPreview = siteConfig('MAGZINE_POST_LIST_PREVIEW') && post.blockMap
|
||||
const { locale } = useGlobal()
|
||||
return (
|
||||
<div key={post.id} className='flex justify-between space-x-6 mb-6 '>
|
||||
@@ -62,10 +60,10 @@ const PostItemCardWide = ({ post, showSummary }) => {
|
||||
className={
|
||||
'flex mt-2 items-center justify-start flex-wrap space-x-3 text-gray-400'
|
||||
}>
|
||||
{siteConfig('MAGZINE_POST_LIST_CATEGORY', null, CONFIG) && (
|
||||
{siteConfig('MAGZINE_POST_LIST_CATEGORY') && (
|
||||
<CategoryItem category={post.category} />
|
||||
)}
|
||||
{siteConfig('MAGZINE_POST_LIST_TAG', null, CONFIG) &&
|
||||
{siteConfig('MAGZINE_POST_LIST_TAG') &&
|
||||
post?.tagItems?.map(tag => (
|
||||
<TagItemMini key={tag.name} tag={tag} />
|
||||
))}
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
import Link from 'next/link'
|
||||
import PostItemCardSimple from './PostItemCardSimple'
|
||||
import PostItemCard from './PostItemCard'
|
||||
import PostListEmpty from './PostListEmpty'
|
||||
|
||||
/**
|
||||
* 博文水平列表
|
||||
* 含封面
|
||||
* 可以指定是否有模块背景色
|
||||
* @returns {JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
const PostListHorizontal = ({ title, href, posts }) => {
|
||||
const PostListHorizontal = ({ title, href, posts, hasBg }) => {
|
||||
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={`w-full py-10 ${hasBg ? 'bg-[#F6F6F1]' : ''}`}>
|
||||
<div className='max-w-screen-2xl w-full mx-auto'>
|
||||
{/* 标题 */}
|
||||
<div className='flex justify-between items-center py-6'>
|
||||
<h3 className='text-2xl'>{title}</h3>
|
||||
@@ -25,9 +26,9 @@ const PostListHorizontal = ({ title, href, posts }) => {
|
||||
</Link>
|
||||
</div>
|
||||
{/* 列表 */}
|
||||
<ul className='flex'>
|
||||
{posts?.map(p => {
|
||||
return <PostItemCardSimple key={p.id} post={p} />
|
||||
<ul className='flex gap-4'>
|
||||
{posts?.map((p, index) => {
|
||||
return <PostItemCard key={index} post={p} />
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
79
themes/magzine/components/PostListRecommend.js
Normal file
79
themes/magzine/components/PostListRecommend.js
Normal file
@@ -0,0 +1,79 @@
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import PostItemCard from './PostItemCard'
|
||||
import PostListEmpty from './PostListEmpty'
|
||||
|
||||
/**
|
||||
* 博文水平列表
|
||||
* 含封面
|
||||
* 可以指定是否有模块背景色
|
||||
* @returns {JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
const PostListRecommend = ({ latestPosts, allNavPages }) => {
|
||||
// 获取推荐文章
|
||||
const recommendPosts = getTopPosts({ latestPosts, allNavPages })
|
||||
if (!recommendPosts || recommendPosts.length === 0) {
|
||||
return <PostListEmpty />
|
||||
}
|
||||
const title = siteConfig('MAGZINE_RECOMMEND_POST_TITLE')
|
||||
|
||||
return (
|
||||
<div className={`w-full py-10 bg-[#F6F6F1]`}>
|
||||
<div className='max-w-screen-2xl w-full mx-auto'>
|
||||
{/* 标题 */}
|
||||
<div className='flex justify-between items-center py-6'>
|
||||
<h3 className='text-4xl font-bold'>{title}</h3>
|
||||
</div>
|
||||
{/* 列表 */}
|
||||
<ul className='flex gap-4 overflow-x-scroll'>
|
||||
{recommendPosts?.map(p => {
|
||||
return <PostItemCard key={p.id} post={p} />
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取推荐置顶文章
|
||||
*/
|
||||
function getTopPosts({ latestPosts, allNavPages }) {
|
||||
// 默认展示最近更新
|
||||
if (
|
||||
!siteConfig('MAGZINE_RECOMMEND_POST_TAG') ||
|
||||
siteConfig('MAGZINE_RECOMMEND_POST_TAG') === ''
|
||||
) {
|
||||
return latestPosts
|
||||
}
|
||||
|
||||
// 显示包含‘推荐’标签的文章
|
||||
let sortPosts = []
|
||||
|
||||
// 排序方式
|
||||
if (siteConfig('MAGZINE_RECOMMEND_POST_SORT_BY_UPDATE_TIME')) {
|
||||
sortPosts = Object.create(allNavPages).sort((a, b) => {
|
||||
const dateA = new Date(a?.lastEditedDate)
|
||||
const dateB = new Date(b?.lastEditedDate)
|
||||
return dateB - dateA
|
||||
})
|
||||
} else {
|
||||
sortPosts = Object.create(allNavPages)
|
||||
}
|
||||
|
||||
const count = siteConfig('MAGZINE_RECOMMEND_POST_COUNT', 6)
|
||||
// 只取前4篇
|
||||
const topPosts = []
|
||||
for (const post of sortPosts) {
|
||||
if (topPosts.length === count) {
|
||||
break
|
||||
}
|
||||
// 查找标签
|
||||
if (post?.tags?.indexOf(siteConfig('MAGZINE_RECOMMEND_POST_TAG')) >= 0) {
|
||||
topPosts.push(post)
|
||||
}
|
||||
}
|
||||
return topPosts
|
||||
}
|
||||
|
||||
export default PostListRecommend
|
||||
@@ -14,7 +14,7 @@ const PostSimpleListHorizontal = ({ title, href, posts }) => {
|
||||
|
||||
return (
|
||||
<div className='w-full py-10 bg-[#F6F6F1]'>
|
||||
<div className='max-w-7xl w-full mx-auto'>
|
||||
<div className='max-w-screen-2xl w-full mx-auto'>
|
||||
{/* 标题 */}
|
||||
<div className='flex justify-between items-center py-6'>
|
||||
<h3 className='text-2xl'>{title}</h3>
|
||||
|
||||
@@ -7,14 +7,14 @@ import { siteConfig } from '@/lib/config'
|
||||
*/
|
||||
const SocialButton = () => {
|
||||
return (
|
||||
<div className='space-x-3 text-xl text-gray-600 dark:text-gray-400 flex-wrap flex justify-start '>
|
||||
<div className='space-x-3 text-xl text-white flex-wrap flex justify-start '>
|
||||
{siteConfig('CONTACT_GITHUB') && (
|
||||
<a
|
||||
target='_blank'
|
||||
rel='noreferrer'
|
||||
title={'github'}
|
||||
href={siteConfig('CONTACT_GITHUB')}>
|
||||
<i className='fab fa-github transform hover:scale-125 duration-150 hover:text-gray-600' />
|
||||
<i className='fab fa-github transform hover:scale-125 duration-150 hover:text-gray-100' />
|
||||
</a>
|
||||
)}
|
||||
{siteConfig('CONTACT_TWITTER') && (
|
||||
@@ -23,7 +23,7 @@ const SocialButton = () => {
|
||||
rel='noreferrer'
|
||||
title={'twitter'}
|
||||
href={siteConfig('CONTACT_TWITTER')}>
|
||||
<i className='fab fa-twitter transform hover:scale-125 duration-150 hover:text-gray-600' />
|
||||
<i className='fab fa-twitter transform hover:scale-125 duration-150 hover:text-gray-100' />
|
||||
</a>
|
||||
)}
|
||||
{siteConfig('CONTACT_TELEGRAM') && (
|
||||
@@ -32,7 +32,7 @@ const SocialButton = () => {
|
||||
rel='noreferrer'
|
||||
href={siteConfig('CONTACT_TELEGRAM')}
|
||||
title={'telegram'}>
|
||||
<i className='fab fa-telegram transform hover:scale-125 duration-150 hover:text-gray-600' />
|
||||
<i className='fab fa-telegram transform hover:scale-125 duration-150 hover:text-gray-100' />
|
||||
</a>
|
||||
)}
|
||||
{siteConfig('CONTACT_LINKEDIN') && (
|
||||
@@ -50,7 +50,7 @@ const SocialButton = () => {
|
||||
rel='noreferrer'
|
||||
title={'weibo'}
|
||||
href={siteConfig('CONTACT_WEIBO')}>
|
||||
<i className='fab fa-weibo transform hover:scale-125 duration-150 hover:text-gray-600' />
|
||||
<i className='fab fa-weibo transform hover:scale-125 duration-150 hover:text-gray-100' />
|
||||
</a>
|
||||
)}
|
||||
{siteConfig('CONTACT_INSTAGRAM') && (
|
||||
@@ -59,7 +59,7 @@ const SocialButton = () => {
|
||||
rel='noreferrer'
|
||||
title={'instagram'}
|
||||
href={siteConfig('CONTACT_INSTAGRAM')}>
|
||||
<i className='fab fa-instagram transform hover:scale-125 duration-150 hover:text-gray-600' />
|
||||
<i className='fab fa-instagram transform hover:scale-125 duration-150 hover:text-gray-100' />
|
||||
</a>
|
||||
)}
|
||||
{siteConfig('CONTACT_EMAIL') && (
|
||||
@@ -68,7 +68,7 @@ const SocialButton = () => {
|
||||
rel='noreferrer'
|
||||
title={'email'}
|
||||
href={`mailto:${siteConfig('CONTACT_EMAIL')}`}>
|
||||
<i className='fas fa-envelope transform hover:scale-125 duration-150 hover:text-gray-600' />
|
||||
<i className='fas fa-envelope transform hover:scale-125 duration-150 hover:text-gray-100' />
|
||||
</a>
|
||||
)}
|
||||
{JSON.parse(siteConfig('ENABLE_RSS')) && (
|
||||
@@ -77,7 +77,7 @@ const SocialButton = () => {
|
||||
rel='noreferrer'
|
||||
title={'RSS'}
|
||||
href={'/rss/feed.xml'}>
|
||||
<i className='fas fa-rss transform hover:scale-125 duration-150 hover:text-gray-600' />
|
||||
<i className='fas fa-rss transform hover:scale-125 duration-150 hover:text-gray-100' />
|
||||
</a>
|
||||
)}
|
||||
{siteConfig('CONTACT_BILIBILI') && (
|
||||
@@ -86,7 +86,7 @@ const SocialButton = () => {
|
||||
rel='noreferrer'
|
||||
title={'bilibili'}
|
||||
href={siteConfig('CONTACT_BILIBILI')}>
|
||||
<i className='fab fa-bilibili transform hover:scale-125 duration-150 hover:text-gray-600' />
|
||||
<i className='fab fa-bilibili transform hover:scale-125 duration-150 hover:text-gray-100' />
|
||||
</a>
|
||||
)}
|
||||
{siteConfig('CONTACT_YOUTUBE') && (
|
||||
@@ -95,7 +95,7 @@ const SocialButton = () => {
|
||||
rel='noreferrer'
|
||||
title={'youtube'}
|
||||
href={siteConfig('CONTACT_YOUTUBE')}>
|
||||
<i className='fab fa-youtube transform hover:scale-125 duration-150 hover:text-gray-600' />
|
||||
<i className='fab fa-youtube transform hover:scale-125 duration-150 hover:text-gray-100' />
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,6 @@ import Collapse from '@/components/Collapse'
|
||||
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'
|
||||
@@ -24,25 +23,25 @@ export default function TopNavBar(props) {
|
||||
icon: 'fas fa-th',
|
||||
name: locale.COMMON.CATEGORY,
|
||||
href: '/category',
|
||||
show: siteConfig('MAGZINE_MENU_CATEGORY', null, CONFIG)
|
||||
show: siteConfig('MAGZINE_MENU_CATEGORY')
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-tag',
|
||||
name: locale.COMMON.TAGS,
|
||||
href: '/tag',
|
||||
show: siteConfig('MAGZINE_MENU_TAG', null, CONFIG)
|
||||
show: siteConfig('MAGZINE_MENU_TAG')
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-archive',
|
||||
name: locale.NAV.ARCHIVE,
|
||||
href: '/archive',
|
||||
show: siteConfig('MAGZINE_MENU_ARCHIVE', null, CONFIG)
|
||||
show: siteConfig('MAGZINE_MENU_ARCHIVE')
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-search',
|
||||
name: locale.NAV.SEARCH,
|
||||
href: '/search',
|
||||
show: siteConfig('MAGZINE_MENU_SEARCH', null, CONFIG)
|
||||
show: siteConfig('MAGZINE_MENU_SEARCH')
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -5,11 +5,19 @@ const CONFIG = {
|
||||
MAGZINE_HOME_BUTTON_URL: '/about',
|
||||
MAGZINE_HOME_BUTTON_TEXT: '了解更多',
|
||||
|
||||
MAGZINE_HOME_HIDDEN_CATEGORY: '分享杂文', //不希望在首页展示的文章分类,用英文逗号隔开
|
||||
|
||||
MAGZINE_HOME_TITLE: '立即开创您的在线业务。完全免费。',
|
||||
MAGZINE_HOME_DESCRIPTION:
|
||||
'借助NotionNext,获得助您开创、经营和扩展业务所需的全部工具和帮助。',
|
||||
MAGZINE_HOME_TIPS: 'AI时代来临,这是属于超级个体的狂欢盛宴!',
|
||||
|
||||
// 首页底部推荐文章标签, 例如 [推荐] , 最多六篇文章; 若留空白'',则推荐最近更新文章
|
||||
MAGZINE_RECOMMEND_POST_TAG: '推荐',
|
||||
MAGZINE_RECOMMEND_POST_COUNT: 6,
|
||||
MAGZINE_RECOMMEND_POST_TITLE: '推荐文章',
|
||||
MAGZINE_RECOMMEND_POST_SORT_BY_UPDATE_TIME: false, // 推荐文章排序,为`true`时将强制按最后修改时间倒序
|
||||
|
||||
// Style
|
||||
MAGZINE_RIGHT_PANEL_DARK: process.env.NEXT_PUBLIC_MAGZINE_RIGHT_DARK || false, // 右侧面板深色模式
|
||||
|
||||
@@ -21,15 +29,95 @@ const CONFIG = {
|
||||
MAGZINE_POST_DETAIL_CATEGORY: true, // 文章显示分类
|
||||
MAGZINE_POST_DETAIL_TAG: true, // 文章显示标签
|
||||
|
||||
// 菜单
|
||||
// 页脚菜单
|
||||
MAGZINE_FOOTER_LINKS: [
|
||||
{
|
||||
name: '友情链接',
|
||||
menus: [
|
||||
{ title: '尘世の歌', href: 'https://chenge.ink' },
|
||||
{
|
||||
title: '设计狮网址导航',
|
||||
href: 'https://ct.ued.cat/'
|
||||
},
|
||||
{
|
||||
title: '积极的长腿怪',
|
||||
href: 'https://jjdctg.com'
|
||||
},
|
||||
{
|
||||
title: '自动驾驶小白说',
|
||||
href: 'https://www.helloxiaobai.cn/about'
|
||||
},
|
||||
{
|
||||
title: 'AI-皇帝',
|
||||
href: 'https://www.ai-hd.com/'
|
||||
},
|
||||
{
|
||||
title: 'Andy`s Pro',
|
||||
href: 'https://tw.andys.pro/'
|
||||
},
|
||||
{ title: 'LUCEN', href: 'https://www.lucenczz.top/' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '开发者',
|
||||
menus: [
|
||||
{ title: 'Github', href: 'https://github.com/tangly1024/NotionNext' },
|
||||
{
|
||||
title: '开发帮助',
|
||||
href: 'https://docs.tangly1024.com/article/how-to-develop-with-notion-next'
|
||||
},
|
||||
{
|
||||
title: '功能反馈',
|
||||
href: 'https://github.com/tangly1024/NotionNext/issues/new/choose'
|
||||
},
|
||||
{
|
||||
title: '技术讨论',
|
||||
href: 'https://github.com/tangly1024/NotionNext/discussions'
|
||||
},
|
||||
{
|
||||
title: '关于作者',
|
||||
href: 'https://blog.tangly1024.com/about'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
name: '支持',
|
||||
menus: [
|
||||
{
|
||||
title: '站长社群',
|
||||
href: 'https://docs.tangly1024.com/article/chat-community'
|
||||
},
|
||||
{
|
||||
title: '咨询与定制',
|
||||
href: 'https://docs.tangly1024.com/article/my-service'
|
||||
},
|
||||
{
|
||||
title: '升级手册',
|
||||
href: 'https://docs.tangly1024.com/article/my-service'
|
||||
},
|
||||
{
|
||||
title: '安装教程',
|
||||
href: 'https://docs.tangly1024.com/article/how-to-update-notionnext'
|
||||
},
|
||||
{ title: 'SEO推广', href: 'https://seo.tangly1024.com/' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '解决方案',
|
||||
menus: [
|
||||
{ title: '建站工具', href: 'https://www.tangly1024.com/' },
|
||||
{ title: 'NotionNext', href: 'https://docs.tangly1024.com/about' }
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
// 旧版本顶部菜单
|
||||
MAGZINE_MENU_CATEGORY: true, // 显示分类
|
||||
MAGZINE_MENU_TAG: true, // 显示标签
|
||||
MAGZINE_MENU_ARCHIVE: true, // 显示归档
|
||||
MAGZINE_MENU_SEARCH: true, // 显示搜索
|
||||
|
||||
// Widget
|
||||
MAGZINE_WIDGET_REVOLVER_MAPS:
|
||||
process.env.NEXT_PUBLIC_WIDGET_REVOLVER_MAPS || 'false', // 地图插件
|
||||
MAGZINE_WIDGET_TO_TOP: true // 跳回顶部
|
||||
}
|
||||
export default CONFIG
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Comment from '@/components/Comment'
|
||||
import LoadingCover from '@/components/LoadingCover'
|
||||
import replaceSearchResult from '@/components/Mark'
|
||||
import NotionPage from '@/components/NotionPage'
|
||||
import ShareBar from '@/components/ShareBar'
|
||||
@@ -8,6 +9,7 @@ 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'
|
||||
@@ -18,8 +20,9 @@ import CategoryItem from './components/CategoryItem'
|
||||
import Footer from './components/Footer'
|
||||
import Header from './components/Header'
|
||||
import Hero from './components/Hero'
|
||||
import PostListHorizontal from './components/PostListHorizontal'
|
||||
import PostBannerGroupByCategory from './components/PostBannerGroupByCategory'
|
||||
import PostListPage from './components/PostListPage'
|
||||
import PostListRecommend from './components/PostListRecommend'
|
||||
import PostListScroll from './components/PostListScroll'
|
||||
import PostSimpleListHorizontal from './components/PostListSimpleHorizontal'
|
||||
import SearchInput from './components/SearchInput'
|
||||
@@ -40,7 +43,7 @@ export const useMagzineGlobal = () => useContext(ThemeGlobalMagzine)
|
||||
* @constructor
|
||||
*/
|
||||
const LayoutBase = props => {
|
||||
const { children, showInfoCard = true, post, notice } = props
|
||||
const { children, notice, showInfoCard = true, post } = props
|
||||
const { locale } = useGlobal()
|
||||
const router = useRouter()
|
||||
const [tocVisible, changeTocVisible] = useState(false)
|
||||
@@ -65,9 +68,14 @@ const LayoutBase = props => {
|
||||
{children}
|
||||
</div>
|
||||
{/* 底部 */}
|
||||
<Announcement
|
||||
post={notice}
|
||||
className={'text-center text-black bg-[#7BE986] py-16'}
|
||||
/>
|
||||
<Footer title={siteConfig('TITLE')} />
|
||||
</div>
|
||||
</main>
|
||||
<LoadingCover />
|
||||
</div>
|
||||
</ThemeGlobalMagzine.Provider>
|
||||
)
|
||||
@@ -80,15 +88,12 @@ const LayoutBase = props => {
|
||||
* @returns
|
||||
*/
|
||||
const LayoutIndex = props => {
|
||||
const { posts, allNavPages } = props
|
||||
const { posts, categoryOptions, allNavPages, latestPosts } = props
|
||||
// 最新文章 从第4个元素开始截取出4个
|
||||
const newPosts = posts.slice(3, 7)
|
||||
|
||||
// 按分类将文章分组成文件夹
|
||||
const categoryFolders = groupArticles(allNavPages.slice(8))
|
||||
|
||||
return (
|
||||
<div className='py-10 md:py-18'>
|
||||
<div className='pt-10 md:pt-18'>
|
||||
{/* 首屏宣传区块 */}
|
||||
<Hero posts={posts} />
|
||||
|
||||
@@ -99,53 +104,14 @@ const LayoutIndex = props => {
|
||||
posts={newPosts}
|
||||
/>
|
||||
|
||||
{/* 不同的分类文章列表 */}
|
||||
{categoryFolders?.map((categoryGroup, index) => {
|
||||
if (
|
||||
!categoryGroup ||
|
||||
!categoryGroup.items ||
|
||||
categoryGroup.items.length < 1
|
||||
) {
|
||||
return null
|
||||
}
|
||||
{/* 文章分类陈列区 */}
|
||||
<PostBannerGroupByCategory {...props} />
|
||||
|
||||
return (
|
||||
<PostListHorizontal
|
||||
title={categoryGroup?.category}
|
||||
href={`/category/${categoryGroup?.category}`}
|
||||
posts={categoryGroup?.items}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
{/* 文章推荐 */}
|
||||
<PostListRecommend {...props} />
|
||||
</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
|
||||
}
|
||||
|
||||
/**
|
||||
* 博客列表
|
||||
@@ -171,13 +137,14 @@ const LayoutPostList = props => {
|
||||
const LayoutSlug = props => {
|
||||
const { post, prev, next, lock, validPassword } = props
|
||||
const { locale } = useGlobal()
|
||||
const router = useRouter()
|
||||
const slotRight = post?.toc && post?.toc?.length >= 3 && (
|
||||
<div key={locale.COMMON.TABLE_OF_CONTENTS}>
|
||||
<Catalog toc={post?.toc} />
|
||||
</div>
|
||||
)
|
||||
console.log('post-文章', post)
|
||||
|
||||
const router = useRouter()
|
||||
useEffect(() => {
|
||||
// 404
|
||||
if (!post) {
|
||||
@@ -198,7 +165,7 @@ const LayoutSlug = props => {
|
||||
}, [post])
|
||||
|
||||
return (
|
||||
<div {...props}>
|
||||
<div {...props} className='w-full mx-auto max-w-screen-2xl'>
|
||||
{/* 文章锁 */}
|
||||
{lock && <ArticleLock validPassword={validPassword} />}
|
||||
|
||||
@@ -209,7 +176,7 @@ const LayoutSlug = props => {
|
||||
|
||||
{/* Notion文章主体 */}
|
||||
<article id='article-wrapper' className='px-1 max-w-4xl'>
|
||||
{post && <NotionPage post={post} />}
|
||||
<NotionPage post={post} />
|
||||
</article>
|
||||
|
||||
{/* 文章底部区域 */}
|
||||
@@ -218,10 +185,11 @@ const LayoutSlug = props => {
|
||||
<ShareBar post={post} />
|
||||
{/* 文章分类和标签信息 */}
|
||||
<div className='flex justify-between'>
|
||||
{siteConfig('MAGZINE_POST_DETAIL_CATEGORY', null, CONFIG) &&
|
||||
post?.category && <CategoryItem category={post?.category} />}
|
||||
{siteConfig('MAGZINE_POST_DETAIL_CATEGORY') && post?.category && (
|
||||
<CategoryItem category={post?.category} />
|
||||
)}
|
||||
<div>
|
||||
{siteConfig('MAGZINE_POST_DETAIL_TAG', null, CONFIG) &&
|
||||
{siteConfig('MAGZINE_POST_DETAIL_TAG') &&
|
||||
post?.tagItems?.map(tag => (
|
||||
<TagItemMini key={tag.name} tag={tag} />
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user