部分参数配置化

This commit is contained in:
tangly1024.com
2023-11-03 17:10:59 +08:00
parent 545c071f81
commit f145d8b28c
23 changed files with 267 additions and 208 deletions

View File

@@ -1,4 +1,4 @@
import BLOG from '@/blog.config'
import { siteConfig } from '@/lib/config'
import { useEffect } from 'react'
/**
@@ -6,7 +6,7 @@ import { useEffect } from 'react'
*/
export default function DisableCopy() {
useEffect(() => {
if (!JSON.parse(BLOG.CAN_COPY)) {
if (!JSON.parse(siteConfig('CAN_COPY'))) {
// 全栈添加禁止复制的样式
document.getElementsByTagName('html')[0].classList.add('forbid-copy')
// 监听复制事件

View File

@@ -9,10 +9,11 @@ import { deepClone } from './utils'
* 1. 优先读取NotionConfig表
* 2. 其次读取环境变量
* 3. 再读取blog.config.js文件
* @param {*} key
* @param {*} key 参数名
* @param {*} defaultVal ; 参数不存在默认返回值
* @returns
*/
export const siteConfig = (key) => {
export const siteConfig = (key, defaultVal = null) => {
let global = null
try {
// eslint-disable-next-line react-hooks/rules-of-hooks
@@ -36,7 +37,7 @@ export const siteConfig = (key) => {
val = siteInfo?.pageCover // 封面图取Notion的封面
break
case 'AVATAR':
val = siteInfo?.icon // 封面图取Notion的封面
val = siteInfo?.icon // 封面图取Notion的头像
break
case 'TITLE':
val = siteInfo?.title // 标题取Notion中的标题
@@ -48,7 +49,10 @@ export const siteConfig = (key) => {
if (!val) {
val = BLOG[key]
}
console.log('实际配置', key, val)
if (!val) {
val = defaultVal
}
// console.log('实际配置', key, val)
return val
}

View File

@@ -75,7 +75,6 @@ export function getQueryVariable(key) {
}
return (false)
}
/**
* 获取 URL 中指定参数的值
* @param {string} url
@@ -83,8 +82,10 @@ export function getQueryVariable(key) {
* @returns {string|null}
*/
export function getQueryParam(url, param) {
const searchParams = new URLSearchParams(url.split('?')[1])
return searchParams.get(param)
// 移除哈希部分
const urlWithoutHash = url.split('#')[0];
const searchParams = new URLSearchParams(urlWithoutHash.split('?')[1]);
return searchParams.get(param);
}
/**
@@ -202,3 +203,46 @@ export const isMobile = () => {
return isMobile
}
/**
* 扫描页面上的所有文本节点将url格式的文本转为可点击链接
* @param {*} node
*/
export const scanAndConvertToLinks = (node) => {
if (node.nodeType === Node.TEXT_NODE) {
const text = node.textContent;
const urlRegex = /https?:\/\/[^\s]+/g;
let lastIndex = 0;
let match;
const newNode = document.createElement('span');
while ((match = urlRegex.exec(text)) !== null) {
const beforeText = text.substring(lastIndex, match.index);
const url = match[0];
if (beforeText) {
newNode.appendChild(document.createTextNode(beforeText));
}
const link = document.createElement('a');
link.href = url;
link.target = '_blank'
link.textContent = url;
newNode.appendChild(link);
lastIndex = urlRegex.lastIndex;
}
if (lastIndex < text.length) {
newNode.appendChild(document.createTextNode(text.substring(lastIndex)));
}
node.parentNode.replaceChild(newNode, node);
} else if (node.nodeType === Node.ELEMENT_NODE) {
for (const childNode of node.childNodes) {
scanAndConvertToLinks(childNode);
}
}
}

View File

@@ -44,7 +44,6 @@ const MyApp = ({ Component, pageProps }) => {
loadExternalResource(url, 'css')
}
}
checkThemeDOM()
}
return (
@@ -55,18 +54,4 @@ const MyApp = ({ Component, pageProps }) => {
)
}
/**
* 切换主题时的特殊处理
*/
const checkThemeDOM = () => {
const elements = document.querySelectorAll('[id^="theme-"]')
if (elements?.length > 1) {
elements[elements.length - 1].scrollIntoView()
// 删除前面的元素,只保留最后一个元素
for (let i = 0; i < elements.length - 1; i++) {
elements[i].parentNode.removeChild(elements[i])
}
}
}
export default MyApp

View File

@@ -1,36 +1,101 @@
import React from 'react'
import BLOG from '@/blog.config'
import { siteConfig } from '@/lib/config'
import Link from 'next/link'
const Footer = ({ title }) => {
/**
* 页脚
* @param {*} param0
* @returns
*/
const Footer = (props) => {
const d = new Date()
const currentYear = d.getFullYear()
const copyrightDate = (function() {
if (Number.isInteger(BLOG.SINCE) && BLOG.SINCE < currentYear) {
return BLOG.SINCE + '-' + currentYear
}
return currentYear
})()
const since = siteConfig('SINCE')
const copyrightDate = parseInt(since) < currentYear ? since + '-' + currentYear : currentYear
const { categoryOptions, customMenu } = props
return (
<footer
className='relative z-10 dark:bg-black flex-shrink-0 bg-hexo-light-gray justify-center text-center m-auto w-full leading-6 text-gray-600 dark:text-gray-100 text-sm p-6'
>
{/* <DarkModeButton/> */}
return <footer id="footer-wrapper" className='relative bg-[#2A2A2A] justify-center text-center m-auto w-full leading-6 text-gray-300 text-sm p-10'>
<i className='fas fa-copyright' /> {`${copyrightDate}`} <span><i className='mx-1 animate-pulse fas fa-heart'/> <a href={BLOG.LINK} className='underline font-bold dark:text-gray-300 '>{siteConfig('AUTHOR')}</a>.<br/>
<div id='footer-container' className='w-full mx-auto max-w-screen-xl'>
{BLOG.BEI_AN && <><i className='fas fa-shield-alt' /> <a href='https://beian.miit.gov.cn/' className='mr-2'>{BLOG.BEI_AN}</a><br/></>}
<div className='flex'>
<div className='flex flex-grow my-6 space-x-20 text-lg'>
<span className='hidden busuanzi_container_site_pv'>
<i className='fas fa-eye'/><span className='px-1 busuanzi_value_site_pv'> </span> </span>
<span className='pl-2 hidden busuanzi_container_site_uv'>
<i className='fas fa-users'/> <span className='px-1 busuanzi_value_site_uv'> </span> </span>
<h1 className='text-xs pt-4 text-light-400 dark:text-gray-400'>{title} {siteConfig('BIO') && <>|</>} {siteConfig('BIO')}</h1>
<p className='text-xs pt-2 text-light-500 dark:text-gray-500'>Powered by <a href='https://github.com/tangly1024/NotionNext' className='dark:text-gray-300'>NotionNext {siteConfig('VERSION')}</a>.</p></span><br/>
{/* 分类菜单 */}
<div>
<div className='font-bold mb-4 text-white'>{siteConfig('COMMERCE_TEXT_MENU_GROUP', 'Product Center')}</div>
<nav id='home-nav-button' className={'flex flex-col space-y-2 text-start'}>
{categoryOptions.map(category => {
return (
<Link
key={`${category.name}`}
title={`${category.name}`}
href={`/category/${category.name}`}
passHref>
{category.name}
</Link>
)
})}
</nav>
</div>
</footer>
)
{/* 系统菜单 */}
<div>
<div className='font-bold mb-4 text-white'>{siteConfig('COMMERCE_TEXT_MENU_TITLE', 'About US')}</div>
<nav id='home-nav-button' className={'flex flex-col space-y-2 text-start'}>
{customMenu.map(menu => {
return (
<Link
key={`${menu.name}`}
title={`${menu.name}`}
href={`${menu.to}`}
passHref>
{menu.name}
</Link>
)
})}
</nav>
</div>
</div>
{siteConfig('COMMERCE_TEXT_SHOP_LINKS') && <div className='border-l pl-4 border-gray-600 my-6 whitespace-pre-line text-left max-w-md'>
<div className='font-bold text-white'>{siteConfig('COMMERCE_TEXT_SHOP_TITLE')}</div>
<div>{siteConfig('COMMERCE_TEXT_SHOP_LINKS')}</div>
</div>}
</div>
{/* 底部版权相关 */}
<div id='footer-copyright-wrapper' className='flex justify-between border-t border-gray-600 pt-8'>
<div className='text-start space-y-1'>
{/* 网站所有者 */}
<div> Copyright <i className='fas fa-copyright' /> {`${copyrightDate}`} <a href={siteConfig('LINK')} className='underline font-bold dark:text-gray-300 '>{siteConfig('AUTHOR')}</a> All Rights Reserved.</div>
{/* 技术支持 */}
<div className='text-xs text-light-500 dark:text-gray-700'>Powered by <a href='https://github.com/tangly1024/NotionNext' className='dark:text-gray-300'>NotionNext {siteConfig('VERSION')}</a>.</div>
{/* 站点统计 */}
<div>
<span className='hidden busuanzi_container_site_pv'>
<i className='fas fa-eye' /><span className='px-1 busuanzi_value_site_pv'> </span> </span>
<span className='pl-2 hidden busuanzi_container_site_uv'>
<i className='fas fa-users' /> <span className='px-1 busuanzi_value_site_uv'> </span> </span>
</div>
</div>
{/* 右边公司名字 */}
<div className='text-right'>
<h1 className='text-xs pt-4 text-light-400 dark:text-gray-400'>{siteConfig('TITLE')} {siteConfig('BIO')}</h1>
<h2> {siteConfig('DESCRIPTION')}</h2>
{/* 可选备案信息 */}
{siteConfig('BEI_AN') && <><i className='fas fa-shield-alt' /> <a href='https://beian.miit.gov.cn/' className='mr-2'>{siteConfig('BEI_AN')}</a></>}
</div>
</div>
</div>
</footer >
}
export default Footer

View File

@@ -1,65 +1,24 @@
// import Image from 'next/image'
import { useEffect, useState } from 'react'
import Typed from 'typed.js'
import CONFIG from '../config'
import NavButtonGroup from './NavButtonGroup'
import { useGlobal } from '@/lib/global'
import LazyImage from '@/components/LazyImage'
import { siteConfig } from '@/lib/config'
let wrapperTop = 0
/**
* 顶部全屏大图
* @returns
*/
const Hero = props => {
const [typed, changeType] = useState()
const { siteInfo } = props
const { locale } = useGlobal()
const scrollToWrapper = () => {
window.scrollTo({ top: wrapperTop, behavior: 'smooth' })
}
const GREETING_WORDS = siteConfig('GREETING_WORDS').split(',')
useEffect(() => {
updateHeaderHeight()
if (!typed && window && document.getElementById('typed')) {
changeType(
new Typed('#typed', {
strings: GREETING_WORDS,
typeSpeed: 200,
backSpeed: 100,
backDelay: 400,
showCursor: true,
smartBackspace: true
})
)
}
window.addEventListener('resize', updateHeaderHeight)
return () => {
window.removeEventListener('resize', updateHeaderHeight)
}
})
function updateHeaderHeight() {
requestAnimationFrame(() => {
const wrapperElement = document.getElementById('wrapper')
wrapperTop = wrapperElement?.offsetTop
})
}
return (
<header
id="header" style={{ zIndex: 1 }}
className="w-full h-[52rem] relative bg-black"
className="w-full h-auto aspect-[5/2] relative bg-black"
>
<div className="text-white absolute bottom-0 flex flex-col h-full items-center justify-center w-full "></div>
<LazyImage id='header-cover' src={siteInfo?.pageCover}
className={`header-cover w-full h-[52rem] object-cover object-center ${CONFIG.HOME_NAV_BACKGROUND_IMG_FIXED ? 'fixed' : ''}`} />
className={`header-cover w-full h-auto aspect-[5/2] object-cover object-center ${CONFIG.HOME_NAV_BACKGROUND_IMG_FIXED ? 'fixed' : ''}`} />
</header>
)

View File

@@ -1,5 +1,5 @@
import Link from 'next/link'
import { siteConfig } from '@/lib/config'
// import { siteConfig } from '@/lib/config'
import LazyImage from '@/components/LazyImage';
/**
@@ -14,7 +14,7 @@ export default function LogoBar (props) {
<Link href='/' className='text-md md:text-xl dark:text-gray-200 r'>
<LazyImage className='h-12 mr-3' src={siteInfo?.icon}/>
</Link>
<div>{siteConfig('TITLE')}</div>
{/* <div>{siteConfig('TITLE')}</div> */}
</div>
);
}

View File

@@ -16,14 +16,14 @@ export const MenuItemDrop = ({ link }) => {
{!hasSubMenu &&
<Link
href={link?.to} target={link?.to?.indexOf('http') === 0 ? '_blank' : '_self'}
className={`${selected && 'border-b-2 border-[#D2232A]'} h-full flex whitespace-nowrap items-center font-sans menu-link pl-2 pr-4 dark:text-gray-200 no-underline tracking-widest pb-1`}>
{link?.icon && <i className={link?.icon}/>} {link?.name}
className={`${selected && 'border-b-2 border-[#D2232A]'} h-full flex space-x-1 whitespace-nowrap items-center font-sans menu-link pl-2 pr-4 dark:text-gray-200 no-underline tracking-widest pb-1`}>
{link?.icon && <i className={link?.icon}/>} <div>{link?.name}</div>
{/* {hasSubMenu && <i className='px-2 fa fa-angle-down'></i>} */}
</Link>}
{hasSubMenu && <>
<div className='h-full flex whitespace-nowrap items-center cursor-pointer font-sans menu-link pl-2 pr-4 dark:text-gray-200 no-underline tracking-widest pb-1'>
{link?.icon && <i className={link?.icon}/>} {link?.name}
<div className='h-full flex space-x-1 whitespace-nowrap items-center cursor-pointer font-sans menu-link pl-2 pr-4 dark:text-gray-200 no-underline tracking-widest pb-1'>
{link?.icon && <i className={link?.icon}/>} <div>{link?.name}</div>
{/* <i className={`px-2 fa fa-angle-down duration-300 ${show ? 'rotate-180' : 'rotate-0'}`}></i> */}
</div>
</>}

View File

@@ -18,7 +18,7 @@ export const MenuListSide = (props) => {
if (customNav) {
links = customNav.concat(links)
}
for (let i = 0; i < links.length; i++) {
if (links[i].id !== i) {
links[i].id = i

View File

@@ -17,7 +17,6 @@ export default function TopNavBar(props) {
const { customNav, customMenu } = props
const [isOpen, changeShow] = useState(false)
const collapseRef = useRef(null)
let windowTop = 0
const { locale } = useGlobal()
@@ -43,19 +42,17 @@ export default function TopNavBar(props) {
}
}, [])
const throttleMs = 200
const throttleMs = 150
const scrollTrigger = throttle(() => {
const scrollS = window.scrollY
const nav = document.querySelector('#navbar')
const nav = document.querySelector('#top-navbar')
const narrowNav = scrollS >= windowTop || scrollS > 200
const narrowNav = scrollS > 50
if (narrowNav) {
nav && nav.classList.replace('h-24', 'h-16')
windowTop = scrollS
nav && nav.classList.replace('h-24', 'h-14')
} else {
nav && nav.classList.replace('h-16', 'h-24')
windowTop = scrollS
nav && nav.classList.replace('h-14', 'h-24')
}
}, throttleMs)
@@ -68,34 +65,32 @@ export default function TopNavBar(props) {
return null
}
return (
<div id='top-nav' className={'sticky top-0 w-full z-40 '}>
return <div id='top-navbar-wrapper' className={'sticky top-0 w-full z-40 shadow bg-white dark:bg-hexo-black-gray '}>
{/* 移动端折叠菜单 */}
<Collapse type='vertical' collapseRef={collapseRef} isOpen={isOpen} className='md:hidden'>
<div className='bg-white dark:bg-hexo-black-gray pt-1 py-2 lg:hidden '>
<MenuBarMobile {...props} onHeightChange={(param) => collapseRef.current?.updateCollapseHeight(param)} />
</div>
</Collapse>
{/* 移动端折叠菜单 */}
<Collapse type='vertical' collapseRef={collapseRef} isOpen={isOpen} className='md:hidden'>
<div className='bg-white dark:bg-hexo-black-gray pt-1 py-2 lg:hidden '>
<MenuBarMobile {...props} onHeightChange={(param) => collapseRef.current?.updateCollapseHeight(param)} />
</div>
</Collapse>
{/* 导航栏菜单 */}
<div id="navbar" className='flex w-full h-24 transition-all duration-200 shadow bg-white dark:bg-hexo-black-gray px-7 items-between'>
{/* 导航栏菜单内容 */}
<div id="top-navbar" className='flex w-full mx-auto max-w-screen-xl h-24 transition-all duration-200 items-between'>
{/* 左侧图标Logo */}
<LogoBar {...props} />
{/* 左侧图标Logo */}
<LogoBar {...props} />
{/* 移动端折叠按钮 */}
<div className='mr-1 flex md:hidden justify-end items-center text-sm space-x-4 font-serif dark:text-gray-200'>
<div onClick={toggleMenuOpen} className='cursor-pointer'>
{isOpen ? <i className='fas fa-times' /> : <i className='fas fa-bars' />}
</div>
</div>
{/* 桌面端顶部菜单 */}
<div className='hidden md:flex items-center'>
{links && links?.map(link => <MenuItemDrop key={link?.id} link={link}/>)}
{/* 移动端折叠按钮 */}
<div className='mr-1 flex md:hidden justify-end items-center text-sm space-x-4 font-serif dark:text-gray-200'>
<div onClick={toggleMenuOpen} className='cursor-pointer'>
{isOpen ? <i className='fas fa-times' /> : <i className='fas fa-bars' />}
</div>
</div>
{/* 桌面端顶部菜单 */}
<div className='hidden md:flex items-center'>
{links && links?.map(link => <MenuItemDrop key={link?.id} link={link} />)}
</div>
</div>
)
</div>
}

View File

@@ -3,9 +3,9 @@ import CONFIG from './config'
import CommonHead from '@/components/CommonHead'
import { useEffect, useRef } from 'react'
import Footer from './components/Footer'
import SideRight from './components/SideRight'
// import SideRight from './components/SideRight'
import { useGlobal } from '@/lib/global'
import { isBrowser } from '@/lib/utils'
import { isBrowser, scanAndConvertToLinks } from '@/lib/utils'
import BlogPostListPage from './components/BlogPostListPage'
import BlogPostListScroll from './components/BlogPostListScroll'
import Hero from './components/Hero'
@@ -41,14 +41,19 @@ import TopNavBar from './components/TopNavBar'
* @constructor
*/
const LayoutBase = props => {
const { children, headerSlot, floatSlot, slotTop, meta, className } = props
const { children, headerSlot, floatSlot, slotTop, slotRight, meta, className } = props
const { onLoading } = useGlobal()
// 查找页面上的 链接,并便成为可点击
useEffect(() => {
scanAndConvertToLinks(document.getElementById('theme-commerce'))
})
return (
<div id='theme-commerce'>
{/* 网页SEO */}
<CommonHead meta={meta}/>
<Style/>
<CommonHead meta={meta} />
<Style />
{/* 顶部导航 */}
<TopNavBar {...props} />
@@ -69,9 +74,9 @@ const LayoutBase = props => {
</Transition>
{/* 主区块 */}
<main id="wrapper" className={`${CONFIG.HOME_BANNER_ENABLE ? '' : 'pt-16'} bg-hexo-background-gray dark:bg-black w-full py-8 md:px-8 lg:px-24 min-h-screen relative`}>
<main id="wrapper" className={`${CONFIG.HOME_BANNER_ENABLE ? '' : 'pt-16'} bg-hexo-background-gray dark:bg-black w-full py-8 md:px-8 lg:px-24 relative`}>
<div id="container-inner" className={(siteConfig('LAYOUT_SIDEBAR_REVERSE') ? 'flex-row-reverse' : '') + ' w-full mx-auto lg:flex lg:space-x-4 justify-center relative z-10'} >
<div className={`${className || ''} w-full max-w-4xl h-full overflow-hidden`}>
<div className={`${className || ''} w-full h-full max-w-screen-xl overflow-hidden`}>
<Transition
show={!onLoading}
@@ -91,8 +96,8 @@ const LayoutBase = props => {
</Transition>
</div>
{/* 右侧栏 */}
<SideRight {...props} />
{slotRight}
</div>
</main>
@@ -100,7 +105,7 @@ const LayoutBase = props => {
<RightFloatArea floatSlot={floatSlot} />
{/* 页脚 */}
<Footer title={siteConfig('TITLE') || siteConfig('TITLE')} />
<Footer {...props} />
</div>
)
}
@@ -112,8 +117,30 @@ const LayoutBase = props => {
* @returns
*/
const LayoutIndex = (props) => {
// 首页Banner条
const headerSlot = CONFIG.HOME_BANNER_ENABLE && <Hero {...props} />
return <LayoutPostList {...props} headerSlot={headerSlot} className='pt-8' />
const { notice } = props
return <LayoutBase headerSlot={headerSlot} {...props}>
{/* 产品中心 */}
<div className='w-full my-4'>
<div className='w-full text-center text-4xl font-bold'>{siteConfig('TEXT_HOME_PRODUCT_CENTER', 'Product Center')}</div>
<div className='flex'>
<div className='hidden md:block w-72 border'> 左侧导航</div>
<div className='w-full border'>右侧产品列表</div>
</div>
</div>
{/* 企业介绍 + 联系 */}
{notice && <div className='w-full my-4'>
<div className='w-full text-center text-4xl font-bold'>{siteConfig('TEXT_HOME_ABOUT_US', notice.title)}</div>
<NotionPage post={notice} />
</div>}
{/* 铺开导航菜单 */}
</LayoutBase>
}
/**

View File

@@ -5,12 +5,8 @@ import { siteConfig } from '@/lib/config'
export const Footer = (props) => {
const d = new Date()
const currentYear = d.getFullYear()
const copyrightDate = (function() {
if (Number.isInteger(BLOG.SINCE) && BLOG.SINCE < currentYear) {
return BLOG.SINCE + '-' + currentYear
}
return currentYear
})()
const since = siteConfig('SINCE')
const copyrightDate = parseInt(since) < currentYear ? since + '-' + currentYear : currentYear
return <footer className="z-10 relative w-full bg-white px-6 border-t dark:border-hexo-black-gray dark:bg-hexo-black-gray ">
<DarkModeButton className='text-center pt-4'/>

View File

@@ -4,12 +4,8 @@ import { siteConfig } from '@/lib/config'
function SiteInfo ({ title }) {
const d = new Date()
const currentYear = d.getFullYear()
const copyrightDate = (function() {
if (Number.isInteger(BLOG.SINCE) && BLOG.SINCE < currentYear) {
return BLOG.SINCE + '-' + currentYear
}
return currentYear
})()
const since = siteConfig('SINCE')
const copyrightDate = parseInt(since) < currentYear ? since + '-' + currentYear : currentYear
return (
<footer

View File

@@ -5,12 +5,8 @@ import { siteConfig } from '@/lib/config'
const Footer = ({ siteInfo }) => {
const d = new Date()
const currentYear = d.getFullYear()
const copyrightDate = (function () {
if (Number.isInteger(BLOG.SINCE) && BLOG.SINCE < currentYear) {
return BLOG.SINCE + '-' + currentYear
}
return currentYear
})()
const since = siteConfig('SINCE')
const copyrightDate = parseInt(since) < currentYear ? since + '-' + currentYear : currentYear
return (
<footer

View File

@@ -6,12 +6,8 @@ import { siteConfig } from '@/lib/config'
const Footer = ({ title }) => {
const d = new Date()
const currentYear = d.getFullYear()
const copyrightDate = (function () {
if (Number.isInteger(BLOG.SINCE) && BLOG.SINCE < currentYear) {
return BLOG.SINCE + '-' + currentYear
}
return currentYear
})()
const since = siteConfig('SINCE')
const copyrightDate = parseInt(since) < currentYear ? since + '-' + currentYear : currentYear
return (
<footer

View File

@@ -5,12 +5,8 @@ import { siteConfig } from '@/lib/config'
const Footer = ({ title }) => {
const d = new Date()
const currentYear = d.getFullYear()
const copyrightDate = (function() {
if (Number.isInteger(BLOG.SINCE) && BLOG.SINCE < currentYear) {
return BLOG.SINCE + '-' + currentYear
}
return currentYear
})()
const since = siteConfig('SINCE')
const copyrightDate = parseInt(since) < currentYear ? since + '-' + currentYear : currentYear
return (
<footer

View File

@@ -6,12 +6,8 @@ import { siteConfig } from '@/lib/config'
const Footer = ({ title }) => {
const d = new Date()
const currentYear = d.getFullYear()
const copyrightDate = (function() {
if (Number.isInteger(BLOG.SINCE) && BLOG.SINCE < currentYear) {
return BLOG.SINCE + '-' + currentYear
}
return currentYear
})()
const since = siteConfig('SINCE')
const copyrightDate = parseInt(since) < currentYear ? since + '-' + currentYear : currentYear
return (
<footer

View File

@@ -4,12 +4,8 @@ import { siteConfig } from '@/lib/config'
const Footer = ({ siteInfo }) => {
const d = new Date()
const currentYear = d.getFullYear()
const copyrightDate = (function () {
if (Number.isInteger(BLOG.SINCE) && BLOG.SINCE < currentYear) {
return BLOG.SINCE + '-' + currentYear
}
return currentYear
})()
const since = siteConfig('SINCE')
const copyrightDate = parseInt(since) < currentYear ? since + '-' + currentYear : currentYear
return (
<footer

View File

@@ -5,12 +5,8 @@ import DarkModeButton from '@/components/DarkModeButton'
const Footer = ({ title }) => {
const d = new Date()
const currentYear = d.getFullYear()
const copyrightDate = (function () {
if (Number.isInteger(BLOG.SINCE) && BLOG.SINCE < currentYear) {
return BLOG.SINCE + '-' + currentYear
}
return currentYear
})()
const since = siteConfig('SINCE')
const copyrightDate = parseInt(since) < currentYear ? since + '-' + currentYear : currentYear
return (
<footer

View File

@@ -8,13 +8,8 @@ export const Footer = (props) => {
const currentYear = d.getFullYear()
const { post } = props
const fullWidth = post?.fullWidth ?? false
const copyrightDate = (function() {
if (Number.isInteger(BLOG.SINCE) && BLOG.SINCE < currentYear) {
return BLOG.SINCE + '-' + currentYear
}
return currentYear
})()
const since = siteConfig('SINCE')
const copyrightDate = parseInt(since) < currentYear ? since + '-' + currentYear : currentYear
return <footer
className={`z-10 relative mt-6 flex-shrink-0 m-auto w-full text-gray-500 dark:text-gray-400 transition-all ${

View File

@@ -6,12 +6,8 @@ export const Footer = (props) => {
const d = new Date()
const currentYear = d.getFullYear()
const copyrightDate = (function() {
if (Number.isInteger(BLOG.SINCE) && BLOG.SINCE < currentYear) {
return BLOG.SINCE + '-' + currentYear
}
return currentYear
})()
const since = siteConfig('SINCE')
const copyrightDate = parseInt(since) < currentYear ? since + '-' + currentYear : currentYear
return <footer className={'z-10 relative mt-6 flex-shrink-0 m-auto w-full text-gray-500 dark:text-gray-400 transition-all' } >
<div className="my-4 text-sm leading-6">

View File

@@ -5,12 +5,8 @@ import { siteConfig } from '@/lib/config'
export const Footer = (props) => {
const d = new Date()
const currentYear = d.getFullYear()
const copyrightDate = (function() {
if (Number.isInteger(BLOG.SINCE) && BLOG.SINCE < currentYear) {
return BLOG.SINCE + '-' + currentYear
}
return currentYear
})()
const since = siteConfig('SINCE')
const copyrightDate = parseInt(since) < currentYear ? since + '-' + currentYear : currentYear
return <footer className="relative w-full bg-black px-6 border-t">
<DarkModeButton className='text-center pt-4'/>

View File

@@ -1,6 +1,6 @@
import cookie from 'react-cookies'
import BLOG from '@/blog.config'
import { getQueryParam, getQueryVariable } from '../lib/utils'
import { getQueryParam, getQueryVariable, isBrowser } from '../lib/utils'
import dynamic from 'next/dynamic'
import getConfig from 'next/config'
import * as ThemeComponents from '@theme-components'
@@ -15,13 +15,38 @@ export const { THEMES = [] } = getConfig().publicRuntimeConfig
export const getLayoutByTheme = ({ router, theme }) => {
const themeQuery = getQueryParam(router.asPath, 'theme') || theme
const layoutName = getLayoutNameByPath(router.pathname)
if (themeQuery !== BLOG.THEME) {
return dynamic(() => import(`@/themes/${themeQuery}`).then(m => m[layoutName]), { ssr: true })
return dynamic(() => import(`@/themes/${themeQuery}`).then(m => {
setTimeout(() => {
checkThemeDOM()
}, 500);
return m[layoutName]
}), { ssr: true })
} else {
setTimeout(() => {
checkThemeDOM()
}, 100);
return ThemeComponents[layoutName]
}
}
/**
* 切换主题时的特殊处理
*/
const checkThemeDOM = () => {
if (isBrowser) {
const elements = document.querySelectorAll('[id^="theme-"]')
if (elements?.length > 1) {
elements[elements.length - 1].scrollIntoView()
// 删除前面的元素,只保留最后一个元素
for (let i = 0; i < elements.length - 1; i++) {
elements[i].parentNode.removeChild(elements[i])
}
}
}
}
/**
* 根据路径 获取对应的layout
* @param {*} path