mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-13 23:16:47 +00:00
修改布局
This commit is contained in:
@@ -9,17 +9,70 @@ import '@/styles/notion.css' // 重写部分样式
|
||||
import 'aos/dist/aos.css' // You can also use <link> for styles
|
||||
|
||||
import { GlobalContextProvider } from '@/lib/global'
|
||||
import { isBrowser, loadExternalResource } from '@/lib/utils'
|
||||
import { getGlobalLayoutByTheme } from '@/themes/theme'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import { getQueryParam } from '../lib/utils'
|
||||
|
||||
// 各种扩展插件 这个要阻塞引入
|
||||
import ExternalPlugins from '@/components/ExternalPlugins'
|
||||
import { CUSTOM_EXTERNAL_CSS, CUSTOM_EXTERNAL_JS, IMG_SHADOW, THEME } from '@/blog.config'
|
||||
|
||||
const MyApp = ({ Component, pageProps }) => {
|
||||
/**
|
||||
* 首页布局
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
const route = useRouter()
|
||||
const queryParam = useMemo(() => {
|
||||
return getQueryParam(route.asPath, 'theme') || THEME
|
||||
}, [route])
|
||||
|
||||
const GLayout = useCallback(
|
||||
props => {
|
||||
// 根据页面路径加载不同Layout文件
|
||||
const Layout = getGlobalLayoutByTheme(queryParam)
|
||||
return <Layout {...props} />
|
||||
},
|
||||
[queryParam]
|
||||
)
|
||||
|
||||
// 自定义样式css和js引入
|
||||
if (isBrowser) {
|
||||
// 初始化AOS动画
|
||||
// 静态导入本地自定义样式
|
||||
loadExternalResource('/css/custom.css', 'css')
|
||||
loadExternalResource('/js/custom.js', 'js')
|
||||
|
||||
// 自动添加图片阴影
|
||||
if (IMG_SHADOW) {
|
||||
loadExternalResource('/css/img-shadow.css', 'css')
|
||||
}
|
||||
|
||||
// 导入外部自定义脚本
|
||||
if (CUSTOM_EXTERNAL_JS && CUSTOM_EXTERNAL_JS.length > 0) {
|
||||
for (const url of CUSTOM_EXTERNAL_JS) {
|
||||
loadExternalResource(url, 'js')
|
||||
}
|
||||
}
|
||||
|
||||
// 导入外部自定义样式
|
||||
if (CUSTOM_EXTERNAL_CSS && CUSTOM_EXTERNAL_CSS.length > 0) {
|
||||
for (const url of CUSTOM_EXTERNAL_CSS) {
|
||||
loadExternalResource(url, 'css')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<GlobalContextProvider {...pageProps}>
|
||||
<Component {...pageProps} />
|
||||
{/* 全局插件 , 自定义样式、组件等在这里统一引入 */}
|
||||
<ExternalPlugins {...pageProps} />
|
||||
</GlobalContextProvider>
|
||||
<GlobalContextProvider {...pageProps}>
|
||||
<GLayout {...pageProps}>
|
||||
<Component {...pageProps} />
|
||||
</GLayout>
|
||||
<ExternalPlugins {...pageProps} />
|
||||
</GlobalContextProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ import { siteConfig } from '@/lib/config'
|
||||
* @returns {JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
let counter = 0
|
||||
const LayoutBase = (props) => {
|
||||
const { children, headerSlot, floatSlot, rightAreaSlot, meta } = props
|
||||
const { onLoading } = useGlobal()
|
||||
@@ -39,7 +40,9 @@ const LayoutBase = (props) => {
|
||||
const floatButtonGroup = useRef(null)
|
||||
const [showRightFloat, switchShow] = useState(false)
|
||||
const [percent, changePercent] = useState(0) // 页面阅读百分比
|
||||
|
||||
useEffect(()=>{
|
||||
console.log('sidebar 渲染次数: ', counter++)
|
||||
}, [])
|
||||
const scrollListener = () => {
|
||||
const targetRef = document.getElementById('wrapper')
|
||||
const clientHeight = targetRef?.clientHeight
|
||||
@@ -140,7 +143,7 @@ const LayoutIndex = (props) => {
|
||||
* @returns
|
||||
*/
|
||||
const LayoutPostList = (props) => {
|
||||
return <LayoutBase {...props} >
|
||||
return <div {...props} >
|
||||
|
||||
<BlogListBar {...props} />
|
||||
|
||||
@@ -148,7 +151,7 @@ const LayoutPostList = (props) => {
|
||||
? <BlogPostListScroll {...props} showSummary={true} />
|
||||
: <BlogPostListPage {...props} />
|
||||
}
|
||||
</LayoutBase>
|
||||
</div>
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,7 +177,7 @@ const LayoutSearch = (props) => {
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<LayoutBase {...props} >
|
||||
<div {...props} >
|
||||
<StickyBar>
|
||||
<div className="p-4 dark:text-gray-200">
|
||||
<i className="mr-1 fas fa-search" />{' '}
|
||||
@@ -187,7 +190,7 @@ const LayoutSearch = (props) => {
|
||||
: <BlogPostListPage {...props} />
|
||||
}
|
||||
</div>
|
||||
</LayoutBase>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -210,7 +213,7 @@ const Layout404 = props => {
|
||||
}, 3000)
|
||||
}, [])
|
||||
|
||||
return <LayoutBase {...props}>
|
||||
return <div {...props}>
|
||||
<div className='md:-mt-20 text-black w-full h-screen text-center justify-center content-center items-center flex flex-col'>
|
||||
<div className='dark:text-gray-200'>
|
||||
<h2 className='inline-block border-r-2 border-gray-600 mr-2 px-3 py-2 align-top'><i className='mr-2 fas fa-spinner animate-spin' />404</h2>
|
||||
@@ -219,7 +222,7 @@ const Layout404 = props => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</LayoutBase>
|
||||
</div>
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,7 +234,7 @@ const LayoutArchive = (props) => {
|
||||
const { archivePosts } = props
|
||||
|
||||
return (
|
||||
<LayoutBase {...props}>
|
||||
<div {...props}>
|
||||
<div className="mb-10 pb-20 bg-white md:p-12 p-3 dark:bg-hexo-black-gray shadow-md min-h-full">
|
||||
{Object.keys(archivePosts).map(archiveTitle => (
|
||||
<BlogPostArchive
|
||||
@@ -241,7 +244,7 @@ const LayoutArchive = (props) => {
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</LayoutBase>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -261,7 +264,7 @@ const LayoutSlug = (props) => {
|
||||
</div>
|
||||
|
||||
return (
|
||||
<LayoutBase {...props} floatSlot={floatSlot}>
|
||||
<div {...props} floatSlot={floatSlot}>
|
||||
|
||||
{post && !lock && <ArticleDetail {...props} />}
|
||||
|
||||
@@ -272,7 +275,7 @@ const LayoutSlug = (props) => {
|
||||
<TocDrawer post={post} cRef={drawerRight} targetRef={targetRef} />
|
||||
</div>}
|
||||
|
||||
</LayoutBase>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -285,7 +288,7 @@ const LayoutCategoryIndex = (props) => {
|
||||
const { allPosts, categoryOptions } = props
|
||||
const { locale } = useGlobal()
|
||||
return (
|
||||
<LayoutBase totalPosts={allPosts} {...props}>
|
||||
<div totalPosts={allPosts} {...props}>
|
||||
<div className='bg-white dark:bg-hexo-black-gray px-10 py-10 shadow h-full'>
|
||||
<div className='dark:text-gray-200 mb-5'>
|
||||
<i className='mr-4 fas faTh' />{locale.COMMON.CATEGORY}:
|
||||
@@ -307,7 +310,7 @@ const LayoutCategoryIndex = (props) => {
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</LayoutBase>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -319,7 +322,7 @@ const LayoutCategoryIndex = (props) => {
|
||||
const LayoutTagIndex = (props) => {
|
||||
const { tagOptions } = props
|
||||
const { locale } = useGlobal()
|
||||
return <LayoutBase {...props}>
|
||||
return <div {...props}>
|
||||
<div className='bg-white dark:bg-hexo-black-gray px-10 py-10 shadow h-full'>
|
||||
<div className='dark:text-gray-200 mb-5'><i className='fas fa-tags mr-4' />{locale.COMMON.TAGS}:</div>
|
||||
<div id='tags-list' className='duration-200 flex flex-wrap'>
|
||||
@@ -328,11 +331,12 @@ const LayoutTagIndex = (props) => {
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</LayoutBase>
|
||||
</div>
|
||||
}
|
||||
|
||||
export {
|
||||
CONFIG as THEME_CONFIG,
|
||||
LayoutBase,
|
||||
LayoutIndex,
|
||||
LayoutSearch,
|
||||
LayoutArchive,
|
||||
@@ -340,5 +344,5 @@ export {
|
||||
Layout404,
|
||||
LayoutCategoryIndex,
|
||||
LayoutPostList,
|
||||
LayoutTagIndex
|
||||
LayoutTagIndex,
|
||||
}
|
||||
|
||||
@@ -2,14 +2,19 @@ import { AdSlot } from '@/components/GoogleAdsense'
|
||||
import Live2D from '@/components/Live2D'
|
||||
import Announcement from './Announcement'
|
||||
import Catalog from './Catalog'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
/**
|
||||
* 侧边栏
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
let counter = 0;
|
||||
export default function SideBar (props) {
|
||||
const { notice } = props
|
||||
useEffect(()=>{
|
||||
console.log('sidebar 渲染次数: ', counter++)
|
||||
}, [])
|
||||
return (<>
|
||||
|
||||
<aside>
|
||||
|
||||
@@ -120,9 +120,9 @@ const LayoutIndex = props => {
|
||||
*/
|
||||
const LayoutPostList = props => {
|
||||
return (
|
||||
<LayoutBase {...props}>
|
||||
<div {...props}>
|
||||
{siteConfig('POST_LIST_STYLE') === 'page' ? <BlogListPage {...props} /> : <BlogListScroll {...props} />}
|
||||
</LayoutBase>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -161,11 +161,11 @@ const LayoutSearch = props => {
|
||||
const LayoutArchive = props => {
|
||||
const { archivePosts } = props
|
||||
return (
|
||||
<LayoutBase {...props}>
|
||||
<div {...props}>
|
||||
<div className="mb-10 pb-20 md:py-12 p-3 min-h-screen w-full">
|
||||
{Object.keys(archivePosts).map(archiveTitle => <BlogArchiveItem key={archiveTitle} archiveTitle={archiveTitle} archivePosts={archivePosts} />)}
|
||||
</div>
|
||||
</LayoutBase>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ const LayoutSlug = props => {
|
||||
const { fullWidth } = useGlobal()
|
||||
|
||||
return (
|
||||
<LayoutBase {...props}>
|
||||
<div {...props}>
|
||||
|
||||
{lock && <ArticleLock validPassword={validPassword} />}
|
||||
|
||||
@@ -208,7 +208,7 @@ const LayoutSlug = props => {
|
||||
|
||||
</div>
|
||||
|
||||
</LayoutBase>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -218,9 +218,9 @@ const LayoutSlug = props => {
|
||||
* @returns
|
||||
*/
|
||||
const Layout404 = (props) => {
|
||||
return <LayoutBase {...props}>
|
||||
return <div {...props}>
|
||||
404 Not found.
|
||||
</LayoutBase>
|
||||
</div>
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,7 +231,7 @@ const Layout404 = (props) => {
|
||||
const LayoutCategoryIndex = props => {
|
||||
const { categoryOptions } = props
|
||||
return (
|
||||
<LayoutBase {...props}>
|
||||
<div {...props}>
|
||||
<div id='category-list' className='duration-200 flex flex-wrap'>
|
||||
{categoryOptions?.map(category => {
|
||||
return (
|
||||
@@ -248,7 +248,7 @@ const LayoutCategoryIndex = props => {
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</LayoutBase>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ const LayoutCategoryIndex = props => {
|
||||
const LayoutTagIndex = (props) => {
|
||||
const { tagOptions } = props
|
||||
return (
|
||||
<LayoutBase {...props}>
|
||||
<div {...props}>
|
||||
<div id='tags-list' className='duration-200 flex flex-wrap'>
|
||||
{tagOptions.map(tag => {
|
||||
return (
|
||||
@@ -276,12 +276,13 @@ const LayoutTagIndex = (props) => {
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</LayoutBase>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export {
|
||||
CONFIG as THEME_CONFIG,
|
||||
LayoutBase,
|
||||
LayoutIndex,
|
||||
LayoutSearch,
|
||||
LayoutArchive,
|
||||
@@ -289,5 +290,5 @@ export {
|
||||
Layout404,
|
||||
LayoutCategoryIndex,
|
||||
LayoutPostList,
|
||||
LayoutTagIndex
|
||||
LayoutTagIndex,
|
||||
}
|
||||
|
||||
@@ -6,6 +6,22 @@ import getConfig from 'next/config'
|
||||
import * as ThemeComponents from '@theme-components'
|
||||
// 所有主题在next.config.js中扫描
|
||||
export const { THEMES = [] } = getConfig().publicRuntimeConfig
|
||||
|
||||
/**
|
||||
* 加载全局布局
|
||||
* 如果是
|
||||
* @param {*} themeQuery
|
||||
* @returns
|
||||
*/
|
||||
export const getGlobalLayoutByTheme = (themeQuery) => {
|
||||
const layout = getLayoutNameByPath(-1)
|
||||
if (themeQuery !== BLOG.THEME) {
|
||||
return dynamic(() => import(`@/themes/${themeQuery}`).then(m => m[layout]), { ssr: true })
|
||||
} else {
|
||||
return ThemeComponents[layout]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载主题文件
|
||||
* 如果是
|
||||
@@ -54,6 +70,8 @@ const checkThemeDOM = () => {
|
||||
*/
|
||||
export const getLayoutNameByPath = (path) => {
|
||||
switch (path) {
|
||||
case -1:
|
||||
return 'LayoutBase'
|
||||
case '/':
|
||||
return 'LayoutIndex'
|
||||
case '/archive':
|
||||
|
||||
Reference in New Issue
Block a user