语言本地化完善;
夜间模式完善;
封装版权声明;
侧边栏sticky优化
This commit is contained in:
tangly1024
2021-12-21 10:40:38 +08:00
parent 807b0f04ef
commit d3a8a02808
12 changed files with 77 additions and 57 deletions

View 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>
}

View File

@@ -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">

View File

@@ -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>
}

View File

@@ -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')

View File

@@ -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 (

View File

@@ -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

View File

@@ -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">

View File

@@ -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}>

View File

@@ -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++) {

View File

@@ -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',

View File

@@ -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: '上一页',

View File

@@ -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>