From b663d984bab89409f4a1e7a5bc4033432fa66884 Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Mon, 13 May 2024 12:15:15 +0800 Subject: [PATCH] =?UTF-8?q?Notion=E5=86=85=E9=93=BE=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9B=BF=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/ExternalPlugins.js | 130 ++++++++++++++++++---------------- components/NotionPage.js | 33 --------- lib/notion/mapPageUrl.js | 40 +++++++++++ lib/utils/index.js | 29 ++++++++ 4 files changed, 138 insertions(+), 94 deletions(-) create mode 100644 lib/notion/mapPageUrl.js diff --git a/components/ExternalPlugins.js b/components/ExternalPlugins.js index cecfae0e..da0b0fb3 100644 --- a/components/ExternalPlugins.js +++ b/components/ExternalPlugins.js @@ -6,71 +6,12 @@ import TianLiGPT from './TianliGPT' import WebWhiz from './Webwhiz' import { CUSTOM_EXTERNAL_CSS, CUSTOM_EXTERNAL_JS } from '@/blog.config' +import { mapPageUrl } from '@/lib/notion/mapPageUrl' import { isBrowser, loadExternalResource } from '@/lib/utils' +import { useRouter } from 'next/router' import { useEffect } from 'react' import { initGoogleAdsense } from './GoogleAdsense' -const TwikooCommentCounter = dynamic( - () => import('@/components/TwikooCommentCounter'), - { ssr: false } -) -const DebugPanel = dynamic(() => import('@/components/DebugPanel'), { - ssr: false -}) -const ThemeSwitch = dynamic(() => import('@/components/ThemeSwitch'), { - ssr: false -}) -const Fireworks = dynamic(() => import('@/components/Fireworks'), { - ssr: false -}) -const MouseFollow = dynamic(() => import('@/components/MouseFollow'), { - ssr: false -}) -const Nest = dynamic(() => import('@/components/Nest'), { ssr: false }) -const FlutteringRibbon = dynamic( - () => import('@/components/FlutteringRibbon'), - { ssr: false } -) -const Ribbon = dynamic(() => import('@/components/Ribbon'), { ssr: false }) -const Sakura = dynamic(() => import('@/components/Sakura'), { ssr: false }) -const StarrySky = dynamic(() => import('@/components/StarrySky'), { - ssr: false -}) -const DifyChatbot = dynamic(() => import('@/components/DifyChatbot'), { - ssr: false -}) -const Analytics = dynamic( - () => - import('@vercel/analytics/react').then(async m => { - return m.Analytics - }), - { ssr: false } -) -const MusicPlayer = dynamic(() => import('@/components/Player'), { ssr: false }) -const Ackee = dynamic(() => import('@/components/Ackee'), { ssr: false }) -const Gtag = dynamic(() => import('@/components/Gtag'), { ssr: false }) -const Busuanzi = dynamic(() => import('@/components/Busuanzi'), { ssr: false }) -const Messenger = dynamic(() => import('@/components/FacebookMessenger'), { - ssr: false -}) -const VConsole = dynamic(() => import('@/components/VConsole'), { ssr: false }) -const CustomContextMenu = dynamic( - () => import('@/components/CustomContextMenu'), - { ssr: false } -) -const DisableCopy = dynamic(() => import('@/components/DisableCopy'), { - ssr: false -}) -const AdBlockDetect = dynamic(() => import('@/components/AdBlockDetect'), { - ssr: false -}) -const LoadingProgress = dynamic(() => import('@/components/LoadingProgress'), { - ssr: false -}) -const AosAnimation = dynamic(() => import('@/components/AOSAnimation'), { - ssr: false -}) - /** * 各种插件脚本 * @param {*} props @@ -155,6 +96,7 @@ const ExternalPlugin = props => { } } + const router = useRouter() useEffect(() => { // 异步渲染谷歌广告 if (ADSENSE_GOOGLE_ID) { @@ -163,6 +105,11 @@ const ExternalPlugin = props => { }, 1000) } + // 映射url + mapPageUrl(props?.allNavPages) + }, [router]) + + useEffect(() => { // 执行注入脚本 // eslint-disable-next-line no-eval eval(GLOBAL_JS) @@ -389,4 +336,65 @@ const ExternalPlugin = props => { ) } +const TwikooCommentCounter = dynamic( + () => import('@/components/TwikooCommentCounter'), + { ssr: false } +) +const DebugPanel = dynamic(() => import('@/components/DebugPanel'), { + ssr: false +}) +const ThemeSwitch = dynamic(() => import('@/components/ThemeSwitch'), { + ssr: false +}) +const Fireworks = dynamic(() => import('@/components/Fireworks'), { + ssr: false +}) +const MouseFollow = dynamic(() => import('@/components/MouseFollow'), { + ssr: false +}) +const Nest = dynamic(() => import('@/components/Nest'), { ssr: false }) +const FlutteringRibbon = dynamic( + () => import('@/components/FlutteringRibbon'), + { ssr: false } +) +const Ribbon = dynamic(() => import('@/components/Ribbon'), { ssr: false }) +const Sakura = dynamic(() => import('@/components/Sakura'), { ssr: false }) +const StarrySky = dynamic(() => import('@/components/StarrySky'), { + ssr: false +}) +const DifyChatbot = dynamic(() => import('@/components/DifyChatbot'), { + ssr: false +}) +const Analytics = dynamic( + () => + import('@vercel/analytics/react').then(async m => { + return m.Analytics + }), + { ssr: false } +) +const MusicPlayer = dynamic(() => import('@/components/Player'), { ssr: false }) +const Ackee = dynamic(() => import('@/components/Ackee'), { ssr: false }) +const Gtag = dynamic(() => import('@/components/Gtag'), { ssr: false }) +const Busuanzi = dynamic(() => import('@/components/Busuanzi'), { ssr: false }) +const Messenger = dynamic(() => import('@/components/FacebookMessenger'), { + ssr: false +}) +const VConsole = dynamic(() => import('@/components/VConsole'), { ssr: false }) +const CustomContextMenu = dynamic( + () => import('@/components/CustomContextMenu'), + { ssr: false } +) +const DisableCopy = dynamic(() => import('@/components/DisableCopy'), { + ssr: false +}) +const AdBlockDetect = dynamic(() => import('@/components/AdBlockDetect'), { + ssr: false +}) +const LoadingProgress = dynamic(() => import('@/components/LoadingProgress'), { + ssr: false +}) +const AosAnimation = dynamic(() => import('@/components/AOSAnimation'), { + ssr: false +}) + export default ExternalPlugin diff --git a/components/NotionPage.js b/components/NotionPage.js index 4c422774..f8e8e396 100644 --- a/components/NotionPage.js +++ b/components/NotionPage.js @@ -47,9 +47,6 @@ const NotionPage = ({ post, className }) => { processDisableDatabaseUrl() } - // 处理页内的url - processPageUrl() - /** * 放大查看图片时替换成高清图像 */ @@ -146,36 +143,6 @@ const processGalleryImg = zoom => { }, 800) } -/** - * 处理页面内连接跳转: - * 1. 若是本站域名,则在当前窗口打开、不开新窗口 - * 2. 若是Notion笔记中的内链,尝试转换成博客中现有的文章地址 - */ -const processPageUrl = () => { - if (isBrowser) { - const currentURL = window.location.origin + window.location.pathname - const allAnchorTags = document.getElementsByTagName('a') // 或者使用 document.querySelectorAll('a') 获取 NodeList - for (const anchorTag of allAnchorTags) { - // 检查url - if (anchorTag.href) { - // 如果是notion页面间的内链,尝试匹配成博客的文章链接 - } - - if (anchorTag?.target === '_blank') { - const hrefWithoutQueryHash = anchorTag.href.split('?')[0].split('#')[0] - const hrefWithRelativeHash = - currentURL.split('#')[0] + anchorTag.href.split('#')[1] - - if ( - currentURL === hrefWithoutQueryHash || - currentURL === hrefWithRelativeHash - ) { - anchorTag.target = '_self' - } - } - } - } -} /** * 根据url参数自动滚动到指定区域 */ diff --git a/lib/notion/mapPageUrl.js b/lib/notion/mapPageUrl.js new file mode 100644 index 00000000..8a7bc73c --- /dev/null +++ b/lib/notion/mapPageUrl.js @@ -0,0 +1,40 @@ +import { uuidToId } from 'notion-utils' +import { checkStrIsNotionId, getLastPartOfUrl, isBrowser } from '../utils' + +/** + * 处理页面内连接跳转: + * 1. 若是本站域名,则在当前窗口打开、不开新窗口 + * 2. 若是Notion笔记中的内链,尝试转换成博客中现有的文章地址 + */ +export const mapPageUrl = allPages => { + if (isBrowser) { + const currentURL = window.location.origin + window.location.pathname + const allAnchorTags = document.getElementsByTagName('a') // 或者使用 document.querySelectorAll('a') 获取 NodeList + for (const anchorTag of allAnchorTags) { + // 检查url + if (anchorTag.href) { + // 如果url是一个Notion_id,尝试匹配成博客的文章内链 + const slug = getLastPartOfUrl(anchorTag.href) + if (checkStrIsNotionId(slug)) { + const slugPage = allPages.find(page => uuidToId(page.id) === slug) + if (slugPage) { + anchorTag.href = slugPage.href + } + } + } + + if (anchorTag?.target === '_blank') { + const hrefWithoutQueryHash = anchorTag.href.split('?')[0].split('#')[0] + const hrefWithRelativeHash = + currentURL.split('#')[0] + anchorTag.href.split('#')[1] + + if ( + currentURL === hrefWithoutQueryHash || + currentURL === hrefWithRelativeHash + ) { + anchorTag.target = '_self' + } + } + } + } +} diff --git a/lib/utils/index.js b/lib/utils/index.js index b0652494..204430d8 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -73,6 +73,35 @@ export function checkContainHttp(str) { } } +// 检查一个字符串是否notionid : 32位,仅由数字英文构成 +export function checkStrIsNotionId(str) { + if (!str) { + return false + } + // 使用正则表达式进行匹配 + const regex = /^[a-zA-Z0-9]{32}$/ + return regex.test(str) +} + +// 截取url中最后一个 / 后面的内容 +export function getLastPartOfUrl(url) { + if (!url) { + return '' + } + // 找到最后一个斜杠的位置 + const lastSlashIndex = url.lastIndexOf('/') + + // 如果找不到斜杠,则返回整个字符串 + if (lastSlashIndex === -1) { + return url + } + + // 截取最后一个斜杠后面的内容 + const lastPart = url.substring(lastSlashIndex + 1) + + return lastPart +} + /** * 加载外部资源 * @param url 地址 例如 https://xx.com/xx.js