From 71701fa314b88f443f632a892c082a6ba9d3432e Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Thu, 16 May 2024 11:04:35 +0800 Subject: [PATCH 001/107] =?UTF-8?q?=E5=87=8F=E5=B0=8FNEXT=5FDATA=E4=BD=93?= =?UTF-8?q?=E7=A7=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/ExternalPlugins.js | 4 +- lib/db/getSiteData.js | 127 +++++++++++++----- .../{mapPageUrl.js => convertInnerUrl.js} | 12 +- lib/notion/getNotionConfig.js | 6 +- lib/notion/getNotionPost.js | 4 +- lib/notion/getPostBlocks.js | 31 +---- package.json | 3 +- 7 files changed, 120 insertions(+), 67 deletions(-) rename lib/notion/{mapPageUrl.js => convertInnerUrl.js} (77%) diff --git a/components/ExternalPlugins.js b/components/ExternalPlugins.js index 89c18688..616792e8 100644 --- a/components/ExternalPlugins.js +++ b/components/ExternalPlugins.js @@ -6,7 +6,7 @@ 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 { convertInnerUrl } from '@/lib/notion/convertInnerUrl' import { isBrowser, loadExternalResource } from '@/lib/utils' import { useRouter } from 'next/router' import { useEffect } from 'react' @@ -106,7 +106,7 @@ const ExternalPlugin = props => { } // 映射url - mapPageUrl(props?.allNavPages) + convertInnerUrl(props?.allNavPages) }, [router]) useEffect(() => { diff --git a/lib/db/getSiteData.js b/lib/db/getSiteData.js index 272c17f1..a4f042bd 100755 --- a/lib/db/getSiteData.js +++ b/lib/db/getSiteData.js @@ -5,9 +5,9 @@ import getAllPageIds from '@/lib/notion/getAllPageIds' import { getAllTags } from '@/lib/notion/getAllTags' import { getConfigMapFromConfigPage } from '@/lib/notion/getNotionConfig' import getPageProperties, { - adjustPageProperties + adjustPageProperties } from '@/lib/notion/getPageProperties' -import { fetchInBatches, getPostBlocks } from '@/lib/notion/getPostBlocks' +import { fetchInBatches, getPage } from '@/lib/notion/getPostBlocks' import { compressImage, mapImgUrl } from '@/lib/notion/mapImage' import { deepClone } from '@/lib/utils' import { idToUuid } from 'notion-utils' @@ -16,7 +16,7 @@ import { extractLangId, extractLangPrefix } from '../utils/pageId' export { getAllTags } from '../notion/getAllTags' export { getPost } from '../notion/getNotionPost' -export { getPostBlocks } from '../notion/getPostBlocks' +export { getPage as getPostBlocks } from '../notion/getPostBlocks' /** * 获取博客数据; 基于Notion实现 @@ -77,7 +77,16 @@ export async function getNotionPageData({ pageId, from }) { } // 返回给前端的数据做处理 - const db = deepClone(data) + return compressData(deepClone(data)) +} + +/** + * 减少返回给前端的数据 + * 并脱敏 + * @param {*} db + */ +function compressData(db) { + // 清理多余数据 delete db.block delete db.schema delete db.rawMetadata @@ -95,38 +104,96 @@ export async function getNotionPageData({ pageId, from }) { if (db?.post) { db.post = cleanBlock(db?.post) } + + db.tagOptions = cleanIds(db?.tagOptions) + db.categoryOptions = cleanIds(db?.categoryOptions) + db.customMenu = cleanIds(db?.customMenu) + + db.latestPosts = cleanIds(db?.latestPosts) + db.allNavPages = shortenIds(db?.allNavPages) + // db.allPages = cleanBlocks(db?.allPages) + return db } +/** + * 清理一组数据的id + * @param {*} items + * @returns + */ +function shortenIds(items) { + if (items && Array.isArray(items)) { + return deepClone( + items.map(item => { + item.short_id = getFirstPart(item.id) + delete item.id + return item + }) + ) + } + return items +} + +function getFirstPart(uuid) { + if (!uuid || uuid.indexOf('-') < 0) { + return uuid + } + // 找到第一个 '-' 的位置 + const index = uuid.indexOf('-') + // 截取从开始到第一个 '-' 之前的部分 + return uuid.substring(0, index) +} + +/** + * 清理一组数据的id + * @param {*} items + * @returns + */ +function cleanIds(items) { + if (items && Array.isArray(items)) { + return deepClone( + items.map(item => { + delete item.id + return item + }) + ) + } + return items +} + /** * 清理block数据 */ -function cleanBlock(post) { +function cleanBlock(item) { + const post = deepClone(item) const pageBlock = post?.blockMap?.block - for (const i in pageBlock) { - pageBlock[i] = cleanBlock(pageBlock[i]) - delete pageBlock[i]?.role - delete pageBlock[i]?.value?.version - delete pageBlock[i]?.value?.created_by_table - delete pageBlock[i]?.value?.created_by_id - delete pageBlock[i]?.value?.last_edited_by_table - delete pageBlock[i]?.value?.last_edited_by_id - delete pageBlock[i]?.value?.space_id - delete pageBlock[i]?.value?.version - delete pageBlock[i]?.value?.format?.copied_from_pointer - delete pageBlock[i]?.value?.format?.block_locked_by - delete pageBlock[i]?.value?.parent_table - delete pageBlock[i]?.value?.copied_from_pointer - delete pageBlock[i]?.value?.copied_from - delete pageBlock[i]?.value?.created_by_table - delete pageBlock[i]?.value?.created_by_id - delete pageBlock[i]?.value?.last_edited_by_table - delete pageBlock[i]?.value?.last_edited_by_id - delete pageBlock[i]?.value?.permissions - delete pageBlock[i]?.value?.alive - } - + delete post?.id // delete post?.blockMap?.collection + + if (pageBlock) { + for (const i in pageBlock) { + pageBlock[i] = cleanBlock(pageBlock[i]) + delete pageBlock[i]?.role + delete pageBlock[i]?.value?.version + delete pageBlock[i]?.value?.created_by_table + delete pageBlock[i]?.value?.created_by_id + delete pageBlock[i]?.value?.last_edited_by_table + delete pageBlock[i]?.value?.last_edited_by_id + delete pageBlock[i]?.value?.space_id + delete pageBlock[i]?.value?.version + delete pageBlock[i]?.value?.format?.copied_from_pointer + delete pageBlock[i]?.value?.format?.block_locked_by + delete pageBlock[i]?.value?.parent_table + delete pageBlock[i]?.value?.copied_from_pointer + delete pageBlock[i]?.value?.copied_from + delete pageBlock[i]?.value?.created_by_table + delete pageBlock[i]?.value?.created_by_id + delete pageBlock[i]?.value?.last_edited_by_table + delete pageBlock[i]?.value?.last_edited_by_id + delete pageBlock[i]?.value?.permissions + delete pageBlock[i]?.value?.alive + } + } return post } @@ -320,7 +387,7 @@ async function getNotice(post) { return null } - post.blockMap = await getPostBlocks(post.id, 'data-notice') + post.blockMap = await getPage(post.id, 'data-notice') return post } @@ -372,7 +439,7 @@ const EmptyData = pageId => { */ async function getDataBaseInfoByNotionAPI({ pageId, from }) { console.log('[Fetching Data]', pageId, from) - const pageRecordMap = await getPostBlocks(pageId, from) + const pageRecordMap = await getPage(pageId, from) if (!pageRecordMap) { console.error('can`t get Notion Data ; Which id is: ', pageId) return {} diff --git a/lib/notion/mapPageUrl.js b/lib/notion/convertInnerUrl.js similarity index 77% rename from lib/notion/mapPageUrl.js rename to lib/notion/convertInnerUrl.js index 80fe70d8..f4539fb4 100644 --- a/lib/notion/mapPageUrl.js +++ b/lib/notion/convertInnerUrl.js @@ -1,12 +1,12 @@ -import { uuidToId } from 'notion-utils' +import { idToUuid } from 'notion-utils' import { checkStrIsNotionId, getLastPartOfUrl, isBrowser } from '../utils' /** * 处理页面内连接跳转: - * 1. 若是本站域名,则在当前窗口打开、不开新窗口 - * 2. 若是Notion笔记中的内链,尝试转换成博客中现有的文章地址 + * 1.若是本站域名,则在当前窗口打开、不开新窗口 + * 2.url是notion-id,转成站内文章链接 */ -export const mapPageUrl = allPages => { +export const convertInnerUrl = allPages => { if (isBrowser) { const currentURL = window.location.origin + window.location.pathname const allAnchorTags = document.getElementsByTagName('a') // 或者使用 document.querySelectorAll('a') 获取 NodeList @@ -16,7 +16,9 @@ export const mapPageUrl = allPages => { // 如果url是一个Notion_id,尝试匹配成博客的文章内链 const slug = getLastPartOfUrl(anchorTag.href) if (checkStrIsNotionId(slug)) { - const slugPage = allPages?.find(page => uuidToId(page.id) === slug) + const slugPage = allPages?.find(page => { + return idToUuid(slug).indexOf(page.short_id) === 0 + }) if (slugPage) { anchorTag.href = slugPage?.href } diff --git a/lib/notion/getNotionConfig.js b/lib/notion/getNotionConfig.js index 889005f2..c0ef7c29 100644 --- a/lib/notion/getNotionConfig.js +++ b/lib/notion/getNotionConfig.js @@ -9,7 +9,7 @@ import { getDateValue, getTextContent } from 'notion-utils' import { deepClone } from '../utils' import getAllPageIds from './getAllPageIds' -import { getPostBlocks } from './getPostBlocks' +import { getPage } from './getPostBlocks' /** * 从Notion中读取Config配置表 @@ -41,12 +41,12 @@ export async function getConfigMapFromConfigPage(allPages) { } const configPageId = configPage.id // console.log('[Notion配置]请求配置数据 ', configPage.id) - let pageRecordMap = await getPostBlocks(configPageId, 'config-table') + let pageRecordMap = await getPage(configPageId, 'config-table') // console.log('配置中心Page', configPageId, pageRecordMap) let content = pageRecordMap.block[configPageId].value.content for (const table of ['Config-Table', 'CONFIG-TABLE']) { if (content) break - pageRecordMap = await getPostBlocks(configPageId, table) + pageRecordMap = await getPage(configPageId, table) content = pageRecordMap.block[configPageId].value.content } diff --git a/lib/notion/getNotionPost.js b/lib/notion/getNotionPost.js index 3e096a11..f5aabb2a 100644 --- a/lib/notion/getNotionPost.js +++ b/lib/notion/getNotionPost.js @@ -2,7 +2,7 @@ import BLOG from '@/blog.config' import { idToUuid } from 'notion-utils' import { defaultMapImageUrl } from 'react-notion-x' import formatDate from '../utils/formatDate' -import { getPostBlocks } from './getPostBlocks' +import { getPage } from './getPostBlocks' /** * 根据页面ID获取内容 @@ -10,7 +10,7 @@ import { getPostBlocks } from './getPostBlocks' * @returns */ export async function getPost(pageId) { - const blockMap = await getPostBlocks(pageId, 'slug') + const blockMap = await getPage(pageId, 'slug') if (!blockMap) { return null } diff --git a/lib/notion/getPostBlocks.js b/lib/notion/getPostBlocks.js index 0b151f17..8bac9e2a 100644 --- a/lib/notion/getPostBlocks.js +++ b/lib/notion/getPostBlocks.js @@ -10,7 +10,7 @@ import { deepClone, delay } from '../utils' * @param {*} slice * @returns */ -export async function getPostBlocks(id, from, slice) { +export async function getPage(id, from, slice) { const cacheKey = 'page_block_' + id let pageBlock = await getDataFromCache(cacheKey) if (pageBlock) { @@ -27,28 +27,6 @@ export async function getPostBlocks(id, from, slice) { return pageBlock } -/** - * 针对在getDataBaseInfoByNotionAPI=>getPostBlocks中获取不到的溢出的block-id,用此方法另外抓取 - * @param {*} id - * @param {*} from - * @returns - */ -export async function getSingleBlock(id, from) { - const cacheKey = 'single_block_' + id - let pageBlock = await getDataFromCache(cacheKey) - if (pageBlock) { - // console.log('[API<<--缓存]', `from:${from}`, cacheKey) - return pageBlock - } - - pageBlock = await getPageWithRetry(id, 'single_' + from) - - if (pageBlock) { - await setDataToCache(cacheKey, pageBlock) - } - return pageBlock -} - /** * 调用接口,失败会重试 * @param {*} id @@ -162,6 +140,11 @@ function filterPostBlocks(id, blockMap, slice) { * @returns */ export const fetchInBatches = async (ids, batchSize = 100) => { + // 如果 ids 不是数组,则将其转换为数组 + if (!Array.isArray(ids)) { + ids = [ids] + } + const authToken = BLOG.NOTION_ACCESS_TOKEN || null const api = new NotionAPI({ authToken, @@ -171,7 +154,7 @@ export const fetchInBatches = async (ids, batchSize = 100) => { let fetchedBlocks = {} for (let i = 0; i < ids.length; i += batchSize) { const batch = ids.slice(i, i + batchSize) - console.log('[API-->>请求] Fetching missing blocks', ids.length) + console.log('[API-->>请求] Fetching missing blocks', batch, ids.length) const start = new Date().getTime() const pageChunk = await api.getBlocks(batch) const end = new Date().getTime() diff --git a/package.json b/package.json index 5e7761c7..9d6259b0 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "start": "next start", "post-build": "next-sitemap --config next-sitemap.config.js", "export": "next build && next-sitemap --config next-sitemap.config.js && next export", - "bundle-report": "cross-env ANALYZE=true yarn build" + "bundle-report": "cross-env ANALYZE=true next build", + "build-all-in-dev": "cross-env VERCEL_ENV=production next build" }, "dependencies": { "@headlessui/react": "^1.7.15", From 59025e801847aebc643613dbbfe4a9d1fac0de6a Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Thu, 16 May 2024 15:29:02 +0800 Subject: [PATCH 002/107] =?UTF-8?q?gitbook=20=E4=B8=BB=E9=A2=98fix?= =?UTF-8?q?=E6=9C=80=E8=BF=91=E9=98=85=E8=AF=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/db/getSiteData.js | 24 ++++++------------------ lib/utils/pageId.js | 16 +++++++++++++++- pages/[prefix]/[slug]/[...suffix].js | 2 +- pages/[prefix]/[slug]/index.js | 2 +- pages/[prefix]/index.js | 2 +- themes/gitbook/index.js | 19 +++++++++---------- 6 files changed, 33 insertions(+), 32 deletions(-) diff --git a/lib/db/getSiteData.js b/lib/db/getSiteData.js index a4f042bd..f113eb20 100755 --- a/lib/db/getSiteData.js +++ b/lib/db/getSiteData.js @@ -5,14 +5,14 @@ import getAllPageIds from '@/lib/notion/getAllPageIds' import { getAllTags } from '@/lib/notion/getAllTags' import { getConfigMapFromConfigPage } from '@/lib/notion/getNotionConfig' import getPageProperties, { - adjustPageProperties + adjustPageProperties } from '@/lib/notion/getPageProperties' import { fetchInBatches, getPage } from '@/lib/notion/getPostBlocks' import { compressImage, mapImgUrl } from '@/lib/notion/mapImage' import { deepClone } from '@/lib/utils' import { idToUuid } from 'notion-utils' import { siteConfig } from '../config' -import { extractLangId, extractLangPrefix } from '../utils/pageId' +import { extractLangId, extractLangPrefix, getShortId } from '../utils/pageId' export { getAllTags } from '../notion/getAllTags' export { getPost } from '../notion/getNotionPost' @@ -100,16 +100,14 @@ function compressData(db) { // 清理多余的块 if (db?.notice) { db.notice = cleanBlock(db?.notice) - } - if (db?.post) { - db.post = cleanBlock(db?.post) + delete db.notice?.id } db.tagOptions = cleanIds(db?.tagOptions) db.categoryOptions = cleanIds(db?.categoryOptions) db.customMenu = cleanIds(db?.customMenu) - db.latestPosts = cleanIds(db?.latestPosts) + db.latestPosts = shortenIds(db?.latestPosts) db.allNavPages = shortenIds(db?.allNavPages) // db.allPages = cleanBlocks(db?.allPages) @@ -125,7 +123,7 @@ function shortenIds(items) { if (items && Array.isArray(items)) { return deepClone( items.map(item => { - item.short_id = getFirstPart(item.id) + item.short_id = getShortId(item.id) delete item.id return item }) @@ -134,16 +132,6 @@ function shortenIds(items) { return items } -function getFirstPart(uuid) { - if (!uuid || uuid.indexOf('-') < 0) { - return uuid - } - // 找到第一个 '-' 的位置 - const index = uuid.indexOf('-') - // 截取从开始到第一个 '-' 之前的部分 - return uuid.substring(0, index) -} - /** * 清理一组数据的id * @param {*} items @@ -167,7 +155,7 @@ function cleanIds(items) { function cleanBlock(item) { const post = deepClone(item) const pageBlock = post?.blockMap?.block - delete post?.id + // delete post?.id // delete post?.blockMap?.collection if (pageBlock) { diff --git a/lib/utils/pageId.js b/lib/utils/pageId.js index e3c648e1..c963df28 100644 --- a/lib/utils/pageId.js +++ b/lib/utils/pageId.js @@ -30,4 +30,18 @@ function extractLangId(str) { } } -module.exports = { extractLangPrefix, extractLangId } +/** + * 列表中用过来区分page只需要端的id足够 + */ + +function getShortId(uuid) { + if (!uuid || uuid.indexOf('-') < 0) { + return uuid + } + // 找到第一个 '-' 的位置 + const index = uuid.indexOf('-') + // 截取从开始到第一个 '-' 之前的部分 + return uuid.substring(0, index) +} + +module.exports = { extractLangPrefix, extractLangId, getShortId } diff --git a/pages/[prefix]/[slug]/[...suffix].js b/pages/[prefix]/[slug]/[...suffix].js index 2050e81d..47537266 100644 --- a/pages/[prefix]/[slug]/[...suffix].js +++ b/pages/[prefix]/[slug]/[...suffix].js @@ -92,7 +92,7 @@ export async function getStaticProps({ } // 文章内容加载 - if (!props?.posts?.blockMap) { + if (!props?.post?.blockMap) { props.post.blockMap = await getPostBlocks(props.post.id, from) } // 生成全文索引 && JSON.parse(BLOG.ALGOLIA_RECREATE_DATA) diff --git a/pages/[prefix]/[slug]/index.js b/pages/[prefix]/[slug]/index.js index 2c844eba..2b414ce4 100644 --- a/pages/[prefix]/[slug]/index.js +++ b/pages/[prefix]/[slug]/index.js @@ -81,7 +81,7 @@ export async function getStaticProps({ params: { prefix, slug }, locale }) { } // 文章内容加载 - if (!props?.posts?.blockMap) { + if (!props?.post?.blockMap) { props.post.blockMap = await getPostBlocks(props.post.id, from) } // 生成全文索引 && JSON.parse(BLOG.ALGOLIA_RECREATE_DATA) diff --git a/pages/[prefix]/index.js b/pages/[prefix]/index.js index 469ca617..973ce321 100644 --- a/pages/[prefix]/index.js +++ b/pages/[prefix]/index.js @@ -145,7 +145,7 @@ export async function getStaticProps({ params: { prefix }, locale }) { } // 文章内容加载 - if (!props?.posts?.blockMap) { + if (!props?.post?.blockMap) { props.post.blockMap = await getPostBlocks(props.post.id, from) } diff --git a/themes/gitbook/index.js b/themes/gitbook/index.js index d70e152e..c81110b0 100644 --- a/themes/gitbook/index.js +++ b/themes/gitbook/index.js @@ -9,6 +9,7 @@ import ShareBar from '@/components/ShareBar' import { siteConfig } from '@/lib/config' import { useGlobal } from '@/lib/global' import { isBrowser } from '@/lib/utils' +import { getShortId } from '@/lib/utils/pageId' import { Transition } from '@headlessui/react' import dynamic from 'next/dynamic' import Link from 'next/link' @@ -54,14 +55,14 @@ function getNavPagesWithLatest(allNavPages, latestPosts, post) { localStorage.getItem('post_read_time') || '{}' ) if (post) { - postReadTime[post.id] = new Date().getTime() + postReadTime[getShortId(post.id)] = new Date().getTime() } // 更新 localStorage.setItem('post_read_time', JSON.stringify(postReadTime)) return allNavPages?.map(item => { const res = { - id: item.id, + short_id: item.short_id, title: item.title || '', pageCoverThumbnail: item.pageCoverThumbnail || '', category: item.category || null, @@ -74,9 +75,9 @@ function getNavPagesWithLatest(allNavPages, latestPosts, post) { } // 属于最新文章通常6篇 && (无阅读记录 || 最近更新时间大于上次阅读时间) if ( - latestPosts.some(post => post.id === item.id) && - (!postReadTime[item.id] || - postReadTime[item.id] < new Date(item.lastEditedDate).getTime()) + latestPosts.some(post => item?.short_id === post?.short_id) && + (!postReadTime[item.short_id] || + postReadTime[item.short_id] < new Date(item.lastEditedDate).getTime()) ) { return { ...res, isLatest: true } } else { @@ -412,11 +413,9 @@ const LayoutArchive = props => { */ const Layout404 = props => { return ( - <> -
- 404 Not found. -
- +
+ 404 Not found. +
) } From 89d385855f0c028d859c02f805dc03cc5b0ddfe2 Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Fri, 17 May 2024 17:54:26 +0800 Subject: [PATCH 003/107] =?UTF-8?q?RSS=20=E7=94=9F=E6=88=90bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/db/getSiteData.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/db/getSiteData.js b/lib/db/getSiteData.js index f113eb20..6bbe4bc9 100755 --- a/lib/db/getSiteData.js +++ b/lib/db/getSiteData.js @@ -107,7 +107,7 @@ function compressData(db) { db.categoryOptions = cleanIds(db?.categoryOptions) db.customMenu = cleanIds(db?.customMenu) - db.latestPosts = shortenIds(db?.latestPosts) + // db.latestPosts = shortenIds(db?.latestPosts) db.allNavPages = shortenIds(db?.allNavPages) // db.allPages = cleanBlocks(db?.allPages) From 45009c94c7273fc6661277f28b362ffad7f1c9de Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Fri, 17 May 2024 18:17:16 +0800 Subject: [PATCH 004/107] theme-hexo seo --- themes/hexo/components/BlogPostCard.js | 74 +++++++++++++--------- themes/hexo/components/Hero.js | 1 + themes/hexo/components/LatestPostsGroup.js | 1 + themes/hexo/components/PaginationNumber.js | 68 ++++++++++---------- 4 files changed, 80 insertions(+), 64 deletions(-) diff --git a/themes/hexo/components/BlogPostCard.js b/themes/hexo/components/BlogPostCard.js index 10a47726..bcaf44d6 100644 --- a/themes/hexo/components/BlogPostCard.js +++ b/themes/hexo/components/BlogPostCard.js @@ -5,42 +5,58 @@ import CONFIG from '../config' import { BlogPostCardInfo } from './BlogPostCardInfo' const BlogPostCard = ({ index, post, showSummary, siteInfo }) => { - const showPreview = siteConfig('HEXO_POST_LIST_PREVIEW', null, CONFIG) && post.blockMap - if (post && !post.pageCoverThumbnail && siteConfig('HEXO_POST_LIST_COVER_DEFAULT', null, CONFIG)) { + const showPreview = + siteConfig('HEXO_POST_LIST_PREVIEW', null, CONFIG) && post.blockMap + if ( + post && + !post.pageCoverThumbnail && + siteConfig('HEXO_POST_LIST_COVER_DEFAULT', null, CONFIG) + ) { post.pageCoverThumbnail = siteInfo?.pageCover } - const showPageCover = siteConfig('HEXO_POST_LIST_COVER', null, CONFIG) && post?.pageCoverThumbnail && !showPreview + const showPageCover = + siteConfig('HEXO_POST_LIST_COVER', null, CONFIG) && + post?.pageCoverThumbnail && + !showPreview // const delay = (index % 2) * 200 return ( - -
-
+
+ {/* 文字内容 */} + - {/* 文字内容 */} - - - {/* 图片封面 */} - {showPageCover && ( -
- - - -
- )} - -
- -
- + {/* 图片封面 */} + {showPageCover && ( +
+ + + +
+ )} +
+ ) } diff --git a/themes/hexo/components/Hero.js b/themes/hexo/components/Hero.js index 91059205..7e1cdc9d 100644 --- a/themes/hexo/components/Hero.js +++ b/themes/hexo/components/Hero.js @@ -92,6 +92,7 @@ const Hero = props => { diff --git a/themes/hexo/components/LatestPostsGroup.js b/themes/hexo/components/LatestPostsGroup.js index 6254def8..5a0a0161 100644 --- a/themes/hexo/components/LatestPostsGroup.js +++ b/themes/hexo/components/LatestPostsGroup.js @@ -42,6 +42,7 @@ const LatestPostsGroup = ({ latestPosts, siteInfo }) => { className={'my-3 flex'}>
diff --git a/themes/hexo/components/PaginationNumber.js b/themes/hexo/components/PaginationNumber.js index 42281b93..2cbbb69c 100644 --- a/themes/hexo/components/PaginationNumber.js +++ b/themes/hexo/components/PaginationNumber.js @@ -12,60 +12,58 @@ const PaginationNumber = ({ page, totalPage }) => { const router = useRouter() const currentPage = +page const showNext = page < totalPage - const pagePrefix = router.asPath.split('?')[0].replace(/\/page\/[1-9]\d*/, '').replace(/\/$/, '') + const pagePrefix = router.asPath + .split('?')[0] + .replace(/\/page\/[1-9]\d*/, '') + .replace(/\/$/, '') const pages = generatePages(pagePrefix, page, currentPage, totalPage) return ( -
- {/* 上一页 */} - + {/* 上一页 */} + + query: router.query.s ? { s: router.query.s } : {} + }} + rel='prev' + className={`${currentPage === 1 ? 'invisible' : 'block'} pb-0.5 border-white dark:border-indigo-700 hover:border-indigo-400 dark:hover:border-indigo-400 w-6 text-center cursor-pointer duration-200 hover:font-bold`}> + + - + {pages} - - - {pages} - - {/* 下一页 */} - - - - - + {/* 下一页 */} + + +
) } function getPageElement(page, currentPage, pagePrefix) { return ( - ( - {page} - - ) + ) } From 8df65b753ca12e70078c0f3351fdab9f418811d7 Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Mon, 20 May 2024 10:51:19 +0800 Subject: [PATCH 005/107] page inner links --- lib/notion/convertInnerUrl.js | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/lib/notion/convertInnerUrl.js b/lib/notion/convertInnerUrl.js index f4539fb4..981722f7 100644 --- a/lib/notion/convertInnerUrl.js +++ b/lib/notion/convertInnerUrl.js @@ -25,16 +25,19 @@ export const convertInnerUrl = allPages => { } } - 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' + for (const anchorTag of allAnchorTags) { + 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' + } } } } From 2bf51757977c45ff88643cdce0a9282fc3235924 Mon Sep 17 00:00:00 2001 From: BrilliantChen Date: Tue, 21 May 2024 17:15:14 +0800 Subject: [PATCH 006/107] Update theme.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户手动调整的网站颜色模型才保存 --- themes/theme.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/theme.js b/themes/theme.js index fb4f94f0..3b89d92a 100644 --- a/themes/theme.js +++ b/themes/theme.js @@ -102,6 +102,7 @@ export const initDarkMode = (updateDarkMode, defaultDarkMode) => { const userDarkMode = loadDarkModeFromLocalStorage() if (userDarkMode) { newDarkMode = userDarkMode === 'dark' || userDarkMode === 'true' + saveDarkModeToLocalStorage(newDarkMode) //用户手动的才保存 } // 如果站点强制设置默认深色,则优先级改过用 @@ -116,7 +117,6 @@ export const initDarkMode = (updateDarkMode, defaultDarkMode) => { } updateDarkMode(newDarkMode) - saveDarkModeToLocalStorage(newDarkMode) document.getElementsByTagName('html')[0].setAttribute('class', newDarkMode ? 'dark' : 'light') } From 3b062037cef04413ea96440a94b5902bf6129d1e Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Thu, 23 May 2024 20:51:09 +0800 Subject: [PATCH 007/107] fix gitbook latest posts badge --- themes/gitbook/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/gitbook/index.js b/themes/gitbook/index.js index c81110b0..25af5a5c 100644 --- a/themes/gitbook/index.js +++ b/themes/gitbook/index.js @@ -75,7 +75,7 @@ function getNavPagesWithLatest(allNavPages, latestPosts, post) { } // 属于最新文章通常6篇 && (无阅读记录 || 最近更新时间大于上次阅读时间) if ( - latestPosts.some(post => item?.short_id === post?.short_id) && + latestPosts.some(post => post?.id.indexOf(item?.short_id) === 0) && (!postReadTime[item.short_id] || postReadTime[item.short_id] < new Date(item.lastEditedDate).getTime()) ) { From 2eb95b2bf88904a20c665e8a5b4f11b0793be3d4 Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Fri, 24 May 2024 16:56:08 +0800 Subject: [PATCH 008/107] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=E5=AF=86=E7=A0=81=EF=BC=8C=E5=B9=B6=E6=B7=BB=E5=8A=A0=E8=A7=A3?= =?UTF-8?q?=E5=AF=86=E9=80=9A=E7=9F=A5=E5=BC=B9=E6=A1=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Notification.js | 59 ++++++++++++++++++++++++ lib/lang/en-US.js | 4 +- lib/lang/ja-JP.js | 7 ++- lib/lang/zh-CN.js | 1 + lib/password.js | 37 +++++++++++++++ pages/[prefix]/index.js | 25 ++++++++-- themes/gitbook/components/NavPostItem.js | 8 ++-- themes/gitbook/index.js | 11 ++--- themes/nav/components/NavPostItem.js | 52 +++++++++++++-------- 9 files changed, 166 insertions(+), 38 deletions(-) create mode 100644 components/Notification.js create mode 100644 lib/password.js diff --git a/components/Notification.js b/components/Notification.js new file mode 100644 index 00000000..02215d35 --- /dev/null +++ b/components/Notification.js @@ -0,0 +1,59 @@ +import { useState } from 'react' + +const useNotification = () => { + const [message, setMessage] = useState('') + const [isVisible, setIsVisible] = useState(false) + + const showNotification = msg => { + setMessage(msg) + setIsVisible(true) + setTimeout(() => { + setIsVisible(false) + }, 3000) + } + + const closeNotification = () => { + setIsVisible(false) + } + + // 测试通知效果 + // const toggleVisible = () => { + // setIsVisible(prev => !prev) // 使用函数式更新 + // } + // useEffect(() => { + // document?.addEventListener('click', toggleVisible) + // return () => { + // document?.removeEventListener('click', toggleVisible) + // } + // }, []) + + /** + * 通知组件 + * @returns + */ + const Notification = () => { + return ( +
+
+ {message} + +
+
+ ) + } + + return { + showNotification, + closeNotification, + Notification + } +} + +export default useNotification diff --git a/lib/lang/en-US.js b/lib/lang/en-US.js index 47bb171c..985e0a24 100644 --- a/lib/lang/en-US.js +++ b/lib/lang/en-US.js @@ -37,11 +37,13 @@ export default { ARTICLE: 'Article', VISITORS: 'Visitors', VIEWS: 'Views', - COPYRIGHT_NOTICE: 'All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!', + COPYRIGHT_NOTICE: + 'All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!', RESULT_OF_SEARCH: 'Results Found', ARTICLE_DETAIL: 'Article Details', PASSWORD_ERROR: 'Password Error!', ARTICLE_LOCK_TIPS: 'Please Enter the password:', + ARTICLE_UNLOCK_TIPS: 'Article Unlocked', NO_RESULTS_FOUND: 'No results found.', SUBMIT: 'Submit', POST_TIME: 'Post on', diff --git a/lib/lang/ja-JP.js b/lib/lang/ja-JP.js index c27eef0b..628b28b3 100644 --- a/lib/lang/ja-JP.js +++ b/lib/lang/ja-JP.js @@ -29,11 +29,14 @@ export default { ARTICLE: '記事', VISITORS: '人の訪問者', VIEWS: '回の閲覧', - COPYRIGHT_NOTICE: 'この記事はCC BY-NC-SA 4.0 ライセンスの下でライセンスされています。転載する場合には出典を明らかにしてください。', + COPYRIGHT_NOTICE: + 'この記事はCC BY-NC-SA 4.0 ライセンスの下でライセンスされています。転載する場合には出典を明らかにしてください。', RESULT_OF_SEARCH: '個の検索結果', ARTICLE_DETAIL: '記事の詳細', PASSWORD_ERROR: 'パスワードが違います!', - ARTICLE_LOCK_TIPS: 'この記事はロックされています。アクセスパスワードを入力してください。', + ARTICLE_LOCK_TIPS: + 'この記事はロックされています。アクセスパスワードを入力してください。', + ARTICLE_UNLOCK_TIPS: '記事がロック解除されました', SUBMIT: '送信', POST_TIME: '公開日', LAST_EDITED_TIME: '最終更新日', diff --git a/lib/lang/zh-CN.js b/lib/lang/zh-CN.js index a2c8b1c7..e38a27bf 100644 --- a/lib/lang/zh-CN.js +++ b/lib/lang/zh-CN.js @@ -45,6 +45,7 @@ export default { ARTICLE_DETAIL: '文章详情', PASSWORD_ERROR: '密码错误!', ARTICLE_LOCK_TIPS: '文章已上锁,请输入访问密码', + ARTICLE_UNLOCK_TIPS: '文章已解锁', SUBMIT: '提交', POST_TIME: '发布于', LAST_EDITED_TIME: '最后更新', diff --git a/lib/password.js b/lib/password.js new file mode 100644 index 00000000..67b341a6 --- /dev/null +++ b/lib/password.js @@ -0,0 +1,37 @@ +import { isBrowser } from './utils' + +/** + * 获取默认密码 + * 用户可以通过url中拼接参数,输入密码 + * 输入过一次的密码会被存储在浏览器中,便于下一次免密访问 + * 返回的是一组历史密码,便于客户端多次尝试 + */ +export const getPasswordQuery = path => { + // 使用 URL 对象解析 URL + const url = new URL(path, isBrowser ? window.location.origin : '') + + // 获取查询参数 + const queryParams = Object.fromEntries(url.searchParams.entries()) + + // 请求中带着密码 + if (queryParams.password) { + // 将已输入密码作为默认密码存放在 localStorage,便于下次读取并自动尝试 + localStorage.setItem('password_default', queryParams.password) + } + + // 获取路径部分 + const cleanedPath = url.pathname + + // 从 localStorage 中获取相关密码 + const storedPassword = localStorage.getItem('password_' + cleanedPath) + const defaultPassword = localStorage.getItem('password_default') + + // 将所有密码存储在一个数组中,并过滤掉无效值 + const passwords = [ + queryParams.password, + storedPassword, + defaultPassword + ].filter(Boolean) + + return passwords +} diff --git a/pages/[prefix]/index.js b/pages/[prefix]/index.js index 973ce321..d9853a5b 100644 --- a/pages/[prefix]/index.js +++ b/pages/[prefix]/index.js @@ -1,7 +1,10 @@ import BLOG from '@/blog.config' +import useNotification from '@/components/Notification' import { siteConfig } from '@/lib/config' import { getGlobalData, getPost, getPostBlocks } from '@/lib/db/getSiteData' +import { useGlobal } from '@/lib/global' import { getPageTableOfContents } from '@/lib/notion/getPageTableOfContents' +import { getPasswordQuery } from '@/lib/password' import { uploadDataToAlgolia } from '@/lib/plugins/algolia' import { checkSlugHasNoSlash, getRecommendPost } from '@/lib/utils/post' import { getLayoutByTheme } from '@/themes/theme' @@ -19,9 +22,11 @@ import { useEffect, useState } from 'react' const Slug = props => { const { post } = props const router = useRouter() + const { locale } = useGlobal() // 文章锁🔐 const [lock, setLock] = useState(post?.password && post?.password !== '') + const { showNotification, Notification } = useNotification() /** * 验证文章密码 @@ -36,6 +41,7 @@ const Slug = props => { setLock(false) // 输入密码存入localStorage,下次自动提交 localStorage.setItem('password_' + router.asPath, passInput) + showNotification(locale.COMMON.ARTICLE_UNLOCK_TIPS) // 设置解锁成功提示显示 return true } return false @@ -56,10 +62,14 @@ const Slug = props => { } } - // 从localStorage中读取上次记录 自动提交密码 - const passInput = localStorage.getItem('password_' + router.asPath) - if (passInput) { - validPassword(passInput) + // 读取上次记录 自动提交密码 + const passInputs = getPasswordQuery(router.asPath) + if (passInputs.length > 0) { + for (const passInput of passInputs) { + if (validPassword(passInput)) { + break // 密码验证成功,停止尝试 + } + } } }, [post]) @@ -83,7 +93,12 @@ const Slug = props => { theme: siteConfig('THEME'), router: useRouter() }) - return + return ( + <> + + {!lock && } + + ) } export async function getStaticPaths() { diff --git a/themes/gitbook/components/NavPostItem.js b/themes/gitbook/components/NavPostItem.js index cd0c1742..4961d7de 100644 --- a/themes/gitbook/components/NavPostItem.js +++ b/themes/gitbook/components/NavPostItem.js @@ -40,8 +40,8 @@ const NavPostItem = props => { !expanded && }
- {group?.items?.map(post => ( -
+ {group?.items?.map((post, index) => ( +
))} @@ -51,8 +51,8 @@ const NavPostItem = props => { } else { return ( <> - {group?.items?.map(post => ( -
+ {group?.items?.map((post, index) => ( +
))} diff --git a/themes/gitbook/index.js b/themes/gitbook/index.js index 25af5a5c..34c4f05d 100644 --- a/themes/gitbook/index.js +++ b/themes/gitbook/index.js @@ -10,7 +10,6 @@ import { siteConfig } from '@/lib/config' import { useGlobal } from '@/lib/global' import { isBrowser } from '@/lib/utils' import { getShortId } from '@/lib/utils/pageId' -import { Transition } from '@headlessui/react' import dynamic from 'next/dynamic' import Link from 'next/link' import { useRouter } from 'next/router' @@ -102,7 +101,7 @@ const LayoutBase = props => { slotRight, slotTop } = props - const { onLoading, fullWidth } = useGlobal() + const { fullWidth } = useGlobal() const router = useRouter() const [tocVisible, changeTocVisible] = useState(false) const [pageNavVisible, changePageNavVisible] = useState(false) @@ -174,7 +173,7 @@ const LayoutBase = props => { {slotTop} - { leave='transition ease-in-out duration-300 transform' leaveFrom='opacity-100 translate-y-0' leaveTo='opacity-0 -translate-y-16' - unmount={false}> - {children} - + unmount={false}> */} + {children} + {/* */} {/* Google广告 */} diff --git a/themes/nav/components/NavPostItem.js b/themes/nav/components/NavPostItem.js index ec27ce90..d9ecde88 100755 --- a/themes/nav/components/NavPostItem.js +++ b/themes/nav/components/NavPostItem.js @@ -1,6 +1,6 @@ -import BlogPostCard from './BlogPostCard' -import { useState } from 'react' import Collapse from '@/components/Collapse' +import { useState } from 'react' +import BlogPostCard from './BlogPostCard' /** * 导航列表 @@ -9,7 +9,7 @@ import Collapse from '@/components/Collapse' * @returns {JSX.Element} * @constructor */ -const NavPostItem = (props) => { +const NavPostItem = props => { const { group } = props const [isOpen, changeIsOpen] = useState(group?.selected) @@ -20,25 +20,37 @@ const NavPostItem = (props) => { console.log(group) if (group?.category) { - return <> -
- {group?.category} -
+ return ( + <> +
+ {group?.category} +
+ +
+
+ + {group?.items?.map((post, index) => ( +
+
- - {group?.items?.map(post => (
-
)) - } -
- + ))} +
+ + ) } else { - return <> - {group?.items?.map(post => (
-
)) - } - + return ( + <> + {group?.items?.map((post, index) => ( +
+ +
+ ))} + + ) } } From b2e3937b20ccd80d6d8f32f2f18c51153a6e95eb Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Sun, 26 May 2024 16:16:16 +0800 Subject: [PATCH 009/107] =?UTF-8?q?=E6=8F=90=E7=A4=BA=E6=A1=86=E5=A4=9A?= =?UTF-8?q?=E4=BD=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/[prefix]/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/[prefix]/index.js b/pages/[prefix]/index.js index d9853a5b..f5b5d2d1 100644 --- a/pages/[prefix]/index.js +++ b/pages/[prefix]/index.js @@ -96,7 +96,7 @@ const Slug = props => { return ( <> - {!lock && } + {post?.password && post?.password !== '' && !lock && } ) } From 86241e15254c817bc99b0b71fa0b55fbe039c168 Mon Sep 17 00:00:00 2001 From: GreyAir Date: Mon, 27 May 2024 08:25:08 +0000 Subject: [PATCH 010/107] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E9=9A=90=E8=97=8F=E8=AF=84=E8=AE=BA=E7=9A=84?= =?UTF-8?q?=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Comment.js | 136 ++++++++++++++++---------------- lib/notion/getPageProperties.js | 1 + 2 files changed, 70 insertions(+), 67 deletions(-) diff --git a/components/Comment.js b/components/Comment.js index ba0d4256..bc702c4d 100644 --- a/components/Comment.js +++ b/components/Comment.js @@ -121,82 +121,84 @@ const Comment = ({ frontMatter, className }) => { return null } - return ( -
- {/* 延迟加载评论区 */} - {!shouldLoad && ( -
- Loading... - -
- )} + if (frontMatter?.comment != 'Hide') { + return ( +
+ {/* 延迟加载评论区 */} + {!shouldLoad && ( +
+ Loading... + +
+ )} - {shouldLoad && ( - - {COMMENT_ARTALK_SERVER && ( -
- -
- )} + {shouldLoad && ( + + {COMMENT_ARTALK_SERVER && ( +
+ +
+ )} - {COMMENT_TWIKOO_ENV_ID && ( -
- -
- )} + {COMMENT_TWIKOO_ENV_ID && ( +
+ +
+ )} - {COMMENT_WALINE_SERVER_URL && ( -
- -
- )} + {COMMENT_WALINE_SERVER_URL && ( +
+ +
+ )} - {COMMENT_VALINE_APP_ID && ( -
- -
- )} + {COMMENT_VALINE_APP_ID && ( +
+ +
+ )} - {COMMENT_GISCUS_REPO && ( -
- -
- )} + {COMMENT_GISCUS_REPO && ( +
+ +
+ )} - {COMMENT_CUSDIS_APP_ID && ( -
- -
- )} + {COMMENT_CUSDIS_APP_ID && ( +
+ +
+ )} - {COMMENT_UTTERRANCES_REPO && ( -
- -
- )} + {COMMENT_UTTERRANCES_REPO && ( +
+ +
+ )} - {COMMENT_GITALK_CLIENT_ID && ( -
- -
- )} + {COMMENT_GITALK_CLIENT_ID && ( +
+ +
+ )} - {COMMENT_WEBMENTION_ENABLE && ( -
- -
- )} -
- )} -
- ) + {COMMENT_WEBMENTION_ENABLE && ( +
+ +
+ )} + + )} +
+ ) + } } export default Comment diff --git a/lib/notion/getPageProperties.js b/lib/notion/getPageProperties.js index 38eede18..17f88e4e 100644 --- a/lib/notion/getPageProperties.js +++ b/lib/notion/getPageProperties.js @@ -94,6 +94,7 @@ export default async function getPageProperties( properties.type = properties.type?.[0] || '' properties.status = properties.status?.[0] || '' properties.category = properties.category?.[0] || '' + properties.comment = properties.comment?.[0] || '' // 映射值:用户个性化type和status字段的下拉框选项,在此映射回代码的英文标识 mapProperties(properties) From 34292132e794f2cfe71b419ff4063c84633fdd62 Mon Sep 17 00:00:00 2001 From: GreyAir Date: Mon, 27 May 2024 09:01:15 +0000 Subject: [PATCH 011/107] fix bug --- components/Comment.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/Comment.js b/components/Comment.js index bc702c4d..a2b73c05 100644 --- a/components/Comment.js +++ b/components/Comment.js @@ -121,7 +121,7 @@ const Comment = ({ frontMatter, className }) => { return null } - if (frontMatter?.comment != 'Hide') { + if (frontMatter?.comment !== 'Hide') { return (
Date: Mon, 27 May 2024 17:13:12 +0800 Subject: [PATCH 012/107] =?UTF-8?q?=E5=85=AC=E5=91=8A=E6=A0=8F-Notion-Page?= =?UTF-8?q?=E5=BE=AE=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- styles/notion.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/styles/notion.css b/styles/notion.css index 0991011e..ec3db101 100644 --- a/styles/notion.css +++ b/styles/notion.css @@ -523,8 +523,8 @@ summary > .notion-h { .notion-page { /* width: var(--notion-max-width); */ width: 100% !important; - padding-left: calc(min(12px, 8vw)); - padding-right: calc(min(12px, 8vw)); + /* padding-left: calc(min(12px, 8vw)); */ + /* padding-right: calc(min(12px, 8vw)); */ } .notion-full-width { From 19de7e1ab816e2f520937f34babd93beb05023fe Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Mon, 27 May 2024 17:40:18 +0800 Subject: [PATCH 013/107] =?UTF-8?q?heo=E4=B8=BB=E9=A2=98=E5=BE=AE=E8=B0=83?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/CustomContextMenu.js | 236 +++++---- styles/notion.css | 2 + themes/heo/components/ArticleAdjacent.js | 87 ---- themes/heo/components/Header.js | 187 +++++++ themes/heo/components/Hero.js | 6 +- themes/heo/components/NavBar.js | 170 ------- themes/heo/components/PostAdjacent.js | 89 ++++ .../{ArticleCopyright.js => PostCopyright.js} | 20 +- themes/heo/components/PostHeader.js | 213 ++++---- .../{ArticleLock.js => PostLock.js} | 38 +- .../{ArticleRecommend.js => PostRecommend.js} | 6 +- themes/heo/index.js | 468 +++++++++--------- 12 files changed, 818 insertions(+), 704 deletions(-) delete mode 100644 themes/heo/components/ArticleAdjacent.js create mode 100644 themes/heo/components/Header.js delete mode 100644 themes/heo/components/NavBar.js create mode 100644 themes/heo/components/PostAdjacent.js rename themes/heo/components/{ArticleCopyright.js => PostCopyright.js} (68%) rename themes/heo/components/{ArticleLock.js => PostLock.js} (58%) rename themes/heo/components/{ArticleRecommend.js => PostRecommend.js} (82%) diff --git a/components/CustomContextMenu.js b/components/CustomContextMenu.js index 46ffb2a0..229d830f 100644 --- a/components/CustomContextMenu.js +++ b/components/CustomContextMenu.js @@ -1,10 +1,10 @@ -import Link from 'next/link' -import { useRouter } from 'next/router' -import { useEffect, useState, useRef, useLayoutEffect } from 'react' -import { useGlobal } from '@/lib/global' -import { saveDarkModeToLocalStorage, THEMES } from '@/themes/theme' import useWindowSize from '@/hooks/useWindowSize' import { siteConfig } from '@/lib/config' +import { useGlobal } from '@/lib/global' +import { THEMES, saveDarkModeToLocalStorage } from '@/themes/theme' +import Link from 'next/link' +import { useRouter } from 'next/router' +import { useEffect, useLayoutEffect, useRef, useState } from 'react' /** * 自定义右键菜单 @@ -20,14 +20,14 @@ export default function CustomContextMenu(props) { const [width, setWidth] = useState(0) const [height, setHeight] = useState(0) - const { latestPosts } = props + const { allNavPages } = props const router = useRouter() /** * 随机跳转文章 */ function handleJumpToRandomPost() { - const randomIndex = Math.floor(Math.random() * latestPosts.length) - const randomPost = latestPosts[randomIndex] + const randomIndex = Math.floor(Math.random() * allNavPages.length) + const randomPost = allNavPages[randomIndex] router.push(`${siteConfig('SUB_PATH', '')}/${randomPost?.slug}`) } @@ -37,16 +37,26 @@ export default function CustomContextMenu(props) { }, []) useEffect(() => { - const handleContextMenu = (event) => { + setShow(false) + }, [router]) + + useEffect(() => { + const handleContextMenu = event => { event.preventDefault() // 计算点击位置加菜单宽高是否超出屏幕,如果超出则贴边弹出 - const x = (event.clientX < windowSize.width - width) ? event.clientX : windowSize.width - width - const y = (event.clientY < windowSize.height - height) ? event.clientY : windowSize.height - height + const x = + event.clientX < windowSize.width - width + ? event.clientX + : windowSize.width - width + const y = + event.clientY < windowSize.height - height + ? event.clientY + : windowSize.height - height setPosition({ y: `${y}px`, x: `${x}px` }) setShow(true) } - const handleClick = (event) => { + const handleClick = event => { if (menuRef.current && !menuRef.current.contains(event.target)) { setShow(false) } @@ -80,19 +90,20 @@ export default function CustomContextMenu(props) { function handleCopyLink() { const url = window.location.href - navigator.clipboard.writeText(url) + navigator.clipboard + .writeText(url) .then(() => { console.log('页面地址已复制') }) - .catch((error) => { + .catch(error => { console.error('复制页面地址失败:', error) }) setShow(false) } /** - * 切换主题 - */ + * 切换主题 + */ function handleChangeTheme() { const randomTheme = THEMES[Math.floor(Math.random() * THEMES.length)] // 从THEMES数组中 随机取一个主题 const query = router.query @@ -104,14 +115,14 @@ export default function CustomContextMenu(props) { * 复制内容 */ function handleCopy() { - const selectedText = document.getSelection().toString(); + const selectedText = document.getSelection().toString() if (selectedText) { - const tempInput = document.createElement('input'); - tempInput.value = selectedText; - document.body.appendChild(tempInput); - tempInput.select(); - document.execCommand('copy'); - document.body.removeChild(tempInput); + const tempInput = document.createElement('input') + tempInput.value = selectedText + document.body.appendChild(tempInput) + tempInput.select() + document.execCommand('copy') + document.body.removeChild(tempInput) // alert("Text copied: " + selectedText); } else { // alert("Please select some text first."); @@ -130,76 +141,119 @@ export default function CustomContextMenu(props) { } return ( -
+
+ {/* 菜单内容 */} +
+ {/* 顶部导航按钮 */} +
+ + + + +
- {/* 菜单内容 */} -
- {/* 顶部导航按钮 */} -
- - - - -
- -
- - {/* 跳转导航按钮 */} -
- - {siteConfig('CUSTOM_RIGHT_CLICK_CONTEXT_MENU_RANDOM_POST') &&
- -
{locale.MENU.WALK_AROUND}
-
} - - {siteConfig('CUSTOM_RIGHT_CLICK_CONTEXT_MENU_CATEGORY') && - -
{locale.MENU.CATEGORY}
- } - - {siteConfig('CUSTOM_RIGHT_CLICK_CONTEXT_MENU_TAG') && - -
{locale.MENU.TAGS}
- } - -
- -
- - {/* 功能按钮 */} -
- - {siteConfig('CAN_COPY') && ( -
- -
{locale.MENU.COPY}
-
- )} - - {siteConfig('CUSTOM_RIGHT_CLICK_CONTEXT_MENU_SHARE_LINK') &&
- -
{locale.MENU.SHARE_URL}
-
} - - {siteConfig('CUSTOM_RIGHT_CLICK_CONTEXT_MENU_DARK_MODE') &&
- {isDarkMode ? : } -
{isDarkMode ? locale.MENU.LIGHT_MODE : locale.MENU.DARK_MODE}
-
} - - {siteConfig('CUSTOM_RIGHT_CLICK_CONTEXT_MENU_THEME_SWITCH') && ( -
- -
{locale.MENU.THEME_SWITCH}
-
- )} - -
+
+ {/* 跳转导航按钮 */} +
+ {siteConfig('CUSTOM_RIGHT_CLICK_CONTEXT_MENU_RANDOM_POST') && ( +
+ +
{locale.MENU.WALK_AROUND}
-
+ )} + + {siteConfig('CUSTOM_RIGHT_CLICK_CONTEXT_MENU_CATEGORY') && ( + + +
{locale.MENU.CATEGORY}
+ + )} + + {siteConfig('CUSTOM_RIGHT_CLICK_CONTEXT_MENU_TAG') && ( + + +
{locale.MENU.TAGS}
+ + )} +
+ +
+ + {/* 功能按钮 */} +
+ {siteConfig('CAN_COPY') && ( +
+ +
{locale.MENU.COPY}
+
+ )} + + {siteConfig('CUSTOM_RIGHT_CLICK_CONTEXT_MENU_SHARE_LINK') && ( +
+ +
{locale.MENU.SHARE_URL}
+
+ )} + + {siteConfig('CUSTOM_RIGHT_CLICK_CONTEXT_MENU_DARK_MODE') && ( +
+ {isDarkMode ? ( + + ) : ( + + )} +
+ {' '} + {isDarkMode ? locale.MENU.LIGHT_MODE : locale.MENU.DARK_MODE} +
+
+ )} + + {siteConfig('CUSTOM_RIGHT_CLICK_CONTEXT_MENU_THEME_SWITCH') && ( +
+ +
+ {locale.MENU.THEME_SWITCH} +
+
+ )} +
+
+
) } diff --git a/styles/notion.css b/styles/notion.css index ec3db101..e5f8c14f 100644 --- a/styles/notion.css +++ b/styles/notion.css @@ -523,6 +523,8 @@ summary > .notion-h { .notion-page { /* width: var(--notion-max-width); */ width: 100% !important; + padding-left: 0px !important; + padding-right: 0px !important; /* padding-left: calc(min(12px, 8vw)); */ /* padding-right: calc(min(12px, 8vw)); */ } diff --git a/themes/heo/components/ArticleAdjacent.js b/themes/heo/components/ArticleAdjacent.js deleted file mode 100644 index d905be08..00000000 --- a/themes/heo/components/ArticleAdjacent.js +++ /dev/null @@ -1,87 +0,0 @@ -import Link from 'next/link' -import { useRouter } from 'next/router' -import { useEffect, useState } from 'react' -import CONFIG from '../config' -import { siteConfig } from '@/lib/config' - -/** - * 上一篇,下一篇文章 - * @param {prev,next} param0 - * @returns - */ -export default function ArticleAdjacent({ prev, next }) { - const [isScrollEnd, setIsScrollEnd] = useState(false) - const router = useRouter() - - useEffect(() => { - setIsScrollEnd(false) - }, [router]) - - useEffect(() => { - // 文章是否已经到了底部 - const targetElement = document.getElementById('article-end') - - const handleIntersect = (entries) => { - entries.forEach((entry) => { - if (entry.isIntersecting) { - setIsScrollEnd(true) - } - }) - } - - const options = { - root: null, - rootMargin: '0px', - threshold: 0.1 - } - - const observer = new IntersectionObserver(handleIntersect, options) - observer.observe(targetElement) - - return () => { - observer.disconnect() - } - }, []) - - if (!prev || !next || !siteConfig('HEO_ARTICLE_ADJACENT', null, CONFIG)) { - return <> - } - - return ( -
- {/* 移动端 */} -
- -
上一篇
-
{prev.title}
- - -
下一篇
-
{next.title}
- -
- - {/* 桌面端 */} - -
- -
下一篇
-
-
{next?.title}
- -
- -
- ) -} diff --git a/themes/heo/components/Header.js b/themes/heo/components/Header.js new file mode 100644 index 00000000..35b6f058 --- /dev/null +++ b/themes/heo/components/Header.js @@ -0,0 +1,187 @@ +import { siteConfig } from '@/lib/config' +import { isBrowser } from '@/lib/utils' +import throttle from 'lodash.throttle' +import { useCallback, useEffect, useRef, useState } from 'react' +import DarkModeButton from './DarkModeButton' +import Logo from './Logo' +import { MenuListTop } from './MenuListTop' +import RandomPostButton from './RandomPostButton' +import ReadingProgress from './ReadingProgress' +import SearchButton from './SearchButton' +import SlideOver from './SlideOver' + +/** + * 页头:顶部导航 + * @param {*} param0 + * @returns + */ +const Header = props => { + const [fixedNav, setFixedNav] = useState(false) + const [textWhite, setTextWhite] = useState(false) + const [navBgWhite, setBgWhite] = useState(false) + const [activeIndex, setActiveIndex] = useState(0) + + const slideOverRef = useRef() + + const toggleMenuOpen = () => { + slideOverRef?.current?.toggleSlideOvers() + } + + /** + * 根据滚动条,切换导航栏样式 + */ + const scrollTrigger = useCallback( + throttle(() => { + const scrollS = window.scrollY + // 导航栏设置 白色背景 + if (scrollS <= 0) { + setFixedNav(false) + setBgWhite(false) + + // 文章详情页特殊处理 + if (document.querySelector('#post-bg')) { + setFixedNav(true) + setTextWhite(true) + setBgWhite(false) + } + } else { + // 向下滚动后的导航样式 + setFixedNav(true) + setTextWhite(false) + setBgWhite(true) + } + }, 200) + ) + + // 监听滚动 + useEffect(() => { + scrollTrigger() + window.addEventListener('scroll', scrollTrigger) + return () => { + window.removeEventListener('scroll', scrollTrigger) + } + }, []) + + // 监听导航栏显示文字 + useEffect(() => { + let prevScrollY = 0 + let ticking = false + + const handleScroll = () => { + if (!ticking) { + window.requestAnimationFrame(() => { + const currentScrollY = window.scrollY + + if (currentScrollY > prevScrollY) { + setActiveIndex(1) // 向下滚动时设置activeIndex为1 + } else { + setActiveIndex(0) // 向上滚动时设置activeIndex为0 + } + + prevScrollY = currentScrollY + ticking = false + }) + + ticking = true + } + } + + if (isBrowser) { + window.addEventListener('scroll', handleScroll) + } + + return () => { + if (isBrowser) { + window.removeEventListener('scroll', handleScroll) + } + } + }, []) + + return ( + <> + + + {/* 顶部导航菜单栏 */} + + + ) +} + +export default Header diff --git a/themes/heo/components/Hero.js b/themes/heo/components/Hero.js index d5462707..656bca55 100644 --- a/themes/heo/components/Hero.js +++ b/themes/heo/components/Hero.js @@ -62,13 +62,13 @@ function BannerGroup(props) { */ function Banner(props) { const router = useRouter() - const { latestPosts } = props + const { allNavPages } = props /** * 随机跳转文章 */ function handleClickBanner() { - const randomIndex = Math.floor(Math.random() * latestPosts.length) - const randomPost = latestPosts[randomIndex] + const randomIndex = Math.floor(Math.random() * allNavPages.length) + const randomPost = allNavPages[randomIndex] router.push(`${siteConfig('SUB_PATH', '')}/${randomPost?.slug}`) } diff --git a/themes/heo/components/NavBar.js b/themes/heo/components/NavBar.js deleted file mode 100644 index f244c742..00000000 --- a/themes/heo/components/NavBar.js +++ /dev/null @@ -1,170 +0,0 @@ -import { useCallback, useEffect, useRef, useState } from 'react' -import Logo from './Logo' -import throttle from 'lodash.throttle' -import RandomPostButton from './RandomPostButton' -import SearchButton from './SearchButton' -import DarkModeButton from './DarkModeButton' -import SlideOver from './SlideOver' -import ReadingProgress from './ReadingProgress' -import { MenuListTop } from './MenuListTop' -import { isBrowser } from '@/lib/utils' -import { siteConfig } from '@/lib/config' - -/** - * 顶部导航 - * @param {*} param0 - * @returns - */ -const NavBar = props => { - const [fixedNav, setFixedNav] = useState(false) - const [textWhite, setTextWhite] = useState(false) - const [navBgWhite, setBgWhite] = useState(false) - - const [activeIndex, setActiveIndex] = useState(0) - - const slideOverRef = useRef() - - const toggleMenuOpen = () => { - slideOverRef?.current?.toggleSlideOvers() - } - - /** - * 根据滚动条,切换导航栏样式 - */ - const scrollTrigger = useCallback(throttle(() => { - const scrollS = window.scrollY - // 导航栏设置 白色背景 - if (scrollS <= 0) { - setFixedNav(false) - setBgWhite(false) - - // 文章详情页特殊处理 - if (document.querySelector('#post-bg')) { - setFixedNav(true) - setTextWhite(true) - setBgWhite(false) - } - } else { - // 向下滚动后的导航样式 - setFixedNav(true) - setTextWhite(false) - setBgWhite(true) - } - }, 200)) - - // 监听滚动 - useEffect(() => { - scrollTrigger() - window.addEventListener('scroll', scrollTrigger) - return () => { - window.removeEventListener('scroll', scrollTrigger) - } - }, []) - - // 监听导航栏显示文字 - useEffect(() => { - let prevScrollY = 0 - let ticking = false - - const handleScroll = () => { - if (!ticking) { - window.requestAnimationFrame(() => { - const currentScrollY = window.scrollY - - if (currentScrollY > prevScrollY) { - setActiveIndex(1) // 向下滚动时设置activeIndex为1 - } else { - setActiveIndex(0) // 向上滚动时设置activeIndex为0 - } - - prevScrollY = currentScrollY - ticking = false - }) - - ticking = true - } - } - - if (isBrowser) { - window.addEventListener('scroll', handleScroll) - } - - return () => { - if (isBrowser) { - window.removeEventListener('scroll', handleScroll) - } - } - }, []) - - return (<> - - - {/* 顶部导航菜单栏 */} - - ) -} - -export default NavBar diff --git a/themes/heo/components/PostAdjacent.js b/themes/heo/components/PostAdjacent.js new file mode 100644 index 00000000..b854e946 --- /dev/null +++ b/themes/heo/components/PostAdjacent.js @@ -0,0 +1,89 @@ +import { siteConfig } from '@/lib/config' +import Link from 'next/link' +import { useRouter } from 'next/router' +import { useEffect, useState } from 'react' +import CONFIG from '../config' + +/** + * 上一篇,下一篇文章 + * @param {prev,next} param0 + * @returns + */ +export default function PostAdjacent({ prev, next }) { + const [isScrollEnd, setIsScrollEnd] = useState(false) + const router = useRouter() + + useEffect(() => { + setIsScrollEnd(false) + }, [router]) + + useEffect(() => { + // 文章是否已经到了底部 + const targetElement = document.getElementById('article-end') + + const handleIntersect = entries => { + entries.forEach(entry => { + if (entry.isIntersecting) { + setIsScrollEnd(true) + } + }) + } + + const options = { + root: null, + rootMargin: '0px', + threshold: 0.1 + } + + const observer = new IntersectionObserver(handleIntersect, options) + observer.observe(targetElement) + + return () => { + observer.disconnect() + } + }, []) + + if (!prev || !next || !siteConfig('HEO_ARTICLE_ADJACENT', null, CONFIG)) { + return <> + } + + return ( +
+ {/* 移动端 */} +
+ +
上一篇
+
+ {prev.title} +
+ + +
下一篇
+
+ {next.title} +
+ +
+ + {/* 桌面端 */} + +
+ +
下一篇
+
+
{next?.title}
+ +
+
+ ) +} diff --git a/themes/heo/components/ArticleCopyright.js b/themes/heo/components/PostCopyright.js similarity index 68% rename from themes/heo/components/ArticleCopyright.js rename to themes/heo/components/PostCopyright.js index 285eb2d4..a209d25e 100644 --- a/themes/heo/components/ArticleCopyright.js +++ b/themes/heo/components/PostCopyright.js @@ -1,11 +1,15 @@ +import { siteConfig } from '@/lib/config' import { useGlobal } from '@/lib/global' import Link from 'next/link' import { useRouter } from 'next/router' import { useEffect, useState } from 'react' import CONFIG from '../config' -import { siteConfig } from '@/lib/config' -export default function ArticleCopyright () { +/** + * 版权声明 + * @returns + */ +export default function PostCopyright() { const router = useRouter() const [path, setPath] = useState(siteConfig('LINK') + router.asPath) useEffect(() => { @@ -19,17 +23,19 @@ export default function ArticleCopyright () { } return ( -
-
    +
    +
    • {locale.COMMON.AUTHOR}: - + {siteConfig('AUTHOR')}
    • - {locale.COMMON.URL}: - + {locale.COMMON.URL}: + {path}
    • diff --git a/themes/heo/components/PostHeader.js b/themes/heo/components/PostHeader.js index 97ce4fff..f2aa5e9b 100644 --- a/themes/heo/components/PostHeader.js +++ b/themes/heo/components/PostHeader.js @@ -1,12 +1,17 @@ -import Link from 'next/link' -import { siteConfig } from '@/lib/config' -import NotionIcon from '@/components/NotionIcon' -import WavesArea from './WavesArea' import { HashTag } from '@/components/HeroIcons' -import WordCount from '@/components/WordCount' import LazyImage from '@/components/LazyImage' +import NotionIcon from '@/components/NotionIcon' +import WordCount from '@/components/WordCount' +import { siteConfig } from '@/lib/config' import { formatDateFmt } from '@/lib/utils/formatDate' +import Link from 'next/link' +import WavesArea from './WavesArea' +/** + * 文章页头 + * @param {*} param0 + * @returns + */ export default function PostHeader({ post, siteInfo }) { if (!post) { return <> @@ -15,91 +20,121 @@ export default function PostHeader({ post, siteInfo }) { const headerImage = post?.pageCover ? post.pageCover : siteInfo?.pageCover return ( -
      - +
      + -
      - - {/* 文章背景图 */} -
      - -
      - - {/* 文章文字描述 */} -
      - {/* 分类+标签 */} -
      - {post.category && <> - -
      - {post.category} -
      - - } - - {post.tagItems && ( -
      - {post.tagItems.map((tag, index) => ( - -
      {tag.name + (tag.count ? `(${tag.count})` : '')}
      - - - ))} -
      - )} -
      - - {/* 文章Title */} -
      - {siteConfig('POST_TITLE_ICON') && }{post.title} -
      - - {/* 标题底部补充信息 */} -
      - -
      -
      - {post?.type !== 'Page' && ( - <> - - {post?.publishDay} - - - )} - -
      - {post.lastEditedDay} -
      - -
      - - {JSON.parse(siteConfig('ANALYTICS_BUSUANZI_ENABLE')) &&
      - -
      } -
      - -
      - - - -
      +
      + {/* 文章背景图 */} +
      +
      + + {/* 文章文字描述 */} +
      + {/* 分类+标签 */} +
      + {post.category && ( + <> + +
      + {post.category} +
      + + + )} + + {post.tagItems && ( +
      + {post.tagItems.map((tag, index) => ( + +
      + {' '} + {tag.name + (tag.count ? `(${tag.count})` : '')}{' '} +
      + + ))} +
      + )} +
      + + {/* 文章Title */} +
      + {siteConfig('POST_TITLE_ICON') && ( + + )} + {post.title} +
      + + {/* 标题底部补充信息 */} +
      +
      +
      + +
      + {post?.type !== 'Page' && ( + <> + + {' '} + {post?.publishDay} + + + )} + +
      + {' '} + {post.lastEditedDay} +
      +
      + + {JSON.parse(siteConfig('ANALYTICS_BUSUANZI_ENABLE')) && ( +
      + {' '} + +
      + )} +
      +
      + + +
      +
      ) } diff --git a/themes/heo/components/ArticleLock.js b/themes/heo/components/PostLock.js similarity index 58% rename from themes/heo/components/ArticleLock.js rename to themes/heo/components/PostLock.js index 7f1da728..1e87d7e8 100644 --- a/themes/heo/components/ArticleLock.js +++ b/themes/heo/components/PostLock.js @@ -8,7 +8,7 @@ import { useEffect, useRef } from 'react' * @param validPassword(bool) 回调函数,校验正确回调入参为true * @returns */ -export const ArticleLock = props => { +export const PostLock = props => { const { validPassword } = props const { locale } = useGlobal() const submitPassword = () => { @@ -27,25 +27,35 @@ export const ArticleLock = props => { passwordInputRef.current.focus() }, []) - return
      -
      -
      {locale.COMMON.ARTICLE_LOCK_TIPS}
      -
      - { + return ( +
      +
      +
      + {locale.COMMON.ARTICLE_LOCK_TIPS} +
      +
      + { if (e.key === 'Enter') { submitPassword() } }} ref={passwordInputRef} // 绑定ref到passwordInputRef变量 - className='outline-none w-full text-sm pl-5 rounded-l transition focus:shadow-lg font-light leading-10 bg-gray-100 dark:bg-gray-500'> - -
      -  {locale.COMMON.SUBMIT} + className='outline-none w-full text-sm pl-5 rounded-l transition focus:shadow-lg font-light leading-10 bg-gray-100 dark:bg-gray-500'> +
      + +  {locale.COMMON.SUBMIT} + +
      -
      -
      +
      -
      + ) } diff --git a/themes/heo/components/ArticleRecommend.js b/themes/heo/components/PostRecommend.js similarity index 82% rename from themes/heo/components/ArticleRecommend.js rename to themes/heo/components/PostRecommend.js index 02874675..c66b8d4f 100644 --- a/themes/heo/components/ArticleRecommend.js +++ b/themes/heo/components/PostRecommend.js @@ -9,7 +9,7 @@ import CONFIG from '../config' * @param {prev,next} param0 * @returns */ -export default function ArticleRecommend({ recommendPosts, siteInfo }) { +export default function PostRecommend({ recommendPosts, siteInfo }) { const { locale } = useGlobal() if ( @@ -55,6 +55,10 @@ export default function ArticleRecommend({ recommendPosts, siteInfo }) { src={headerImage} className='absolute top-0 w-full h-full object-cover object-center group-hover:scale-110 group-hover:brightness-50 transform duration-200' /> + {/* 卡片的阴影遮罩,为了凸显图片上的文字 */} +
      +
      +
      ) diff --git a/themes/heo/index.js b/themes/heo/index.js index 36f84b1f..f7725939 100644 --- a/themes/heo/index.js +++ b/themes/heo/index.js @@ -6,41 +6,41 @@ * 2. 更多说明参考此[文档](https://docs.tangly1024.com/article/notionnext-heo) */ -import CONFIG from './config' -import { useEffect, useState } from 'react' -import Footer from './components/Footer' -import SideRight from './components/SideRight' -import NavBar from './components/NavBar' +import Comment from '@/components/Comment' +import { AdSlot } from '@/components/GoogleAdsense' +import { HashTag } from '@/components/HeroIcons' +import LazyImage from '@/components/LazyImage' +import replaceSearchResult from '@/components/Mark' +import NotionPage from '@/components/NotionPage' +import ShareBar from '@/components/ShareBar' +import WWAds from '@/components/WWAds' +import { siteConfig } from '@/lib/config' import { useGlobal } from '@/lib/global' +import { loadWowJS } from '@/lib/plugins/wow' +import { isBrowser } from '@/lib/utils' +import { Transition } from '@headlessui/react' +import Link from 'next/link' +import { useRouter } from 'next/router' +import { useEffect, useState } from 'react' +import BlogPostArchive from './components/BlogPostArchive' import BlogPostListPage from './components/BlogPostListPage' import BlogPostListScroll from './components/BlogPostListScroll' -import Hero from './components/Hero' -import { useRouter } from 'next/router' -import SearchNav from './components/SearchNav' -import BlogPostArchive from './components/BlogPostArchive' -import { ArticleLock } from './components/ArticleLock' -import PostHeader from './components/PostHeader' -import Comment from '@/components/Comment' -import NotionPage from '@/components/NotionPage' -import ArticleAdjacent from './components/ArticleAdjacent' -import ArticleCopyright from './components/ArticleCopyright' -import ArticleRecommend from './components/ArticleRecommend' -import ShareBar from '@/components/ShareBar' -import Link from 'next/link' import CategoryBar from './components/CategoryBar' -import { Transition } from '@headlessui/react' -import { Style } from './style' -import { NoticeBar } from './components/NoticeBar' -import { HashTag } from '@/components/HeroIcons' -import LatestPostsGroup from './components/LatestPostsGroup' import FloatTocButton from './components/FloatTocButton' -import replaceSearchResult from '@/components/Mark' -import LazyImage from '@/components/LazyImage' -import WWAds from '@/components/WWAds' -import { AdSlot } from '@/components/GoogleAdsense' -import { siteConfig } from '@/lib/config' -import { isBrowser } from '@/lib/utils' -import { loadWowJS } from '@/lib/plugins/wow' +import Footer from './components/Footer' +import Header from './components/Header' +import Hero from './components/Hero' +import LatestPostsGroup from './components/LatestPostsGroup' +import { NoticeBar } from './components/NoticeBar' +import PostAdjacent from './components/PostAdjacent' +import PostCopyright from './components/PostCopyright' +import PostHeader from './components/PostHeader' +import { PostLock } from './components/PostLock' +import PostRecommend from './components/PostRecommend' +import SearchNav from './components/SearchNav' +import SideRight from './components/SideRight' +import CONFIG from './config' +import { Style } from './style' /** * 基础布局 采用上中下布局,移动端使用顶部侧边导航栏 @@ -49,38 +49,39 @@ import { loadWowJS } from '@/lib/plugins/wow' * @constructor */ const LayoutBase = props => { - const { - children, - slotTop, - className - } = props + const { children, slotTop, className } = props // 全屏模式下的最大宽度 const { fullWidth } = useGlobal() const router = useRouter() const headerSlot = ( -
      +
      {/* 顶部导航 */} - +
      {/* 通知横幅 */} - {router.route === '/' - ? <> - - + {router.route === '/' ? ( + <> + + - : null} + ) : null} {fullWidth ? null : }
      ) // 右侧栏 用户信息+标签列表 - const slotRight = (router.route === '/404' || fullWidth) ? null : + const slotRight = + router.route === '/404' || fullWidth ? null : const maxWidth = fullWidth ? 'max-w-[96rem] mx-auto' : 'max-w-[86rem]' // 普通最大宽度是86rem和顶部菜单栏对齐,留空则与窗口对齐 - const HEO_HERO_BODY_REVERSE = siteConfig('HEO_HERO_BODY_REVERSE', false, CONFIG) + const HEO_HERO_BODY_REVERSE = siteConfig( + 'HEO_HERO_BODY_REVERSE', + false, + CONFIG + ) // 加载wow动画 useEffect(() => { @@ -89,10 +90,8 @@ const LayoutBase = props => { return (
      - + id='theme-heo' + className={`${siteConfig('FONT_STYLE')} bg-[#f7f9fe] dark:bg-[#18171d] h-full min-h-screen flex flex-col scroll-smooth`}>
      + className={`${isDarkMode ? 'bg-[#CA8A04]' : 'bg-[#0060e0]'} absolute top-0 w-full h-full py-10 flex justify-center items-center`}> {/* 文章背景图 */}
      @@ -61,7 +61,10 @@ export default function SideRight(props) { {/* 标签和成绩 */} - +
      diff --git a/themes/heo/index.js b/themes/heo/index.js index 619bb90d..8e19a166 100644 --- a/themes/heo/index.js +++ b/themes/heo/index.js @@ -52,7 +52,7 @@ const LayoutBase = props => { const { children, slotTop, className } = props // 全屏模式下的最大宽度 - const { fullWidth } = useGlobal() + const { fullWidth, isDarkMode } = useGlobal() const router = useRouter() const headerSlot = ( @@ -67,7 +67,7 @@ const LayoutBase = props => { ) : null} - {fullWidth ? null : } + {fullWidth ? null : }
      ) From f7258fd2c66c44756e3479ccd7dc85f07d4bbacb Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Wed, 29 May 2024 14:25:58 +0800 Subject: [PATCH 025/107] =?UTF-8?q?heo=20=E4=B8=BB=E9=A2=98=20=E4=B8=80?= =?UTF-8?q?=E7=82=B9=E7=82=B9=E7=BB=86=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/lang/en-US.js | 3 + lib/lang/zh-CN.js | 3 + styles/notion.css | 1 + themes/heo/components/BlogPostCard.js | 4 +- themes/heo/components/CategoryBar.js | 50 +++-- themes/heo/components/Hero.js | 15 +- themes/heo/components/LatestPostsGroupMini.js | 6 +- themes/heo/components/MenuItemCollapse.js | 4 +- themes/heo/components/MenuItemDrop.js | 4 +- themes/heo/components/MenuListSide.js | 2 +- themes/heo/components/NoticeBar.js | 23 +- themes/heo/components/PostHeader.js | 11 +- themes/heo/components/SlideOver.js | 208 ++++++++++-------- themes/heo/components/TagItemMini.js | 9 +- 14 files changed, 205 insertions(+), 138 deletions(-) diff --git a/lib/lang/en-US.js b/lib/lang/en-US.js index 49339220..f60b375a 100644 --- a/lib/lang/en-US.js +++ b/lib/lang/en-US.js @@ -33,6 +33,9 @@ export default { COPYRIGHT: 'Copyright', AUTHOR: 'Author', URL: 'URL', + NOW: 'NOW', + RECOMMEND_BADGES: 'Recommend', + BLOG: 'Blog', POSTS: 'Posts', ARTICLE: 'Article', VISITORS: 'Visitors', diff --git a/lib/lang/zh-CN.js b/lib/lang/zh-CN.js index 827f376f..4dd1962e 100644 --- a/lib/lang/zh-CN.js +++ b/lib/lang/zh-CN.js @@ -35,6 +35,9 @@ export default { AUTHOR: '作者', URL: '链接', ANALYTICS: '统计', + RECOMMEND_BADGES: '荐', + BLOG: '博客', + NOW: '此刻', POSTS: '篇文章', ARTICLE: '文章', VISITORS: '位访客', diff --git a/styles/notion.css b/styles/notion.css index e5f8c14f..ba794f88 100644 --- a/styles/notion.css +++ b/styles/notion.css @@ -1451,6 +1451,7 @@ code[class*='language-'] { .notion-collection-card-property .notion-page-title-text { border-bottom: 0 none; + @apply dark:text-gray-200; } .notion-collection-card-property diff --git a/themes/heo/components/BlogPostCard.js b/themes/heo/components/BlogPostCard.js index 3a1cf689..b26256e4 100644 --- a/themes/heo/components/BlogPostCard.js +++ b/themes/heo/components/BlogPostCard.js @@ -50,11 +50,11 @@ const BlogPostCard = ({ index, post, showSummary, siteInfo }) => { {/* 分类 */} {post?.category && ( diff --git a/themes/heo/components/CategoryBar.js b/themes/heo/components/CategoryBar.js index eccd9685..9879d8a7 100644 --- a/themes/heo/components/CategoryBar.js +++ b/themes/heo/components/CategoryBar.js @@ -29,23 +29,40 @@ export default function CategoryBar(props) { } } - return
      +
      + + {categoryOptions?.map((c, index) => ( + + ))} +
      -
      - - {categoryOptions?.map((c, index) => )} -
      - -
      - - - {locale.MENU.CATEGORY} - +
      + + + {locale.MENU.CATEGORY} + +
      + ) } /** @@ -57,7 +74,10 @@ const MenuItem = ({ href, name }) => { const router = useRouter() const { category } = router.query const selected = category === name - return
      - {name} + return ( +
      + {name}
      + ) } diff --git a/themes/heo/components/Hero.js b/themes/heo/components/Hero.js index 656bca55..b43987e6 100644 --- a/themes/heo/components/Hero.js +++ b/themes/heo/components/Hero.js @@ -2,6 +2,7 @@ import { ArrowSmallRight, PlusSmall } from '@/components/HeroIcons' import LazyImage from '@/components/LazyImage' import { siteConfig } from '@/lib/config' +import { useGlobal } from '@/lib/global' import Link from 'next/link' import { useRouter } from 'next/router' import { useImperativeHandle, useRef, useState } from 'react' @@ -206,6 +207,7 @@ function GroupMenu() { */ function TopGroup(props) { const { latestPosts, allNavPages, siteInfo } = props + const { locale } = useGlobal() const todayCardRef = useRef() function handleMouseLeave() { todayCardRef.current.coverUp() @@ -238,7 +240,7 @@ function TopGroup(props) {
      {/* hover 悬浮的 ‘荐’ 字 */}
      - 荐 + {locale.COMMON.RECOMMEND_BADGES}
      @@ -304,6 +306,7 @@ function getTopPosts({ latestPosts, allNavPages }) { function TodayCard({ cRef, siteInfo }) { const router = useRouter() const link = siteConfig('HEO_HERO_TITLE_LINK', null, CONFIG) + const { locale } = useGlobal() // 卡牌是否盖住下层 const [isCoverUp, setIsCoverUp] = useState(true) @@ -348,7 +351,7 @@ function TodayCard({ cRef, siteInfo }) { isCoverUp ? 'opacity-100 cursor-pointer' : 'opacity-0 transform scale-110 pointer-events-none' - } shadow transition-all duration-200 today-card h-full bg-[#0E57D5] rounded-xl relative overflow-hidden flex items-end`}> + } shadow transition-all duration-200 today-card h-full bg-[#0E57D5] dark:bg-yellow-500 rounded-xl relative overflow-hidden flex items-end`}>
      @@ -364,12 +367,14 @@ function TodayCard({ cRef, siteInfo }) { onClick={handleClickMore} className={`'${ isCoverUp ? '' : 'hidden pointer-events-none ' - } flex items-center px-3 h-10 justify-center bg-[#425aef] hover:bg-[#4259efcb] transition-colors duration-100 rounded-3xl`}> + } flex items-center px-3 h-10 justify-center bg-[#425aef] hover:bg-[#4259efcb] dark:bg-yellow-500 dark:hover:bg-yellow-600 transition-colors duration-100 rounded-3xl`}>
      - 更多推荐 + {locale.COMMON.MORE}
      diff --git a/themes/heo/components/LatestPostsGroupMini.js b/themes/heo/components/LatestPostsGroupMini.js index 7bc65df3..c8f0dcf4 100644 --- a/themes/heo/components/LatestPostsGroupMini.js +++ b/themes/heo/components/LatestPostsGroupMini.js @@ -50,13 +50,13 @@ export default function LatestPostsGroupMini({ latestPosts, siteInfo }) {
      {post.title}
      -
      {post.lastEditedDay}
      +
      {post.lastEditedDay}
      diff --git a/themes/heo/components/MenuItemCollapse.js b/themes/heo/components/MenuItemCollapse.js index f0f9486b..6278cebe 100644 --- a/themes/heo/components/MenuItemCollapse.js +++ b/themes/heo/components/MenuItemCollapse.js @@ -28,7 +28,7 @@ export const MenuItemCollapse = ({ link }) => { return ( <>
      {!hasSubMenu && ( { return (
      + className='dark:bg-hexo-black-gray dark:text-gray-200 text-left px-3 justify-start bg-gray-50 hover:bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200 py-3 pr-6'> {link?.icon && }{' '} diff --git a/themes/heo/components/MenuItemDrop.js b/themes/heo/components/MenuItemDrop.js index 2e6929a7..4f8241fc 100644 --- a/themes/heo/components/MenuItemDrop.js +++ b/themes/heo/components/MenuItemDrop.js @@ -36,12 +36,12 @@ export const MenuItemDrop = ({ link }) => { {hasSubMenu && (
    ) } diff --git a/themes/heo/index.js b/themes/heo/index.js index 8e19a166..26c1aeda 100644 --- a/themes/heo/index.js +++ b/themes/heo/index.js @@ -297,7 +297,7 @@ const LayoutSlug = props => { data-wow-delay='.2s' className='wow fadeInUp'> {/* Notion文章主体 */} -
    +
    {post && } From 884b3864812abdcc85ed53349da851327dacc7d2 Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Fri, 31 May 2024 15:34:58 +0800 Subject: [PATCH 033/107] v4.5.4 --- .env.local | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.local b/.env.local index 314ae9ad..d5612ac8 100644 --- a/.env.local +++ b/.env.local @@ -1,5 +1,5 @@ # 环境变量 @see https://www.nextjs.cn/docs/basic-features/environment-variables -NEXT_PUBLIC_VERSION=4.5.3 +NEXT_PUBLIC_VERSION=4.5.4 # 可在此添加环境变量,去掉最左边的(# )注释即可 diff --git a/package.json b/package.json index 9d6259b0..8f9373d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "notion-next", - "version": "4.5.3", + "version": "4.5.4", "homepage": "https://github.com/tangly1024/NotionNext.git", "license": "MIT", "repository": { From 0541bb03f9883a54b58131da323ffab89d2c1038 Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Fri, 31 May 2024 16:21:09 +0800 Subject: [PATCH 034/107] =?UTF-8?q?Hero=20show=20more=20=E6=8C=89=E9=92=AE?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- themes/heo/components/Hero.js | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/themes/heo/components/Hero.js b/themes/heo/components/Hero.js index b43987e6..7e999ebe 100644 --- a/themes/heo/components/Hero.js +++ b/themes/heo/components/Hero.js @@ -247,6 +247,7 @@ function TopGroup(props) { ) })}
+ {/* 一个大的跳转文章卡片 */}
) @@ -322,10 +323,10 @@ function TodayCard({ cRef, siteInfo }) { }) /** - * 点击更多 + * 查看更多 * @param {*} e */ - function handleClickMore(e) { + function handleClickShowMore(e) { e.stopPropagation() setIsCoverUp(false) } @@ -351,10 +352,11 @@ function TodayCard({ cRef, siteInfo }) { isCoverUp ? 'opacity-100 cursor-pointer' : 'opacity-0 transform scale-110 pointer-events-none' - } shadow transition-all duration-200 today-card h-full bg-[#0E57D5] dark:bg-yellow-500 rounded-xl relative overflow-hidden flex items-end`}> + } shadow transition-all duration-200 today-card h-full bg-black rounded-xl relative overflow-hidden flex items-end`}> + {/* 卡片文字信息 */}
+ className='flex justify-between w-full relative text-white p-10 items-end'>
{siteConfig('HEO_HERO_TITLE_4', null, CONFIG)} @@ -363,14 +365,14 @@ function TodayCard({ cRef, siteInfo }) { {siteConfig('HEO_HERO_TITLE_5', null, CONFIG)}
+ {/* 查看更多的按钮 */}
+ onClick={handleClickShowMore} + className={`'${isCoverUp ? '' : 'hidden pointer-events-none'} z-10 group flex items-center px-3 h-10 justify-center rounded-3xl + glassmorphism transition-colors duration-100 `}>
@@ -378,14 +380,16 @@ function TodayCard({ cRef, siteInfo }) {
-
+ } hover:scale-110 duration-1000 object-cover cursor-pointer today-card-cover absolute w-full h-full top-0`} + />
) From b22a53c6a3c8e0505ff0155aca9b3c356064a1ba Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Mon, 3 Jun 2024 15:45:51 +0800 Subject: [PATCH 035/107] Update README_EN.md --- README_EN.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README_EN.md b/README_EN.md index dbb75684..dd4063e5 100644 --- a/README_EN.md +++ b/README_EN.md @@ -35,15 +35,15 @@ Live Demo:[https://preview.tangly1024.com/](https://preview.tangly1024.com/) It only takes a few minutes to set up your personal site: -- [Quick Deployment Tutorial - Multiple Options Available](https://tangly1024.com/article/notion-next) +- [Quick Deployment Tutorial - Multiple Options Available](https://docs.tangly1024.com/article/vercel-deploy-notion-next) -- [Customization Guide - How to Configure Feature Plugins](https://tangly1024.com/article/notion-next-guide) +- [Customization Guide - How to Configure Feature Plugins](https://docs.tangly1024.com/article/how-to-config-notion-next) -- [Development Guide - How to Conduct Local Development](https://tangly1024.com/article/how-to-develop-with-notion-next) +- [Development Guide - How to Conduct Local Development](https://docs.tangly1024.com/article/how-to-develop-with-notion-next) -- [Update Guide - How to Get the Latest Upgrade Patch](https://tangly1024.com/article/how-to-update-notionnext) +- [Update Guide - How to Get the Latest Upgrade Patch](https://docs.tangly1024.com/article/how-to-update-notionnext) -- [Version History - Check Feature Highlights for Each Version](https://tangly1024.com/article/notion-next-changelogs) +- [Version History - Check Feature Highlights for Each Version](https://docs.tangly1024.com/article/latest) ## Acknowledgements From 1f5b77406adf1bf51b02331cb0e22654763faa8e Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Mon, 3 Jun 2024 18:02:09 +0800 Subject: [PATCH 036/107] =?UTF-8?q?=E5=8A=A8=E6=95=88=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E7=AB=AF=E7=89=B9=E6=AE=8A=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Fireworks.js | 6 +++++- components/MouseFollow.js | 20 +++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/components/Fireworks.js b/components/Fireworks.js index cb6a2d98..e61585f1 100644 --- a/components/Fireworks.js +++ b/components/Fireworks.js @@ -35,7 +35,11 @@ const Fireworks = () => { loadFireworks() return () => { - // 在组件卸载时清理资源(如果需要) + // 在组件卸载时清理资源 + const fireworksElements = document.getElementsByClassName('fireworks') + while (fireworksElements.length > 0) { + fireworksElements[0].parentNode.removeChild(fireworksElements[0]) + } } }, []) diff --git a/components/MouseFollow.js b/components/MouseFollow.js index 2215a0ce..cc10d29c 100644 --- a/components/MouseFollow.js +++ b/components/MouseFollow.js @@ -15,8 +15,26 @@ const MOUSE_FOLLOW = () => { loadExternalResource('/js/mouse-follow.js', 'js').then(url => { window.createMouseCanvas && window.createMouseCanvas()({ type, color }) }) + + return () => { + // 在组件卸载时清理资源 + const mouseFollowElement = document.getElementById('vixcityCanvas') + mouseFollowElement?.parentNode?.removeChild(mouseFollowElement) + } }, []) - return <> + return ( + <> + + + ) } export default MOUSE_FOLLOW From 71106860bd4c97f67cf4f7cdffa0018c883c5d96 Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Mon, 3 Jun 2024 18:02:23 +0800 Subject: [PATCH 037/107] =?UTF-8?q?gitbook=20=E5=B8=83=E5=B1=80=E4=BA=A4?= =?UTF-8?q?=E4=BA=92=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/CatalogDrawerWrapper.js | 60 +++++++++++++++++++ themes/gitbook/components/FloatTocButton.js | 25 -------- themes/gitbook/components/Header.js | 2 +- themes/gitbook/components/JumpToTopButton.js | 24 ++++---- themes/gitbook/components/LogoBar.js | 12 ---- .../gitbook/components/MobileButtonCatalog.js | 27 +++++++++ .../gitbook/components/MobileButtonPageNav.js | 27 +++++++++ themes/gitbook/components/PageNavDrawer.js | 12 +++- themes/gitbook/components/TocDrawer.js | 34 ----------- themes/gitbook/index.js | 24 +++++--- themes/gitbook/style.js | 16 +++-- themes/nav/components/FloatButtonCatalog.js | 27 +++++++++ themes/nav/components/FloatTocButton.js | 25 -------- themes/nav/index.js | 4 +- 14 files changed, 195 insertions(+), 124 deletions(-) create mode 100644 themes/gitbook/components/CatalogDrawerWrapper.js delete mode 100644 themes/gitbook/components/FloatTocButton.js create mode 100644 themes/gitbook/components/MobileButtonCatalog.js create mode 100644 themes/gitbook/components/MobileButtonPageNav.js delete mode 100644 themes/gitbook/components/TocDrawer.js create mode 100644 themes/nav/components/FloatButtonCatalog.js delete mode 100755 themes/nav/components/FloatTocButton.js diff --git a/themes/gitbook/components/CatalogDrawerWrapper.js b/themes/gitbook/components/CatalogDrawerWrapper.js new file mode 100644 index 00000000..3b6ee8da --- /dev/null +++ b/themes/gitbook/components/CatalogDrawerWrapper.js @@ -0,0 +1,60 @@ +import { useGlobal } from '@/lib/global' +import { useGitBookGlobal } from '@/themes/gitbook' +import Catalog from './Catalog' + +/** + * 悬浮抽屉目录 + * @param toc + * @param post + * @returns {JSX.Element} + * @constructor + */ +const CatalogDrawerWrapper = ({ post, cRef }) => { + const { tocVisible, changeTocVisible } = useGitBookGlobal() + const { locale } = useGlobal() + const switchVisible = () => { + changeTocVisible(!tocVisible) + } + return ( + <> +
+ {/* 侧边菜单 */} +
+ {post && ( + <> +
+ {locale.COMMON.TABLE_OF_CONTENTS} + { + changeTocVisible(false) + }}> +
+
+ +
+ + )} +
+
+ {/* 背景蒙版 */} +
diff --git a/themes/gitbook/components/JumpToTopButton.js b/themes/gitbook/components/JumpToTopButton.js index 0afdbb6c..21b53733 100644 --- a/themes/gitbook/components/JumpToTopButton.js +++ b/themes/gitbook/components/JumpToTopButton.js @@ -1,4 +1,3 @@ - /** * 跳转到网页顶部 * 当屏幕下滑500像素后会出现该控件 @@ -9,15 +8,20 @@ */ const JumpToTopButton = ({ showPercent = false, percent, className }) => { return ( -
- { window.scrollTo({ top: 0, behavior: 'smooth' }) }} /> -
+
+ { + window.scrollTo({ top: 0, behavior: 'smooth' }) + }} + /> +
) } diff --git a/themes/gitbook/components/LogoBar.js b/themes/gitbook/components/LogoBar.js index c2d1c453..dfe3cadd 100644 --- a/themes/gitbook/components/LogoBar.js +++ b/themes/gitbook/components/LogoBar.js @@ -1,6 +1,5 @@ import LazyImage from '@/components/LazyImage' import { siteConfig } from '@/lib/config' -import { useGitBookGlobal } from '@/themes/gitbook' import Link from 'next/link' import CONFIG from '../config' @@ -11,19 +10,8 @@ import CONFIG from '../config' */ export default function LogoBar(props) { const { siteInfo } = props - const { pageNavVisible, changePageNavVisible } = useGitBookGlobal() - - const togglePageNavVisible = () => { - changePageNavVisible(!pageNavVisible) - } return (
-
- -
diff --git a/themes/gitbook/components/MobileButtonCatalog.js b/themes/gitbook/components/MobileButtonCatalog.js new file mode 100644 index 00000000..2c612894 --- /dev/null +++ b/themes/gitbook/components/MobileButtonCatalog.js @@ -0,0 +1,27 @@ +import { useGitBookGlobal } from '@/themes/gitbook' + +/** + * 移动端目录按钮 + */ +export default function MobileButtonCatalog() { + const { tocVisible, changeTocVisible } = useGitBookGlobal() + + const toggleToc = () => { + changeTocVisible(!tocVisible) + } + + return ( +
+ ) +} diff --git a/themes/gitbook/components/MobileButtonPageNav.js b/themes/gitbook/components/MobileButtonPageNav.js new file mode 100644 index 00000000..65a3c39a --- /dev/null +++ b/themes/gitbook/components/MobileButtonPageNav.js @@ -0,0 +1,27 @@ +import { useGitBookGlobal } from '@/themes/gitbook' + +/** + * 移动端文章导航按钮 + */ +export default function MobileButtonPageNav() { + const { pageNavVisible, changePageNavVisible } = useGitBookGlobal() + + const togglePageNavVisible = () => { + changePageNavVisible(!pageNavVisible) + } + + return ( + + ) +} diff --git a/themes/gitbook/components/PageNavDrawer.js b/themes/gitbook/components/PageNavDrawer.js index b5657d18..eb927762 100644 --- a/themes/gitbook/components/PageNavDrawer.js +++ b/themes/gitbook/components/PageNavDrawer.js @@ -1,3 +1,4 @@ +import { useGlobal } from '@/lib/global' import { useGitBookGlobal } from '@/themes/gitbook' import NavPostList from './NavPostList' @@ -11,6 +12,7 @@ import NavPostList from './NavPostList' const PageNavDrawer = props => { const { pageNavVisible, changePageNavVisible } = useGitBookGlobal() const { filteredNavPages } = props + const { locale } = useGlobal() const switchVisible = () => { changePageNavVisible(!pageNavVisible) @@ -24,7 +26,15 @@ const PageNavDrawer = props => { {/* 侧边菜单 */}
+ overflow-y-hidden shadow-card w-72 duration-200 fixed left-1 bottom-16 rounded py-2 bg-white dark:bg-hexo-black-gray`}> +
+ {locale.COMMON.ARTICLE} + { + changePageNavVisible(false) + }}> +
{/* 所有文章列表 */}
diff --git a/themes/gitbook/components/TocDrawer.js b/themes/gitbook/components/TocDrawer.js deleted file mode 100644 index 7b07044a..00000000 --- a/themes/gitbook/components/TocDrawer.js +++ /dev/null @@ -1,34 +0,0 @@ -import { useGitBookGlobal } from '@/themes/gitbook' -import Catalog from './Catalog' - -/** - * 悬浮抽屉目录 - * @param toc - * @param post - * @returns {JSX.Element} - * @constructor - */ -const TocDrawer = ({ post, cRef }) => { - const { tocVisible, changeTocVisible } = useGitBookGlobal() - const switchVisible = () => { - changeTocVisible(!tocVisible) - } - return <> -
- {/* 侧边菜单 */} -
- {post && <> -
- -
- } -
-
- {/* 背景蒙版 */} -
- -} -export default TocDrawer diff --git a/themes/gitbook/index.js b/themes/gitbook/index.js index 34c4f05d..9fe1682e 100644 --- a/themes/gitbook/index.js +++ b/themes/gitbook/index.js @@ -20,18 +20,19 @@ import ArticleInfo from './components/ArticleInfo' import { ArticleLock } from './components/ArticleLock' import BlogArchiveItem from './components/BlogArchiveItem' import Catalog from './components/Catalog' +import CatalogDrawerWrapper from './components/CatalogDrawerWrapper' import CategoryItem from './components/CategoryItem' -import FloatTocButton from './components/FloatTocButton' import Footer from './components/Footer' import Header from './components/Header' import InfoCard from './components/InfoCard' import JumpToTopButton from './components/JumpToTopButton' +import MobileButtonCatalog from './components/MobileButtonCatalog' +import MobileButtonPageNav from './components/MobileButtonPageNav' import NavPostList from './components/NavPostList' import PageNavDrawer from './components/PageNavDrawer' import RevolverMaps from './components/RevolverMaps' import SearchInput from './components/SearchInput' import TagItemMini from './components/TagItemMini' -import TocDrawer from './components/TocDrawer' import CONFIG from './config' import { Style } from './style' @@ -211,6 +212,7 @@ const LayoutBase = props => {
+ {/* 桌面端目录 */} {slotRight} {router.route === '/' && ( @@ -235,12 +237,17 @@ const LayoutBase = props => { )} - {/* 移动端悬浮目录按钮 */} - {showTocButton && !tocVisible && ( -
- + {/* 移动端底部按钮 */} +
+
+
- )} + {showTocButton && ( +
+ +
+ )} +
{/* 移动端导航抽屉 */} @@ -366,7 +373,8 @@ const LayoutSlug = props => { )} - + {/* 文章目录 */} +
)} diff --git a/themes/gitbook/style.js b/themes/gitbook/style.js index 5e8eaa5a..904da2a7 100644 --- a/themes/gitbook/style.js +++ b/themes/gitbook/style.js @@ -5,14 +5,18 @@ * @returns */ const Style = () => { - return + .bottom-button-group { + box-shadow: 0px -3px 10px 0px rgba(0, 0, 0, 0.1); + } + `} + ) } export { Style } diff --git a/themes/nav/components/FloatButtonCatalog.js b/themes/nav/components/FloatButtonCatalog.js new file mode 100644 index 00000000..753451da --- /dev/null +++ b/themes/nav/components/FloatButtonCatalog.js @@ -0,0 +1,27 @@ +import { useNavGlobal } from '@/themes/nav' + +/** + * 移动端悬浮目录按钮 + */ +export default function FloatButtonCatalog() { + const { tocVisible, changeTocVisible } = useNavGlobal() + + const toggleToc = () => { + changeTocVisible(!tocVisible) + } + + return ( +
+ ) +} diff --git a/themes/nav/components/FloatTocButton.js b/themes/nav/components/FloatTocButton.js deleted file mode 100755 index d4ff317d..00000000 --- a/themes/nav/components/FloatTocButton.js +++ /dev/null @@ -1,25 +0,0 @@ -import { useNavGlobal } from '@/themes/nav' - -/** - * 移动端悬浮目录按钮 - */ -export default function FloatTocButton () { - const { tocVisible, changeTocVisible } = useNavGlobal() - - const toggleToc = () => { - changeTocVisible(!tocVisible) - } - - return ( - - ) -} diff --git a/themes/nav/index.js b/themes/nav/index.js index 54cea4b8..4a9bd724 100755 --- a/themes/nav/index.js +++ b/themes/nav/index.js @@ -25,7 +25,7 @@ import BlogArchiveItem from './components/BlogArchiveItem' import BlogPostCard from './components/BlogPostCard' import BlogPostListAll from './components/BlogPostListAll' import CategoryItem from './components/CategoryItem' -import FloatTocButton from './components/FloatTocButton' +import FloatButtonCatalog from './components/FloatButtonCatalog' import Footer from './components/Footer' import JumpToTopButton from './components/JumpToTopButton' import LogoBar from './components/LogoBar' @@ -187,7 +187,7 @@ const LayoutBase = props => { {/* 移动端悬浮目录按钮 */} {showTocButton && !tocVisible && (
- +
)} From 3a62c471276d65d800e7032bf7da805fc8a26adb Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Mon, 3 Jun 2024 18:15:48 +0800 Subject: [PATCH 038/107] =?UTF-8?q?gitbook=20=E4=B8=BB=E9=A2=98=E4=BA=BF?= =?UTF-8?q?=E7=82=B9=E7=BB=86=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- themes/gitbook/components/Footer.js | 62 ++++++++++++++++++++--------- themes/gitbook/index.js | 22 +++++----- 2 files changed, 56 insertions(+), 28 deletions(-) diff --git a/themes/gitbook/components/Footer.js b/themes/gitbook/components/Footer.js index 78a91cd5..d0e2a150 100644 --- a/themes/gitbook/components/Footer.js +++ b/themes/gitbook/components/Footer.js @@ -4,30 +4,56 @@ const Footer = ({ siteInfo }) => { const d = new Date() const currentYear = d.getFullYear() const since = siteConfig('SINCE') - const copyrightDate = parseInt(since) < currentYear ? since + '-' + currentYear : currentYear + const copyrightDate = + parseInt(since) < currentYear ? since + '-' + currentYear : currentYear return ( -
) } diff --git a/themes/gitbook/index.js b/themes/gitbook/index.js index 9fe1682e..89240a63 100644 --- a/themes/gitbook/index.js +++ b/themes/gitbook/index.js @@ -140,9 +140,8 @@ const LayoutBase = props => {
{/* 左侧推拉抽屉 */} {fullWidth ? null : ( @@ -150,16 +149,19 @@ const LayoutBase = props => { className={ 'hidden md:block border-r dark:border-transparent relative z-10 dark:bg-hexo-black-gray' }> -
- {slotLeft} - -
+
+ {/* 导航 */} +
+ {/* 嵌入 */} + {slotLeft} + {/* 搜索框 */} + + + {/* 文章列表 */} {/* 所有文章列表 */}
-
- -
+ {/* 页脚 */}
From dc7e53343cfeb18cd8f49ca0f0afb0cc6ebea521 Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Mon, 3 Jun 2024 18:47:52 +0800 Subject: [PATCH 039/107] =?UTF-8?q?fukasawa=20=E4=B8=80=E7=82=B9=E5=BE=AE?= =?UTF-8?q?=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- themes/fukasawa/components/AsideLeft.js | 203 ++++++++++++-------- themes/fukasawa/components/Header.js | 64 +++++++ themes/fukasawa/components/TopNav.js | 50 ----- themes/fukasawa/index.js | 237 ++++++++++++++---------- 4 files changed, 321 insertions(+), 233 deletions(-) create mode 100644 themes/fukasawa/components/Header.js delete mode 100644 themes/fukasawa/components/TopNav.js diff --git a/themes/fukasawa/components/AsideLeft.js b/themes/fukasawa/components/AsideLeft.js index f534d1b6..b0ea2313 100644 --- a/themes/fukasawa/components/AsideLeft.js +++ b/themes/fukasawa/components/AsideLeft.js @@ -1,22 +1,22 @@ -import Logo from './Logo' -import GroupCategory from './GroupCategory' -import { MenuList } from './MenuList' -import GroupTag from './GroupTag' -import SearchInput from './SearchInput' -import SiteInfo from './SiteInfo' -import Catalog from './Catalog' -import Announcement from './Announcement' -import { useRouter } from 'next/router' import DarkModeButton from '@/components/DarkModeButton' -import SocialButton from './SocialButton' -import CONFIG from '@/themes/fukasawa/config' import { AdSlot } from '@/components/GoogleAdsense' import { siteConfig } from '@/lib/config' -import MailChimpForm from './MailChimpForm' import { useGlobal } from '@/lib/global' -import { useEffect, useMemo, useState } from 'react' import { isBrowser } from '@/lib/utils' +import CONFIG from '@/themes/fukasawa/config' import { debounce } from 'lodash' +import { useRouter } from 'next/router' +import { useEffect, useMemo, useState } from 'react' +import Announcement from './Announcement' +import Catalog from './Catalog' +import GroupCategory from './GroupCategory' +import GroupTag from './GroupTag' +import Logo from './Logo' +import MailChimpForm from './MailChimpForm' +import { MenuList } from './MenuList' +import SearchInput from './SearchInput' +import SiteInfo from './SiteInfo' +import SocialButton from './SocialButton' /** * 侧边栏 @@ -24,16 +24,41 @@ import { debounce } from 'lodash' * @returns */ function AsideLeft(props) { - const { tagOptions, currentTag, categoryOptions, currentCategory, post, slot, notice } = props + const { + tagOptions, + currentTag, + categoryOptions, + currentCategory, + post, + slot, + notice + } = props const router = useRouter() const { fullWidth } = useGlobal() - const FUKASAWA_SIDEBAR_COLLAPSE_SATUS_DEFAULT = fullWidth || siteConfig('FUKASAWA_SIDEBAR_COLLAPSE_SATUS_DEFAULT', null, CONFIG) + const FUKASAWA_SIDEBAR_COLLAPSE_SATUS_DEFAULT = + fullWidth || + siteConfig('FUKASAWA_SIDEBAR_COLLAPSE_SATUS_DEFAULT', null, CONFIG) + + const FUKASAWA_SIDEBAR_COLLAPSE_ON_SCROLL = siteConfig( + 'FUKASAWA_SIDEBAR_COLLAPSE_ON_SCROLL', + false, + CONFIG + ) + + const FUKASAWA_SIDEBAR_COLLAPSE_BUTTON = siteConfig( + 'FUKASAWA_SIDEBAR_COLLAPSE_BUTTON', + null, + CONFIG + ) // 侧边栏折叠从 本地存储中获取 open 状态的初始值 const [isCollapsed, setIsCollapse] = useState(() => { if (typeof window !== 'undefined') { - return localStorage.getItem('fukasawa-sidebar-collapse') === 'true' || FUKASAWA_SIDEBAR_COLLAPSE_SATUS_DEFAULT + return ( + localStorage.getItem('fukasawa-sidebar-collapse') === 'true' || + FUKASAWA_SIDEBAR_COLLAPSE_SATUS_DEFAULT + ) } return FUKASAWA_SIDEBAR_COLLAPSE_SATUS_DEFAULT }) @@ -69,7 +94,7 @@ function AsideLeft(props) { // 自动折叠侧边栏 onResize 窗口宽度小于1366 || 滚动条滚动至页面的300px时 ; 将open设置为false useEffect(() => { - if (!siteConfig('FUKASAWA_SIDEBAR_COLLAPSE_ON_SCROLL', false, CONFIG)) { + if (!FUKASAWA_SIDEBAR_COLLAPSE_ON_SCROLL) { return } const handleResize = debounce(() => { @@ -92,73 +117,89 @@ function AsideLeft(props) { } } }, []) - - - return
- {/* 移动端底部导航按钮 */} -
-
- -
- {showTocButton && ( -
- -
- )} -
- {/* 移动端导航抽屉 */} {/* 移动端底部导航栏 */} - {/* */} +
) From 528986403b71b32a18b146d6963134f55cf90b0e Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Mon, 24 Jun 2024 10:29:12 +0800 Subject: [PATCH 072/107] =?UTF-8?q?hexo=20=E5=9B=BE=E7=89=87=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E8=B7=B3=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- themes/hexo/components/BlogPostCard.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/themes/hexo/components/BlogPostCard.js b/themes/hexo/components/BlogPostCard.js index bcaf44d6..e6217c8a 100644 --- a/themes/hexo/components/BlogPostCard.js +++ b/themes/hexo/components/BlogPostCard.js @@ -45,13 +45,15 @@ const BlogPostCard = ({ index, post, showSummary, siteInfo }) => { {/* 图片封面 */} {showPageCover && (
- - + + <> + +
)} From bce5d4e07634155c5fe7de0be29828f123fc7fff Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Mon, 24 Jun 2024 13:48:13 +0800 Subject: [PATCH 073/107] =?UTF-8?q?=E6=9B=BF=E6=8D=A2RSS=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- themes/commerce/components/SocialButton.js | 128 +++++++++++++----- themes/fukasawa/components/SocialButton.js | 128 +++++++++++++----- themes/gitbook/components/SocialButton.js | 6 +- themes/heo/components/SocialButton.js | 128 +++++++++++++----- themes/hexo/components/SocialButton.js | 6 +- themes/matery/components/SocialButton.js | 143 +++++++++++++++------ themes/medium/components/SocialButton.js | 124 +++++++++++++----- themes/nav/components/SocialButton.js | 100 ++++++++++---- themes/next/components/SocialButton.js | 128 +++++++++++++----- themes/plog/components/SocialButton.js | 128 +++++++++++++----- themes/simple/components/SocialButton.js | 128 +++++++++++++----- themes/starter/components/SocialButton.js | 128 +++++++++++++----- 12 files changed, 950 insertions(+), 325 deletions(-) diff --git a/themes/commerce/components/SocialButton.js b/themes/commerce/components/SocialButton.js index 555e8ea6..24823924 100644 --- a/themes/commerce/components/SocialButton.js +++ b/themes/commerce/components/SocialButton.js @@ -5,39 +5,101 @@ import { siteConfig } from '@/lib/config' * @constructor */ const SocialButton = () => { - return
-
- {siteConfig('CONTACT_GITHUB') && - - } - {siteConfig('CONTACT_TWITTER') && - - } - {siteConfig('CONTACT_TELEGRAM') && - - } - {siteConfig('CONTACT_LINKEDIN') && - - } - {siteConfig('CONTACT_WEIBO') && - - } - {siteConfig('CONTACT_INSTAGRAM') && - - } - {siteConfig('CONTACT_EMAIL') && - - } - {JSON.parse(siteConfig('ENABLE_RSS')) && - - } - {siteConfig('CONTACT_BILIBILI') && - - } - {siteConfig('CONTACT_YOUTUBE') && - - } + return ( +
+
+ {siteConfig('CONTACT_GITHUB') && ( + + + + )} + {siteConfig('CONTACT_TWITTER') && ( + + + + )} + {siteConfig('CONTACT_TELEGRAM') && ( + + + + )} + {siteConfig('CONTACT_LINKEDIN') && ( + + + + )} + {siteConfig('CONTACT_WEIBO') && ( + + + + )} + {siteConfig('CONTACT_INSTAGRAM') && ( + + + + )} + {siteConfig('CONTACT_EMAIL') && ( + + + + )} + {JSON.parse(siteConfig('ENABLE_RSS')) && ( + + + + )} + {siteConfig('CONTACT_BILIBILI') && ( + + + + )} + {siteConfig('CONTACT_YOUTUBE') && ( + + + + )} +
-
+ ) } export default SocialButton diff --git a/themes/fukasawa/components/SocialButton.js b/themes/fukasawa/components/SocialButton.js index 796d5c5f..87c35d12 100644 --- a/themes/fukasawa/components/SocialButton.js +++ b/themes/fukasawa/components/SocialButton.js @@ -6,39 +6,101 @@ import { siteConfig } from '@/lib/config' * @constructor */ const SocialButton = () => { - return
-
- {siteConfig('CONTACT_GITHUB') && - - } - {siteConfig('CONTACT_TWITTER') && - - } - {siteConfig('CONTACT_TELEGRAM') && - - } - {siteConfig('CONTACT_LINKEDIN') && - - } - {siteConfig('CONTACT_WEIBO') && - - } - {siteConfig('CONTACT_INSTAGRAM') && - - } - {siteConfig('CONTACT_EMAIL') && - - } - {JSON.parse(siteConfig('ENABLE_RSS')) && - - } - {siteConfig('CONTACT_BILIBILI') && - - } - {siteConfig('CONTACT_YOUTUBE') && - - } + return ( +
+
+ {siteConfig('CONTACT_GITHUB') && ( + + + + )} + {siteConfig('CONTACT_TWITTER') && ( + + + + )} + {siteConfig('CONTACT_TELEGRAM') && ( + + + + )} + {siteConfig('CONTACT_LINKEDIN') && ( + + + + )} + {siteConfig('CONTACT_WEIBO') && ( + + + + )} + {siteConfig('CONTACT_INSTAGRAM') && ( + + + + )} + {siteConfig('CONTACT_EMAIL') && ( + + + + )} + {JSON.parse(siteConfig('ENABLE_RSS')) && ( + + + + )} + {siteConfig('CONTACT_BILIBILI') && ( + + + + )} + {siteConfig('CONTACT_YOUTUBE') && ( + + + + )} +
-
+ ) } export default SocialButton diff --git a/themes/gitbook/components/SocialButton.js b/themes/gitbook/components/SocialButton.js index 43b6102b..36c7edd6 100644 --- a/themes/gitbook/components/SocialButton.js +++ b/themes/gitbook/components/SocialButton.js @@ -99,7 +99,11 @@ const SocialButton = () => { )} {ENABLE_RSS && ( - + )} diff --git a/themes/heo/components/SocialButton.js b/themes/heo/components/SocialButton.js index c13cab43..9d4c6b0f 100644 --- a/themes/heo/components/SocialButton.js +++ b/themes/heo/components/SocialButton.js @@ -6,39 +6,101 @@ import { siteConfig } from '@/lib/config' * @constructor */ const SocialButton = () => { - return
-
- {siteConfig('CONTACT_GITHUB') && - - } - {siteConfig('CONTACT_TWITTER') && - - } - {siteConfig('CONTACT_TELEGRAM') && - - } - {siteConfig('CONTACT_LINKEDIN') && - - } - {siteConfig('CONTACT_WEIBO') && - - } - {siteConfig('CONTACT_INSTAGRAM') && - - } - {siteConfig('CONTACT_EMAIL') && - - } - {JSON.parse(siteConfig('ENABLE_RSS')) && - - } - {siteConfig('CONTACT_BILIBILI') && - - } - {siteConfig('CONTACT_YOUTUBE') && - - } + return ( +
+
+ {siteConfig('CONTACT_GITHUB') && ( + + + + )} + {siteConfig('CONTACT_TWITTER') && ( + + + + )} + {siteConfig('CONTACT_TELEGRAM') && ( + + + + )} + {siteConfig('CONTACT_LINKEDIN') && ( + + + + )} + {siteConfig('CONTACT_WEIBO') && ( + + + + )} + {siteConfig('CONTACT_INSTAGRAM') && ( + + + + )} + {siteConfig('CONTACT_EMAIL') && ( + + + + )} + {JSON.parse(siteConfig('ENABLE_RSS')) && ( + + + + )} + {siteConfig('CONTACT_BILIBILI') && ( + + + + )} + {siteConfig('CONTACT_YOUTUBE') && ( + + + + )} +
-
+ ) } export default SocialButton diff --git a/themes/hexo/components/SocialButton.js b/themes/hexo/components/SocialButton.js index e16cbe41..3e220cf7 100644 --- a/themes/hexo/components/SocialButton.js +++ b/themes/hexo/components/SocialButton.js @@ -99,7 +99,11 @@ const SocialButton = () => { )} {ENABLE_RSS && ( - + )} diff --git a/themes/matery/components/SocialButton.js b/themes/matery/components/SocialButton.js index ae15d1f0..4e15fed7 100644 --- a/themes/matery/components/SocialButton.js +++ b/themes/matery/components/SocialButton.js @@ -12,42 +12,113 @@ const SocialButton = () => { setShow(!show) } - return
- {!show && } - {show && <> - {siteConfig('CONTACT_GITHUB') && - - } - {siteConfig('CONTACT_TWITTER') && - - } - {siteConfig('CONTACT_TELEGRAM') && - - } - {siteConfig('CONTACT_LINKEDIN') && - - } - {siteConfig('CONTACT_WEIBO') && - - } - {siteConfig('CONTACT_INSTAGRAM') && - - } - {siteConfig('CONTACT_EMAIL') && - - } - {JSON.parse(siteConfig('ENABLE_RSS')) && - - } - {siteConfig('CONTACT_BILIBILI') && - - } - {siteConfig('CONTACT_YOUTUBE') && - - } - - - } + return ( +
+ {!show && ( + + )} + {show && ( + <> + {siteConfig('CONTACT_GITHUB') && ( + + + + )} + {siteConfig('CONTACT_TWITTER') && ( + + + + )} + {siteConfig('CONTACT_TELEGRAM') && ( + + + + )} + {siteConfig('CONTACT_LINKEDIN') && ( + + + + )} + {siteConfig('CONTACT_WEIBO') && ( + + + + )} + {siteConfig('CONTACT_INSTAGRAM') && ( + + + + )} + {siteConfig('CONTACT_EMAIL') && ( + + + + )} + {JSON.parse(siteConfig('ENABLE_RSS')) && ( + + + + )} + {siteConfig('CONTACT_BILIBILI') && ( + + + + )} + {siteConfig('CONTACT_YOUTUBE') && ( + + + + )} + + + )}
+ ) } export default SocialButton diff --git a/themes/medium/components/SocialButton.js b/themes/medium/components/SocialButton.js index e522f114..95b8b412 100644 --- a/themes/medium/components/SocialButton.js +++ b/themes/medium/components/SocialButton.js @@ -6,37 +6,99 @@ import { siteConfig } from '@/lib/config' * @constructor */ const SocialButton = () => { - return
- {siteConfig('CONTACT_GITHUB') && - - } - {siteConfig('CONTACT_TWITTER') && - - } - {siteConfig('CONTACT_TELEGRAM') && - - } - {siteConfig('CONTACT_LINKEDIN') && - - } - {siteConfig('CONTACT_WEIBO') && - - } - {siteConfig('CONTACT_INSTAGRAM') && - - } - {siteConfig('CONTACT_EMAIL') && - - } - {JSON.parse(siteConfig('ENABLE_RSS')) && - - } - {siteConfig('CONTACT_BILIBILI') && - - } - {siteConfig('CONTACT_YOUTUBE') && - - } + return ( +
+ {siteConfig('CONTACT_GITHUB') && ( + + + + )} + {siteConfig('CONTACT_TWITTER') && ( + + + + )} + {siteConfig('CONTACT_TELEGRAM') && ( + + + + )} + {siteConfig('CONTACT_LINKEDIN') && ( + + + + )} + {siteConfig('CONTACT_WEIBO') && ( + + + + )} + {siteConfig('CONTACT_INSTAGRAM') && ( + + + + )} + {siteConfig('CONTACT_EMAIL') && ( + + + + )} + {JSON.parse(siteConfig('ENABLE_RSS')) && ( + + + + )} + {siteConfig('CONTACT_BILIBILI') && ( + + + + )} + {siteConfig('CONTACT_YOUTUBE') && ( + + + + )}
+ ) } export default SocialButton diff --git a/themes/nav/components/SocialButton.js b/themes/nav/components/SocialButton.js index b1bd85f9..74fdad37 100755 --- a/themes/nav/components/SocialButton.js +++ b/themes/nav/components/SocialButton.js @@ -6,31 +6,81 @@ import { siteConfig } from '@/lib/config' * @constructor */ const SocialButton = () => { - return
- {siteConfig('CONTACT_GITHUB') && - - } - {siteConfig('CONTACT_TWITTER') && - - } - {siteConfig('CONTACT_TELEGRAM') && - - } - {siteConfig('CONTACT_LINKEDIN') && - - } - {siteConfig('CONTACT_WEIBO') && - - } - {siteConfig('CONTACT_INSTAGRAM') && - - } - {siteConfig('CONTACT_EMAIL') && - - } - {JSON.parse(siteConfig('ENABLE_RSS')) && - - } + return ( +
+ {siteConfig('CONTACT_GITHUB') && ( + + + + )} + {siteConfig('CONTACT_TWITTER') && ( + + + + )} + {siteConfig('CONTACT_TELEGRAM') && ( + + + + )} + {siteConfig('CONTACT_LINKEDIN') && ( + + + + )} + {siteConfig('CONTACT_WEIBO') && ( + + + + )} + {siteConfig('CONTACT_INSTAGRAM') && ( + + + + )} + {siteConfig('CONTACT_EMAIL') && ( + + + + )} + {JSON.parse(siteConfig('ENABLE_RSS')) && ( + + + + )}
+ ) } export default SocialButton diff --git a/themes/next/components/SocialButton.js b/themes/next/components/SocialButton.js index 6da30787..8ade39ea 100644 --- a/themes/next/components/SocialButton.js +++ b/themes/next/components/SocialButton.js @@ -6,39 +6,101 @@ import { siteConfig } from '@/lib/config' * @constructor */ const SocialButton = () => { - return
-
- {siteConfig('CONTACT_GITHUB') && - - } - {siteConfig('CONTACT_TWITTER') && - - } - {siteConfig('CONTACT_TELEGRAM') && - - } - {siteConfig('CONTACT_LINKEDIN') && - - } - {siteConfig('CONTACT_WEIBO') && - - } - {siteConfig('CONTACT_INSTAGRAM') && - - } - {siteConfig('CONTACT_EMAIL') && - - } - {JSON.parse(siteConfig('ENABLE_RSS')) && - - } - {siteConfig('CONTACT_BILIBILI') && - - } - {siteConfig('CONTACT_YOUTUBE') && - - } + return ( +
+
+ {siteConfig('CONTACT_GITHUB') && ( + + + + )} + {siteConfig('CONTACT_TWITTER') && ( + + + + )} + {siteConfig('CONTACT_TELEGRAM') && ( + + + + )} + {siteConfig('CONTACT_LINKEDIN') && ( + + + + )} + {siteConfig('CONTACT_WEIBO') && ( + + + + )} + {siteConfig('CONTACT_INSTAGRAM') && ( + + + + )} + {siteConfig('CONTACT_EMAIL') && ( + + + + )} + {JSON.parse(siteConfig('ENABLE_RSS')) && ( + + + + )} + {siteConfig('CONTACT_BILIBILI') && ( + + + + )} + {siteConfig('CONTACT_YOUTUBE') && ( + + + + )} +
-
+ ) } export default SocialButton diff --git a/themes/plog/components/SocialButton.js b/themes/plog/components/SocialButton.js index 56cf9490..c1c1f769 100644 --- a/themes/plog/components/SocialButton.js +++ b/themes/plog/components/SocialButton.js @@ -6,39 +6,101 @@ import { siteConfig } from '@/lib/config' * @constructor */ const SocialButton = () => { - return
-
- {siteConfig('CONTACT_GITHUB') && - - } - {siteConfig('CONTACT_TWITTER') && - - } - {siteConfig('CONTACT_TELEGRAM') && - - } - {siteConfig('CONTACT_LINKEDIN') && - - } - {siteConfig('CONTACT_WEIBO') && - - } - {siteConfig('CONTACT_INSTAGRAM') && - - } - {siteConfig('CONTACT_EMAIL') && - - } - {JSON.parse(siteConfig('ENABLE_RSS')) && - - } - {siteConfig('CONTACT_BILIBILI') && - - } - {siteConfig('CONTACT_YOUTUBE') && - - } + return ( +
+
+ {siteConfig('CONTACT_GITHUB') && ( + + + + )} + {siteConfig('CONTACT_TWITTER') && ( + + + + )} + {siteConfig('CONTACT_TELEGRAM') && ( + + + + )} + {siteConfig('CONTACT_LINKEDIN') && ( + + + + )} + {siteConfig('CONTACT_WEIBO') && ( + + + + )} + {siteConfig('CONTACT_INSTAGRAM') && ( + + + + )} + {siteConfig('CONTACT_EMAIL') && ( + + + + )} + {JSON.parse(siteConfig('ENABLE_RSS')) && ( + + + + )} + {siteConfig('CONTACT_BILIBILI') && ( + + + + )} + {siteConfig('CONTACT_YOUTUBE') && ( + + + + )} +
-
+ ) } export default SocialButton diff --git a/themes/simple/components/SocialButton.js b/themes/simple/components/SocialButton.js index b9def55b..d11f3423 100644 --- a/themes/simple/components/SocialButton.js +++ b/themes/simple/components/SocialButton.js @@ -6,39 +6,101 @@ import { siteConfig } from '@/lib/config' * @constructor */ const SocialButton = () => { - return
-
- {siteConfig('CONTACT_GITHUB') && - - } - {siteConfig('CONTACT_TWITTER') && - - } - {siteConfig('CONTACT_TELEGRAM') && - - } - {siteConfig('CONTACT_LINKEDIN') && - - } - {siteConfig('CONTACT_WEIBO') && - - } - {siteConfig('CONTACT_INSTAGRAM') && - - } - {siteConfig('CONTACT_EMAIL') && - - } - {JSON.parse(siteConfig('ENABLE_RSS')) && - - } - {siteConfig('CONTACT_BILIBILI') && - - } - {siteConfig('CONTACT_YOUTUBE') && - - } + return ( +
+
+ {siteConfig('CONTACT_GITHUB') && ( + + + + )} + {siteConfig('CONTACT_TWITTER') && ( + + + + )} + {siteConfig('CONTACT_TELEGRAM') && ( + + + + )} + {siteConfig('CONTACT_LINKEDIN') && ( + + + + )} + {siteConfig('CONTACT_WEIBO') && ( + + + + )} + {siteConfig('CONTACT_INSTAGRAM') && ( + + + + )} + {siteConfig('CONTACT_EMAIL') && ( + + + + )} + {JSON.parse(siteConfig('ENABLE_RSS')) && ( + + + + )} + {siteConfig('CONTACT_BILIBILI') && ( + + + + )} + {siteConfig('CONTACT_YOUTUBE') && ( + + + + )} +
-
+ ) } export default SocialButton diff --git a/themes/starter/components/SocialButton.js b/themes/starter/components/SocialButton.js index b9def55b..d11f3423 100644 --- a/themes/starter/components/SocialButton.js +++ b/themes/starter/components/SocialButton.js @@ -6,39 +6,101 @@ import { siteConfig } from '@/lib/config' * @constructor */ const SocialButton = () => { - return
-
- {siteConfig('CONTACT_GITHUB') && - - } - {siteConfig('CONTACT_TWITTER') && - - } - {siteConfig('CONTACT_TELEGRAM') && - - } - {siteConfig('CONTACT_LINKEDIN') && - - } - {siteConfig('CONTACT_WEIBO') && - - } - {siteConfig('CONTACT_INSTAGRAM') && - - } - {siteConfig('CONTACT_EMAIL') && - - } - {JSON.parse(siteConfig('ENABLE_RSS')) && - - } - {siteConfig('CONTACT_BILIBILI') && - - } - {siteConfig('CONTACT_YOUTUBE') && - - } + return ( +
+
+ {siteConfig('CONTACT_GITHUB') && ( + + + + )} + {siteConfig('CONTACT_TWITTER') && ( + + + + )} + {siteConfig('CONTACT_TELEGRAM') && ( + + + + )} + {siteConfig('CONTACT_LINKEDIN') && ( + + + + )} + {siteConfig('CONTACT_WEIBO') && ( + + + + )} + {siteConfig('CONTACT_INSTAGRAM') && ( + + + + )} + {siteConfig('CONTACT_EMAIL') && ( + + + + )} + {JSON.parse(siteConfig('ENABLE_RSS')) && ( + + + + )} + {siteConfig('CONTACT_BILIBILI') && ( + + + + )} + {siteConfig('CONTACT_YOUTUBE') && ( + + + + )} +
-
+ ) } export default SocialButton From 50d79ebe8842ed8608f76969d081a6a8a63643dd Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Wed, 26 Jun 2024 10:56:38 +0800 Subject: [PATCH 074/107] rss --- pages/sitemap.xml.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/sitemap.xml.js b/pages/sitemap.xml.js index eb7f7bd8..b5325513 100644 --- a/pages/sitemap.xml.js +++ b/pages/sitemap.xml.js @@ -55,7 +55,7 @@ function generateLocalesSitemap(link, allPages, locale) { priority: '0.7' }, { - loc: `${link}${locale}/feed`, + loc: `${link}${locale}/rss/feed.xml`, lastmod: new Date().toISOString().split('T')[0], changefreq: 'daily', priority: '0.7' From 8f0ae9267a8c4a9040bc5246b44d9dcb27f7e7f9 Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Wed, 26 Jun 2024 11:12:38 +0800 Subject: [PATCH 075/107] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=A4=96=E9=93=BE?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E6=89=93=E5=8C=85=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/db/getSiteData.js | 2 +- lib/notion/getPageProperties.js | 44 ++++++++++++++++----------------- lib/utils/index.js | 9 +++++-- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/lib/db/getSiteData.js b/lib/db/getSiteData.js index 84e764fb..71b38572 100755 --- a/lib/db/getSiteData.js +++ b/lib/db/getSiteData.js @@ -526,7 +526,7 @@ async function getDataBaseInfoByNotionAPI({ pageId, from }) { return ( post && post?.slug && - !post?.slug?.startsWith('http') && + // !post?.slug?.startsWith('http') && (post?.status === 'Invisible' || post?.status === 'Published') ) }) diff --git a/lib/notion/getPageProperties.js b/lib/notion/getPageProperties.js index d3cbc2fb..5579e6b8 100644 --- a/lib/notion/getPageProperties.js +++ b/lib/notion/getPageProperties.js @@ -8,8 +8,7 @@ import { siteConfig } from '../config' import { checkStartWithHttp, convertUrlStartWithOneSlash, - getLastSegmentFromUrl, - sliceUrlFromHttp + getLastSegmentFromUrl } from '../utils' import { extractLangPrefix } from '../utils/pageId' import { mapImgUrl } from './mapImage' @@ -188,29 +187,26 @@ export function adjustPageProperties(properties, NOTION_CONFIG) { properties.name = properties.title ?? '' } - // 开启伪静态路径 - if (siteConfig('PSEUDO_STATIC', false, NOTION_CONFIG)) { - if ( - !properties?.href?.endsWith('.html') && - !properties?.href?.startsWith('http') && - properties?.href !== '' && - properties?.href !== '#' && - properties?.href !== '/' - ) { - properties.href += '.html' - } - } - - // 检查处理外链 - properties.href = checkStartWithHttp(properties?.href) - ? sliceUrlFromHttp(properties?.href) - : convertUrlStartWithOneSlash(properties?.href) - - // 设置链接在页内或新页面打开 - if (properties.href?.indexOf('http') === 0) { + // http or https 开头的视为外链 + if (checkStartWithHttp(properties?.slug)) { + properties.href = properties?.slug properties.target = '_blank' } else { properties.target = '_self' + // 伪静态路径右侧拼接.html + if (siteConfig('PSEUDO_STATIC', false, NOTION_CONFIG)) { + if ( + !properties?.href?.endsWith('.html') && + !properties?.href?.startsWith('http') && + properties?.href !== '' && + properties?.href !== '#' && + properties?.href !== '/' + ) { + properties.href += '.html' + } + } + // 相对路径转绝对路径:url左侧拼接 / + convertUrlStartWithOneSlash(properties?.href) } // 如果跳转链接是多语言,则在新窗口打开 @@ -239,6 +235,10 @@ export function adjustPageProperties(properties, NOTION_CONFIG) { * @returns */ function generateCustomizeSlug(postProperties, NOTION_CONFIG) { + // 外链不处理 + if (checkStartWithHttp(postProperties.slug)) { + return postProperties.slug + } let fullPrefix = '' const allSlugPatterns = siteConfig( 'POST_URL_PREFIX', diff --git a/lib/utils/index.js b/lib/utils/index.js index 70122b12..27a6494f 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -47,7 +47,12 @@ export const memorize = Component => { return memo(MemoizedComponent) } -// 转换外链 +/** + * 诸如 article/https://test.com 等被错误拼接前缀的slug进行处理 + * 转换为 https://test.com + * @param {*} str + * @returns + */ export function sliceUrlFromHttp(str) { // 检查字符串是否包含http if (str?.includes('http:') || str?.includes('https:')) { @@ -99,7 +104,7 @@ export function checkStartWithHttp(str) { // 检查字符串是否包含http if (str?.indexOf('http:') === 0 || str?.indexOf('https:') === 0) { // 如果包含,找到http的位置 - return str?.indexOf('http') > -1 + return true } else { // 不包含 return false From 00da3e3e7b6eb8b97374aefe9b553e160831f61e Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Thu, 27 Jun 2024 09:15:28 +0800 Subject: [PATCH 076/107] =?UTF-8?q?fix=20=E4=B8=BB=E9=A2=98=E6=8B=96?= =?UTF-8?q?=E6=8B=BD=E6=8C=89=E9=92=AE=E5=8D=A1=E9=A1=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/ThemeSwitch.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/components/ThemeSwitch.js b/components/ThemeSwitch.js index 6e9e3543..33c7ff8f 100644 --- a/components/ThemeSwitch.js +++ b/components/ThemeSwitch.js @@ -53,11 +53,13 @@ const ThemeSwitch = () => {
+ className='fixed group flex flex-col items-start space-y-2 overflow-hidden z-50 p-3 + dark:text-white bg-white dark:bg-black + rounded-xl shadow-lg hover:scale-105 hover:shadow-2xl '> {/* 主题切换按钮 */} -
+
-
+
@@ -79,21 +81,21 @@ const ThemeSwitch = () => {
{/* 深色按钮 */} -
+
+ className='cursor-pointer w-0 group-hover:w-24 duration-200 overflow-hidden whitespace-nowrap pl-1 h-auto'> {isDarkMode ? locale.MENU.DARK_MODE : locale.MENU.LIGHT_MODE}
{/* 翻译按钮 */} -
+
-
+