diff --git a/README.md b/README.md index 14c81beb..df20f48e 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,9 @@ yarn run start # 本地启动NextJS服务 ifyz
ifyz

🔧 🐛 + SwwweetOrange
SwwweetOrange

🔧 🐛 + + diff --git a/lib/notion/getPageProperties.js b/lib/notion/getPageProperties.js index 771915e9..1eced850 100644 --- a/lib/notion/getPageProperties.js +++ b/lib/notion/getPageProperties.js @@ -79,8 +79,8 @@ export default async function getPageProperties(id, block, schema, authToken, ta properties.createdTime = formatDate(new Date(value.created_time).toString(), BLOG.LANG) properties.lastEditedTime = formatDate(new Date(value?.last_edited_time).toString(), BLOG.LANG) properties.fullWidth = value.format?.page_full_width ?? false - properties.pageIcon = getPageIcon(id, block) ?? '' - properties.page_cover = getPostCover(id, block) ?? siteInfo?.pageCover + properties.pageIcon = getImageUrl(block[id].value?.format?.page_icon, block[id].value) ?? '' + properties.page_cover = getImageUrl(block[id].value?.format?.page_cover, block[id].value) ?? siteInfo?.pageCover properties.content = value.content ?? [] properties.tagItems = properties?.tags?.map(tag => { return { name: tag, color: tagOptions?.find(t => t.value === tag)?.color || 'gray' } @@ -89,20 +89,23 @@ export default async function getPageProperties(id, block, schema, authToken, ta return properties // 从Block获取封面图;优先取PageCover,否则取内容图片 - function getPostCover(id, block) { - const pageCover = block[id].value?.format?.page_cover - if (pageCover) { - if (pageCover.startsWith('/')) return 'https://www.notion.so' + pageCover - if (pageCover.startsWith('http')) return defaultMapImageUrl(pageCover, block[id].value) + function getImageUrl(imgObj, blockVal) { + if (!imgObj) { + return null + } + if (imgObj.startsWith('/')) { + return 'https://www.notion.so' + imgObj // notion内部图片转相对路径为绝对路径 } - } -} -function getPageIcon(id, block) { - const pageIcon = block[id].value?.format?.page_icon - if (pageIcon) { - if (pageIcon.startsWith('/')) return 'https://www.notion.so' + pageIcon - if (pageIcon.startsWith('http')) return defaultMapImageUrl(pageIcon, block[id].value) - return pageIcon + if (imgObj.startsWith('http')) { + // 判断如果是notion上传的图片要拼接访问token + const u = new URL(imgObj) + if (u.pathname.startsWith('/secure.notion-static.com') && u.hostname.endsWith('.amazonaws.com')) { + return defaultMapImageUrl(imgObj, blockVal) // notion上传的图片需要转换请求地址 + } + } + + // 其他图片链接 或 emoji + return imgObj } } diff --git a/package.json b/package.json index d111033e..2f5be0dc 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "gitalk": "^1.7.2", "localStorage": "^1.0.4", "lodash.throttle": "^4.1.1", + "mark.js": "^8.11.1", "memory-cache": "^0.2.0", "mermaid": "9.2.2", "mongodb": "^4.6.0", diff --git a/themes/example/LayoutSearch.js b/themes/example/LayoutSearch.js index 984e47e7..23b10b7a 100644 --- a/themes/example/LayoutSearch.js +++ b/themes/example/LayoutSearch.js @@ -4,6 +4,7 @@ import { BlogListScroll } from './components/BlogListScroll' import { useRouter } from 'next/router' import { useEffect } from 'react' import SearchInput from './components/SearchInput' +import Mark from 'mark.js' import LayoutBase from './LayoutBase' import { isBrowser } from '@/lib/utils' @@ -15,8 +16,12 @@ export const LayoutSearch = props => { setTimeout(() => { const container = isBrowser() && document.getElementById('container') if (container && container.innerHTML) { - const re = new RegExp(`${keyword}`, 'gim') - container.innerHTML = container.innerHTML.replace(re, `${keyword}`) + const re = new RegExp(keyword, 'gim') + const instance = new Mark(container) + instance.markRegExp(re, { + element: 'span', + className: 'text-red-500 border-b border-dashed' + }) } }, 100) }, [router.events]) diff --git a/themes/fukasawa/LayoutSearch.js b/themes/fukasawa/LayoutSearch.js index 9329846d..fcfa35b2 100644 --- a/themes/fukasawa/LayoutSearch.js +++ b/themes/fukasawa/LayoutSearch.js @@ -4,6 +4,7 @@ import BlogListPage from './components/BlogListPage' import BlogListScroll from './components/BlogListScroll' import { useRouter } from 'next/router' import { useEffect } from 'react' +import Mark from 'mark.js' import { isBrowser } from '@/lib/utils' export const LayoutSearch = (props) => { @@ -14,8 +15,12 @@ export const LayoutSearch = (props) => { setTimeout(() => { const container = isBrowser() && document.getElementById('container') if (container && container.innerHTML) { - const re = new RegExp(`${currentSearch}`, 'gim') - container.innerHTML = container.innerHTML.replace(re, `${currentSearch}`) + const re = new RegExp(currentSearch, 'gim') + const instance = new Mark(container) + instance.markRegExp(re, { + element: 'span', + className: 'text-red-500 border-b border-dashed' + }) } }, 100) }) diff --git a/themes/hexo/LayoutSearch.js b/themes/hexo/LayoutSearch.js index 6454ef3a..679975cb 100644 --- a/themes/hexo/LayoutSearch.js +++ b/themes/hexo/LayoutSearch.js @@ -6,6 +6,7 @@ import BlogPostListPage from './components/BlogPostListPage' import LayoutBase from './LayoutBase' import SearchInput from './components/SearchInput' import { useGlobal } from '@/lib/global' +import Mark from 'mark.js' import TagItemMini from './components/TagItemMini' import Card from './components/Card' import Link from 'next/link' @@ -25,10 +26,12 @@ export const LayoutSearch = props => { const targets = document.getElementsByClassName('replace') for (const container of targets) { if (container && container.innerHTML) { - const re = new RegExp(`${currentSearch}`, 'gim') - container.innerHTML = container.innerHTML.replace( - re, `${currentSearch}` - ) + const re = new RegExp(currentSearch, 'gim') + const instance = new Mark(container) + instance.markRegExp(re, { + element: 'span', + className: 'text-red-500 border-b border-dashed' + }) } } } diff --git a/themes/medium/LayoutSearch.js b/themes/medium/LayoutSearch.js index 9a34bcec..76a9ddae 100644 --- a/themes/medium/LayoutSearch.js +++ b/themes/medium/LayoutSearch.js @@ -6,6 +6,7 @@ import CategoryGroup from './components/CategoryGroup' import { useEffect } from 'react' import { isBrowser } from '@/lib/utils' import BLOG from '@/blog.config' +import Mark from 'mark.js' import BlogPostListScroll from './components/BlogPostListScroll' import BlogPostListPage from './components/BlogPostListPage' @@ -16,8 +17,12 @@ export const LayoutSearch = (props) => { setTimeout(() => { const container = isBrowser() && document.getElementById('container') if (container && container.innerHTML) { - const re = new RegExp(`${keyword}`, 'gim') - container.innerHTML = container.innerHTML.replace(re, `${keyword}`) + const re = new RegExp(keyword, 'gim') + const instance = new Mark(container) + instance.markRegExp(re, { + element: 'span', + className: 'text-red-500 border-b border-dashed' + }) } }, 100) diff --git a/themes/next/LayoutSearch.js b/themes/next/LayoutSearch.js index d4ec1bb8..78664343 100644 --- a/themes/next/LayoutSearch.js +++ b/themes/next/LayoutSearch.js @@ -4,6 +4,7 @@ import { useGlobal } from '@/lib/global' import { isBrowser } from '@/lib/utils' import BlogPostListScroll from './components/BlogPostListScroll' import BlogPostListPage from './components/BlogPostListPage' +import Mark from 'mark.js' import BLOG from '@/blog.config' export const LayoutSearch = (props) => { @@ -12,8 +13,12 @@ export const LayoutSearch = (props) => { setTimeout(() => { const container = isBrowser() && document.getElementById('container') if (container && container.innerHTML) { - const re = new RegExp(`${keyword}`, 'gim') - container.innerHTML = container.innerHTML.replace(re, `${keyword}`) + const re = new RegExp(keyword, 'gim') + const instance = new Mark(container) + instance.markRegExp(re, { + element: 'span', + className: 'text-red-500 border-b border-dashed' + }) } }, 200) return (