diff --git a/README.md b/README.md index 5621da75..aa972080 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ 访问帮助:[NotionNext帮助手册](https://docs.tangly1024.com/) -> 本项目教程为免费、公开资源,仅限个人学习使用。严禁任何个人或组织将本教程用于商业用途,包括但不限于直接售卖、间接收费、或其他变相盈利行为。转载、复制或介绍本教程内容时,须保留作者信息并明确注明来源。 +> 本项目教程为免费、公开资源,仅限个人学习使用,禁止利用本教程建立的博客发布非法内容、进行违法犯罪活动。严禁任何个人或组织将本教程用于商业用途,包括但不限于直接售卖、间接收费、或其他变相盈利行为。转载、复制或介绍本教程内容时,须保留作者信息并明确注明来源。 > 本项目仅提供由作者团队授权的付费咨询服务,请注意辨别,谨防诈骗行为。任何未经授权的收费服务均可能存在法律风险。 Notion是一个能让效率暴涨的生产力引擎,可以帮你书写文档、管理笔记,搭建知识库,甚至可以为你规划项目、时间管理、组织团队、提高生产力、还有当前最强大的AI技术加持。 diff --git a/components/DebugPanel.js b/components/DebugPanel.js index 845da502..a0264eb1 100644 --- a/components/DebugPanel.js +++ b/components/DebugPanel.js @@ -1,10 +1,10 @@ -import { useEffect, useState } from 'react' -import Select from './Select' +import { siteConfigMap } from '@/lib/config' import { useGlobal } from '@/lib/global' +import { getQueryParam } from '@/lib/utils' import { THEMES } from '@/themes/theme' import { useRouter } from 'next/router' -import { siteConfigMap } from '@/lib/config' -import { getQueryParam } from '@/lib/utils' +import { useEffect, useState } from 'react' +import Select from './Select' /** * @@ -50,79 +50,83 @@ const DebugPanel = () => { } return ( - <> - {/* 调试按钮 */} -
-
- {show - ?  {locale.COMMON.DEBUG_CLOSE} - :  {locale.COMMON.DEBUG_OPEN}} -
-
+ <> + {/* 调试按钮 */} +
+
+ {show ? ( +  {locale.COMMON.DEBUG_CLOSE} + ) : ( +  {locale.COMMON.DEBUG_OPEN} + )} +
+
- {/* 调试侧拉抽屉 */} + {/* 调试侧拉抽屉 */} +
+
+
+ -
- -
-
- -
- -
-
- -
- {/*
-
- 主题配置{`config_${debugTheme}.js`}: -
-
- {Object.keys(themeConfig).map(k => ( -
- - {k} - - - {filterResult(themeConfig[k] + '')} - -
- ))} -
-
*/} -
- 站点配置[blog.config.js] -
-
- {siteConfig && Object.keys(siteConfig).map(k => ( -
- - {k} - - - {filterResult(siteConfig[k] + '')} - -
- ))} -
-
- + className='p-2 cursor-pointer' + onClick={handleChangeDebugTheme}> +
- + + +
+ +
+ + +
+ {/* +
+
+ 主题配置{`config_${debugTheme}.js`}: +
+
+ {Object.keys(themeConfig).map(k => ( +
+ + {k} + + + {filterResult(themeConfig[k] + '')} + +
+ ))} +
+
+ */} +
+ 站点配置[blog.config.js] +
+
+ {siteConfig && + Object.keys(siteConfig).map(k => ( +
+ + {k} + + + {filterResult(siteConfig[k] + '')} + +
+ ))} +
+
+ + ) } export default DebugPanel diff --git a/components/ExternalPlugins.js b/components/ExternalPlugins.js index 65932a39..fd92820e 100644 --- a/components/ExternalPlugins.js +++ b/components/ExternalPlugins.js @@ -11,6 +11,8 @@ import Head from 'next/head' import ExternalScript from './ExternalScript' import WebWhiz from './Webwhiz' import { useGlobal } from '@/lib/global' +import IconFont from './IconFont' + /** * 各种插件脚本 @@ -126,6 +128,8 @@ const ExternalPlugin = props => { NOTION_CONFIG ) + const ENABLE_ICON_FONT = siteConfig('ENABLE_ICON_FONT', false) + // 自定义样式css和js引入 if (isBrowser) { // 初始化AOS动画 @@ -186,6 +190,7 @@ const ExternalPlugin = props => { <> {/* 全局样式嵌入 */} + {ENABLE_ICON_FONT && } {MOUSE_FOLLOW && } {THEME_SWITCH && } {DEBUG && } diff --git a/components/IconFont.js b/components/IconFont.js new file mode 100644 index 00000000..ddf15d48 --- /dev/null +++ b/components/IconFont.js @@ -0,0 +1,54 @@ +import { siteConfig } from '@/lib/config' +import { loadExternalResource } from '@/lib/utils' +import { useRouter } from 'next/router' +import { useEffect } from 'react' + +/** + * iconfont + */ +export default function IconFont() { + const router = useRouter() + + useEffect(() => { + loadExternalResource('/webfonts/iconfont.js').then(u => { + console.log('iconfont loaded') + + // 查找所有 标签且 class 包含 'icon-' + const iElements = document.querySelectorAll('i[class*="icon-"]'); + iElements.forEach(element => { + const className = Array.from(element.classList).find(cls => cls.startsWith('icon-')); + if (className) { + // 创建新的 元素 + const svgElement = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + svgElement.setAttribute('class', 'icon'); + svgElement.setAttribute('aria-hidden', 'true'); + + const useElement = document.createElementNS('http://www.w3.org/2000/svg', 'use'); + useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', `#${className}`); + svgElement.appendChild(useElement); + + // 替换原来的 元素 + element.replaceWith(svgElement); + console.log(`Replaced with class "${className}" to `); + } + }); + }) + }, [router]) + + return +} diff --git a/components/NotionPage.js b/components/NotionPage.js index eace0637..1e5bd607 100644 --- a/components/NotionPage.js +++ b/components/NotionPage.js @@ -98,6 +98,22 @@ const NotionPage = ({ post, className }) => { }) }) } + + // 查找所有具有 'notion-collection-page-properties' 类的元素,删除notion自带的页面properties + const timer = setTimeout(() => { + // 查找所有具有 'notion-collection-page-properties' 类的元素 + const elements = document.querySelectorAll( + '.notion-collection-page-properties' + ) + + // 遍历这些元素并将其从 DOM 中移除 + elements?.forEach(element => { + element?.remove() + }) + }, 1000) // 1000 毫秒 = 1 秒 + + // 清理定时器,防止组件卸载时执行 + return () => clearTimeout(timer) }, [post]) return ( diff --git a/components/PrismMac.js b/components/PrismMac.js index 5d04fb22..7e81fc01 100644 --- a/components/PrismMac.js +++ b/components/PrismMac.js @@ -43,9 +43,15 @@ const PrismMac = () => { loadExternalResource('/css/prism-mac-style.css', 'css') } // 加载prism样式 - loadPrismThemeCSS(isDarkMode, prismThemeSwitch, prismThemeDarkPath, prismThemeLightPath, prismThemePrefixPath) + loadPrismThemeCSS( + isDarkMode, + prismThemeSwitch, + prismThemeDarkPath, + prismThemeLightPath, + prismThemePrefixPath + ) // 折叠代码 - loadExternalResource(prismjsAutoLoader, 'js').then((url) => { + loadExternalResource(prismjsAutoLoader, 'js').then(url => { if (window?.Prism?.plugins?.autoloader) { window.Prism.plugins.autoloader.languages_path = prismjsPath } @@ -62,7 +68,13 @@ const PrismMac = () => { /** * 加载Prism主题样式 */ -const loadPrismThemeCSS = (isDarkMode, prismThemeSwitch, prismThemeDarkPath, prismThemeLightPath, prismThemePrefixPath) => { +const loadPrismThemeCSS = ( + isDarkMode, + prismThemeSwitch, + prismThemeDarkPath, + prismThemeLightPath, + prismThemePrefixPath +) => { let PRISM_THEME let PRISM_PREVIOUS if (prismThemeSwitch) { @@ -73,8 +85,14 @@ const loadPrismThemeCSS = (isDarkMode, prismThemeSwitch, prismThemeDarkPath, pri PRISM_THEME = prismThemeLightPath PRISM_PREVIOUS = prismThemeDarkPath } - const previousTheme = document.querySelector(`link[href="${PRISM_PREVIOUS}"]`) - if (previousTheme && previousTheme.parentNode && previousTheme.parentNode.contains(previousTheme)) { + const previousTheme = document.querySelector( + `link[href="${PRISM_PREVIOUS}"]` + ) + if ( + previousTheme && + previousTheme.parentNode && + previousTheme.parentNode.contains(previousTheme) + ) { previousTheme.parentNode.removeChild(previousTheme) } loadExternalResource(PRISM_THEME, 'css') @@ -103,14 +121,17 @@ const renderCollapseCode = (codeCollapse, codeCollapseExpandDefault) => { const collapseWrapper = document.createElement('div') collapseWrapper.className = 'collapse-wrapper w-full py-2' const panelWrapper = document.createElement('div') - panelWrapper.className = 'border dark:border-gray-600 rounded-md hover:border-indigo-500 duration-200 transition-colors' + panelWrapper.className = + 'border dark:border-gray-600 rounded-md hover:border-indigo-500 duration-200 transition-colors' const header = document.createElement('div') - header.className = 'flex justify-between items-center px-4 py-2 cursor-pointer select-none' + header.className = + 'flex justify-between items-center px-4 py-2 cursor-pointer select-none' header.innerHTML = `

${language}

` const panel = document.createElement('div') - panel.className = 'invisible h-0 transition-transform duration-200 border-t border-gray-300' + panel.className = + 'invisible h-0 transition-transform duration-200 border-t border-gray-300' panelWrapper.appendChild(header) panelWrapper.appendChild(panel) @@ -145,7 +166,7 @@ const renderMermaid = async(mermaidCDN) => { if (m.target.className === 'notion-code language-mermaid') { const chart = m.target.querySelector('code').textContent if (chart && !m.target.querySelector('.mermaid')) { - const mermaidChart = document.createElement('div') + const mermaidChart = document.createElement('pre') mermaidChart.className = 'mermaid' mermaidChart.innerHTML = chart m.target.appendChild(mermaidChart) @@ -172,7 +193,10 @@ const renderMermaid = async(mermaidCDN) => { } }) if (document.querySelector('#notion-article')) { - observer.observe(document.querySelector('#notion-article'), { attributes: true, subtree: true }) + observer.observe(document.querySelector('#notion-article'), { + attributes: true, + subtree: true + }) } } @@ -234,7 +258,10 @@ const fixCodeLineStyle = () => { } } }) - observer.observe(document.querySelector('#notion-article'), { attributes: true, subtree: true }) + observer.observe(document.querySelector('#notion-article'), { + attributes: true, + subtree: true + }) setTimeout(() => { const preCodes = document.querySelectorAll('pre.notion-code') for (const preCode of preCodes) { diff --git a/components/SEO.js b/components/SEO.js index cd7d78c6..7f0cc0c2 100644 --- a/components/SEO.js +++ b/components/SEO.js @@ -247,7 +247,7 @@ const getSEOMeta = (props, router, locale) => { } case '/404': return { - title: `${siteInfo?.title} | 页面找不到啦`, + title: `${siteInfo?.title} | ${locale.NAV.PAGE_NOT_FOUND}`, image: `${siteInfo?.pageCover}` } case '/tag': diff --git a/conf/code.config.js b/conf/code.config.js index c8047f84..10225061 100644 --- a/conf/code.config.js +++ b/conf/code.config.js @@ -28,7 +28,7 @@ module.exports = { // Mermaid 图表CDN MERMAID_CDN: process.env.NEXT_PUBLIC_MERMAID_CDN || - 'https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.2.4/mermaid.min.js' // CDN + 'https://cdnjs.cloudflare.com/ajax/libs/mermaid/11.4.0/mermaid.min.js' // CDN // END********代码相关******** } diff --git a/lib/lang/en-US.js b/lib/lang/en-US.js index 1649c6d3..7229a152 100644 --- a/lib/lang/en-US.js +++ b/lib/lang/en-US.js @@ -17,7 +17,9 @@ export default { NAVIGATOR: 'NAV', ABOUT: 'About', MAIL: 'E-Mail', - ARCHIVE: 'Archive' + ARCHIVE: 'Archive', + PAGE_NOT_FOUND: 'Page Not Found', + PAGE_NOT_FOUND_REDIRECT: 'Page Not Found, Redirecting to Home Page...' }, COMMON: { THEME: 'Theme', diff --git a/lib/lang/zh-CN.js b/lib/lang/zh-CN.js index 265bb0c2..f51b6ba5 100644 --- a/lib/lang/zh-CN.js +++ b/lib/lang/zh-CN.js @@ -17,7 +17,9 @@ export default { ABOUT: '关于', NAVIGATOR: '导航', MAIL: '邮箱', - ARCHIVE: '归档' + ARCHIVE: '归档', + PAGE_NOT_FOUND: '页面找不到啦', + PAGE_NOT_FOUND_REDIRECT: '页面无法加载,即将返回首页' }, COMMON: { THEME: 'Theme', diff --git a/lib/notion/convertInnerUrl.js b/lib/notion/convertInnerUrl.js index 16ef17c0..213443cd 100644 --- a/lib/notion/convertInnerUrl.js +++ b/lib/notion/convertInnerUrl.js @@ -1,20 +1,18 @@ import { idToUuid } from 'notion-utils' import { checkStrIsNotionId, getLastPartOfUrl, isBrowser } from '../utils' -import { getCurrentLang } from '@/lib/lang' -import BLOG from '@/blog.config' /** * 处理页面内连接跳转: * 1.若是本站域名,则在当前窗口打开、不开新窗口 * 2.url是notion-id,转成站内文章链接 */ -export const convertInnerUrl = ({allPages,lang}) => { +export const convertInnerUrl = ({ allPages, lang }) => { if (!isBrowser) { return } const allAnchorTags = document ?.getElementById('notion-article') - ?.querySelectorAll('a.notion-link') + ?.querySelectorAll('a.notion-link, a.notion-collection-card') if (!allAnchorTags) { return @@ -49,5 +47,19 @@ export const convertInnerUrl = ({allPages,lang}) => { anchorTag.target = '_self' } } + + // 如果链接以#号结尾,则强制在新窗口打开 + if (anchorTag.href.endsWith('#')) { + anchorTag.target = '_blank' + } + } + + for (const anchorTag of allAnchorTags) { + const slug = getLastPartOfUrl(anchorTag.href) + const slugPage = allPages?.find(page => { + return page.slug.indexOf(slug) >= 0 + }) + if (slugPage) { + } } } diff --git a/lib/plugins/gtag.js b/lib/plugins/gtag.js index 9d62181f..e484e6dd 100644 --- a/lib/plugins/gtag.js +++ b/lib/plugins/gtag.js @@ -1,5 +1,6 @@ // https://developers.google.com/analytics/devguides/collection/gtagjs/pages export const pageview = (url, ANALYTICS_GOOGLE_ID) => { + if (window.gtag === undefined) { return } window.gtag('config', ANALYTICS_GOOGLE_ID, { page_path: url }) @@ -7,6 +8,7 @@ export const pageview = (url, ANALYTICS_GOOGLE_ID) => { // https://developers.google.com/analytics/devguides/collection/gtagjs/events export const event = ({ action, category, label, value }) => { + if (window.gtag === undefined) { return } window.gtag('event', action, { event_category: category, event_label: label, diff --git a/public/js/ribbon.js b/public/js/ribbon.js index 55c6731c..2877be34 100644 --- a/public/js/ribbon.js +++ b/public/js/ribbon.js @@ -22,7 +22,7 @@ function createRibbon() { a = window.innerWidth, l = window.innerHeight, d = e.s - i.id = id + i.id = '__next' let r, s const u = Math let h = 0 diff --git a/styles/notion.css b/styles/notion.css index 319c37e2..7e3c0ff9 100644 --- a/styles/notion.css +++ b/styles/notion.css @@ -2027,6 +2027,10 @@ code.language-mermaid { display: none; } +.mermaid .invisible{ + visibility: inherit; +} + .code-toolbar { @apply w-full shadow-md pb-0; } diff --git a/themes/fukasawa/index.js b/themes/fukasawa/index.js index 5553167c..4176ed11 100644 --- a/themes/fukasawa/index.js +++ b/themes/fukasawa/index.js @@ -215,6 +215,7 @@ const LayoutArchive = props => { */ const Layout404 = props => { const router = useRouter() + const { locale } = useGlobal() useEffect(() => { // 延时3秒如果加载失败就返回首页 setTimeout(() => { @@ -232,7 +233,7 @@ const Layout404 = props => {

404

-

页面无法加载,即将返回首页

+

{locale.NAV.PAGE_NOT_FOUND_REDIRECT}

diff --git a/themes/game/index.js b/themes/game/index.js index cd46246a..a2ad09e0 100644 --- a/themes/game/index.js +++ b/themes/game/index.js @@ -6,9 +6,11 @@ import NotionPage from '@/components/NotionPage' import { PWA as initialPWA } from '@/components/PWA' import ShareBar from '@/components/ShareBar' import { siteConfig } from '@/lib/config' +import { useGlobal } from '@/lib/global' import { loadWowJS } from '@/lib/plugins/wow' import { deepClone, isBrowser, shuffleArray } from '@/lib/utils' import Link from 'next/link' +import { useRouter } from 'next/router' import { createContext, useContext, useEffect, useRef, useState } from 'react' import Announcement from './components/Announcement' import { ArticleLock } from './components/ArticleLock' @@ -30,7 +32,6 @@ import SideBarContent from './components/SideBarContent' import SideBarDrawer from './components/SideBarDrawer' import CONFIG from './config' import { Style } from './style' -import { useRouter } from 'next/router' // const AlgoliaSearchModal = dynamic(() => import('@/components/AlgoliaSearchModal'), { ssr: false }) @@ -354,6 +355,7 @@ const LayoutSlug = props => { */ const Layout404 = props => { const router = useRouter() + const { locale } = useGlobal() useEffect(() => { // 延时3秒如果加载失败就返回首页 setTimeout(() => { @@ -366,16 +368,21 @@ const Layout404 = props => { }, 3000) }, []) - return <> -
-
-

404

-
-

页面无法加载,即将返回首页

-
-
+ return ( + <> +
+
+

+ + 404 +

+
+

{locale.NAV.PAGE_NOT_FOUND_REDIRECT}

+
+
+ ) } /** diff --git a/themes/gitbook/index.js b/themes/gitbook/index.js index 2da36965..13014b72 100644 --- a/themes/gitbook/index.js +++ b/themes/gitbook/index.js @@ -438,6 +438,7 @@ const LayoutArchive = props => { */ const Layout404 = props => { const router = useRouter() + const { locale } = useGlobal() useEffect(() => { // 延时3秒如果加载失败就返回首页 setTimeout(() => { @@ -455,7 +456,7 @@ const Layout404 = props => {

404

-

页面无法加载,即将返回首页

+

{locale.NAV.PAGE_NOT_FOUND_REDIRECT}