mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-13 23:16:47 +00:00
支持文章内容嵌入广告
This commit is contained in:
@@ -3,25 +3,33 @@ import { loadExternalResource } from '@/lib/utils'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
function requestAd() {
|
||||
const ads = document.getElementsByClassName('adsbygoogle')
|
||||
const adsbygoogle = window.adsbygoogle
|
||||
if (adsbygoogle && ads.length > 0) {
|
||||
for (let i = 0; i <= ads.length; i++) {
|
||||
try {
|
||||
const adStatus = ads[i].getAttribute('data-adsbygoogle-status')
|
||||
if (!adStatus || adStatus !== 'done') {
|
||||
adsbygoogle.push(ads[i])
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化谷歌广告
|
||||
* @returns
|
||||
*/
|
||||
export default function GoogleAdsense() {
|
||||
const initGoogleAdsense = () => {
|
||||
loadExternalResource(`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${siteConfig('ADSENSE_GOOGLE_ID')}`, 'js').then(url => {
|
||||
loadExternalResource(
|
||||
`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${siteConfig('ADSENSE_GOOGLE_ID')}`,
|
||||
'js'
|
||||
).then(url => {
|
||||
setTimeout(() => {
|
||||
const ads = document.getElementsByClassName('adsbygoogle')
|
||||
const adsbygoogle = window.adsbygoogle
|
||||
if (ads.length > 0) {
|
||||
for (let i = 0; i <= ads.length; i++) {
|
||||
try {
|
||||
adsbygoogle.push(ads[i])
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
requestAd()
|
||||
}, 100)
|
||||
})
|
||||
}
|
||||
@@ -49,44 +57,92 @@ const AdSlot = ({ type = 'show' }) => {
|
||||
}
|
||||
// 文章内嵌广告
|
||||
if (type === 'in-article') {
|
||||
return <ins className="adsbygoogle"
|
||||
style={{ display: 'block', textAlign: 'center' }}
|
||||
data-ad-layout="in-article"
|
||||
data-ad-format="fluid"
|
||||
data-adtest={siteConfig('ADSENSE_GOOGLE_TEST') ? 'on' : 'off'}
|
||||
data-ad-client={siteConfig('ADSENSE_GOOGLE_ID')}
|
||||
data-ad-slot={siteConfig('ADSENSE_GOOGLE_SLOT_IN_ARTICLE')}></ins>
|
||||
return (
|
||||
<ins
|
||||
className='adsbygoogle'
|
||||
style={{ display: 'block', textAlign: 'center' }}
|
||||
data-ad-layout='in-article'
|
||||
data-ad-format='fluid'
|
||||
data-adtest={siteConfig('ADSENSE_GOOGLE_TEST') ? 'on' : 'off'}
|
||||
data-ad-client={siteConfig('ADSENSE_GOOGLE_ID')}
|
||||
data-ad-slot={siteConfig('ADSENSE_GOOGLE_SLOT_IN_ARTICLE')}></ins>
|
||||
)
|
||||
}
|
||||
|
||||
// 信息流广告
|
||||
if (type === 'flow') {
|
||||
return <ins className="adsbygoogle"
|
||||
data-ad-format="fluid"
|
||||
data-ad-layout-key="-5j+cz+30-f7+bf"
|
||||
style={{ display: 'block' }}
|
||||
data-adtest={siteConfig('ADSENSE_GOOGLE_TEST') ? 'on' : 'off'}
|
||||
data-ad-client={siteConfig('ADSENSE_GOOGLE_ID')}
|
||||
data-ad-slot={siteConfig('ADSENSE_GOOGLE_SLOT_FLOW')}></ins>
|
||||
return (
|
||||
<ins
|
||||
className='adsbygoogle'
|
||||
data-ad-format='fluid'
|
||||
data-ad-layout-key='-5j+cz+30-f7+bf'
|
||||
style={{ display: 'block' }}
|
||||
data-adtest={siteConfig('ADSENSE_GOOGLE_TEST') ? 'on' : 'off'}
|
||||
data-ad-client={siteConfig('ADSENSE_GOOGLE_ID')}
|
||||
data-ad-slot={siteConfig('ADSENSE_GOOGLE_SLOT_FLOW')}></ins>
|
||||
)
|
||||
}
|
||||
|
||||
// 原生广告
|
||||
if (type === 'native') {
|
||||
return <ins className="adsbygoogle"
|
||||
style={{ display: 'block', textAlign: 'center' }}
|
||||
data-ad-format="autorelaxed"
|
||||
data-adtest={siteConfig('ADSENSE_GOOGLE_TEST') ? 'on' : 'off'}
|
||||
data-ad-client={siteConfig('ADSENSE_GOOGLE_ID')}
|
||||
data-ad-slot={siteConfig('ADSENSE_GOOGLE_SLOT_NATIVE')}></ins>
|
||||
return (
|
||||
<ins
|
||||
className='adsbygoogle'
|
||||
style={{ display: 'block', textAlign: 'center' }}
|
||||
data-ad-format='autorelaxed'
|
||||
data-adtest={siteConfig('ADSENSE_GOOGLE_TEST') ? 'on' : 'off'}
|
||||
data-ad-client={siteConfig('ADSENSE_GOOGLE_ID')}
|
||||
data-ad-slot={siteConfig('ADSENSE_GOOGLE_SLOT_NATIVE')}></ins>
|
||||
)
|
||||
}
|
||||
|
||||
// 展示广告
|
||||
return <ins className="adsbygoogle"
|
||||
style={{ display: 'block' }}
|
||||
data-ad-client={siteConfig('ADSENSE_GOOGLE_ID')}
|
||||
data-adtest={siteConfig('ADSENSE_GOOGLE_TEST') ? 'on' : 'off'}
|
||||
data-ad-slot={siteConfig('ADSENSE_GOOGLE_SLOT_AUTO')}
|
||||
data-ad-format="auto"
|
||||
data-full-width-responsive="true"></ins>
|
||||
return (
|
||||
<ins
|
||||
className='adsbygoogle'
|
||||
style={{ display: 'block' }}
|
||||
data-ad-client={siteConfig('ADSENSE_GOOGLE_ID')}
|
||||
data-adtest={siteConfig('ADSENSE_GOOGLE_TEST') ? 'on' : 'off'}
|
||||
data-ad-slot={siteConfig('ADSENSE_GOOGLE_SLOT_AUTO')}
|
||||
data-ad-format='auto'
|
||||
data-full-width-responsive='true'></ins>
|
||||
)
|
||||
}
|
||||
|
||||
export { AdSlot }
|
||||
/**
|
||||
* 嵌入到文章内部的广告单元
|
||||
* 检测文本内容 出现<ins/> 关键词时自动替换为广告
|
||||
* @param {*} props
|
||||
*/
|
||||
const AdEmbed = () => {
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
// 找到所有 class 为 notion-text 且内容为 '<ins/>' 的 div 元素
|
||||
const notionTextElements = document.querySelectorAll('div.notion-text')
|
||||
|
||||
// 遍历找到的元素
|
||||
notionTextElements?.forEach(element => {
|
||||
// 检查元素的内容是否为 '<ins/>'
|
||||
if (element.innerHTML.trim() === '<ins/>') {
|
||||
// 创建新的 <ins> 元素
|
||||
const newInsElement = document.createElement('ins')
|
||||
newInsElement.className = 'adsbygoogle w-full py-1'
|
||||
newInsElement.style.display = 'block'
|
||||
newInsElement.setAttribute('data-ad-client', siteConfig('ADSENSE_GOOGLE_ID'))
|
||||
newInsElement.setAttribute('data-adtest', siteConfig('ADSENSE_GOOGLE_TEST') ? 'on' : 'off')
|
||||
newInsElement.setAttribute('data-ad-slot', siteConfig('ADSENSE_GOOGLE_SLOT_AUTO'))
|
||||
newInsElement.setAttribute('data-ad-format', 'auto')
|
||||
newInsElement.setAttribute('data-full-width-responsive', 'true')
|
||||
|
||||
// 用新创建的 <ins> 元素替换掉原来的 div 元素
|
||||
element?.parentNode?.replaceChild(newInsElement, element)
|
||||
}
|
||||
})
|
||||
|
||||
requestAd()
|
||||
}, 1000)
|
||||
}, [])
|
||||
return <></>
|
||||
}
|
||||
|
||||
export { AdEmbed, AdSlot }
|
||||
|
||||
@@ -1,33 +1,34 @@
|
||||
import dynamic from 'next/dynamic'
|
||||
import mediumZoom from '@fisch0920/medium-zoom'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import 'katex/dist/katex.min.css'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { compressImage, mapImgUrl } from '@/lib/notion/mapImage'
|
||||
import { isBrowser } from '@/lib/utils'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import mediumZoom from '@fisch0920/medium-zoom'
|
||||
import 'katex/dist/katex.min.css'
|
||||
import dynamic from 'next/dynamic'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { NotionRenderer } from 'react-notion-x'
|
||||
|
||||
const Code = dynamic(() =>
|
||||
import('react-notion-x/build/third-party/code').then(async (m) => {
|
||||
return m.Code
|
||||
}), { ssr: false }
|
||||
const Code = dynamic(
|
||||
() =>
|
||||
import('react-notion-x/build/third-party/code').then(async m => {
|
||||
return m.Code
|
||||
}),
|
||||
{ ssr: false }
|
||||
)
|
||||
|
||||
// 公式
|
||||
const Equation = dynamic(() =>
|
||||
import('@/components/Equation').then(async (m) => {
|
||||
// 化学方程式
|
||||
await import('@/lib/plugins/mhchem')
|
||||
return m.Equation
|
||||
}), { ssr: false }
|
||||
const Equation = dynamic(
|
||||
() =>
|
||||
import('@/components/Equation').then(async m => {
|
||||
// 化学方程式
|
||||
await import('@/lib/plugins/mhchem')
|
||||
return m.Equation
|
||||
}),
|
||||
{ ssr: false }
|
||||
)
|
||||
|
||||
const Pdf = dynamic(
|
||||
() => import('react-notion-x/build/third-party/pdf').then((m) => m.Pdf),
|
||||
{
|
||||
ssr: false
|
||||
}
|
||||
)
|
||||
const Pdf = dynamic(() => import('react-notion-x/build/third-party/pdf').then(m => m.Pdf), {
|
||||
ssr: false
|
||||
})
|
||||
|
||||
// https://github.com/txs
|
||||
// import PrismMac from '@/components/PrismMac'
|
||||
@@ -42,13 +43,16 @@ const TweetEmbed = dynamic(() => import('react-tweet-embed'), {
|
||||
ssr: false
|
||||
})
|
||||
|
||||
const Collection = dynamic(() =>
|
||||
import('react-notion-x/build/third-party/collection').then((m) => m.Collection), { ssr: true }
|
||||
)
|
||||
/**
|
||||
* 文内google广告
|
||||
*/
|
||||
const AdEmbed = dynamic(() => import('@/components/GoogleAdsense').then(m => m.AdEmbed), { ssr: true })
|
||||
|
||||
const Modal = dynamic(
|
||||
() => import('react-notion-x/build/third-party/modal').then((m) => m.Modal), { ssr: false }
|
||||
)
|
||||
const Collection = dynamic(() => import('react-notion-x/build/third-party/collection').then(m => m.Collection), {
|
||||
ssr: true
|
||||
})
|
||||
|
||||
const Modal = dynamic(() => import('react-notion-x/build/third-party/modal').then(m => m.Modal), { ssr: false })
|
||||
|
||||
const Tweet = ({ id }) => {
|
||||
return <TweetEmbed tweetId={id} />
|
||||
@@ -64,15 +68,17 @@ const NotionPage = ({ post, className }) => {
|
||||
autoScrollToTarget()
|
||||
}, [])
|
||||
|
||||
const zoom = typeof window !== 'undefined' && mediumZoom({
|
||||
container: '.notion-viewport',
|
||||
background: 'rgba(0, 0, 0, 0.2)',
|
||||
margin: getMediumZoomMargin()
|
||||
})
|
||||
const zoom =
|
||||
typeof window !== 'undefined' &&
|
||||
mediumZoom({
|
||||
container: '.notion-viewport',
|
||||
background: 'rgba(0, 0, 0, 0.2)',
|
||||
margin: getMediumZoomMargin()
|
||||
})
|
||||
const zoomRef = useRef(zoom ? zoom.clone() : null)
|
||||
|
||||
useEffect(() => {
|
||||
if (!isBrowser) return;
|
||||
if (!isBrowser) return
|
||||
|
||||
// 将相册gallery下的图片加入放大功能
|
||||
if (siteConfig('POST_DISABLE_GALLERY_CLICK')) {
|
||||
@@ -81,7 +87,7 @@ const NotionPage = ({ post, className }) => {
|
||||
const imgList = document?.querySelectorAll('.notion-collection-card-cover img')
|
||||
if (imgList && zoomRef.current) {
|
||||
for (let i = 0; i < imgList.length; i++) {
|
||||
(zoomRef.current).attach(imgList[i])
|
||||
zoomRef.current.attach(imgList[i])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,45 +125,48 @@ const NotionPage = ({ post, className }) => {
|
||||
if (mutation.target.classList.contains('medium-zoom-image--opened')) {
|
||||
// 等待动画完成后替换为更高清的图像
|
||||
setTimeout(() => {
|
||||
// 获取该元素的 src 属性
|
||||
const src = mutation?.target?.getAttribute('src');
|
||||
// 获取该元素的 src 属性
|
||||
const src = mutation?.target?.getAttribute('src')
|
||||
// 替换为更高清的图像
|
||||
mutation?.target?.setAttribute('src', compressImage(src, siteConfig('IMAGE_ZOOM_IN_WIDTH', 1200)));
|
||||
}, 800);
|
||||
mutation?.target?.setAttribute('src', compressImage(src, siteConfig('IMAGE_ZOOM_IN_WIDTH', 1200)))
|
||||
}, 800)
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
// 监视整个文档中的元素和属性的变化
|
||||
observer.observe(document.body, { attributes: true, subtree: true, attributeFilter: ['class'] });
|
||||
observer.observe(document.body, { attributes: true, subtree: true, attributeFilter: ['class'] })
|
||||
|
||||
return () => {
|
||||
observer.disconnect();
|
||||
};
|
||||
observer.disconnect()
|
||||
}
|
||||
}, [])
|
||||
|
||||
if (!post || !post.blockMap) {
|
||||
return <>{post?.summary || ''}</>
|
||||
}
|
||||
|
||||
return <div id='notion-article' className={`mx-auto overflow-hidden ${className || ''}`}>
|
||||
<NotionRenderer
|
||||
recordMap={post.blockMap}
|
||||
mapPageUrl={mapPageUrl}
|
||||
mapImageUrl={mapImgUrl}
|
||||
components={{
|
||||
Code,
|
||||
Collection,
|
||||
Equation,
|
||||
Modal,
|
||||
Pdf,
|
||||
Tweet
|
||||
}} />
|
||||
return (
|
||||
<div id='notion-article' className={`mx-auto overflow-hidden ${className || ''}`}>
|
||||
<NotionRenderer
|
||||
recordMap={post.blockMap}
|
||||
mapPageUrl={mapPageUrl}
|
||||
mapImageUrl={mapImgUrl}
|
||||
components={{
|
||||
Code,
|
||||
Collection,
|
||||
Equation,
|
||||
Modal,
|
||||
Pdf,
|
||||
Tweet
|
||||
}}
|
||||
/>
|
||||
|
||||
<PrismMac/>
|
||||
|
||||
</div>
|
||||
<AdEmbed />
|
||||
<PrismMac />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user