目录组件百分比进度
This commit is contained in:
tangly1024
2021-12-22 16:22:17 +08:00
parent 0ef9da886f
commit 565b3ac194
9 changed files with 33 additions and 23 deletions

View File

@@ -165,10 +165,13 @@ export default function ArticleDetail ({ post, blockMap, recommendPosts, prev, n
{/* 悬浮目录按钮 */}
<div className="block lg:hidden">
<TocDrawerButton onClick={() => { drawerRight.current.handleSwitchVisible() }} />
<TocDrawer post={post} cRef={drawerRight} />
<TocDrawer post={post} cRef={drawerRight} targetRef={targetRef} />
</div>
<Progress targetRef={targetRef} />
{/* 移动端顶部进度条 */}
{/* <div className='fixed left-0 top-0 w-full z-40 block md:hidden'>
<Progress targetRef={targetRef} />
</div> */}
</>)
}

View File

@@ -12,7 +12,7 @@ import smoothscroll from 'smoothscroll-polyfill'
* @returns {JSX.Element}
* @constructor
*/
const JumpToBottomButton = ({ targetRef, showPercent = true }) => {
const JumpToBottomButton = ({ targetRef, showPercent = false }) => {
const { locale } = useGlobal()
const [show, switchShow] = useState(false)
const [percent, changePercent] = useState(0)

View File

@@ -12,7 +12,7 @@ import smoothscroll from 'smoothscroll-polyfill'
* @returns {JSX.Element}
* @constructor
*/
const JumpToTopButton = ({ targetRef, showPercent = true }) => {
const JumpToTopButton = ({ targetRef, showPercent = false }) => {
const { locale } = useGlobal()
const [show, switchShow] = useState(false)
const [percent, changePercent] = useState(0)
@@ -39,7 +39,7 @@ const JumpToTopButton = ({ targetRef, showPercent = true }) => {
return (<div id='jump-to-top' className='right-3 fixed flex bottom-48 duration-500 z-20'>
<div onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}
className={(show ? '' : 'hidden') + ' animate__fadeInRight animate__animated animate__faster shadow-card rounded-xl glassmorphism py-1 cursor-pointer '}>
className={(show ? '' : 'hidden') + ' animate__fadeInRight animate__animated animate__faster shadow-card rounded-xl glassmorphism py-3 cursor-pointer '}>
<div className='text-center'>
<div className='w-10 dark:text-gray-200 transform hover:scale-150 duration-200 text-xs' title={locale.POST.TOP} >
<FontAwesomeIcon icon={faArrowUp} />

View File

@@ -8,7 +8,7 @@ import React, { useEffect, useState } from 'react'
const Progress = ({ targetRef }) => {
const [percent, changePercent] = useState(0)
const scrollListener = () => {
if (targetRef.current) {
if (targetRef?.current) {
const clientHeight = targetRef ? (targetRef.current.clientHeight) : 0
const scrollY = window.pageYOffset
const fullHeight = clientHeight - window.outerHeight
@@ -23,8 +23,9 @@ const Progress = ({ targetRef }) => {
return () => document.removeEventListener('scroll', scrollListener)
}, [percent])
return (<div className='h-1 fixed left-0 top-0 w-full shadow-2xl z-40 bg-blue-200'>
<div className='h-1 bg-blue-600 fixed left-0 top-0 duration-200 rounded' style={{ width: `${percent}%` }}/>
return (<div className='h-4 w-full shadow-2xl bg-purple-400'>
<div className='text-center w-full absolute text-white text-xs'>{percent}%</div>
<div className='h-4 bg-purple-700 duration-200 rounded-r' style={{ width: `${percent}%` }}/>
</div>)
}

View File

@@ -8,6 +8,7 @@ import { faAngleDoubleRight, faChartBar, faThList } from '@fortawesome/free-soli
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import Link from 'next/link'
import React from 'react'
import Progress from './Progress'
/**
* 侧边平铺
@@ -21,7 +22,7 @@ import React from 'react'
* @returns {JSX.Element}
* @constructor
*/
const SideAreaLeft = ({ title, tags, currentTag, post, posts, categories, currentCategory, currentSearch }) => {
const SideAreaLeft = ({ title, tags, currentTag, post, posts, categories, currentCategory, currentSearch, targetRef }) => {
const { locale } = useGlobal()
const showToc = post && post.toc && post.toc.length > 1
const postCount = posts?.length || 0
@@ -71,10 +72,10 @@ const SideAreaLeft = ({ title, tags, currentTag, post, posts, categories, curren
{showToc && (
<section className='sticky top-8 pb-20 rounded-xl shadow-md bg-white dark:bg-gray-800 hover:shadow-2xl duration-200'>
<div className='border-b text-2xl bg-white text-black rounded-t-xl dark:border-gray-700 dark:bg-gray-700 dark:text-white py-6 px-6'>
<div className='border-b text-center text-2xl bg-white text-black rounded-t-xl dark:border-gray-700 dark:bg-gray-700 dark:text-white py-6 px-6'>
{locale.COMMON.TABLE_OF_CONTENTS}
</div>
<Toc toc={post.toc} />
<Toc toc={post.toc} targetRef={targetRef} />
</section>
)}
</>

View File

@@ -1,6 +1,7 @@
import React, { useCallback } from 'react'
import throttle from 'lodash.throttle'
import { uuidToId } from 'notion-utils'
import Progress from './Progress'
// import { cs } from 'react-notion-x'
/**
@@ -9,7 +10,7 @@ import { uuidToId } from 'notion-utils'
* @returns {JSX.Element}
* @constructor
*/
const Toc = ({ toc }) => {
const Toc = ({ toc, targetRef }) => {
// 无目录就直接返回空
if (!toc || toc.length < 1) return <></>
@@ -51,6 +52,9 @@ const Toc = ({ toc }) => {
}, throttleMs))
return <>
<div className='w-full'>
<Progress targetRef={targetRef}/>
</div>
<nav className=' dark:text-gray-100 bg-white dark:bg-gray-800 overflow-y-auto scroll-hidden p-6'>
{toc.map((tocItem) => {
const id = uuidToId(tocItem.id)
@@ -58,9 +62,9 @@ const Toc = ({ toc }) => {
<a
key={id}
href={`#${id}`}
className={`notion-table-of-contents-item duration-300 transform font-light
className={`notion-table-of-contents-item duration-300 transform font-mono
notion-table-of-contents-item-indent-level-${tocItem.indentLevel}
${activeSection === id && ' font-bold text-blue-400 dark:text-white'}`}
${activeSection === id && ' font-bold text-purple-500 dark:text-purple-400'}`}
>
<span
style={{

View File

@@ -9,7 +9,7 @@ import { useGlobal } from '@/lib/global'
* @returns {JSX.Element}
* @constructor
*/
const TocDrawer = ({ post, cRef }) => {
const TocDrawer = ({ post, cRef, targetRef }) => {
// 暴露给父组件 通过cRef.current.handleMenuClick 调用
useImperativeHandle(cRef, () => {
return {
@@ -26,13 +26,13 @@ const TocDrawer = ({ post, cRef }) => {
{/* 侧边菜单 */}
<div
className={(showDrawer ? 'animate__slideInRight ' : ' -mr-72 animate__slideOutRight') +
' shadow-xl animate__animated animate__faster max-h-96 ' +
' shadow-card animate__animated animate__faster max-h-96 ' +
' w-60 duration-200 fixed right-4 top-16 rounded overflow-y-auto'}>
{post && <>
<div className='text-xl font-bold text-black dark:text-white bg-gray-200 dark:bg-gray-600 py-2 px-6'>
<div className='text-xl font-bold text-center text-black dark:text-white bg-white dark:bg-gray-600 py-2 px-6'>
{locale.COMMON.TABLE_OF_CONTENTS}
</div>
<Toc toc={post.toc}/>
<Toc toc={post.toc} targetRef={targetRef}/>
</>
}
</div>

View File

@@ -75,7 +75,7 @@ const BaseLayout = ({
<div className='flex justify-center flex-1 mx-auto md:pt-8 pb-12'>
<div id='left' className='hidden lg:block flex-col w-72'>
<SideAreaLeft title={meta.title} post={post} posts={totalPosts} tags={tags} currentSearch={currentSearch} currentTag={currentTag} categories={categories} currentCategory={currentCategory} />
<SideAreaLeft targetRef={targetRef} title={meta.title} post={post} posts={totalPosts} tags={tags} currentSearch={currentSearch} currentTag={currentTag} categories={categories} currentCategory={currentCategory} />
</div>
<div id='center' className='flex-grow max-w-4xl min-h-screen md:mx-10' ref={targetRef}>
@@ -94,7 +94,7 @@ const BaseLayout = ({
</div>
<Footer title={meta.title}/>
<JumpToTopButton targetRef={targetRef} showPercent={true} />
<JumpToTopButton targetRef={targetRef} showPercent={false} />
<JumpToBottomButton targetRef={targetRef} showPercent={false}/>
<FloatDarkModeButton/>
</div>

View File

@@ -1,4 +1,5 @@
import { getCacheFromMemory, setCacheToMemory } from '@/lib/cache/memory_cache'
// import { getCacheFromMemory, setCacheToMemory } from '@/lib/cache/memory_cache'
import { getCacheFromFile, setCacheToFile } from './local_file_cache'
const enableCache = true // 生产环境禁用
/**
@@ -10,7 +11,7 @@ export async function getDataFromCache (key) {
if (!enableCache) {
return null
}
const dataFromCache = await getCacheFromMemory(key)
const dataFromCache = await getCacheFromFile(key)
if (JSON.stringify(dataFromCache) === '[]') {
return null
}
@@ -21,5 +22,5 @@ export async function setDataToCache (key, data) {
if (!enableCache || !data) {
return
}
await setCacheToMemory(key, data)
await setCacheToFile(key, data)
}