mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-14 07:26:52 +00:00
feat: 优化css
This commit is contained in:
@@ -3,8 +3,7 @@
|
||||
const BLOG = {
|
||||
// Important page_id!!!Duplicate Template from https://www.notion.so/tanghh/02ab3b8678004aa69e9e415905ef32a5
|
||||
NOTION_PAGE_ID:
|
||||
process.env.NOTION_PAGE_ID ||
|
||||
'02ab3b8678004aa69e9e415905ef32a5,en:7c1d570661754c8fbc568e00a01fd70e',
|
||||
process.env.NOTION_PAGE_ID || '20cb7f4f464a80db8541cbd0da70a64b',
|
||||
THEME: process.env.NEXT_PUBLIC_THEME || 'typography', // 当前主题,在 themes 文件夹下可找到所有支持的主题;主题名称就是文件夹名,例如 example,fukasawa,gitbook,heo,hexo,landing,matery,medium,next,nobelium,plog,simple
|
||||
LANG: process.env.NEXT_PUBLIC_LANG || 'zh-CN', // e.g 'zh-CN','en-US' see /lib/lang.js for more.
|
||||
SINCE: process.env.NEXT_PUBLIC_SINCE || 2021, // e.g if leave this empty, current year will be used.
|
||||
@@ -20,7 +19,8 @@ const BLOG = {
|
||||
KEYWORDS: process.env.NEXT_PUBLIC_KEYWORD || 'Notion, 博客', // 网站关键词 英文逗号隔开
|
||||
BLOG_FAVICON: process.env.NEXT_PUBLIC_FAVICON || '/favicon.ico', // blog favicon 配置,默认使用 /public/favicon.ico,支持在线图片,如 https://img.imesong.com/favicon.png
|
||||
BEI_AN: process.env.NEXT_PUBLIC_BEI_AN || '', // 备案号 闽 ICP 备 XXXXXX
|
||||
BEI_AN_LINK: process.env.NEXT_PUBLIC_BEI_AN_LINK || 'https://beian.miit.gov.cn/', // 备案查询链接,如果用了萌备等备案请在这里填写
|
||||
BEI_AN_LINK:
|
||||
process.env.NEXT_PUBLIC_BEI_AN_LINK || 'https://beian.miit.gov.cn/', // 备案查询链接,如果用了萌备等备案请在这里填写
|
||||
|
||||
// RSS 订阅
|
||||
ENABLE_RSS: process.env.NEXT_PUBLIC_ENABLE_RSS || true, // 是否开启 RSS 订阅功能
|
||||
|
||||
@@ -14,7 +14,6 @@ export const BlogItem = props => {
|
||||
const showPageCover = siteConfig('SIMPLE_POST_COVER_ENABLE', false, CONFIG)
|
||||
const showPreview =
|
||||
siteConfig('POST_LIST_PREVIEW', false, NOTION_CONFIG) && post.blockMap
|
||||
console.log(post);
|
||||
return (
|
||||
<div
|
||||
key={post.id}
|
||||
|
||||
@@ -35,7 +35,7 @@ export default function BlogListPage(props) {
|
||||
.replace('.html', '')
|
||||
|
||||
return (
|
||||
<div className='w-full md:pr-8 mb-12 md:mt-20'>
|
||||
<div className='w-full md:pr-8 mb-12'>
|
||||
<div id='posts-wrapper'>
|
||||
{posts?.map((p, index) => (
|
||||
<div key={p.id}>
|
||||
|
||||
@@ -18,38 +18,71 @@ const Catalog = ({ post }) => {
|
||||
|
||||
// 监听滚动事件
|
||||
useEffect(() => {
|
||||
const throttleMs = 200
|
||||
// 如果没有文章或目录,不执行任何操作
|
||||
if (!post || !post?.toc || post?.toc?.length < 1) {
|
||||
return
|
||||
}
|
||||
|
||||
const throttleMs = 100 // 降低节流时间提高响应速度
|
||||
|
||||
const actionSectionScrollSpy = throttle(() => {
|
||||
const sections = document.getElementsByClassName('notion-h')
|
||||
if (!sections || sections.length === 0) return
|
||||
|
||||
let prevBBox = null
|
||||
let currentSectionId = activeSection
|
||||
let currentSectionId = null
|
||||
|
||||
// 先检查当前视口中的所有标题
|
||||
for (let i = 0; i < sections.length; ++i) {
|
||||
const section = sections[i]
|
||||
if (!section || !(section instanceof Element)) continue
|
||||
if (!currentSectionId) {
|
||||
currentSectionId = section.getAttribute('data-id')
|
||||
}
|
||||
|
||||
const bbox = section.getBoundingClientRect()
|
||||
const prevHeight = prevBBox ? bbox.top - prevBBox.bottom : 0
|
||||
const offset = Math.max(150, prevHeight / 4)
|
||||
const offset = 100 // 固定偏移量,避免计算不稳定
|
||||
|
||||
// 如果标题在视口上方或接近顶部,认为是当前标题
|
||||
if (bbox.top - offset < 0) {
|
||||
currentSectionId = section.getAttribute('data-id')
|
||||
prevBBox = bbox
|
||||
continue
|
||||
} else {
|
||||
// 找到第一个在视口下方的标题就停止
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没找到任何标题在视口上方,使用第一个标题
|
||||
if (!currentSectionId && sections.length > 0) {
|
||||
currentSectionId = sections[0].getAttribute('data-id')
|
||||
}
|
||||
|
||||
// 只有当 ID 变化时才更新状态,减少不必要的渲染
|
||||
if (currentSectionId !== activeSection) {
|
||||
setActiveSection(currentSectionId)
|
||||
|
||||
// 查找目录中对应的索引并滚动
|
||||
const index = post?.toc?.findIndex(
|
||||
obj => uuidToId(obj.id) === currentSectionId
|
||||
)
|
||||
|
||||
if (index !== -1 && tRef?.current) {
|
||||
tRef.current.scrollTo({ top: 28 * index, behavior: 'smooth' })
|
||||
}
|
||||
break
|
||||
}
|
||||
setActiveSection(currentSectionId)
|
||||
const index = post?.toc?.findIndex(
|
||||
obj => uuidToId(obj.id) === currentSectionId
|
||||
)
|
||||
tRef?.current?.scrollTo({ top: 28 * index, behavior: 'smooth' })
|
||||
}, throttleMs)
|
||||
|
||||
window.addEventListener('scroll', actionSectionScrollSpy)
|
||||
actionSectionScrollSpy()
|
||||
|
||||
const content = document.querySelector('#container-inner')
|
||||
if (!content) return // 防止 content 不存在
|
||||
|
||||
// 添加滚动和内容变化的监听
|
||||
content.addEventListener('scroll', actionSectionScrollSpy)
|
||||
|
||||
// 初始执行一次
|
||||
setTimeout(() => {
|
||||
actionSectionScrollSpy()
|
||||
}, 300) // 延迟执行确保 DOM 已完全加载
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('scroll', actionSectionScrollSpy)
|
||||
content?.removeEventListener('scroll', actionSectionScrollSpy)
|
||||
}
|
||||
}, [post])
|
||||
|
||||
@@ -68,21 +101,27 @@ const Catalog = ({ post }) => {
|
||||
<div
|
||||
className='overflow-y-auto overscroll-none max-h-36 lg:max-h-96 scroll-hidden'
|
||||
ref={tRef}>
|
||||
<nav className='h-full text-black'>
|
||||
<nav className='h-full text-black group'>
|
||||
{post?.toc?.map(tocItem => {
|
||||
const id = uuidToId(tocItem.id)
|
||||
return (
|
||||
<a
|
||||
key={id}
|
||||
href={`#${id}`}
|
||||
className={`${activeSection === id && 'dark:border-white border-red-700 text-red-700 font-bold'} hover:font-semibold border-l pl-4 block hover:text-red-600 border-lduration-300 transform dark:text-red-400 dark:border-red-400
|
||||
notion-table-of-contents-item-indent-level-${tocItem.indentLevel} catalog-item `}>
|
||||
className={`${activeSection === id
|
||||
? 'dark:border-white border-red-700 text-red-700 font-bold'
|
||||
: 'text-[var(--primary-color)] dark:text-gray-500 filter blur-[1px] opacity-50 group-hover:filter-none group-hover:blur-0 group-hover:opacity-100'}
|
||||
hover:font-semibold hover:text-red-600 hover:filter-none hover:blur-0 hover:opacity-100
|
||||
border-l pl-4 block border-lduration-300 transform
|
||||
dark:hover:text-red-400 dark:border-gray-600
|
||||
notion-table-of-contents-item-indent-level-${tocItem.indentLevel} catalog-item
|
||||
transition-all duration-300 ease-in-out`}>
|
||||
<span
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
marginLeft: tocItem.indentLevel * 16
|
||||
}}
|
||||
className={`truncate ${activeSection === id ? ' font-bold text-red-600 dark:text-white underline' : ''}`}>
|
||||
className={`truncate ${activeSection === id ? 'font-bold text-red-600 dark:text-white underline' : ''}`}>
|
||||
{tocItem.text}
|
||||
</span>
|
||||
</a>
|
||||
|
||||
@@ -14,11 +14,15 @@ import Link from 'next/link'
|
||||
export default function NavBar(props) {
|
||||
return (
|
||||
<div className='flex flex-col justify-between md:mt-20 md:h-[70vh]'>
|
||||
<header className='md:pb-8 md:border-l-2 md:border-gray-700 text-[var(--primary-color)] md:[writing-mode:vertical-lr] px-4'>
|
||||
<header className='w-fit self-center md:self-start md:pb-8 md:border-l-2 md:border-[var(--primary-color)] text-[var(--primary-color)] md:[writing-mode:vertical-lr] px-4 hover:bg-[var(--primary-color)] hover:text-white ease-in-out duration-700 md:hover:pt-4 md:hover:pb-4'>
|
||||
<Link href='/'>
|
||||
<div className='flex flex-col-reverse md:flex-col items-center md:items-start'>
|
||||
<div className='font-bold text-4xl text-center' id='blog-name'>活版印字</div>
|
||||
<div className='font-bold text-xl text-center' id='blog-name-en'>Typography</div>
|
||||
<div className='font-bold text-4xl text-center' id='blog-name'>
|
||||
活版印字
|
||||
</div>
|
||||
<div className='font-bold text-xl text-center' id='blog-name-en'>
|
||||
Typography
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</header>
|
||||
|
||||
@@ -12,6 +12,7 @@ import { createContext, useContext, useEffect, useRef } from 'react'
|
||||
import BlogPostBar from './components/BlogPostBar'
|
||||
import CONFIG from './config'
|
||||
import { Style } from './style'
|
||||
import Catalog from './components/Catalog'
|
||||
|
||||
const AlgoliaSearchModal = dynamic(
|
||||
() => import('@/components/AlgoliaSearchModal'),
|
||||
@@ -19,9 +20,7 @@ const AlgoliaSearchModal = dynamic(
|
||||
)
|
||||
|
||||
// 主题组件
|
||||
const BlogListScroll = dynamic(() => import('./components/BlogListScroll'), {
|
||||
ssr: false
|
||||
})
|
||||
|
||||
const BlogArchiveItem = dynamic(() => import('./components/BlogArchiveItem'), {
|
||||
ssr: false
|
||||
})
|
||||
@@ -35,9 +34,7 @@ const Comment = dynamic(() => import('@/components/Comment'), { ssr: false })
|
||||
const ArticleAround = dynamic(() => import('./components/ArticleAround'), {
|
||||
ssr: false
|
||||
})
|
||||
const ShareBar = dynamic(() => import('@/components/ShareBar'), { ssr: false })
|
||||
const TopBar = dynamic(() => import('./components/TopBar'), { ssr: false })
|
||||
const Header = dynamic(() => import('./components/Header'), { ssr: false })
|
||||
const NavBar = dynamic(() => import('./components/NavBar'), { ssr: false })
|
||||
const JumpToTopButton = dynamic(() => import('./components/JumpToTopButton'), {
|
||||
ssr: false
|
||||
@@ -66,9 +63,11 @@ export const useSimpleGlobal = () => useContext(ThemeGlobalSimple)
|
||||
*/
|
||||
const LayoutBase = props => {
|
||||
const { children, slotTop } = props
|
||||
const { onLoading, fullWidth } = useGlobal()
|
||||
// const { onLoading, fullWidth } = useGlobal()
|
||||
const onLoading = true
|
||||
const searchModal = useRef(null)
|
||||
|
||||
console.log('aa', props)
|
||||
return (
|
||||
<ThemeGlobalSimple.Provider value={{ searchModal }}>
|
||||
<div
|
||||
@@ -78,13 +77,19 @@ const LayoutBase = props => {
|
||||
|
||||
{siteConfig('SIMPLE_TOP_BAR', null, CONFIG) && <TopBar {...props} />}
|
||||
|
||||
<div className='flex flex-1 gap-24 mx-auto overflow-hidden p-8 md:p-0 md:max-w-7xl md:w-8/12 w-screen'>
|
||||
<div className='flex flex-1 mx-auto overflow-hidden p-8 md:p-0 md:max-w-7xl md:w-8/12 w-screen'>
|
||||
{/* 主体 - 使用 flex 布局 */}
|
||||
<div className='overflow-hidden'>
|
||||
{/* 文章详情才显示 */}
|
||||
{props.post && (
|
||||
<div className='mt-20 hidden md:block'>
|
||||
<Catalog {...props} />
|
||||
</div>
|
||||
)}
|
||||
<div className='overflow-hidden mt-20'>
|
||||
{/* 左侧内容区域 - 可滚动 */}
|
||||
<div
|
||||
id='container-inner'
|
||||
className='flex-1 h-full w-full overflow-y-auto scroll-hidden'>
|
||||
className='flex-1 h-full w-full px-24 overflow-y-auto scroll-hidden'>
|
||||
{/* 移动端导航 - 显示在顶部 */}
|
||||
<div className='md:hidden'>
|
||||
<NavBar {...props} />
|
||||
@@ -103,6 +108,17 @@ const LayoutBase = props => {
|
||||
|
||||
{children}
|
||||
</Transition>
|
||||
|
||||
{onLoading && (
|
||||
<div className="flex flex-col justify-center items-center min-h-[50vh]">
|
||||
<div className="flex space-x-2">
|
||||
<div className="w-2 h-2 bg-gray-500 dark:bg-gray-300 rounded-full animate-bounce [animation-delay:-0.3s]"></div>
|
||||
<div className="w-2 h-2 bg-gray-500 dark:bg-gray-300 rounded-full animate-bounce [animation-delay:-0.15s]"></div>
|
||||
<div className="w-2 h-2 bg-gray-500 dark:bg-gray-300 rounded-full animate-bounce"></div>
|
||||
</div>
|
||||
<div className="text-xl font-medium text-gray-600 dark:text-gray-300">别着急,坐和放宽</div>
|
||||
</div>
|
||||
)}
|
||||
<AdSlot type='native' />
|
||||
{/* 移动端页脚 - 显示在底部 */}
|
||||
<div className='md:hidden z-30 dark:bg-black'>
|
||||
@@ -110,6 +126,7 @@ const LayoutBase = props => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 右侧导航和页脚 - 固定不滚动 */}
|
||||
<div className='hidden md:flex md:flex-col md:flex-shrink-0 md:h-[100vh] sticky top-20'>
|
||||
<NavBar {...props} />
|
||||
@@ -217,7 +234,7 @@ const LayoutSlug = props => {
|
||||
|
||||
{!lock && post && (
|
||||
<div
|
||||
className={`px-2 md:pt-20 pt-3 ${fullWidth ? '' : 'xl:max-w-4xl 2xl:max-w-6xl'}`}>
|
||||
className={`px-2 pt-3 ${fullWidth ? '' : 'xl:max-w-4xl 2xl:max-w-6xl'}`}>
|
||||
{/* 文章信息 */}
|
||||
<ArticleInfo post={post} />
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ const Style = () => {
|
||||
#theme-typography {
|
||||
--primary-color: #2e405b;
|
||||
background-color: rgb(255 255 255) / 1;
|
||||
color: rgb(46, 64, 91);
|
||||
color: #2e405b;
|
||||
background-size: 7px 7px;
|
||||
text-shadow: 1px 1px 1px rgb(0 0 0 / 0.04);
|
||||
background-image: linear-gradient(
|
||||
|
||||
Reference in New Issue
Block a user