gitbook 增加新文章红点机制

This commit is contained in:
tangly1024.com
2024-03-06 14:57:54 +08:00
parent 9494daee36
commit 0d1004a7b1
12 changed files with 86 additions and 23 deletions

View File

@@ -3,17 +3,22 @@ import Link from 'next/link'
import { useRouter } from 'next/router'
import { checkContainHttp, sliceUrlFromHttp } from '@/lib/utils'
import NotionIcon from '@/components/NotionIcon'
import Badge from '@/components/Badge'
import CONFIG from '../config'
const BlogPostCard = ({ post, className }) => {
const router = useRouter()
const currentSelected = router.asPath.split('?')[0] === '/' + post.slug
const url = checkContainHttp(post.slug) ? sliceUrlFromHttp(post.slug) : `${siteConfig('SUB_PATH', '')}/${post.slug}`
return (
<Link href={url} passHref> <div key={post.id} className={`${className} py-1.5 cursor-pointer px-1.5 hover:bg-gray-50 rounded-md dark:hover:bg-gray-600 ${currentSelected ? 'bg-green-50 text-green-500' : ''}`}>
<div className="w-full select-none">
<NotionIcon icon={post?.pageIcon}/> {post.title}
<Link href={url} passHref>
<div key={post.id} className={`${className} relative py-1.5 cursor-pointer px-1.5 hover:bg-gray-50 rounded-md dark:hover:bg-gray-600 ${currentSelected ? 'bg-green-50 text-green-500 dark:bg-yellow-100 dark:text-yellow-600' : ''}`}>
<div className="w-full select-none">
<NotionIcon icon={post?.pageIcon}/> {post.title}
</div>
{/* 最新文章加个红点 */}
{post?.isLatest && siteConfig('GITBOOK_LATEST_POST_RED_BADGE', false, CONFIG) && <Badge/>}
</div>
</div>
</Link>
)
}

View File

