4.0 仿Youtube界面样式

This commit is contained in:
tangly1024
2021-10-11 17:14:52 +08:00
parent 3d02b0f6e2
commit 05d79a3db9
22 changed files with 391 additions and 300 deletions

View File

@@ -8,7 +8,7 @@ const DarkModeButton = () => {
changeTheme(newTheme)
localStorage.setItem('theme', newTheme)
}
return <div className='z-10 p-1 border hover:shadow-xl duration-200 dark:border-gray-500 mr-2 h-12 my-2 bg-white dark:bg-gray-600 dark:bg-opacity-70 bg-opacity-70 dark:hover:bg-gray-100 text-xl cursor-pointer dark:text-gray-300 dark:hover:text-black'>
return <div className='z-10 p-1 duration-200 mr-2 h-12 bg-white dark:bg-gray-600 dark:bg-opacity-70 bg-opacity-70 text-xl cursor-pointer dark:text-gray-300 '>
<i className={'fa p-2.5 hover:scale-125 transform duration-200 ' + (theme === 'dark' ? ' fa-sun-o' : ' fa-moon-o') } onClick={handleChangeDarkMode} />
</div>
}

View File

@@ -4,15 +4,13 @@ import React from 'react'
const Footer = ({ fullWidth = true }) => {
const d = new Date()
const y = d.getFullYear()
const from = +BLOG.since
return (
<footer
className='flex-shrink-0 m-auto w-full text-gray-500 dark:text-gray-400 text-sm text-gray-400'
className='flex-shrink-0 m-auto w-full text-gray-500 dark:text-gray-400 text-xs text-gray-400 p-6'
>
<hr className='py-2'/>
<span className='fa fa-shield leading-6'> <a href='https://beian.miit.gov.cn/' className='ml-1'>闽ICP备20010331号</a></span>
<br />
<span className='fa fa-copyright leading-6'> {from === y || !from ? y : `${from} - ${y}`} {BLOG.author} </span>
<span className='fa fa-copyright leading-6'> {` ${y}`} {BLOG.author} </span>
<br />
<span id='busuanzi_container_site_pv' className='hidden'>
<a id='busuanzi_container_site_pv' href='https://www.cnzz.com/stat/website.php?web_id=1279970751' target='_blank'

View File

@@ -26,7 +26,7 @@ const NavBar = () => {
)
}
const Header = ({ navBarTitle, fullWidth }) => {
const Header = ({ navBarTitle, fullWidth = true }) => {
const navRef = useRef(null)
const sentinelRef = useRef([])
// 当Header移出屏幕时改变的样式
@@ -49,7 +49,7 @@ const Header = ({ navBarTitle, fullWidth }) => {
}, [sentinelRef])
return (
<>
{ BLOG.autoCollapsedNavBar === true && (
{BLOG.autoCollapsedNavBar === true && (
<script
dangerouslySetInnerHTML={{
__html: `
@@ -70,38 +70,41 @@ const Header = ({ navBarTitle, fullWidth }) => {
}}
/>
)}
<div className='observer-element h-0.5' ref={sentinelRef}/>
<div className='observer-element h-0.5 ' ref={sentinelRef} />
<div
className={`sticky-nav m-auto w-full h-6 flex flex-row justify-between items-center mb-2 py-8 bg-opacity-60 ${
!fullWidth ? 'max-w-5xl px-4' : 'px-4 md:px-24'
}`}
className='z-30 px-4 sticky-nav m-auto w-full h-6 flex flex-row justify-between items-center py-6 bg-white bg-opacity-80 '
id='sticky-nav'
ref={navRef}
>
<div className='flex items-center'>
<Link href='/'>
<a>
<div className='h-6'>
<Image
alt={BLOG.author}
width={24}
height={24}
src='/favicon.svg'
className='rounded-full'
/>
</div>
</a>
</Link>
<div className='flex cursor-pointer'>
<div className='px-2 text-xl'>
<i className='fa fa-bars hover:scale-125 transform duration-200' />
</div>
<Image
alt={BLOG.author}
width={28}
height={28}
src='/avatar.svg'
className='rounded-full'
/>
<div
className='mx-1 text-center cursor-pointer text-xl p-1
dark:bg-gray-900 dark:text-gray-300 font-semibold
dark:hover:bg-gray-600 text-black hover:scale-105
hover:shadow-2xl duration-200 transform'>{BLOG.title}</div>
</div>
{navBarTitle
? (
<p className='ml-2 font-medium text-gray-500 dark:text-night header-name'>
<p className='ml-1 font-medium text-gray-500 dark:text-night header-name'>
{navBarTitle}
</p>
)
: (
<p className='ml-2 font-medium text-500 dark:text-night header-name'>
{BLOG.title} {' '}
{BLOG.title},{' '}
<p className='ml-1 font-medium dark:text-night header-name'>
<span className='font-normal'>{BLOG.description}</span>
</p>
)}

View File

@@ -3,11 +3,12 @@ import throttle from 'lodash.throttle'
import { useLocale } from '@/lib/locale'
/**
* 跳转到网页顶部当屏幕下滑500像素后会出现该控件
* 跳转到网页顶部
* 当屏幕下滑500像素后会出现该控件
* @returns {JSX.Element}
* @constructor
*/
const TopJumper = () => {
const JumpToTop = () => {
const locale = useLocale()
const [show, switchShow] = useState(false)
@@ -36,4 +37,4 @@ const TopJumper = () => {
)
}
export default TopJumper
export default JumpToTop

View File

@@ -0,0 +1,42 @@
import React, { useEffect, useState } from 'react'
import throttle from 'lodash.throttle'
import DarkModeButton from '@/components/DarkModeButton'
/**
* 左上角悬浮菜单栏
* @returns {JSX.Element}
* @constructor
*/
const LeftFloatButton = () => {
// 监听resize事件
useEffect(() => {
window.addEventListener('resize', collapseSideBar)
collapseSideBar()
return () => {
window.removeEventListener('resize', collapseSideBar)
}
}, [])
const collapseSideBar = throttle(() => {
if (window.innerWidth > 1300) {
changeCollapse(false)
} else {
changeCollapse(true)
}
}, 500)
const [collapse, changeCollapse] = useState(true)
console.log(collapse)
return <div
className={(collapse ? 'left-0' : 'left-72') + ' z-30 fixed flex flex-nowrap md:flex-col top-0 pl-4 py-1 duration-500 ease-in-out'}>
{/* 菜单折叠 */}
<div className='p-1 border hover:shadow-xl duration-200 dark:border-gray-500 h-12 bg-white dark:bg-gray-600 dark:bg-opacity-70 bg-opacity-70
dark:hover:bg-gray-100 text-xl cursor-pointer mr-2 my-2 dark:text-gray-300 dark:hover:text-black'>
<i className='fa fa-bars p-2.5 hover:scale-125 transform duration-200'
onClick={() => changeCollapse(!collapse)} />
</div>
{/* 夜间模式 */}
<DarkModeButton />
</div>
}
export default LeftFloatButton

11
components/Logo.js Normal file
View File

@@ -0,0 +1,11 @@
import Link from 'next/link'
import BLOG from '@/blog.config'
import React from 'react'
const Logo = () => {
return <Link href='/'>
<div
className='mx-auto text-center cursor-pointer text-3xl dark:bg-gray-900 dark:text-gray-300 font-semibold dark:hover:bg-gray-600 bg-gray-700 text-white p-2 hover:scale-105 hover:shadow-2xl duration-200 transform'>{BLOG.title}</div>
</Link>
}
export default Logo

View File

@@ -3,6 +3,13 @@ import { useLocale } from '@/lib/locale'
import Link from 'next/link'
import { useRouter } from 'next/router'
/**
* 翻页插件
* @param page 当前页码
* @param showNext 是否有下一页
* @returns {JSX.Element}
* @constructor
*/
const Pagination = ({ page, showNext }) => {
const locale = useLocale()
const router = useRouter()

View File

@@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'
import throttle from 'lodash.throttle'
/**
* 跳转到网页顶部当屏幕下滑500像素后会出现该控件
* 顶部页面阅读进度条
* @returns {JSX.Element}
* @constructor
*/

View File

@@ -2,7 +2,7 @@ import React from 'react'
import { createPopper } from '@popperjs/core'
/**
* 赞赏模块
* 赞赏按钮
* @returns {JSX.Element}
* @constructor
*/

View File

@@ -2,8 +2,15 @@ import React, { useState } from 'react'
import TocBar from '@/components/TocBar'
import throttle from 'lodash.throttle'
import ShareButton from '@/components/ShareButton'
import TopJumper from '@/components/TopJumper'
import JumpToTop from '@/components/JumpToTop'
/**
* 右侧边栏
* @param toc
* @param post
* @returns {JSX.Element}
* @constructor
*/
const RightAside = ({ toc, post }) => {
// 无目录就直接返回空
if (toc.length < 1) return <></>
@@ -43,7 +50,7 @@ const RightAside = ({ toc, post }) => {
{/* 分享按钮 */}
<ShareButton post={post} />
{/* 跳回顶部 */}
<TopJumper />
<JumpToTop />
</div>
</div>

View File

@@ -1,11 +0,0 @@
import React from 'react'
import TopJumper from '@/components/TopJumper'
import ShareButton from '@/components/ShareButton'
const RightWidget = ({ post }) => {
return <div className='flex-wrap'>
<ShareButton post={post} />
<TopJumper />
</div>
}
export default RightWidget

View File

@@ -1,134 +0,0 @@
import Tags from '@/components/Tags'
import { useLocale } from '@/lib/locale'
import Link from 'next/link'
import BLOG from '@/blog.config'
import React, { useEffect, useState } from 'react'
import Router, { useRouter } from 'next/router'
import DarkModeButton from '@/components/DarkModeButton'
import Footer from '@/components/Footer'
import throttle from 'lodash.throttle'
import TocBar from '@/components/TocBar'
import SocialButton from '@/components/SocialButton'
const SideBar = ({ tags, currentTag, post }) => {
const locale = useLocale()
const router = useRouter()
const [searchValue, setSearchValue] = useState('')
const handleKeyUp = (e) => {
if (e.keyCode === 13) {
Router.push({ pathname: '/', query: { s: searchValue } })
}
}
// 监听resize事件
useEffect(() => {
window.addEventListener('resize', collapseSideBar)
collapseSideBar()
return () => {
window.removeEventListener('resize', collapseSideBar)
}
}, [])
const collapseSideBar = throttle(() => {
if (window.innerWidth > 1300) {
changeCollapse(false)
} else {
changeCollapse(true)
}
}, 500)
const [collapse, changeCollapse] = useState(true)
return <aside className='z-10'>
<div
className={(collapse ? '-ml-80 ' : 'shadow-2xl xl:shadow-none ') + ' dark:bg-gray-800 bg-white sidebar h-full w-72 duration-500 ease-in-out'}>
{/* Logo */}
<section className='flex border-b px-5 pt-8 pb-6 flex-col sticky top-0 bg-white dark:bg-gray-800 z-10'>
<Link href='/'>
<div
className='mx-auto text-center cursor-pointer text-3xl dark:bg-gray-900 dark:text-gray-300 font-semibold dark:hover:bg-gray-600 bg-gray-700 text-white p-2 hover:scale-105 hover:shadow-2xl duration-200 transform'>{BLOG.title}</div>
</Link>
<i className='mx-auto fa fa-map-marker pl-1 dark:text-gray-300 mt-5' >&nbsp;Fuzhou, China</i>
</section>
{/* 搜索框 */}
<section className={ (post ? ' ' : ' sticky top-36 ') + ' z-20 border-t border-b flex justify-center items-center py-5 pr-5 pl-2 bg-gray-100 dark:bg-black'}>
<input
type='text'
placeholder={
currentTag ? `${locale.SEARCH.TAGS} #${currentTag}` : `${locale.SEARCH.ARTICLES}`
}
className='shadow-inner duration-200 pl-2 rounded w-full py-2 border dark:border-gray-600 bg-white text-black dark:bg-gray-700 dark:text-white'
onKeyUp={handleKeyUp}
onChange={e => setSearchValue(e.target.value)}
defaultValue={router.query.s ?? ''}
/>
<i className='fa fa-search text-gray-400 -ml-8' />
</section>
{/* wrapper */}
<div className={ (post ? ' ' : ' ') + 'px-6'}>
{/* 菜单 */}
<nav className='mt-6'>
<strong className='text-2xl text-gray-600 dark:text-gray-400'>菜单</strong>
<ul className='mt-4 leading-8 text-gray-500 dark:text-gray-400'>
<li><a className='fa fa-info hover:underline' href='/article/about' id='about'><span
className='ml-2'>关于本站</span></a></li>
<li><a className='fa fa-rss hover:underline' href='/feed' target='_blank' id='feed'><span
className='ml-2'>RSS订阅</span></a></li>
<li></li>
</ul>
</nav>
{/* 标签云 */}
<section className='mt-6'>
<strong className='text-2xl text-gray-600 dark:text-gray-400'>标签</strong>
<div className='mt-4'>
<Tags tags={tags} currentTag={currentTag} />
</div>
</section>
{/* 联系 */}
<section>
<div className='mt-6'>
<strong className='text-2xl text-gray-600 dark:text-gray-400'>联系我</strong>
<div className='mt-2 py-2'>
<SocialButton />
</div>
</div>
</section>
{/* 站点信息 */}
<section className='my-3'>
<Footer />
</section>
</div>
{post && (
<div className='sticky top-36'>
<TocBar toc={post.toc} />
</div>
)}
</div>
{/* 顶部菜单按钮 */}
<div
className={(collapse ? 'left-0' : 'left-72') + ' z-30 fixed flex flex-nowrap md:flex-col top-0 pl-4 py-1 duration-500 ease-in-out'}>
{/* 菜单折叠 */}
<div className='p-1 border hover:shadow-xl duration-200 dark:border-gray-500 h-12 bg-white dark:bg-gray-600 dark:bg-opacity-70 bg-opacity-70
dark:hover:bg-gray-100 text-xl cursor-pointer mr-2 my-2 dark:text-gray-300 dark:hover:text-black'>
<i className='fa fa-bars p-2.5 hover:scale-125 transform duration-200'
onClick={() => changeCollapse(!collapse)} />
</div>
{/* 夜间模式 */}
<DarkModeButton />
</div>
</aside>
}
export default SideBar

View File

@@ -0,0 +1,67 @@
import React from 'react'
import Footer from '@/components/Footer'
import TocBar from '@/components/TocBar'
import SocialButton from '@/components/SocialButton'
const SideBarEmbed = ({ tags, currentTag, post }) => {
return <aside className='z-30 bg-white dark:border-gray-500 border-gray-200'>
<div
className='dark:bg-gray-800 scroll-hidden left-0 duration-500 ease-in-out '>
{/* wrapper */}
<div className='sticky top-12'>
{/* 菜单 */}
<nav>
<ul className='leading-8 text-gray-700 dark:text-gray-400'>
<li className='hover:bg-gray-100 dark:hover:bg-black duration-100 p-2'>
<a className='fa fa-home w-full px-4' href='/' id='home'>
<span className='ml-2'>主页</span>
</a>
</li>
<li className='hover:bg-gray-100 dark:hover:bg-black duration-100 p-2'>
<a className='fa fa-info-circle w-full px-4' href='/article/about' id='about'>
<span className='ml-2'>关于本站</span>
</a>
</li>
<li className='hover:bg-gray-100 dark:hover:bg-black duration-100 p-2'>
<a className='fa fa-rss-square w-full px-4' href='/feed' target='_blank' id='feed'>
<span className='ml-2'>RSS订阅</span>
</a>
</li>
</ul>
</nav>
<hr className='dark:border-gray-600'/>
{/* 联系 */}
<section className='mt-6 mb-6 '>
<strong className='text-gray-600 dark:text-gray-400 px-6'>联系我</strong>
<div>
<i className='fa fa-map-marker text-sm dark:text-gray-300 px-6 mt-3' >&nbsp;Fuzhou, China</i>
</div>
<div>
<SocialButton />
</div>
</section>
{/* 站点信息 */}
<section className='my-3 xl:block'>
<hr className='dark:border-gray-600'/>
<Footer />
</section>
</div>
{post && (
<div className='sticky top-12'>
<TocBar toc={post.toc} />
</div>
)}
</div>
</aside>
}
export default SideBarEmbed

View File

@@ -0,0 +1,67 @@
import React from 'react'
import Footer from '@/components/Footer'
import TocBar from '@/components/TocBar'
import SocialButton from '@/components/SocialButton'
const SideBarResponsive = ({ tags, currentTag, post }) => {
return <aside className='z-10 bg-white dark:border-gray-500 border-gray-200 mt-12 hidden md:block'>
<div
className='dark:bg-gray-800 border-r dark:border-gray-700 h-full scroll-hidden left-0 duration-500 ease-in-out min-h-screen'>
{/* wrapper */}
<div className='hidden md:block sticky top-12'>
{/* 菜单 */}
<nav>
<ul className='leading-8 text-gray-700 dark:text-gray-400'>
<li className='hover:bg-gray-100 dark:hover:bg-black duration-100 p-2'>
<a className='fa fa-home w-full px-4' href='/' id='home'>
<span className='ml-2 hidden xl:inline-block'>主页</span>
</a>
</li>
<li className='hover:bg-gray-100 dark:hover:bg-black duration-100 p-2'>
<a className='fa fa-info-circle w-full px-4' href='/article/about' id='about'>
<span className='ml-2 hidden xl:inline-block'>关于本站</span>
</a>
</li>
<li className='hover:bg-gray-100 dark:hover:bg-black duration-100 p-2'>
<a className='fa fa-rss-square w-full px-4' href='/feed' target='_blank' id='feed'>
<span className='ml-2 hidden xl:inline-block'>RSS订阅</span>
</a>
</li>
</ul>
</nav>
<hr className='dark:border-gray-600'/>
{/* 联系 */}
<section className='mt-6 mb-6 hidden xl:inline-block'>
<strong className='text-gray-600 dark:text-gray-400 px-6'>联系我</strong>
<div>
<i className='fa fa-map-marker text-sm dark:text-gray-300 px-6 mt-3' >&nbsp;Fuzhou, China</i>
</div>
<div>
<SocialButton />
</div>
</section>
{/* 站点信息 */}
<section className='my-3 hidden xl:block'>
<hr className='dark:border-gray-600'/>
<Footer />
</section>
</div>
{post && (
<div className='sticky top-12'>
<TocBar toc={post.toc} />
</div>
)}
</div>
</aside>
}
export default SideBarResponsive

View File

@@ -1,8 +1,13 @@
import React from 'react'
/**
* 社交联系方式按钮组
* @returns {JSX.Element}
* @constructor
*/
const SocialButton = () => {
return <>
<div className='space-x-3 text-2xl text-gray-500 dark:text-gray-400'>
return <div className='w-52'>
<div className='space-x-3 text-2xl text-black dark:text-gray-400 px-6'>
<a target='_blank' rel='noreferrer' title={'github'}
href={'https://github.com/tangly1024'} >
<div className='fa fa-github transform hover:scale-125 duration-150'/>
@@ -18,7 +23,8 @@ const SocialButton = () => {
href={'https://weibo.com/tangly1024'} >
<div className='fa fa-weibo transform hover:scale-125 duration-150'/>
</a>
</div>
</>
</div>
}
export default SocialButton

View File

@@ -1,16 +1,23 @@
import Link from 'next/link'
/**
* 标签组
* @param tags
* @param currentTag
* @returns {JSX.Element}
* @constructor
*/
const Tags = ({ tags, currentTag }) => {
if (!tags) return <></>
return (
<ul className='flex flex-wrap py-1 max-w-full overflow-x-auto'>
return (<div className='bg-white dark:bg-gray-800 flex overflow-x-auto'>
<ul id='tag-container' className='px-20 flex py-1 space-x-3'>
{Object.keys(tags).map(key => {
const selected = key === currentTag
return (
<Link key={key} href={`/tag/${encodeURIComponent(key)}`}>
<Link key={key} href={selected ? '/' : `/tag/${encodeURIComponent(key)}`}>
<li
className={`cursor-pointer hover:bg-gray-600 rounded-sm hover:text-white duration-200 mr-1 my-1 px-2 py-1 font-medium text-xs whitespace-nowrap
dark:text-gray-300 dark:hover:bg-gray-600 ${selected ? 'text-white bg-black dark:border-gray-600' : 'bg-gray-200 text-gray-600 dark:bg-gray-900 dark:border-gray-600'
className={`cursor-pointer border hover:bg-gray-300 rounded-xl duration-200 mr-1 my-1 px-2 py-1 font-medium font-light text-sm whitespace-nowrap
dark:text-gray-300 dark:hover:bg-gray-800 ${selected ? 'text-white bg-black dark:hover:bg-gray-900 dark:bg-black dark:border-gray-800' : 'bg-gray-100 text-gray-600 dark:bg-gray-600 dark:border-gray-600'
}`}
>
<a>
@@ -21,6 +28,7 @@ const Tags = ({ tags, currentTag }) => {
)
})}
</ul>
</div>
)
}

View File

@@ -4,7 +4,10 @@ import { uuidToId } from 'notion-utils'
import { cs } from 'react-notion-x'
/**
* 目录组件
* 目录导航组件
* @param toc
* @returns {JSX.Element}
* @constructor
*/
const TocBar = ({ toc }) => {
// 无目录就直接返回空
@@ -47,8 +50,8 @@ const TocBar = ({ toc }) => {
setActiveSection(currentSectionId)
}, throttleMs)
return <div className='bg-white dark:bg-gray-800 pb-10'>
<div className='border-t border-b text-2xl bg-gray-100 font-bold text-black dark:bg-black dark:text-white py-6 px-6'>
return <div className='bg-white dark:bg-gray-800 pb-10 w-52 hidden md:block min-h-screen'>
<div className='border-t dark:border-gray-600 border-b text-2xl bg-gray-100 font-bold text-black dark:bg-black dark:text-white py-6 px-6'>
文章目录
</div>
<nav className='text-gray-500 dark:text-gray-400 underline overflow-y-auto overflow-x-hidden'>

View File

@@ -1,72 +1,105 @@
import Link from 'next/link'
import BLOG from '@/blog.config'
import { useState } from 'react'
import React, { useState } from 'react'
import { useLocale } from '@/lib/locale'
import Router, { useRouter } from 'next/router'
import DarkModeButton from '@/components/DarkModeButton'
import SocialButton from '@/components/SocialButton'
import Image from 'next/image'
import SideBarEmbed from '@/components/SideBarEmbed'
const TopNav = ({ tags, currentTag }) => {
const TopNav = ({ tags, currentTag, post }) => {
const locale = useLocale()
const [hiddenMenu, switchHiddenMenu] = useState(!currentTag)
// 点击按钮更改菜单状态
const [showDrawer, switchShowDrawer] = useState(false)
// 点击按钮更改侧边抽屉状态
const handleMenuClick = () => {
switchHiddenMenu(!hiddenMenu)
switchShowDrawer(!showDrawer)
}
const router = useRouter()
const [searchValue, setSearchValue] = useState('')
const handleSearch = () => {
if (searchValue && searchValue !== '') {
Router.push({ pathname: '/', query: { s: searchValue } }).then(r => {
console.log(r)
})
}
}
const handleKeyUp = (e) => {
if (e.keyCode === 13) {
Router.push({ pathname: '/', query: { s: searchValue } })
handleSearch()
}
}
return (
<div className='bg-white dark:bg-gray-600'>
{/* 隐藏的顶部菜单 */}
<nav
className={(hiddenMenu ? '-mt-10' : ' ') + ' py-1 overflow-hidden bg-gray-800 text-xl text-gray-200 w-full ease-in-out duration-500'}>
<ul className='mx-5 duration-300'>
<li>
<SocialButton/>
</li>
</ul>
</nav>
<div className='bg-white dark:bg-gray-600 border-b dark:border-gray-700'>
<div className='fixed top-0 left-0 z-30 h-full'>
<div className={(showDrawer ? 'shadow-2xl' : '-ml-52') + ' duration-200 w-52 h-full bg-white dark:bg-gray-800 border-r dark:border-gray-600'}>
<div className='flex space-x-4 px-5 dark:bg-gray-600'>
<div
className='z-10 p-1 duration-200 mr-2 bg-white dark:bg-gray-600 text-gray-600 text-xl cursor-pointer dark:text-gray-300'>
<i className='fa hover:scale-125 transform duration-200 fa-bars ' onClick={handleMenuClick}/>
</div>
<Link href='/'>
<a
className='flex justify-center font-bold font-semibold hover:bg-gray-800 hover:text-white p-2 duration-200
dark:text-gray-300
'>{BLOG.title}</a>
</Link>
</div>
<SideBarEmbed post={post}/>
</div>
</div>
<div className={(showDrawer ? 'block' : 'hidden') + ' fixed top-0 left-0 z-20 w-full h-full bg-black bg-opacity-40' } onClick={handleMenuClick}/>
{/* 导航栏 */}
<div
id='sticky-nav'
className='text-sm ticky-nav m-auto w-full flex flex-row justify-between items-center px-5 '
className='text-sm m-auto w-full flex flex-row justify-between items-center px-5'
>
<div>
<div className='flex space-x-4'>
<div
className='z-10 p-1 duration-200 mr-2 bg-white dark:bg-gray-600 text-gray-600 text-xl cursor-pointer dark:text-gray-300'>
<i className='fa hover:scale-125 transform duration-200 fa-bars '
onClick={handleMenuClick} />
</div>
<Link href='/'>
<a
className='flex justify-center border-black border-2 bg-whitefont-semibold hover:bg-gray-800 hover:text-white p-2 duration-200
dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-100 dark:hover:text-black
className='flex justify-center font-bold font-semibold hover:bg-gray-800 hover:text-white p-2 duration-200
dark:text-gray-300
'>{BLOG.title}</a>
</Link>
</div>
<div>
{/* 搜索框 */}
<div className='px-4 flex w-20'>
<i className='py-3 fa fa-search text-gray-400 absolute cursor-pointer px-2' />
<div className='flex border dark:border-gray-600'>
<input
type='text'
placeholder={currentTag ? `${locale.SEARCH.TAGS} #${currentTag}` : `${locale.SEARCH.ARTICLES}`}
className={'transition duration-200 leading-10 pl-8 block border-gray-300 dark:border-gray-600 bg-white text-black dark:bg-gray-800 dark:text-white'}
className={'md:w-80 transition border-r dark:border-gray-700 duration-200 leading-10 pl-2 block border-gray-300 bg-white text-black dark:bg-gray-800 dark:text-white'}
onKeyUp={handleKeyUp}
onChange={e => setSearchValue(e.target.value)}
defaultValue={router.query.s ?? ''}
/>
<div className='py-3 px-5 bg-gray-50 flex dark:bg-gray-500 justify-center align-middle cursor-pointer'
onClick={handleSearch}>
<i className='fa fa-search text-black absolute cursor-pointer' />
</div>
</div>
</div>
<div className='flex flex-nowrap space-x-1'>
<div className='z-10 p-1 border hover:shadow-xl duration-200 dark:border-gray-500 mr-2 h-12 my-2 bg-white dark:bg-gray-600 dark:bg-opacity-70 bg-opacity-70 dark:hover:bg-gray-100 text-xl cursor-pointer dark:text-gray-300 dark:hover:text-black'>
<i className={'fa p-2.5 hover:scale-125 transform duration-200 ' + (hiddenMenu ? ' fa-bars ' : ' fa-times') } onClick={handleMenuClick} />
</div>
<DarkModeButton/>
<DarkModeButton />
<a className='flex align-middle cursor-pointer' href='/article/about'>
<Image
alt={BLOG.author}
width={28}
height={28}
src='/avatar.svg'
className='rounded-full border-black'
/>
</a>
</div>
</div>
</div>

View File

@@ -1,13 +1,21 @@
import BLOG from '@/blog.config'
import { useEffect } from 'react'
/**
* 评论插件
* @param issueTerm
* @param layout
* @returns {JSX.Element}
* @constructor
*/
const Utterances = ({ issueTerm, layout }) => {
useEffect(() => {
const theme =
BLOG.appearance === 'auto'
? 'preferred-color-scheme'
: BLOG.appearance === 'light'
? 'github-light'
: 'github-dark'
? 'github-light'
: 'github-dark'
const script = document.createElement('script')
const anchor = document.getElementById('comments')
script.setAttribute('src', 'https://utteranc.es/client.js')

View File

@@ -9,12 +9,13 @@ import { useRef } from 'react'
import Image from 'next/image'
import RewardButton from '@/components/RewardButton'
import { useTheme } from '@/lib/theme'
import SideBar from '@/components/SideBar'
import BlogPostMini from '@/components/BlogPostMini'
import { useRouter } from 'next/router'
import ShareButton from '@/components/ShareButton'
import TopJumper from '@/components/TopJumper'
import JumpToTop from '@/components/JumpToTop'
import CommonHead from '@/components/CommonHead'
import TopNav from '@/components/TopNav'
import SideBarResponsive from '@/components/SideBarResponsive'
const mapPageUrl = id => {
return 'https://www.notion.so/' + id.replace(/-/g, '')
@@ -47,10 +48,14 @@ const ArticleLayout = ({
<Progress targetRef={targetRef} />
<div className=' fixed w-full top-0 z-20'>
<TopNav post={frontMatter}/>
</div>
{/* Wrapper */}
<div className='flex justify-between bg-gray-100 dark:bg-black'>
<SideBar tags={tags} post={frontMatter} />
<SideBarResponsive tags={tags} post={frontMatter} />
{/* 主体区块 */}
<main className='bg-gray-100 dark:bg-black w-full'>
@@ -163,7 +168,7 @@ const ArticleLayout = ({
{/* 分享按钮 */}
<ShareButton post={frontMatter} />
{/* 跳回顶部 */}
<TopJumper />
<JumpToTop />
</div>
</div>
</div>

View File

@@ -4,10 +4,10 @@ import Pagination from '@/components/Pagination'
import BLOG from '@/blog.config'
import { useRouter } from 'next/router'
import { useTheme } from '@/lib/theme'
import { useEffect, useState } from 'react'
import SideBar from '@/components/SideBar'
import throttle from 'lodash.throttle'
import CommonHead from '@/components/CommonHead'
import TopNav from '@/components/TopNav'
import Tags from '@/components/Tags'
import SideBarResponsive from '@/components/SideBarResponsive'
const DefaultLayout = ({ tags, posts, page, currentTag, ...customMeta }) => {
const meta = {
@@ -44,80 +44,53 @@ const DefaultLayout = ({ tags, posts, page, currentTag, ...customMeta }) => {
showNext = page * BLOG.postsPerPage < totalPosts
}
useEffect(() => {
// 首页隐藏看板娘
// const ref = document.getElementById('waifu')
// if (ref) {
// ref.remove()
// }
window.addEventListener('resize', changeColumnCount)
changeColumnCount()
return () => {
window.removeEventListener('resize', changeColumnCount)
}
}, [])
const changeColumnCount = throttle(() => {
if (window.innerWidth > 2500) {
changeColumn(5)
} else if (window.innerWidth > 1800) {
changeColumn(4)
} else if (window.innerWidth > 1300) {
changeColumn(3)
} else if (window.innerWidth > 900) {
changeColumn(2)
} else if (window.innerWidth <= 900) {
changeColumn(1)
}
}, 500)
const [column, changeColumn] = useState(3)
const { theme } = useTheme()
return (
<div id='wrapper' className={theme}>
<CommonHead meta={meta} />
<div className={`${BLOG.font} flex bg-gray-100 dark:bg-black min-h-screen`}>
<div className=' fixed w-full top-0 z-20'>
<TopNav />
</div>
<div className={`${BLOG.font} flex justify-between bg-gray-100 dark:bg-black min-h-screen`}>
{/* 侧边菜单 */}
<SideBar tags={tags} currentTag={currentTag} />
<main className='md:px-24 p-5 flex-grow'>
{(!page || page === 1) && (<div className='py-5' />)}
<SideBarResponsive />
{/* 标签 */}
{currentTag && (
<div className='pb-5 dark:text-gray-200'>
<div className='py-1'>标签: {currentTag}</div>
<hr />
</div>
)}
{/* 当前搜索 */}
{(currentSearch || (page && page !== 1)) && (
<div className='pb-5'>
<div className='dark:text-gray-200 flex justify-between py-1'>
{currentSearch && (<span>搜索关键词: {currentSearch}</span>)}
{page && page !== 1 && (<span> {page} / {totalPages}</span>)}
</div>
<hr />
</div>
)}
<div className='mx-auto'>
{/* 文章列表 */}
<div style={{ columnCount: column }}>
{!postsToShow.length && (
<p className='text-gray-500 dark:text-gray-300'>No posts found.</p>
)}
{postsToShow.map(post => (
<BlogPost key={post.id} post={post} tags={tags} />
))}
</div>
<Pagination page={page} showNext={showNext} />
<div className='flex-grow'>
<div className='fixed top-12 z-10 w-full border-b dark:border-gray-600'>
<Tags tags={tags} currentTag={currentTag} />
</div>
</main>
<main id='post-list-wrapper' className='py-24 px-8 md:px-20'>
{(!page || page === 1) && (<div className='py-5' />)}
{/* 当前搜索 */}
{(currentSearch || (page && page !== 1)) && (
<div className='pb-5'>
<div className='dark:text-gray-200 flex justify-between py-1'>
{page && page !== 1 && (<span> {page} / {totalPages}</span>)}
</div>
</div>
)}
<div className=''>
{/* 文章列表 */}
<div className='grid xl:grid-cols-3 lg:grid-cols-2 grid-cols-1 gap-3'>
{!postsToShow.length && (
<p className='text-gray-500 dark:text-gray-300'>No posts found.</p>
)}
{postsToShow.map(post => (
<BlogPost key={post.id} post={post} tags={tags} />
))}
</div>
<Pagination page={page} showNext={showNext} />
</div>
</main>
</div>
</div>
</div>
)

View File

@@ -109,12 +109,9 @@ nav {
@apply right-auto left-0 hidden lg:block z-10 !important
}
@media (max-width: 1300px){
.sidebar{
-ms-overflow-style: none;
overflow: -moz-scrollbars-none;
@apply border-r border-gray-200 h-screen overflow-y-scroll fixed left-0
}
.sidebar::-webkit-scrollbar { width: 0 !important }
.scroll-hidden{
-ms-overflow-style: none;
overflow: -moz-scrollbars-none;
}
.scroll-hidden::-webkit-scrollbar { width: 0 !important }