mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-14 07:26:52 +00:00
feature:
语言本地化完善; 夜间模式完善; 封装版权声明; 侧边栏sticky优化
This commit is contained in:
26
components/ArticleCopyright.js
Normal file
26
components/ArticleCopyright.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Link from 'next/link'
|
||||
|
||||
export default function ArticleCopyright ({ author, url }) {
|
||||
const { locale } = useGlobal()
|
||||
return <section className="dark:text-gray-300 mt-6">
|
||||
<div className="text-2xl mb-2">{locale.COMMON.COPYRIGHT}</div>
|
||||
<ul className="text-sm dark:bg-gray-900 bg-gray-100 p-5 leading-8 border-l-4 border-red-500">
|
||||
<li>
|
||||
<strong className='mr-2'>{locale.COMMON.AUTHOR}:</strong>
|
||||
<Link href="/about">
|
||||
<a className="hover:underline">{author}</a>
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<strong className='mr-2'>{locale.COMMON.URL}:</strong>
|
||||
<a className="hover:underline" href={url}>
|
||||
{url}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
{locale.COMMON.COPYRIGHT_NOTICE}
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import { faEye, faFolderOpen } from '@fortawesome/free-solid-svg-icons'
|
||||
import BlogAround from '@/components/BlogAround'
|
||||
import { useRef } from 'react'
|
||||
import WordCount from './WordCount'
|
||||
import ArticleCopyright from './ArticleCopyright'
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -36,7 +37,7 @@ export default function ArticleDetail ({ post, blockMap, recommendPosts, prev, n
|
||||
const drawerRight = useRef(null)
|
||||
const url = BLOG.link + useRouter().asPath
|
||||
const { locale } = useGlobal()
|
||||
const date = formatDate(post?.date?.start_date || post.createdTime, BLOG.lang)
|
||||
const date = formatDate(post?.date?.start_date || post.createdTime, locale.LOCALE)
|
||||
|
||||
return (<>
|
||||
<div id="article-wrapper" ref={targetRef} className="flex-grow mt-14 md:mt-0 max-w-5xl mx-auto w-screen md:w-full ">
|
||||
@@ -134,27 +135,7 @@ export default function ArticleDetail ({ post, blockMap, recommendPosts, prev, n
|
||||
<RecommendPosts currentPost={post} recommendPosts={recommendPosts} />
|
||||
|
||||
{/* 版权声明 */}
|
||||
<section className="dark:text-gray-300 mt-6">
|
||||
<div className="text-2xl mb-2">版权声明</div>
|
||||
<ul className="text-sm dark:bg-gray-900 bg-gray-100 p-5 leading-8 border-l-4 border-red-500">
|
||||
<li>
|
||||
本文作者:{' '}
|
||||
<Link href="/about">
|
||||
<a className="hover:underline">{BLOG.author}</a>
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
本文链接:{' '}
|
||||
<a className="hover:underline" href={url}>
|
||||
{url}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
本博客所有文章除特别声明外,均采用 BY-NC-SA
|
||||
许可协议。转载请注明出处!
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
<ArticleCopyright author={BLOG.author} url={url} />
|
||||
|
||||
{/* 标签列表 */}
|
||||
<section className="md:flex md:justify-between">
|
||||
|
||||
@@ -4,6 +4,7 @@ import BLOG from '@/blog.config'
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import throttle from 'lodash.throttle'
|
||||
import BlogPostListEmpty from '@/components/BlogPostListEmpty'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
|
||||
/**
|
||||
* 博客列表滚动分页
|
||||
@@ -47,6 +48,7 @@ const BlogPostListScroll = ({ posts = [], tags, currentSearch, currentCategory,
|
||||
})
|
||||
|
||||
const targetRef = useRef(null)
|
||||
const { locale } = useGlobal()
|
||||
|
||||
if (!postsToShow || postsToShow.length === 0) {
|
||||
return <BlogPostListEmpty currentSearch={currentSearch} />
|
||||
@@ -65,7 +67,7 @@ const BlogPostListScroll = ({ posts = [], tags, currentSearch, currentCategory,
|
||||
handleGetMore()
|
||||
}}
|
||||
className='w-full my-4 py-4 text-center cursor-pointer glassmorphism shadow-xl rounded-xl dark:text-gray-200'
|
||||
> {hasMore ? '继续加载' : '加载完了😰'} </div>
|
||||
> {hasMore ? locale.COMMON.MORE : `${locale.COMMON.NO_MORE} 😰`} </div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
const DarkModeButton = () => {
|
||||
const { changeTheme } = useGlobal()
|
||||
const userTheme = loadUserThemeFromCookies()
|
||||
|
||||
// 用户手动设置主题
|
||||
const handleChangeDarkMode = () => {
|
||||
const newTheme = (userTheme === 'light' ? 'dark' : 'light')
|
||||
|
||||
@@ -25,6 +25,10 @@ export default function FloatDarkModeButton () {
|
||||
const newTheme = userTheme === 'light' ? 'dark' : 'light'
|
||||
saveTheme(newTheme)
|
||||
changeTheme(newTheme)
|
||||
const htmlElement = document.getElementsByTagName('html')[0]
|
||||
console.log('切换主题', htmlElement)
|
||||
htmlElement.classList.remove(userTheme)
|
||||
htmlElement.classList.add(newTheme)
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -21,28 +21,25 @@ import React from 'react'
|
||||
* @returns {JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
const SideArea = ({ title, tags, currentTag, post, posts, categories, currentCategory, currentSearch }) => {
|
||||
const SideAreaLeft = ({ title, tags, currentTag, post, posts, categories, currentCategory, currentSearch }) => {
|
||||
const { locale } = useGlobal()
|
||||
const showToc = post && post.toc && post.toc.length > 1
|
||||
return <>
|
||||
|
||||
return <aside id='sidebar' className='scroll-hidden h-full w-72 z-10'>
|
||||
|
||||
<div className={(!post ? 'sticky top-5' : '') + ' pb-4'}>
|
||||
|
||||
<section className='hidden lg:block bg-white dark:bg-gray-800 rounded-xl hover:shadow-2xl duration-200 py-8 shadow-md'>
|
||||
<div className={(!post ? 'sticky top-10 ' : ' ') + ' w-72'}>
|
||||
<section className='hidden lg:block mb-5 bg-white dark:bg-gray-800 rounded-xl hover:shadow-2xl duration-200 py-8 shadow-md'>
|
||||
<InfoCard />
|
||||
</section>
|
||||
|
||||
{/* 菜单 */}
|
||||
<section className='hidden lg:block mt-5 py-5 rounded-xl shadow-md bg-white dark:bg-gray-800 hover:shadow-2xl duration-200'>
|
||||
<section className='hidden lg:block mb-5 py-5 rounded-xl shadow-md bg-white dark:bg-gray-800 hover:shadow-2xl duration-200'>
|
||||
<MenuButtonGroup allowCollapse={true} />
|
||||
<div className='px-5 pt-2'>
|
||||
<SearchInput currentTag={currentTag} currentSearch={currentSearch} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 分类 */}
|
||||
{!post && categories && (
|
||||
<section className='rounded-xl shadow-md py-4 mt-5 bg-white dark:bg-gray-800 hover:shadow-2xl duration-200'>
|
||||
<section className='rounded-xl shadow-md py-4 mb-5 bg-white dark:bg-gray-800 hover:shadow-2xl duration-200'>
|
||||
<div className='text-sm px-5 mb-2 flex flex-nowrap justify-between font-light'>
|
||||
<div className='pb-1 text-gray-600 dark:text-gray-200'><FontAwesomeIcon icon={faThList} className='mr-2' />{locale.COMMON.CATEGORY}</div>
|
||||
<Link href='/category' passHref>
|
||||
@@ -54,18 +51,16 @@ const SideArea = ({ title, tags, currentTag, post, posts, categories, currentCat
|
||||
<CategoryGroup currentCategory={currentCategory} categories={categories} />
|
||||
</section>
|
||||
)}
|
||||
|
||||
</div>
|
||||
|
||||
{post && post.toc && post.toc.length > 1 && (
|
||||
<section id='left-toc' className='sticky top-6 pb-20 rounded-xl shadow-md bg-white dark:bg-gray-800 hover:shadow-2xl duration-200'>
|
||||
{showToc && (
|
||||
<section className='sticky top-10 pb-20 rounded-xl shadow-md bg-white dark:bg-gray-800 hover:shadow-2xl duration-200'>
|
||||
<div className='border-b text-2xl bg-white text-black rounded-t-xl dark:border-gray-700 dark:bg-gray-700 dark:text-white py-6 px-6'>
|
||||
{locale.COMMON.TABLE_OF_CONTENTS}
|
||||
</div>
|
||||
<Toc toc={post.toc} />
|
||||
</section>
|
||||
)}
|
||||
|
||||
</aside>
|
||||
</>
|
||||
}
|
||||
export default SideArea
|
||||
export default SideAreaLeft
|
||||
@@ -51,7 +51,7 @@ const SideAreaRight = ({
|
||||
></ins>
|
||||
</section>
|
||||
|
||||
<div className="sticky top-5">
|
||||
<div className="sticky top-10">
|
||||
{/* 最新文章 */}
|
||||
{posts && (
|
||||
<section className="rounded-xl shadow-md py-4 mt-5 bg-white dark:bg-gray-800 hover:shadow-2xl duration-200">
|
||||
|
||||
@@ -3,7 +3,7 @@ import FloatDarkModeButton from '@/components/FloatDarkModeButton'
|
||||
import Footer from '@/components/Footer'
|
||||
import JumpToTopButton from '@/components/JumpToTopButton'
|
||||
import LoadingCover from '@/components/LoadingCover'
|
||||
import SideArea from '@/components/SideArea'
|
||||
import SideAreaLeft from '@/components/SideAreaLeft'
|
||||
import SideAreaRight from '@/components/SideAreaRight'
|
||||
import TopNav from '@/components/TopNav'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
@@ -61,19 +61,20 @@ const BaseLayout = ({
|
||||
window.removeEventListener('scroll', scrollTrigger)
|
||||
}
|
||||
}, [])
|
||||
const { theme, onLoading } = useGlobal()
|
||||
const { onLoading } = useGlobal()
|
||||
const targetRef = useRef(null)
|
||||
|
||||
return (<div id='wrapper' className={`${theme}`}>
|
||||
return (<div id='wrapper'>
|
||||
|
||||
<CommonHead meta={meta} />
|
||||
|
||||
{/* 顶部导航栏 */}
|
||||
<TopNav tags={tags} post={post} posts={totalPosts} currentSearch={currentSearch} categories={categories} currentCategory={currentCategory} />
|
||||
|
||||
<div className='flex max-w-full mx-auto lg:px-16 lg:space-x-10 md:pt-10 pb-12 bg-gray-100 dark:bg-gray-900'>
|
||||
<div id='left' className='hidden lg:block'>
|
||||
<SideArea title={meta.title} post={post} posts={totalPosts} tags={tags} currentSearch={currentSearch} currentTag={currentTag} categories={categories} currentCategory={currentCategory} />
|
||||
<div className='flex max-w-full mx-auto lg:px-16 lg:space-x-10 md:pt-10 pb-12 '>
|
||||
|
||||
<div id='left' className='hidden xl:block flex-col w-72'>
|
||||
<SideAreaLeft title={meta.title} post={post} posts={totalPosts} tags={tags} currentSearch={currentSearch} currentTag={currentTag} categories={categories} currentCategory={currentCategory} />
|
||||
</div>
|
||||
|
||||
<div id='center' className='flex flex-grow min-h-screen' ref={targetRef}>
|
||||
|
||||
@@ -88,33 +88,31 @@ const initTheme = (theme, changeTheme) => {
|
||||
const date = new Date()
|
||||
const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
const useDark = prefersDarkMode || (date.getHours() >= 18 || date.getHours() < 6)
|
||||
const htmlElement = document.getElementsByTagName('html')
|
||||
|
||||
if (useDark) {
|
||||
changeTheme('dark')
|
||||
saveTheme('dark')
|
||||
htmlElement.classList.remove('light')
|
||||
htmlElement.classList.add('dark')
|
||||
} else {
|
||||
changeTheme('light')
|
||||
saveTheme('light')
|
||||
htmlElement.classList.remove('dark')
|
||||
htmlElement.classList.add('light')
|
||||
}
|
||||
}
|
||||
const baseLayoutClass = document.getElementById('wrapper')?.classList
|
||||
if (baseLayoutClass && !baseLayoutClass.contains(theme)) {
|
||||
baseLayoutClass.add(theme)
|
||||
}
|
||||
}
|
||||
|
||||
export function handleRouteChange (url) {
|
||||
console.log('路由变化', url)
|
||||
initGoogleAdsense()
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化谷歌广告
|
||||
*/
|
||||
// let activeAdsCount = 0
|
||||
function initGoogleAdsense () {
|
||||
const ads = document.getElementsByClassName('adsbygoogle').length
|
||||
// const newAdsCount = ads - activeAdsCount
|
||||
// console.log(`Start: 总广告${ads}, 已激活${activeAdsCount} 新广告${newAdsCount}`)
|
||||
const newAdsCount = ads
|
||||
if (newAdsCount > 0) {
|
||||
for (let i = 0; i <= newAdsCount; i++) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export default {
|
||||
LOCALE: 'en-US',
|
||||
NAV: {
|
||||
INDEX: 'Blog',
|
||||
RSS: 'RSS',
|
||||
@@ -9,6 +10,7 @@ export default {
|
||||
},
|
||||
COMMON: {
|
||||
MORE: 'More',
|
||||
NO_MORE: 'No More',
|
||||
LATEST_POSTS: 'Latest posts',
|
||||
TAGS: 'Tags',
|
||||
NO_TAG: 'NoTag',
|
||||
@@ -17,7 +19,11 @@ export default {
|
||||
SCAN_QR_CODE: 'Scan QRCode',
|
||||
URL_COPIED: 'URL has copied!',
|
||||
TABLE_OF_CONTENTS: 'Table of Contents',
|
||||
RELATE_POSTS: 'Relate Posts'
|
||||
RELATE_POSTS: 'Relate Posts',
|
||||
COPYRIGHT: 'Copyright',
|
||||
AUTHOR: 'Author',
|
||||
URL: 'URL',
|
||||
COPYRIGHT_NOTICE: 'All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!'
|
||||
},
|
||||
PAGINATION: {
|
||||
PREV: 'Prev',
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export default {
|
||||
LOCALE: 'zh-CN',
|
||||
NAV: {
|
||||
INDEX: '首页',
|
||||
RSS: '订阅',
|
||||
@@ -10,6 +11,7 @@ export default {
|
||||
},
|
||||
COMMON: {
|
||||
MORE: '更多',
|
||||
NO_MORE: '没有更多了',
|
||||
LATEST_POSTS: '最新文章',
|
||||
TAGS: '标签',
|
||||
NO_TAG: 'NoTag',
|
||||
@@ -18,7 +20,11 @@ export default {
|
||||
SCAN_QR_CODE: '扫一扫二维码',
|
||||
URL_COPIED: '链接已复制!',
|
||||
TABLE_OF_CONTENTS: '目录',
|
||||
RELATE_POSTS: '相关文章'
|
||||
RELATE_POSTS: '相关文章',
|
||||
COPYRIGHT: '版权声明',
|
||||
AUTHOR: '作者',
|
||||
URL: '链接',
|
||||
COPYRIGHT_NOTICE: '本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!'
|
||||
},
|
||||
PAGINATION: {
|
||||
PREV: '上一页',
|
||||
|
||||
@@ -18,7 +18,7 @@ class MyDocument extends Document {
|
||||
<ThirdPartyScript />
|
||||
</Head>
|
||||
|
||||
<body>
|
||||
<body className='bg-gray-100 dark:bg-gray-900 duration-200'>
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user