From cd8a39a6e48d894f60655f5f43a3a2f52f1b4443 Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Sun, 11 Dec 2022 17:43:37 +0800 Subject: [PATCH 1/9] LatestPosts --- styles/globals.css | 11 +++++++++++ themes/hexo/components/LatestPostsGroup.js | 14 ++++++++------ themes/next/components/LatestPostsGroup.js | 12 ++++++------ 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/styles/globals.css b/styles/globals.css index 6035eed9..a4e86ff1 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -191,4 +191,15 @@ nav { .wl-meta > span { @apply dark:bg-gray-800 !important +} + +/* 固定两行 */ +.text-line-2 { + overflow : hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + word-wrap: break-word; + word-break: break-all; } \ No newline at end of file diff --git a/themes/hexo/components/LatestPostsGroup.js b/themes/hexo/components/LatestPostsGroup.js index 3c4a9a46..96eda369 100644 --- a/themes/hexo/components/LatestPostsGroup.js +++ b/themes/hexo/components/LatestPostsGroup.js @@ -10,12 +10,14 @@ import { useRouter } from 'next/router' * @constructor */ const LatestPostsGroup = ({ latestPosts, siteInfo }) => { - if (!latestPosts) { - return <> - } // 获取当前路径 const currentPath = useRouter().asPath const { locale } = useGlobal() + + if (!latestPosts) { + return <> + } + return ( <>
@@ -37,7 +39,7 @@ const LatestPostsGroup = ({ latestPosts, siteInfo }) => { href={`${BLOG.SUB_PATH}/${post.slug}`} passHref > - +
{
-
{post.title}
+
{post.title}
{post.lastEditedTime}
diff --git a/themes/next/components/LatestPostsGroup.js b/themes/next/components/LatestPostsGroup.js index a55e1bf1..79de1c5c 100644 --- a/themes/next/components/LatestPostsGroup.js +++ b/themes/next/components/LatestPostsGroup.js @@ -10,13 +10,14 @@ import { useRouter } from 'next/router' * @constructor */ const LatestPostsGroup = ({ latestPosts }) => { - if (!latestPosts) { - return <> - } // 获取当前路径 const currentPath = useRouter().asPath const { locale } = useGlobal() + if (!latestPosts) { + return <> + } + return ( <>
@@ -40,12 +41,11 @@ const LatestPostsGroup = ({ latestPosts }) => { (selected ? 'text-white bg-gray-600 ' : 'text-gray-500 dark:text-gray-400 ') + - ' text-xs py-1.5 flex overflow-x-hidden whitespace-nowrap hover:bg-gray-500 px-2 duration-200 w-full ' + + ' text-xs py-1.5 flex hover:bg-gray-500 px-2 duration-200 w-full ' + 'hover:text-white dark:hover:text-white cursor-pointer' } > - -
{post.title}
+
  • {post.title}
  • From 87da9c0dbfcf5a80efd40de6e6c16e0f10c8158f Mon Sep 17 00:00:00 2001 From: xloong Date: Mon, 12 Dec 2022 14:44:33 +0800 Subject: [PATCH 2/9] =?UTF-8?q?fix=20=E4=BB=85=E6=96=87=E7=AB=A0=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E4=B8=BAPublished=E7=9A=84=EF=BC=8C=E8=AE=A1=E7=AE=97?= =?UTF-8?q?category=E4=B8=8Etags=E8=AE=A1=E6=95=B0=EF=BC=8CInvisible?= =?UTF-8?q?=E7=9A=84=E6=96=87=E7=AB=A0=E4=B8=8D=E5=8F=82=E4=B8=8E=E8=AE=A1?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/notion/getAllCategories.js | 2 +- lib/notion/getAllTags.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/notion/getAllCategories.js b/lib/notion/getAllCategories.js index 2225b965..b7700bc1 100644 --- a/lib/notion/getAllCategories.js +++ b/lib/notion/getAllCategories.js @@ -14,7 +14,7 @@ import { isIterable } from '../utils' * @returns {Promise<{}|*[]>} */ export function getAllCategories({ allPages, categoryOptions, sliceCount = 0 }) { - const allPosts = allPages.filter(page => page.type === 'Post') + const allPosts = allPages.filter(page => page.type === 'Post' && page.status === 'Published') if (!allPosts || !categoryOptions) { return [] } diff --git a/lib/notion/getAllTags.js b/lib/notion/getAllTags.js index 098f62fb..b9144be8 100644 --- a/lib/notion/getAllTags.js +++ b/lib/notion/getAllTags.js @@ -8,7 +8,7 @@ import { isIterable } from '../utils' * @returns {Promise<{}|*[]>} */ export function getAllTags({ allPages, sliceCount = 0, tagOptions }) { - const allPosts = allPages.filter(page => page.type === 'Post') + const allPosts = allPages.filter(page => page.type === 'Post' && page.status === 'Published') if (!allPosts || !tagOptions) { return [] From 5d8c852c52f4a4f1f2893b35f1c59fe727d7215d Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Tue, 13 Dec 2022 09:50:49 +0800 Subject: [PATCH 3/9] =?UTF-8?q?toggle-header=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- styles/notion.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/styles/notion.css b/styles/notion.css index 92acdb96..d010bb0c 100644 --- a/styles/notion.css +++ b/styles/notion.css @@ -392,7 +392,7 @@ .notion-h { position: relative; - display: block; + /* display: block; */ font-weight: 600; line-height: 1.3; padding: 3px 2px; From afe4c679fa537e6e824124132c18750f1077fdd5 Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Tue, 13 Dec 2022 21:21:32 +0800 Subject: [PATCH 4/9] =?UTF-8?q?hook=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- themes/hexo/LayoutSlug.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/hexo/LayoutSlug.js b/themes/hexo/LayoutSlug.js index 7875c990..0818ba01 100644 --- a/themes/hexo/LayoutSlug.js +++ b/themes/hexo/LayoutSlug.js @@ -15,6 +15,7 @@ import { isBrowser } from '@/lib/utils' export const LayoutSlug = props => { const { post, lock, validPassword } = props + const drawerRight = useRef(null) if (!post) { return { post.toc = getPageTableOfContents(post, post.blockMap) } - const drawerRight = useRef(null) const targetRef = isBrowser() ? document.getElementById('container') : null const floatSlot = <> From ff24524aae59bce9187c5de59befabb434315cc9 Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Wed, 14 Dec 2022 12:19:28 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E5=B0=81=E8=A3=85=E5=8A=A0=E5=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/[...slug].js | 13 ++++++++++--- themes/example/LayoutSlug.js | 8 +------- themes/example/components/ArticleLock.js | 6 ++---- themes/fukasawa/LayoutSlug.js | 10 ++-------- themes/fukasawa/components/ArticleLock.js | 6 ++---- themes/hexo/LayoutSlug.js | 8 +------- themes/hexo/components/ArticleLock.js | 6 ++---- themes/hexo/components/HeaderArticle.js | 3 ++- themes/medium/LayoutSlug.js | 9 +-------- themes/medium/components/ArticleLock.js | 6 ++---- themes/next/LayoutSlug.js | 8 +------- themes/next/components/ArticleLock.js | 6 ++---- 12 files changed, 28 insertions(+), 61 deletions(-) diff --git a/pages/[...slug].js b/pages/[...slug].js index c790f211..cae6d4b1 100644 --- a/pages/[...slug].js +++ b/pages/[...slug].js @@ -4,7 +4,7 @@ import { getGlobalNotionData } from '@/lib/notion/getNotionData' import { useGlobal } from '@/lib/global' import * as ThemeMap from '@/themes' import React from 'react' -import { idToUuid } from 'notion-utils' +import { idToUuid, getPageTableOfContents } from 'notion-utils' import Router from 'next/router' import { isBrowser } from '@/lib/utils' import { getNotion } from '@/lib/notion/getNotion' @@ -28,6 +28,11 @@ const Slug = props => { if (post?.password && post?.password !== '') { setLock(true) } else { + if (!lock && post?.blockMap?.block) { + post.content = Object.keys(post.blockMap.block) + post.toc = getPageTableOfContents(post, post.blockMap) + } + setLock(false) } }, [post]) @@ -51,10 +56,12 @@ const Slug = props => { * 验证文章密码 * @param {*} result */ - const validPassword = result => { - if (result) { + const validPassword = passInput => { + if (passInput && passInput === post.password) { setLock(false) + return true } + return false } props = { ...props, lock, setLock, validPassword } diff --git a/themes/example/LayoutSlug.js b/themes/example/LayoutSlug.js index 1f7fd409..b16892b7 100644 --- a/themes/example/LayoutSlug.js +++ b/themes/example/LayoutSlug.js @@ -1,4 +1,3 @@ -import { getPageTableOfContents } from 'notion-utils' import LayoutBase from './LayoutBase' import { ArticleLock } from './components/ArticleLock' import NotionPage from '@/components/NotionPage' @@ -12,15 +11,10 @@ export const LayoutSlug = props => { return } - if (!lock && post?.blockMap?.block) { - post.content = Object.keys(post.blockMap.block) - post.toc = getPageTableOfContents(post, post.blockMap) - } - return ( - {lock && } + {lock && } {!lock &&
    diff --git a/themes/example/components/ArticleLock.js b/themes/example/components/ArticleLock.js index a9f5f59d..43b6647e 100644 --- a/themes/example/components/ArticleLock.js +++ b/themes/example/components/ArticleLock.js @@ -8,14 +8,12 @@ import { useGlobal } from '@/lib/global' * @returns */ export const ArticleLock = props => { - const { password, validPassword } = props + const { validPassword } = props const { locale } = useGlobal() const submitPassword = () => { const p = document.getElementById('password') - if (p && p.value && p.value === password) { - validPassword(true) - } else { + if (!validPassword(p?.value)) { const tips = document.getElementById('tips') if (tips) { tips.innerHTML = '' diff --git a/themes/fukasawa/LayoutSlug.js b/themes/fukasawa/LayoutSlug.js index 30265a6c..fb78690c 100644 --- a/themes/fukasawa/LayoutSlug.js +++ b/themes/fukasawa/LayoutSlug.js @@ -1,19 +1,13 @@ -import { getPageTableOfContents } from 'notion-utils' import ArticleDetail from './components/ArticleDetail' import LayoutBase from './LayoutBase' import { ArticleLock } from './components/ArticleLock' export const LayoutSlug = (props) => { - const { post, lock, validPassword } = props - if (!lock && post?.blockMap?.block) { - post.content = Object.keys(post.blockMap.block) - post.toc = getPageTableOfContents(post, post.blockMap) - } - + const { lock, validPassword } = props return ( {!lock && } - {lock && } + {lock && } ) } diff --git a/themes/fukasawa/components/ArticleLock.js b/themes/fukasawa/components/ArticleLock.js index 23112eeb..8ae18a4e 100644 --- a/themes/fukasawa/components/ArticleLock.js +++ b/themes/fukasawa/components/ArticleLock.js @@ -8,14 +8,12 @@ import { useGlobal } from '@/lib/global' * @returns */ export const ArticleLock = props => { - const { password, validPassword } = props + const { validPassword } = props const { locale } = useGlobal() const submitPassword = () => { const p = document.getElementById('password') - if (p && p.value && p.value === password) { - validPassword(true) - } else { + if (!validPassword(p?.value)) { const tips = document.getElementById('tips') if (tips) { tips.innerHTML = '' diff --git a/themes/hexo/LayoutSlug.js b/themes/hexo/LayoutSlug.js index 0818ba01..327497ac 100644 --- a/themes/hexo/LayoutSlug.js +++ b/themes/hexo/LayoutSlug.js @@ -1,4 +1,3 @@ -import { getPageTableOfContents } from 'notion-utils' import { useRef } from 'react' import { ArticleLock } from './components/ArticleLock' import HeaderArticle from './components/HeaderArticle' @@ -26,11 +25,6 @@ export const LayoutSlug = props => { > } - if (!lock && post?.blockMap?.block) { - post.content = Object.keys(post.blockMap.block) - post.toc = getPageTableOfContents(post, post.blockMap) - } - const targetRef = isBrowser() ? document.getElementById('container') : null const floatSlot = <> @@ -53,7 +47,7 @@ export const LayoutSlug = props => { floatSlot={floatSlot} >
    - {lock && } + {lock && } {!lock &&
    diff --git a/themes/hexo/components/ArticleLock.js b/themes/hexo/components/ArticleLock.js index 84ef905f..1a1bd193 100644 --- a/themes/hexo/components/ArticleLock.js +++ b/themes/hexo/components/ArticleLock.js @@ -8,13 +8,11 @@ import { useGlobal } from '@/lib/global' * @returns */ export const ArticleLock = props => { - const { password, validPassword } = props + const { validPassword } = props const { locale } = useGlobal() const submitPassword = () => { const p = document.getElementById('password') - if (p && p.value && p.value === password) { - validPassword(true) - } else { + if (!validPassword(p?.value)) { const tips = document.getElementById('tips') if (tips) { tips.innerHTML = '' diff --git a/themes/hexo/components/HeaderArticle.js b/themes/hexo/components/HeaderArticle.js index 918c75c7..8ebfe2bd 100644 --- a/themes/hexo/components/HeaderArticle.js +++ b/themes/hexo/components/HeaderArticle.js @@ -4,12 +4,13 @@ import formatDate from '@/lib/formatDate' import BLOG from '@/blog.config' export default function HeaderArticle({ post, siteInfo }) { + const { locale } = useGlobal() + if (!post) { return <> } const headerImage = post?.page_cover ? `url("${post.page_cover}")` : `url("${siteInfo?.pageCover}")` - const { locale } = useGlobal() const date = formatDate( post?.date?.start_date || post?.createdTime, locale.LOCALE diff --git a/themes/medium/LayoutSlug.js b/themes/medium/LayoutSlug.js index f7fdc4d0..bdeec1a5 100644 --- a/themes/medium/LayoutSlug.js +++ b/themes/medium/LayoutSlug.js @@ -1,5 +1,3 @@ -import { getPageTableOfContents } from 'notion-utils' - import LayoutBase from './LayoutBase' import { useGlobal } from '@/lib/global' import React from 'react' @@ -16,11 +14,6 @@ export const LayoutSlug = props => { /> } - if (!lock && post?.blockMap?.block) { - post.content = Object.keys(post.blockMap.block) - post.toc = getPageTableOfContents(post, post.blockMap) - } - const slotRight = post?.toc && post?.toc?.length > 3 && (
    @@ -29,7 +22,7 @@ export const LayoutSlug = props => { return ( - {!lock ? : } + {!lock ? : } ) } diff --git a/themes/medium/components/ArticleLock.js b/themes/medium/components/ArticleLock.js index 4b969835..1e1bb228 100644 --- a/themes/medium/components/ArticleLock.js +++ b/themes/medium/components/ArticleLock.js @@ -8,14 +8,12 @@ import { useGlobal } from '@/lib/global' * @returns */ export const ArticleLock = props => { - const { password, validPassword } = props + const { validPassword } = props const { locale } = useGlobal() const submitPassword = () => { const p = document.getElementById('password') - if (p && p.value && p.value === password) { - validPassword(true) - } else { + if (!validPassword(p?.value)) { const tips = document.getElementById('tips') if (tips) { tips.innerHTML = '' diff --git a/themes/next/LayoutSlug.js b/themes/next/LayoutSlug.js index aa1cc4d2..fa1915a1 100644 --- a/themes/next/LayoutSlug.js +++ b/themes/next/LayoutSlug.js @@ -1,4 +1,3 @@ -import { getPageTableOfContents } from 'notion-utils' import TocDrawerButton from './components/TocDrawerButton' import LayoutBase from './LayoutBase' import Card from './components/Card' @@ -12,11 +11,6 @@ import { isBrowser } from '@/lib/utils' export const LayoutSlug = (props) => { const { post, latestPosts, lock, validPassword } = props - if (!lock && post?.blockMap?.block) { - post.content = Object.keys(post.blockMap.block) - post.toc = getPageTableOfContents(post, post.blockMap) - } - const drawerRight = useRef(null) const targetRef = isBrowser() ? document.getElementById('container') : null const floatSlot = post?.toc?.length > 1 @@ -45,7 +39,7 @@ export const LayoutSlug = (props) => { {!lock && } - {lock && } + {lock && } {/* 悬浮目录按钮 */}
    diff --git a/themes/next/components/ArticleLock.js b/themes/next/components/ArticleLock.js index 4bb2ef65..3e4a2019 100644 --- a/themes/next/components/ArticleLock.js +++ b/themes/next/components/ArticleLock.js @@ -8,14 +8,12 @@ import { useGlobal } from '@/lib/global' * @returns */ export const ArticleLock = props => { - const { password, validPassword } = props + const { validPassword } = props const { locale } = useGlobal() const submitPassword = () => { const p = document.getElementById('password') - if (p && p.value && p.value === password) { - validPassword(true) - } else { + if (!validPassword(p?.value)) { const tips = document.getElementById('tips') if (tips) { tips.innerHTML = '' From 771819985aee595157182fc6dceb5293f27ffdfd Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Wed, 14 Dec 2022 13:47:14 +0800 Subject: [PATCH 6/9] encrypt-password --- lib/notion/getNotionData.js | 5 ++--- lib/notion/getPageProperties.js | 2 ++ package.json | 1 + pages/[...slug].js | 3 ++- themes/medium/LayoutCategory.js | 2 +- themes/medium/LayoutTag.js | 2 +- 6 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/notion/getNotionData.js b/lib/notion/getNotionData.js index 11913b2d..80444cdb 100644 --- a/lib/notion/getNotionData.js +++ b/lib/notion/getNotionData.js @@ -212,17 +212,16 @@ async function getPageRecordMapByNotionAPI({ pageId, from }) { collectionData.push(properties) } } - // 读取映射 配置 - let postCount = 0 // 获取page作为自定义菜单 const customNav = getCustomNav({ allPages: collectionData.filter(post => post.type === 'Page' && post.status === 'Published') }) + // 文章计数 + let postCount = 0 const allPages = collectionData.filter(post => { if (post.type === 'Post' && post.status === 'Published') { postCount++ } - return post && post.type && (post.type === 'Post' || post.type === 'Page') && diff --git a/lib/notion/getPageProperties.js b/lib/notion/getPageProperties.js index f4ee3282..ef93f84b 100644 --- a/lib/notion/getPageProperties.js +++ b/lib/notion/getPageProperties.js @@ -3,6 +3,7 @@ import { NotionAPI } from 'notion-client' import BLOG from '@/blog.config' import formatDate from '../formatDate' import { defaultMapImageUrl } from 'react-notion-x' +import md5 from 'js-md5' export default async function getPageProperties(id, block, schema, authToken, tagOptions, siteInfo) { const rawProperties = Object.entries(block?.[id]?.value?.properties || []) @@ -89,6 +90,7 @@ export default async function getPageProperties(id, block, schema, authToken, ta properties.pageIcon = getImageUrl(block[id].value?.format?.page_icon, block[id].value) ?? '' properties.page_cover = getImageUrl(block[id].value?.format?.page_cover, block[id].value) ?? siteInfo?.pageCover properties.content = value.content ?? [] + properties.password = properties.password ? md5(properties.slug + properties.password) : '' properties.tagItems = properties?.tags?.map(tag => { return { name: tag, color: tagOptions?.find(t => t.value === tag)?.color || 'gray' } }) || [] diff --git a/package.json b/package.json index c9e3b948..f022f9d0 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "eslint-plugin-react-hooks": "^4.6.0", "feed": "^4.2.2", "gitalk": "^1.7.2", + "js-md5": "^0.7.3", "localStorage": "^1.0.4", "lodash.throttle": "^4.1.1", "mark.js": "^8.11.1", diff --git a/pages/[...slug].js b/pages/[...slug].js index cae6d4b1..9d521d8f 100644 --- a/pages/[...slug].js +++ b/pages/[...slug].js @@ -8,6 +8,7 @@ import { idToUuid, getPageTableOfContents } from 'notion-utils' import Router from 'next/router' import { isBrowser } from '@/lib/utils' import { getNotion } from '@/lib/notion/getNotion' +import md5 from 'js-md5' /** * 根据notion的slug访问页面 @@ -57,7 +58,7 @@ const Slug = props => { * @param {*} result */ const validPassword = passInput => { - if (passInput && passInput === post.password) { + if (passInput && md5(post.slug + passInput) === post.password) { setLock(false) return true } diff --git a/themes/medium/LayoutCategory.js b/themes/medium/LayoutCategory.js index a3018144..7522e264 100644 --- a/themes/medium/LayoutCategory.js +++ b/themes/medium/LayoutCategory.js @@ -5,7 +5,7 @@ import BLOG from '@/blog.config' export const LayoutCategory = props => { const { category } = props - const slotTop =
    分类:
    {category}
    + const slotTop =
    分类:
    {category}
    return {BLOG.POST_LIST_STYLE === 'page' ? : } diff --git a/themes/medium/LayoutTag.js b/themes/medium/LayoutTag.js index 6f072aa9..41164ce3 100644 --- a/themes/medium/LayoutTag.js +++ b/themes/medium/LayoutTag.js @@ -5,7 +5,7 @@ import BlogPostListPage from './components/BlogPostListPage' export const LayoutTag = (props) => { const { tag } = props - const slotTop =
    标签:
    {tag}
    + const slotTop =
    标签:
    {tag}
    return {BLOG.POST_LIST_STYLE === 'page' ? : } From 727fa0e2e605a25b791abafc0343bf1b1569e6b9 Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Wed, 14 Dec 2022 21:14:56 +0800 Subject: [PATCH 7/9] get-page-table-of-content --- lib/notion/getPageTableOfContents.js | 76 ++++++++++++++++++++++++++++ pages/[...slug].js | 3 +- 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 lib/notion/getPageTableOfContents.js diff --git a/lib/notion/getPageTableOfContents.js b/lib/notion/getPageTableOfContents.js new file mode 100644 index 00000000..a15ebe2d --- /dev/null +++ b/lib/notion/getPageTableOfContents.js @@ -0,0 +1,76 @@ +import { getTextContent } from 'notion-utils' + +const indentLevels = { + header: 0, + sub_header: 1, + sub_sub_header: 2 +} + +/** + * @see https://github.com/NotionX/react-notion-x/blob/master/packages/notion-utils/src/get-page-table-of-contents.ts + * Gets the metadata for a table of contents block by parsing the page's + * H1, H2, and H3 elements. + */ +export const getPageTableOfContents = (page, recordMap) => { + const toc = (page.content ?? []).map((blockId) => { + const block = recordMap.block[blockId]?.value + + if (block) { + const { type } = block + + if ( + type === 'header' || + type === 'sub_header' || + type === 'sub_sub_header' + ) { + return { + id: blockId, + type, + text: getTextContent(block.properties?.title), + indentLevel: indentLevels[type] + } + } + } + + return null + }).filter(e => e) + + console.log('目录', toc) + + const indentLevelStack = [ + { + actual: -1, + effective: -1 + } + ] + + // Adjust indent levels to always change smoothly. + // This is a little tricky, but the key is that when increasing indent levels, + // they should never jump more than one at a time. + for (const tocItem of toc) { + const { indentLevel } = tocItem + const actual = indentLevel + + do { + const prevIndent = indentLevelStack[indentLevelStack.length - 1] + const { actual: prevActual, effective: prevEffective } = prevIndent + + if (actual > prevActual) { + tocItem.indentLevel = prevEffective + 1 + indentLevelStack.push({ + actual, + effective: tocItem.indentLevel + }) + } else if (actual === prevActual) { + tocItem.indentLevel = prevEffective + break + } else { + indentLevelStack.pop() + } + + // eslint-disable-next-line no-constant-condition + } while (true) + } + + return toc +} diff --git a/pages/[...slug].js b/pages/[...slug].js index 9d521d8f..6ca98c93 100644 --- a/pages/[...slug].js +++ b/pages/[...slug].js @@ -4,11 +4,12 @@ import { getGlobalNotionData } from '@/lib/notion/getNotionData' import { useGlobal } from '@/lib/global' import * as ThemeMap from '@/themes' import React from 'react' -import { idToUuid, getPageTableOfContents } from 'notion-utils' +import { idToUuid } from 'notion-utils' import Router from 'next/router' import { isBrowser } from '@/lib/utils' import { getNotion } from '@/lib/notion/getNotion' import md5 from 'js-md5' +import { getPageTableOfContents } from '@/lib/notion/getPageTableOfContents' /** * 根据notion的slug访问页面 From 068639647d1de773d8d0000d96ba360996815550 Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Thu, 15 Dec 2022 10:37:37 +0800 Subject: [PATCH 8/9] rewrite.toc. --- lib/notion/getPageTableOfContents.js | 64 +++++++++++++++++----------- styles/notion.css | 2 +- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/lib/notion/getPageTableOfContents.js b/lib/notion/getPageTableOfContents.js index a15ebe2d..a23be7cb 100644 --- a/lib/notion/getPageTableOfContents.js +++ b/lib/notion/getPageTableOfContents.js @@ -12,31 +12,8 @@ const indentLevels = { * H1, H2, and H3 elements. */ export const getPageTableOfContents = (page, recordMap) => { - const toc = (page.content ?? []).map((blockId) => { - const block = recordMap.block[blockId]?.value - - if (block) { - const { type } = block - - if ( - type === 'header' || - type === 'sub_header' || - type === 'sub_sub_header' - ) { - return { - id: blockId, - type, - text: getTextContent(block.properties?.title), - indentLevel: indentLevels[type] - } - } - } - - return null - }).filter(e => e) - - console.log('目录', toc) - + const contents = (page.content ?? []) + const toc = getBlockHeader(contents, recordMap) const indentLevelStack = [ { actual: -1, @@ -74,3 +51,40 @@ export const getPageTableOfContents = (page, recordMap) => { return toc } + +/** + * 重写获取目录方法 + */ +function getBlockHeader(contents, recordMap, toc) { + if (!toc) { + toc = [] + } + if (!contents) { + return toc + } + + for (const blockId of contents) { + const block = recordMap.block[blockId]?.value + if (!block) { + continue + } + const { type } = block + if (type.indexOf('header') >= 0) { + const existed = toc.find(e => e.id === blockId) + if (!existed) { + toc.push({ + id: blockId, + type, + text: getTextContent(block.properties?.title), + indentLevel: indentLevels[type] + }) + } + } + + if (block.content?.length > 0) { + getBlockHeader(block.content, recordMap, toc) + } + } + + return toc +} diff --git a/styles/notion.css b/styles/notion.css index d010bb0c..d55d8456 100644 --- a/styles/notion.css +++ b/styles/notion.css @@ -427,7 +427,7 @@ margin-top: 2px; } */ .notion-h2 { - font-size: 1.5em; + font-size: 1.4em; margin-top: 1.1em; } .notion-h3 { From 25f24d69c7418b7676345800ec31f7d0f1e0892d Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Thu, 15 Dec 2022 10:58:23 +0800 Subject: [PATCH 9/9] v3.6.3 --- .env.local | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.local b/.env.local index 618efc87..ffa93893 100644 --- a/.env.local +++ b/.env.local @@ -1,2 +1,2 @@ # 环境变量 @see https://www.nextjs.cn/docs/basic-features/environment-variables -NEXT_PUBLIC_VERSION=3.6.5 \ No newline at end of file +NEXT_PUBLIC_VERSION=3.6.6 \ No newline at end of file diff --git a/package.json b/package.json index f022f9d0..b7d9f09f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "notion-next", - "version": "3.6.5", + "version": "3.6.6", "homepage": "https://github.com/tangly1024/NotionNext.git", "license": "MIT", "repository": {