mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-15 23:16:48 +00:00
夜间模式按钮
This commit is contained in:
21
components/DarkModeButton.js
Normal file
21
components/DarkModeButton.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { saveDarkModeToCookies } from '@/lib/theme'
|
||||
|
||||
const DarkModeButton = (props) => {
|
||||
const { isDarkMode, updateDarkMode } = useGlobal()
|
||||
// 用户手动设置主题
|
||||
const handleChangeDarkMode = () => {
|
||||
const newStatus = !isDarkMode
|
||||
saveDarkModeToCookies(newStatus)
|
||||
updateDarkMode(newStatus)
|
||||
const htmlElement = document.getElementsByTagName('html')[0]
|
||||
htmlElement.classList?.remove(newStatus ? 'light' : 'dark')
|
||||
htmlElement.classList?.add(newStatus ? 'dark' : 'light')
|
||||
}
|
||||
|
||||
return <div className={'z-10 duration-200 text-xl cursor-pointer py-2 ' + props.className}>
|
||||
<i id='darkModeButton' className={`hover:scale-125 transform duration-200 fas ${isDarkMode ? 'fa-sun' : 'fa-moon'}`}
|
||||
onClick={handleChangeDarkMode} />
|
||||
</div>
|
||||
}
|
||||
export default DarkModeButton
|
||||
@@ -9,8 +9,7 @@ export function ThemeSwitch () {
|
||||
return (
|
||||
<div draggable="true" className="fixed left-4 bottom-12 text-white bg-black rounded z-50">
|
||||
<div className="p-2 cursor-pointer" onClick={switchTheme}>
|
||||
<i className="fas fa-sync mr-1" />
|
||||
切换主题:{theme}
|
||||
<i className="fas fa-palette mr-1" /> {theme} <i className='fas fa-sync text-xs'/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -15,7 +15,7 @@ import JumpToTopButton from './components/JumpToTopButton'
|
||||
const LayoutBase = props => {
|
||||
const { children, meta } = props
|
||||
return (
|
||||
<div className='dark:text-gray-300'>
|
||||
<div className='dark:text-gray-300 bg-white dark:bg-black'>
|
||||
<CommonHead meta={meta} />
|
||||
{/* 顶栏LOGO */}
|
||||
<Header {...props} />
|
||||
@@ -24,7 +24,7 @@ const LayoutBase = props => {
|
||||
<Nav {...props} />
|
||||
|
||||
{/* 主体 */}
|
||||
<div className="w-full bg-white">
|
||||
<div className="w-full">
|
||||
|
||||
<Title {...props} />
|
||||
|
||||
|
||||
@@ -24,19 +24,19 @@ export const BlogList = (props) => {
|
||||
<article key={p.id} className="mb-12" >
|
||||
<h2 className="mb-4">
|
||||
<Link href={`/article/${p.slug}`}>
|
||||
<a className="text-black text-xl md:text-2xl no-underline hover:underline"> {p.title}</a>
|
||||
<a className="text-black dark:text-gray-100 text-xl md:text-2xl no-underline hover:underline"> {p.title}</a>
|
||||
</Link>
|
||||
</h2>
|
||||
|
||||
<div className="mb-4 text-sm text-gray-700">
|
||||
by <a href="#" className="text-gray-700">{BLOG.AUTHOR}</a> on {p.date?.start_date || p.createdTime}
|
||||
<div className="mb-4 text-sm text-gray-700 dark:text-gray-300">
|
||||
by <a href="#" className="text-gray-700 dark:text-gray-300">{BLOG.AUTHOR}</a> on {p.date?.start_date || p.createdTime}
|
||||
<span className="font-bold mx-1"> | </span>
|
||||
<a href="#" className="text-gray-700">{p.category}</a>
|
||||
<a href="#" className="text-gray-700 dark:text-gray-300">{p.category}</a>
|
||||
{/* <span className="font-bold mx-1"> | </span> */}
|
||||
{/* <a href="#" className="text-gray-700">2 Comments</a> */}
|
||||
</div>
|
||||
|
||||
<p className="text-gray-700 leading-normal">
|
||||
<p className="text-gray-700 dark:text-gray-400 leading-normal">
|
||||
{p.summary}
|
||||
</p>
|
||||
{/* 搜索结果 */}
|
||||
|
||||
@@ -1,45 +1,21 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import DarkModeButton from '@/components/DarkModeButton'
|
||||
|
||||
export const Footer = (props) => {
|
||||
const d = new Date()
|
||||
const currentYear = d.getFullYear()
|
||||
const startYear = BLOG.SINCE && BLOG.SINCE !== currentYear && BLOG.SINCE + '-'
|
||||
|
||||
// {/* 页脚 */}
|
||||
// <footer className="font-sans dark:bg-gray-900 flex-shrink-0 justify-center text-center m-auto w-full leading-6 text-sm p-6">
|
||||
// <i className="fas fa-copyright" /> {`${startYear}${currentYear}`}{' '}
|
||||
return <footer className="w-full bg-white px-6 border-t dark:border-hexo-black-gray dark:bg-hexo-black-gray ">
|
||||
<DarkModeButton className='text-center pt-4'/>
|
||||
|
||||
// <br />
|
||||
// <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>
|
||||
// <br />
|
||||
// <h1>{meta?.title || siteInfo?.title}</h1>
|
||||
// <span className='text-xs font-serif'>
|
||||
// Powered by{' '}
|
||||
// <a
|
||||
// href="https://github.com/tangly1024/NotionNext"
|
||||
// className="underline dark:text-gray-300"
|
||||
// >
|
||||
// NotionNext {BLOG.VERSION}
|
||||
// </a>
|
||||
// .
|
||||
// </span>
|
||||
// </footer>
|
||||
|
||||
return <footer className="w-full bg-white px-6 border-t">
|
||||
<div className="container mx-auto max-w-4xl py-6 flex flex-wrap md:flex-no-wrap justify-between items-center text-sm">
|
||||
©{`${startYear}${currentYear}`} {BLOG.AUTHOR}. All rights reserved.
|
||||
<div className="pt-4 md:p-0 text-center md:text-right text-xs">
|
||||
<div className="container mx-auto max-w-4xl py-6 md:flex flex-wrap md:flex-no-wrap md:justify-between items-center text-sm">
|
||||
<div className='text-center'> ©{`${startYear}${currentYear}`} {BLOG.AUTHOR}. All rights reserved.</div>
|
||||
<div className="md:p-0 text-center md:text-right text-xs">
|
||||
{/* 右侧链接 */}
|
||||
{/* <a href="#" className="text-black no-underline hover:underline">Privacy Policy</a> */}
|
||||
{BLOG.BEI_AN && (<a href="https://beian.miit.gov.cn/" className="text-black no-underline hover:underline ml-4">{BLOG.BEI_AN} </a>)}
|
||||
<span className='text-black no-underline ml-4'>
|
||||
{BLOG.BEI_AN && (<a href="https://beian.miit.gov.cn/" className="text-black dark:text-gray-200 no-underline hover:underline ml-4">{BLOG.BEI_AN} </a>)}
|
||||
<span className='dark:text-gray-200 no-underline ml-4'>
|
||||
Powered by
|
||||
<a href="https://github.com/tangly1024/NotionNext" className=' hover:underline'> NotionNext {BLOG.VERSION} </a>
|
||||
</span>
|
||||
|
||||
@@ -7,7 +7,7 @@ import Link from 'next/link'
|
||||
export const Header = (props) => {
|
||||
const { siteInfo } = props
|
||||
|
||||
return <header className="w-full px-6 bg-white">
|
||||
return <header className="w-full px-6 bg-white dark:bg-black">
|
||||
<div className="container mx-auto max-w-4xl md:flex justify-between items-center">
|
||||
<Link href='/'>
|
||||
<a className="py-6 w-full text-center md:text-left md:w-auto text-gray-dark no-underline flex justify-center items-center">
|
||||
|
||||
@@ -20,12 +20,12 @@ export const Nav = (props) => {
|
||||
links = links.concat(customNav)
|
||||
}
|
||||
|
||||
return <nav className="w-full bg-white md:pt-0 px-6 relative z-20 border-t border-b border-gray-light">
|
||||
return <nav className="w-full bg-white md:pt-0 px-6 relative z-20 border-t border-b border-gray-light dark:border-hexo-black-gray dark:bg-black">
|
||||
<div className="container mx-auto max-w-4xl md:flex justify-between items-center text-sm md:text-md md:justify-start">
|
||||
<div className="w-full md:w-2/3 text-center md:text-left py-4 flex flex-wrap justify-center items-stretch md:justify-start md:items-start">
|
||||
{links.map(link => {
|
||||
return link && <Link href={link.to}>
|
||||
<a className="px-2 md:pl-0 md:mr-3 md:pr-3 text-gray-700 no-underline md:border-r border-gray-light">
|
||||
<a className="px-2 md:pl-0 md:mr-3 md:pr-3 text-gray-700 dark:text-gray-200 no-underline md:border-r border-gray-light">
|
||||
{link.name}
|
||||
</a>
|
||||
</Link>
|
||||
|
||||
@@ -8,7 +8,7 @@ export const SideBar = (props) => {
|
||||
return <div className="w-full md:w-64 sticky top-8">
|
||||
|
||||
<aside className="rounded shadow overflow-hidden mb-6">
|
||||
<h3 className="text-sm bg-gray-100 text-gray-700 py-3 px-4 border-b">{locale.COMMON.CATEGORY}</h3>
|
||||
<h3 className="text-sm bg-gray-100 text-gray-700 dark:bg-hexo-black-gray dark:text-gray-200 py-3 px-4 dark:border-hexo-black-gray border-b">{locale.COMMON.CATEGORY}</h3>
|
||||
|
||||
<div className="p-4">
|
||||
<ul className="list-reset leading-normal">
|
||||
@@ -23,7 +23,7 @@ export const SideBar = (props) => {
|
||||
</aside>
|
||||
|
||||
<aside className="rounded shadow overflow-hidden mb-6">
|
||||
<h3 className="text-sm bg-gray-100 text-gray-700 py-3 px-4 border-b">{locale.COMMON.LATEST_POSTS}</h3>
|
||||
<h3 className="text-sm bg-gray-100 text-gray-700 dark:bg-hexo-black-gray dark:text-gray-200 py-3 px-4 dark:border-hexo-black-gray border-b">{locale.COMMON.LATEST_POSTS}</h3>
|
||||
|
||||
<div className="p-4">
|
||||
<ul className="list-reset leading-normal">
|
||||
|
||||
@@ -10,7 +10,7 @@ export const Title = (props) => {
|
||||
const title = post?.title || siteInfo?.description
|
||||
const description = post?.description || BLOG.AUTHOR
|
||||
|
||||
return <div className="text-center px-6 py-12 mb-6 bg-gray-100 border-b">
|
||||
return <div className="text-center px-6 py-12 mb-6 bg-gray-100 dark:bg-hexo-black-gray dark:border-hexo-black-gray border-b">
|
||||
<h1 className=" text-xl md:text-4xl pb-4">{title}</h1>
|
||||
<p className="leading-loose text-gray-dark">
|
||||
{description}
|
||||
|
||||
@@ -6,6 +6,7 @@ import SearchInput from './SearchInput'
|
||||
import SiteInfo from './SiteInfo'
|
||||
import Catalog from './Catalog'
|
||||
import { useRouter } from 'next/router'
|
||||
import DarkModeButton from '@/components/DarkModeButton'
|
||||
|
||||
function AsideLeft (props) {
|
||||
const { tags, currentTag, categories, currentCategory, post, slot, siteInfo } = props
|
||||
@@ -49,6 +50,9 @@ function AsideLeft (props) {
|
||||
<div>{slot}</div>
|
||||
</div>
|
||||
</section>
|
||||
<section className='flex justify-center dark:text-gray-200'>
|
||||
<DarkModeButton/>
|
||||
</section>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import JumpToTopButton from './JumpToTopButton'
|
||||
|
||||
export default function BottomMenuBar ({ className }) {
|
||||
return (
|
||||
<div className={'sticky bottom-0 w-full h-12 bg-white ' + className}>
|
||||
<div className={'sticky bottom-0 w-full h-12 bg-white dark:bg-hexo-black-gray ' + className}>
|
||||
<div className='flex justify-between h-full shadow-card'>
|
||||
<Link href='/' passHref>
|
||||
<div className='flex w-full items-center justify-center cursor-pointer'>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from 'react'
|
||||
import BLOG from '@/blog.config'
|
||||
import DarkModeButton from '@/components/DarkModeButton'
|
||||
|
||||
const Footer = ({ title }) => {
|
||||
const d = new Date()
|
||||
@@ -9,6 +10,7 @@ const Footer = ({ title }) => {
|
||||
<footer
|
||||
className='dark:bg-hexo-black-gray flex-shrink-0 justify-center text-center m-auto w-full leading-6 text-gray-400 text-sm p-6'
|
||||
>
|
||||
<DarkModeButton/>
|
||||
<i className='fas fa-copyright' /> {`${startYear}${currentYear}`} <span><i className='mx-1 animate-pulse fas fa-heart'/> <a href={BLOG.LINK} className='underline font-bold text-gray-500 dark:text-gray-300 '>{BLOG.AUTHOR}</a>.<br/>
|
||||
|
||||
{BLOG.BEI_AN && <><i className='fas fa-shield-alt'/> <a href='https://beian.miit.gov.cn/' className='mr-2'>{BLOG.BEI_AN}</a><br/></>}
|
||||
|
||||
@@ -19,8 +19,8 @@ export default function TopNavBar(props) {
|
||||
}
|
||||
|
||||
return <div id='top-nav' className={'sticky top-0 lg:relative w-full z-40 ' + className}>
|
||||
<Collapse type='vertical' isOpen={isOpen} className='flex md:hidden'>
|
||||
<div className='py-1 px-5'>
|
||||
<Collapse type='vertical' isOpen={isOpen} className='md:hidden'>
|
||||
<div className='bg-white dark:bg-hexo-black-gray pt-1 py-2 px-5 lg:hidden '>
|
||||
<GroupMenu {...props} />
|
||||
</div>
|
||||
</Collapse>
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { loadDarkModeFromCookies, saveDarkModeToCookies } from '@/lib/theme'
|
||||
import { saveDarkModeToCookies } from '@/lib/theme'
|
||||
|
||||
const DarkModeButton = () => {
|
||||
const { updateDarkMode } = useGlobal()
|
||||
const isDarkMode = loadDarkModeFromCookies()
|
||||
|
||||
const { isDarkMode, updateDarkMode } = useGlobal()
|
||||
// 用户手动设置主题
|
||||
const handleChangeDarkMode = () => {
|
||||
const newTheme = (isDarkMode ? 'dark' : 'light')
|
||||
saveDarkModeToCookies(newTheme)
|
||||
updateDarkMode(newTheme)
|
||||
const newStatus = !isDarkMode
|
||||
saveDarkModeToCookies(newStatus)
|
||||
updateDarkMode(newStatus)
|
||||
const htmlElement = document.getElementsByTagName('html')[0]
|
||||
htmlElement.classList?.remove(newStatus ? 'light' : 'dark')
|
||||
htmlElement.classList?.add(newStatus ? 'dark' : 'light')
|
||||
}
|
||||
|
||||
return <div className='z-10 duration-200 text-xs cursor-pointer py-1.5 px-1'>
|
||||
<i id='darkModeButton' className={`hover:scale-125 transform duration-200 fas ${isDarkMode ? 'fa-sun' : 'fa-moon'}`}
|
||||
onClick={handleChangeDarkMode} />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from 'react'
|
||||
import BLOG from '@/blog.config'
|
||||
import DarkModeButton from '@/components/DarkModeButton'
|
||||
|
||||
const Footer = ({ title }) => {
|
||||
const d = new Date()
|
||||
@@ -9,6 +10,7 @@ const Footer = ({ title }) => {
|
||||
<footer
|
||||
className='dark:bg-gray-900 flex-shrink-0 justify-center text-center m-auto w-full leading-6 text-sm p-6 dark:text-gray-400'
|
||||
>
|
||||
<DarkModeButton/>
|
||||
<i className='fas fa-copyright' /> {`${startYear}${currentYear}`} <span><i className='mx-1 animate-pulse fas fas-heart' /> <a href={BLOG.LINK} className='underline font-bold '>{BLOG.AUTHOR}</a>.<br />
|
||||
|
||||
{BLOG.BEI_AN && <><i className='fas fa-shield-alt' /> <a href='https://beian.miit.gov.cn/' className='mr-2'>{BLOG.BEI_AN}</a><br /></>}
|
||||
|
||||
Reference in New Issue
Block a user