@@ -1,6 +1,9 @@
import BlogPostCard from './BlogPostCard'
import { useState } from 'react'
import Collapse from '@/components/Collapse'
import Badge from '@/components/Badge'
import { siteConfig } from '@/lib/config'
import CONFIG from '../config'
/**
* 导航列表
@@ -17,12 +20,15 @@ const NavPostItem = (props) => {
changeIsOpen(!isOpen)
}
const groupHasLatest = group?.items?.some(post => post.isLatest)
if (group?.category) {
return <>
<div onClick={toggleOpenSubMenu}
className='select-none flex justify-between text-sm cursor-pointer p-2 hover:bg-gray-50 rounded-md dark:hover:bg-gray-600' key={group?.category}>
className='select-none relative flex justify-between text-sm cursor-pointer p-2 hover:bg-gray-50 rounded-md dark:hover:bg-gray-600' key={group?.category}>
<span>{group?.category}</span>
<div className='inline-flex items-center select-none pointer-events-none '><i className={`px-2 fas fa-chevron-left transition-all duration-200 ${isOpen ? '-rotate-90' : ''}`}></i></div>
<div className='inline-flex items-center select-none pointer-events-none '><i className={`px-2 fas fa-chevron-left transition-all opacity-50 duration-200 ${isOpen ? '-rotate-90' : ''}`}></i></div>
{groupHasLatest && siteConfig('GITBOOK_LATEST_POST_RED_BADGE', false, CONFIG) && !isOpen && <Badge/>}
</div>
<Collapse isOpen={isOpen} onHeightChange={props.onHeightChange}>
{group?.items?.map(post => (<div key={post.id} className='ml-3 border-l'>

View File

@@ -103,7 +103,7 @@ const SearchInput = ({ currentSearch, cRef, className }) => {
<input
ref={searchInputRef}
type='text'
className={`${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`}
className={`${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-800 dark:text-white`}
onFocus={handleFocus}
onKeyUp={handleKeyUp}
onCompositionStart={lockSearchInput}

View File

@@ -4,6 +4,8 @@ const CONFIG = {
GITBOOK_AUTO_SORT: process.env.NEXT_PUBLIC_GITBOOK_AUTO_SORT || true, // 是否自动按分类名 归组排序文章自动归组可能会打乱您Notion中的文章顺序
GITBOOK_LATEST_POST_RED_BADGE: process.env.NEXT_PUBLIC_GITBOOK_LATEST_POST_RED_BADGE || true, // 是否给最新文章显示红点
// 菜单
GITBOOK_MENU_CATEGORY: true, // 显示分类
GITBOOK_BOOK_MENU_TAG: true, // 显示标签

View File

@@ -42,6 +42,38 @@ const WWAds = dynamic(() => import('@/components/WWAds'), { ssr: false })
const ThemeGlobalGitbook = createContext()
export const useGitBookGlobal = () => useContext(ThemeGlobalGitbook)
/**
* 给最新的文章标一个红点
*/
function getNavPagesWithLatest(allNavPages, latestPosts, post) {
// 检测需要去除红点的文章 ; localStorage 的 posts_read = {"${post.id}":"Date()"} 保存了所有已读的页面id和阅读时间
// 如果页面在这里面则不显示红点
const postRead = JSON.parse(localStorage.getItem('post_read') || '[]');
if (post && !postRead.includes(post.id)) {
postRead.push(post.id);
}
localStorage.setItem('post_read', JSON.stringify(postRead));
return allNavPages?.map(item => {
const res = {
id: item.id,
title: item.title || '',
pageCoverThumbnail: item.pageCoverThumbnail || '',
category: item.category || null,
tags: item.tags || null,
summary: item.summary || null,
slug: item.slug,
pageIcon: item.pageIcon || '',
lastEditedDate: item.lastEditedDate
}
if (latestPosts.some(post => post.id === item.id) && !postRead.includes(item.id)) {
return { ...res, isLatest: true };
} else {
return res;
}
})
}
/**
* 基础布局
* 采用左右两侧布局,移动端使用顶部导航栏
@@ -49,7 +81,7 @@ export const useGitBookGlobal = () => useContext(ThemeGlobalGitbook)
* @constructor
*/
const LayoutBase = (props) => {
const { children, post, allNavPages, slotLeft, slotRight, slotTop } = props
const { children, post, allNavPages, latestPosts, slotLeft, slotRight, slotTop } = props
const { onLoading, fullWidth } = useGlobal()
const router = useRouter()
const [tocVisible, changeTocVisible] = useState(false)
@@ -60,8 +92,8 @@ const LayoutBase = (props) => {
const searchModal = useRef(null)
useEffect(() => {
setFilteredNavPages(allNavPages)
}, [post])
setFilteredNavPages(getNavPagesWithLatest(allNavPages, latestPosts, post))
}, [router])
return (
<ThemeGlobalGitbook.Provider value={{ searchModal, tocVisible, changeTocVisible, filteredNavPages, setFilteredNavPages, allNavPages, pageNavVisible, changePageNavVisible }}>
@@ -78,7 +110,7 @@ const LayoutBase = (props) => {
{/* 左侧推拉抽屉 */}
{fullWidth
? null
: (<div className={'hidden md:block border-r dark:border-transparent relative z-10 '}>
: (<div className={'hidden md:block border-r dark:border-transparent relative z-10 dark:bg-hexo-black-gray'}>
<div className='w-72 py-14 px-6 sticky top-0 overflow-y-scroll h-screen scroll-hidden'>
{slotLeft}
<SearchInput className='my-3 rounded-md' />
@@ -94,7 +126,7 @@ const LayoutBase = (props) => {
</div>
</div>) }
<div id='center-wrapper' className='flex flex-col justify-between w-full relative z-10 pt-14 min-h-screen'>
<div id='center-wrapper' className='flex flex-col justify-between w-full relative z-10 pt-14 min-h-screen dark:bg-black'>
<div id='container-inner' className={`w-full px-7 ${fullWidth ? 'px-10' : 'max-w-3xl'} justify-center mx-auto`}>
{slotTop}