mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-06-03 23:16:52 +00:00
heo 主题 一点点细节
This commit is contained in:
@@ -33,6 +33,9 @@ export default {
|
|||||||
COPYRIGHT: 'Copyright',
|
COPYRIGHT: 'Copyright',
|
||||||
AUTHOR: 'Author',
|
AUTHOR: 'Author',
|
||||||
URL: 'URL',
|
URL: 'URL',
|
||||||
|
NOW: 'NOW',
|
||||||
|
RECOMMEND_BADGES: 'Recommend',
|
||||||
|
BLOG: 'Blog',
|
||||||
POSTS: 'Posts',
|
POSTS: 'Posts',
|
||||||
ARTICLE: 'Article',
|
ARTICLE: 'Article',
|
||||||
VISITORS: 'Visitors',
|
VISITORS: 'Visitors',
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ export default {
|
|||||||
AUTHOR: '作者',
|
AUTHOR: '作者',
|
||||||
URL: '链接',
|
URL: '链接',
|
||||||
ANALYTICS: '统计',
|
ANALYTICS: '统计',
|
||||||
|
RECOMMEND_BADGES: '荐',
|
||||||
|
BLOG: '博客',
|
||||||
|
NOW: '此刻',
|
||||||
POSTS: '篇文章',
|
POSTS: '篇文章',
|
||||||
ARTICLE: '文章',
|
ARTICLE: '文章',
|
||||||
VISITORS: '位访客',
|
VISITORS: '位访客',
|
||||||
|
|||||||
@@ -1451,6 +1451,7 @@ code[class*='language-'] {
|
|||||||
|
|
||||||
.notion-collection-card-property .notion-page-title-text {
|
.notion-collection-card-property .notion-page-title-text {
|
||||||
border-bottom: 0 none;
|
border-bottom: 0 none;
|
||||||
|
@apply dark:text-gray-200;
|
||||||
}
|
}
|
||||||
|
|
||||||
.notion-collection-card-property
|
.notion-collection-card-property
|
||||||
|
|||||||
@@ -50,11 +50,11 @@ const BlogPostCard = ({ index, post, showSummary, siteInfo }) => {
|
|||||||
{/* 分类 */}
|
{/* 分类 */}
|
||||||
{post?.category && (
|
{post?.category && (
|
||||||
<div
|
<div
|
||||||
className={`flex mb-1 items-center ${showPreview ? 'justify-center' : 'justify-start'} hidden md:block flex-wrap dark:text-gray-500 text-gray-600 `}>
|
className={`flex mb-1 items-center ${showPreview ? 'justify-center' : 'justify-start'} hidden md:block flex-wrap dark:text-gray-300 text-gray-600 hover:text-indigo-700 dark:hover:text-yellow-500`}>
|
||||||
<Link
|
<Link
|
||||||
passHref
|
passHref
|
||||||
href={`/category/${post.category}`}
|
href={`/category/${post.category}`}
|
||||||
className='cursor-pointer text-xs font-normal menu-link hover:text-indigo-700 dark:hover:text-yellow-700 dark:text-gray-600 transform'>
|
className='cursor-pointer text-xs font-normal menu-link '>
|
||||||
{post.category}
|
{post.category}
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -29,23 +29,40 @@ export default function CategoryBar(props) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div id='category-bar' className={`flex flex-nowrap justify-between items-center h-12 mb-4 space-x-2 w-full lg:bg-white dark:lg:bg-[#1e1e1e]
|
return (
|
||||||
|
<div
|
||||||
|
id='category-bar'
|
||||||
|
className={`flex flex-nowrap justify-between items-center h-12 mb-4 space-x-2 w-full lg:bg-white dark:lg:bg-[#1e1e1e]
|
||||||
${border ? 'lg:border lg:hover:border dark:lg:border-gray-800 hover:border-indigo-600 dark:hover:border-yellow-600 ' : ''} py-2 lg:px-2 rounded-xl transition-colors duration-200`}>
|
${border ? 'lg:border lg:hover:border dark:lg:border-gray-800 hover:border-indigo-600 dark:hover:border-yellow-600 ' : ''} py-2 lg:px-2 rounded-xl transition-colors duration-200`}>
|
||||||
|
<div
|
||||||
|
id='category-bar-items'
|
||||||
|
ref={categoryBarItemsRef}
|
||||||
|
className='scroll-smooth max-w-4xl rounded-lg scroll-hidden flex justify-start flex-nowrap items-center overflow-x-scroll'>
|
||||||
|
<MenuItem href='/' name={locale.NAV.INDEX} />
|
||||||
|
{categoryOptions?.map((c, index) => (
|
||||||
|
<MenuItem key={index} href={`/category/${c.name}`} name={c.name} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id='category-bar-items' ref={categoryBarItemsRef} className='scroll-smooth max-w-4xl rounded-lg scroll-hidden flex justify-start flex-nowrap items-center overflow-x-scroll'>
|
<div id='category-bar-next' className='flex items-center justify-center'>
|
||||||
<MenuItem href='/' name={locale.NAV.INDEX} />
|
<div
|
||||||
{categoryOptions?.map((c, index) => <MenuItem key={index} href={`/category/${c.name}`} name={c.name} />)}
|
id='right'
|
||||||
</div>
|
className='cursor-pointer mx-2 dark:text-gray-300 dark:hover:text-yellow-600 hover:text-indigo-600'
|
||||||
|
onClick={handleToggleScroll}>
|
||||||
<div id='category-bar-next' className='flex items-center justify-center'>
|
{scrollRight ? (
|
||||||
<div id='right' className='cursor-pointer mx-2' onClick={handleToggleScroll}>
|
<ChevronDoubleLeft className={'w-5 h-5'} />
|
||||||
{scrollRight ? <ChevronDoubleLeft className={'w-5 h-5'} /> : <ChevronDoubleRight className={'w-5 h-5'} /> }
|
) : (
|
||||||
</div>
|
<ChevronDoubleRight className={'w-5 h-5'} />
|
||||||
<Link href='/category' className='whitespace-nowrap font-bold text-gray-900 dark:text-white transition-colors duration-200 hover:text-indigo-600'>
|
)}
|
||||||
{locale.MENU.CATEGORY}
|
|
||||||
</Link>
|
|
||||||
</div>
|
</div>
|
||||||
|
<Link
|
||||||
|
href='/category'
|
||||||
|
className='whitespace-nowrap font-bold text-gray-900 dark:text-white transition-colors duration-200 hover:text-indigo-600 dark:hover:text-yellow-600'>
|
||||||
|
{locale.MENU.CATEGORY}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,7 +74,10 @@ const MenuItem = ({ href, name }) => {
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { category } = router.query
|
const { category } = router.query
|
||||||
const selected = category === name
|
const selected = category === name
|
||||||
return <div className={`whitespace-nowrap mr-2 duration-200 transition-all font-bold px-2 py-0.5 rounded-md text-gray-900 dark:text-white hover:text-white hover:bg-indigo-600 dark:hover:bg-yellow-600 ${selected ? 'text-white bg-indigo-600 dark:bg-yellow-600' : ''}`}>
|
return (
|
||||||
<Link href={href}>{name}</Link>
|
<div
|
||||||
|
className={`whitespace-nowrap mr-2 duration-200 transition-all font-bold px-2 py-0.5 rounded-md text-gray-900 dark:text-white hover:text-white hover:bg-indigo-600 dark:hover:bg-yellow-600 ${selected ? 'text-white bg-indigo-600 dark:bg-yellow-600' : ''}`}>
|
||||||
|
<Link href={href}>{name}</Link>
|
||||||
</div>
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { ArrowSmallRight, PlusSmall } from '@/components/HeroIcons'
|
import { ArrowSmallRight, PlusSmall } from '@/components/HeroIcons'
|
||||||
import LazyImage from '@/components/LazyImage'
|
import LazyImage from '@/components/LazyImage'
|
||||||
import { siteConfig } from '@/lib/config'
|
import { siteConfig } from '@/lib/config'
|
||||||
|
import { useGlobal } from '@/lib/global'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import { useImperativeHandle, useRef, useState } from 'react'
|
import { useImperativeHandle, useRef, useState } from 'react'
|
||||||
@@ -206,6 +207,7 @@ function GroupMenu() {
|
|||||||
*/
|
*/
|
||||||
function TopGroup(props) {
|
function TopGroup(props) {
|
||||||
const { latestPosts, allNavPages, siteInfo } = props
|
const { latestPosts, allNavPages, siteInfo } = props
|
||||||
|
const { locale } = useGlobal()
|
||||||
const todayCardRef = useRef()
|
const todayCardRef = useRef()
|
||||||
function handleMouseLeave() {
|
function handleMouseLeave() {
|
||||||
todayCardRef.current.coverUp()
|
todayCardRef.current.coverUp()
|
||||||
@@ -238,7 +240,7 @@ function TopGroup(props) {
|
|||||||
</div>
|
</div>
|
||||||
{/* hover 悬浮的 ‘荐’ 字 */}
|
{/* hover 悬浮的 ‘荐’ 字 */}
|
||||||
<div className='opacity-0 group-hover:opacity-100 -translate-x-4 group-hover:translate-x-0 duration-200 transition-all absolute -top-2 -left-2 bg-indigo-600 dark:bg-yellow-600 text-white rounded-xl overflow-hidden pr-2 pb-2 pl-4 pt-4 text-xs'>
|
<div className='opacity-0 group-hover:opacity-100 -translate-x-4 group-hover:translate-x-0 duration-200 transition-all absolute -top-2 -left-2 bg-indigo-600 dark:bg-yellow-600 text-white rounded-xl overflow-hidden pr-2 pb-2 pl-4 pt-4 text-xs'>
|
||||||
荐
|
{locale.COMMON.RECOMMEND_BADGES}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
@@ -304,6 +306,7 @@ function getTopPosts({ latestPosts, allNavPages }) {
|
|||||||
function TodayCard({ cRef, siteInfo }) {
|
function TodayCard({ cRef, siteInfo }) {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const link = siteConfig('HEO_HERO_TITLE_LINK', null, CONFIG)
|
const link = siteConfig('HEO_HERO_TITLE_LINK', null, CONFIG)
|
||||||
|
const { locale } = useGlobal()
|
||||||
// 卡牌是否盖住下层
|
// 卡牌是否盖住下层
|
||||||
const [isCoverUp, setIsCoverUp] = useState(true)
|
const [isCoverUp, setIsCoverUp] = useState(true)
|
||||||
|
|
||||||
@@ -348,7 +351,7 @@ function TodayCard({ cRef, siteInfo }) {
|
|||||||
isCoverUp
|
isCoverUp
|
||||||
? 'opacity-100 cursor-pointer'
|
? 'opacity-100 cursor-pointer'
|
||||||
: 'opacity-0 transform scale-110 pointer-events-none'
|
: 'opacity-0 transform scale-110 pointer-events-none'
|
||||||
} shadow transition-all duration-200 today-card h-full bg-[#0E57D5] rounded-xl relative overflow-hidden flex items-end`}>
|
} shadow transition-all duration-200 today-card h-full bg-[#0E57D5] dark:bg-yellow-500 rounded-xl relative overflow-hidden flex items-end`}>
|
||||||
<div
|
<div
|
||||||
id='today-card-info'
|
id='today-card-info'
|
||||||
className='z-10 flex justify-between w-full relative text-white p-10 items-end'>
|
className='z-10 flex justify-between w-full relative text-white p-10 items-end'>
|
||||||
@@ -364,12 +367,14 @@ function TodayCard({ cRef, siteInfo }) {
|
|||||||
onClick={handleClickMore}
|
onClick={handleClickMore}
|
||||||
className={`'${
|
className={`'${
|
||||||
isCoverUp ? '' : 'hidden pointer-events-none '
|
isCoverUp ? '' : 'hidden pointer-events-none '
|
||||||
} flex items-center px-3 h-10 justify-center bg-[#425aef] hover:bg-[#4259efcb] transition-colors duration-100 rounded-3xl`}>
|
} flex items-center px-3 h-10 justify-center bg-[#425aef] hover:bg-[#4259efcb] dark:bg-yellow-500 dark:hover:bg-yellow-600 transition-colors duration-100 rounded-3xl`}>
|
||||||
<PlusSmall
|
<PlusSmall
|
||||||
className={'w-6 h-6 mr-2 bg-white rounded-full stroke-indigo-400'}
|
className={
|
||||||
|
'w-6 h-6 mr-2 bg-white rounded-full stroke-indigo-400 dark:stroke-yellow-400'
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<div id='more' className='select-none'>
|
<div id='more' className='select-none'>
|
||||||
更多推荐
|
{locale.COMMON.MORE}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -50,13 +50,13 @@ export default function LatestPostsGroupMini({ latestPosts, siteInfo }) {
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
(selected ? ' text-indigo-400 ' : 'dark:text-gray-400 ') +
|
(selected ? ' text-indigo-400 ' : 'dark:text-gray-200') +
|
||||||
' text-sm overflow-x-hidden hover:text-indigo-600 px-2 duration-200 w-full rounded ' +
|
' text-sm overflow-x-hidden hover:text-indigo-600 px-2 duration-200 w-full rounded ' +
|
||||||
' hover:text-indigo-400 cursor-pointer items-center flex'
|
' hover:text-indigo-400 dark:hover:text-yellow-600 cursor-pointer items-center flex'
|
||||||
}>
|
}>
|
||||||
<div>
|
<div>
|
||||||
<div className='line-clamp-2 menu-link'>{post.title}</div>
|
<div className='line-clamp-2 menu-link'>{post.title}</div>
|
||||||
<div className='text-gray-500'>{post.lastEditedDay}</div>
|
<div className='text-gray-400'>{post.lastEditedDay}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export const MenuItemCollapse = ({ link }) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className='select-none w-full px-2 py-2 border rounded-xl text-left dark:bg-hexo-black-gray'
|
className='select-none w-full p-2 border dark:border-gray-600 rounded-lg text-left dark:bg-[#1e1e1e]'
|
||||||
onClick={toggleShow}>
|
onClick={toggleShow}>
|
||||||
{!hasSubMenu && (
|
{!hasSubMenu && (
|
||||||
<Link
|
<Link
|
||||||
@@ -62,7 +62,7 @@ export const MenuItemCollapse = ({ link }) => {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
className='dark:bg-black dark:text-gray-200 text-left px-3 justify-start bg-gray-50 hover:bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200 py-3 pr-6'>
|
className='dark:bg-hexo-black-gray dark:text-gray-200 text-left px-3 justify-start bg-gray-50 hover:bg-gray-50 dark:hover:bg-gray-900 tracking-widest transition-all duration-200 py-3 pr-6'>
|
||||||
<Link href={sLink.href} target={link?.target}>
|
<Link href={sLink.href} target={link?.target}>
|
||||||
<span className='text-sm ml-4 whitespace-nowrap'>
|
<span className='text-sm ml-4 whitespace-nowrap'>
|
||||||
{link?.icon && <i className={sLink.icon + ' mr-2'} />}{' '}
|
{link?.icon && <i className={sLink.icon + ' mr-2'} />}{' '}
|
||||||
|
|||||||
@@ -36,12 +36,12 @@ export const MenuItemDrop = ({ link }) => {
|
|||||||
{hasSubMenu && (
|
{hasSubMenu && (
|
||||||
<ul
|
<ul
|
||||||
style={{ backdropFilter: 'blur(3px)' }}
|
style={{ backdropFilter: 'blur(3px)' }}
|
||||||
className={`${show ? 'visible opacity-100 top-14' : 'invisible opacity-0 top-20'} drop-shadow-md overflow-hidden rounded-xl bg-white transition-all duration-300 z-20 absolute`}>
|
className={`${show ? 'visible opacity-100 top-14' : 'invisible opacity-0 top-20'} drop-shadow-md overflow-hidden rounded-xl bg-white dark:bg-[#1e1e1e] border dark:border-gray-700 transition-all duration-300 z-20 absolute`}>
|
||||||
{link.subMenus.map((sLink, index) => {
|
{link.subMenus.map((sLink, index) => {
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
key={index}
|
key={index}
|
||||||
className='cursor-pointer hover:bg-blue-600 hover:text-white text-gray-900 tracking-widest transition-all duration-200 dark:border-gray-700 py-1 pr-6 pl-3'>
|
className='cursor-pointer hover:bg-blue-600 dark:hover:bg-yellow-600 hover:text-white text-gray-900 dark:text-gray-100 tracking-widest transition-all duration-200 dark:border-gray-700 py-1 pr-6 pl-3'>
|
||||||
<Link href={sLink.href} target={link?.target}>
|
<Link href={sLink.href} target={link?.target}>
|
||||||
<span className='text-sm text-nowrap font-extralight'>
|
<span className='text-sm text-nowrap font-extralight'>
|
||||||
{link?.icon && <i className={sLink?.icon}> </i>}
|
{link?.icon && <i className={sLink?.icon}> </i>}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export const MenuListSide = props => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav className='flex-col space-y-2'>
|
<nav className='flex-col space-y-1'>
|
||||||
{links?.map((link, index) => (
|
{links?.map((link, index) => (
|
||||||
<MenuItemCollapse key={index} link={link} />
|
<MenuItemCollapse key={index} link={link} />
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
|
|
||||||
import { ArrowRightCircle } from '@/components/HeroIcons'
|
import { ArrowRightCircle } from '@/components/HeroIcons'
|
||||||
|
import { siteConfig } from '@/lib/config'
|
||||||
|
import { useGlobal } from '@/lib/global'
|
||||||
import CONFIG from '../config'
|
import CONFIG from '../config'
|
||||||
import Swipe from './Swipe'
|
import Swipe from './Swipe'
|
||||||
import { siteConfig } from '@/lib/config'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通知横幅
|
* 通知横幅
|
||||||
*/
|
*/
|
||||||
export function NoticeBar() {
|
export function NoticeBar() {
|
||||||
let notices = siteConfig('HEO_NOTICE_BAR', null, CONFIG)
|
let notices = siteConfig('HEO_NOTICE_BAR', null, CONFIG)
|
||||||
|
const { locale } = useGlobal()
|
||||||
if (typeof notices === 'string') {
|
if (typeof notices === 'string') {
|
||||||
notices = JSON.parse(notices)
|
notices = JSON.parse(notices)
|
||||||
}
|
}
|
||||||
@@ -17,14 +18,16 @@ export function NoticeBar() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="max-w-[86rem] w-full mx-auto flex h-12 mb-4 px-5 font-bold">
|
<div className='max-w-[86rem] w-full mx-auto flex h-12 mb-4 px-5 font-bold'>
|
||||||
<div className="animate__animated animate__fadeIn animate__fast group cursor-pointer bg-white dark:bg-[#1e1e1e] dark:text-white hover:border-indigo-600 dark:hover:border-yellow-600 border dark:border-gray-700 duration-200 hover:shadow-md transition-all rounded-xl w-full h-full flex items-center justify-between px-5">
|
<div className='animate__animated animate__fadeIn animate__fast group cursor-pointer bg-white dark:bg-[#1e1e1e] dark:text-white hover:border-indigo-600 dark:hover:border-yellow-600 border dark:border-gray-700 duration-200 hover:shadow-md transition-all rounded-xl w-full h-full flex items-center justify-between px-5'>
|
||||||
<span className='whitespace-nowrap'>此刻</span>
|
<span className='whitespace-nowrap'>{locale.COMMON.NOW}</span>
|
||||||
<div className="w-full h-full hover:text-indigo-600 flex justify-center items-center">
|
<div className='w-full h-full hover:text-indigo-600 dark:hover:text-yellow-600 flex justify-center items-center'>
|
||||||
<Swipe items={notices} />
|
<Swipe items={notices} />
|
||||||
</div>
|
|
||||||
<div><ArrowRightCircle className={'w-5 h-5'} /></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<ArrowRightCircle className={'w-5 h-5'} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export default function PostHeader({ post, siteInfo, isDarkMode }) {
|
|||||||
}
|
}
|
||||||
// 文章头图
|
// 文章头图
|
||||||
const headerImage = post?.pageCover ? post.pageCover : siteInfo?.pageCover
|
const headerImage = post?.pageCover ? post.pageCover : siteInfo?.pageCover
|
||||||
|
const ANALYTICS_BUSUANZI_ENABLE = siteConfig('ANALYTICS_BUSUANZI_ENABLE')
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
id='post-bg'
|
id='post-bg'
|
||||||
@@ -67,7 +67,7 @@ export default function PostHeader({ post, siteInfo, isDarkMode }) {
|
|||||||
className='mr-4'
|
className='mr-4'
|
||||||
passHref
|
passHref
|
||||||
legacyBehavior>
|
legacyBehavior>
|
||||||
<div className='cursor-pointer font-sm font-bold px-3 py-1 rounded-lg bg-blue-500 hover:bg-white text-white hover:text-blue-500 duration-200 '>
|
<div className='cursor-pointer font-sm font-bold px-3 py-1 rounded-lg hover:bg-white text-white bg-blue-500 dark:bg-yellow-500 hover:text-blue-500 duration-200 '>
|
||||||
{post.category}
|
{post.category}
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
@@ -103,8 +103,8 @@ export default function PostHeader({ post, siteInfo, isDarkMode }) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 标题底部补充信息 */}
|
{/* 标题底部补充信息 */}
|
||||||
<section className='flex-wrap shadow-text-md flex text-sm justify-center md:justify-start mt-4 text-white dark:text-gray-400 font-light leading-8'>
|
<section className='flex-wrap dark:text-gray-200 text-opacity-70 shadow-text-md flex text-sm justify-center md:justify-start mt-4 text-white font-light leading-8'>
|
||||||
<div className='flex justify-center dark:text-gray-200 text-opacity-70'>
|
<div className='flex justify-center '>
|
||||||
<div className='mr-2'>
|
<div className='mr-2'>
|
||||||
<WordCount />
|
<WordCount />
|
||||||
</div>
|
</div>
|
||||||
@@ -126,7 +126,8 @@ export default function PostHeader({ post, siteInfo, isDarkMode }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{JSON.parse(siteConfig('ANALYTICS_BUSUANZI_ENABLE')) && (
|
{/* 阅读统计 */}
|
||||||
|
{ANALYTICS_BUSUANZI_ENABLE && (
|
||||||
<div className='busuanzi_container_page_pv font-light mr-2'>
|
<div className='busuanzi_container_page_pv font-light mr-2'>
|
||||||
<i className='fa-solid fa-fire-flame-curved'></i>{' '}
|
<i className='fa-solid fa-fire-flame-curved'></i>{' '}
|
||||||
<span className='mr-2 busuanzi_value_page_pv' />
|
<span className='mr-2 busuanzi_value_page_pv' />
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
|
|
||||||
import { Fragment, useImperativeHandle, useRef, useState } from 'react'
|
|
||||||
import { Dialog, Transition } from '@headlessui/react'
|
|
||||||
import DarkModeButton from '@/components/DarkModeButton'
|
import DarkModeButton from '@/components/DarkModeButton'
|
||||||
|
import { useGlobal } from '@/lib/global'
|
||||||
|
import { Dialog, Transition } from '@headlessui/react'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import TagGroups from './TagGroups'
|
import { useRouter } from 'next/router'
|
||||||
|
import {
|
||||||
|
Fragment,
|
||||||
|
useEffect,
|
||||||
|
useImperativeHandle,
|
||||||
|
useRef,
|
||||||
|
useState
|
||||||
|
} from 'react'
|
||||||
import { MenuListSide } from './MenuListSide'
|
import { MenuListSide } from './MenuListSide'
|
||||||
|
import TagGroups from './TagGroups'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 侧边抽屉
|
* 侧边抽屉
|
||||||
@@ -13,101 +20,105 @@ import { MenuListSide } from './MenuListSide'
|
|||||||
export default function SlideOver(props) {
|
export default function SlideOver(props) {
|
||||||
const { cRef, tagOptions } = props
|
const { cRef, tagOptions } = props
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
|
const { locale } = useGlobal()
|
||||||
|
const router = useRouter()
|
||||||
/**
|
/**
|
||||||
* 函数组件暴露方法useImperativeHandle
|
* 函数组件暴露方法useImperativeHandle
|
||||||
*/
|
**/
|
||||||
useImperativeHandle(cRef, () => ({
|
useImperativeHandle(cRef, () => ({
|
||||||
toggleSlideOvers: toggleSlideOvers
|
toggleSlideOvers: toggleSlideOvers
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开关侧拉抽屉
|
||||||
|
*/
|
||||||
const toggleSlideOvers = () => {
|
const toggleSlideOvers = () => {
|
||||||
setOpen(!open)
|
setOpen(!open)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动关闭抽屉
|
||||||
|
*/
|
||||||
|
useEffect(() => {
|
||||||
|
setOpen(false)
|
||||||
|
}, [router])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Transition.Root show={open} as={Fragment}>
|
<Transition.Root show={open} as={Fragment}>
|
||||||
<Dialog as="div" className="relative z-20" onClose={setOpen}>
|
<Dialog as='div' className='relative z-20' onClose={setOpen}>
|
||||||
<Transition.Child
|
<Transition.Child
|
||||||
|
as={Fragment}
|
||||||
|
enter='ease-in-out duration-500'
|
||||||
|
enterFrom='opacity-0'
|
||||||
|
enterTo='opacity-100'
|
||||||
|
leave='ease-in-out duration-500'
|
||||||
|
leaveFrom='opacity-100'
|
||||||
|
leaveTo='opacity-0'>
|
||||||
|
<div className='fixed inset-0 glassmorphism bg-black bg-opacity-30 transition-opacity' />
|
||||||
|
</Transition.Child>
|
||||||
|
|
||||||
|
<div className='fixed inset-0 overflow-hidden'>
|
||||||
|
<div className='absolute inset-0 overflow-hidden'>
|
||||||
|
<div className='pointer-events-none fixed inset-y-0 right-0 flex max-w-full pl-10'>
|
||||||
|
<Transition.Child
|
||||||
|
as={Fragment}
|
||||||
|
enter='transform transition ease-in-out duration-500 sm:duration-700'
|
||||||
|
enterFrom='translate-x-full'
|
||||||
|
enterTo='translate-x-0'
|
||||||
|
leave='transform transition ease-in-out duration-500 sm:duration-700'
|
||||||
|
leaveFrom='translate-x-0'
|
||||||
|
leaveTo='translate-x-full'>
|
||||||
|
<Dialog.Panel className='pointer-events-auto relative w-96 max-w-md'>
|
||||||
|
<Transition.Child
|
||||||
as={Fragment}
|
as={Fragment}
|
||||||
enter="ease-in-out duration-500"
|
enter='ease-in-out duration-500'
|
||||||
enterFrom="opacity-0"
|
enterFrom='opacity-0'
|
||||||
enterTo="opacity-100"
|
enterTo='opacity-100'
|
||||||
leave="ease-in-out duration-500"
|
leave='ease-in-out duration-500'
|
||||||
leaveFrom="opacity-100"
|
leaveFrom='opacity-100'
|
||||||
leaveTo="opacity-0"
|
leaveTo='opacity-0'>
|
||||||
>
|
<div className='absolute left-0 top-0 -ml-8 flex pr-2 pt-4 sm:-ml-10 sm:pr-4'>
|
||||||
<div className="fixed inset-0 glassmorphism bg-black bg-opacity-30 transition-opacity" />
|
<button
|
||||||
</Transition.Child>
|
type='button'
|
||||||
|
className='rounded-md text-gray-500 hover:text-white focus:outline-none focus:ring-2 focus:ring-white'
|
||||||
<div className="fixed inset-0 overflow-hidden">
|
onClick={() => setOpen(false)}>
|
||||||
<div className="absolute inset-0 overflow-hidden">
|
<span className='sr-only'>Close panel</span>
|
||||||
<div className="pointer-events-none fixed inset-y-0 right-0 flex max-w-full pl-10">
|
<i className='fa-solid fa-xmark px-2'></i>
|
||||||
<Transition.Child
|
</button>
|
||||||
as={Fragment}
|
|
||||||
enter="transform transition ease-in-out duration-500 sm:duration-700"
|
|
||||||
enterFrom="translate-x-full"
|
|
||||||
enterTo="translate-x-0"
|
|
||||||
leave="transform transition ease-in-out duration-500 sm:duration-700"
|
|
||||||
leaveFrom="translate-x-0"
|
|
||||||
leaveTo="translate-x-full"
|
|
||||||
>
|
|
||||||
<Dialog.Panel className="pointer-events-auto relative w-96 max-w-md">
|
|
||||||
<Transition.Child
|
|
||||||
as={Fragment}
|
|
||||||
enter="ease-in-out duration-500"
|
|
||||||
enterFrom="opacity-0"
|
|
||||||
enterTo="opacity-100"
|
|
||||||
leave="ease-in-out duration-500"
|
|
||||||
leaveFrom="opacity-100"
|
|
||||||
leaveTo="opacity-0"
|
|
||||||
>
|
|
||||||
<div className="absolute left-0 top-0 -ml-8 flex pr-2 pt-4 sm:-ml-10 sm:pr-4">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="rounded-md text-gray-500 hover:text-white focus:outline-none focus:ring-2 focus:ring-white"
|
|
||||||
onClick={() => setOpen(false)}
|
|
||||||
>
|
|
||||||
<span className="sr-only">Close panel</span>
|
|
||||||
<i className="fa-solid fa-xmark px-2"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</Transition.Child>
|
|
||||||
{/* 内容 */}
|
|
||||||
<div className="flex h-full flex-col overflow-y-scroll bg-white dark:bg-[#18171d] py-6 shadow-xl">
|
|
||||||
<div className="relative mt-6 flex-1 flex-col space-y-3 px-4 sm:px-6 dark:text-white ">
|
|
||||||
|
|
||||||
<section className='space-y-2 flex flex-col'>
|
|
||||||
<div>功能</div>
|
|
||||||
{/* 切换深色模式 */}
|
|
||||||
<DarkModeBlockButton />
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section className='space-y-2 flex flex-col'>
|
|
||||||
<div>博客</div>
|
|
||||||
{/* 导航按钮 */}
|
|
||||||
<div className='gap-2 grid grid-cols-2'>
|
|
||||||
<Button title={'主页'} url={'/'} />
|
|
||||||
<Button title={'关于'} url={'/about'} />
|
|
||||||
</div>
|
|
||||||
{/* 用户自定义菜单 */}
|
|
||||||
<MenuListSide {...props}/>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section className='space-y-2 flex flex-col'>
|
|
||||||
<div>标签</div>
|
|
||||||
<TagGroups tags={tagOptions} />
|
|
||||||
</section>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Dialog.Panel>
|
|
||||||
</Transition.Child>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Transition.Child>
|
||||||
</Dialog>
|
{/* 内容 */}
|
||||||
</Transition.Root>
|
<div className='flex h-full flex-col overflow-y-scroll bg-white dark:bg-[#18171d] py-6 shadow-xl'>
|
||||||
|
<div className='relative mt-6 flex-1 flex-col space-y-3 px-4 sm:px-6 dark:text-white '>
|
||||||
|
<section className='space-y-2 flex flex-col'>
|
||||||
|
{/* 切换深色模式 */}
|
||||||
|
<DarkModeBlockButton />
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className='space-y-2 flex flex-col'>
|
||||||
|
<div>{locale.COMMON.BLOG}</div>
|
||||||
|
{/* 导航按钮 */}
|
||||||
|
<div className='gap-2 grid grid-cols-2'>
|
||||||
|
<Button title={'主页'} url={'/'} />
|
||||||
|
<Button title={'关于'} url={'/about'} />
|
||||||
|
</div>
|
||||||
|
{/* 用户自定义菜单 */}
|
||||||
|
<MenuListSide {...props} />
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className='space-y-2 flex flex-col'>
|
||||||
|
<div>{locale.COMMON.TAGS}</div>
|
||||||
|
<TagGroups tags={tagOptions} />
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Dialog.Panel>
|
||||||
|
</Transition.Child>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
</Transition.Root>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,19 +127,34 @@ export default function SlideOver(props) {
|
|||||||
*/
|
*/
|
||||||
function DarkModeBlockButton() {
|
function DarkModeBlockButton() {
|
||||||
const darkModeRef = useRef()
|
const darkModeRef = useRef()
|
||||||
|
const { isDarkMode, locale } = useGlobal()
|
||||||
|
|
||||||
function handleChangeDarkMode() {
|
function handleChangeDarkMode() {
|
||||||
darkModeRef?.current?.handleChangeDarkMode()
|
darkModeRef?.current?.handleChangeDarkMode()
|
||||||
}
|
}
|
||||||
return <button onClick={handleChangeDarkMode} className={'group duration-200 hover:text-white hover:shadow-md hover:bg-blue-600 flex justify-between items-center px-2 py-2 border dark:border-gray-600 bg-white dark:bg-[#ff953e] rounded-lg'}>
|
return (
|
||||||
<DarkModeButton cRef={darkModeRef} className='group-hover:text-white' /> 显示模式
|
<button
|
||||||
|
onClick={handleChangeDarkMode}
|
||||||
|
className={
|
||||||
|
'group duration-200 hover:text-white hover:shadow-md hover:bg-blue-600 flex justify-between items-center px-2 py-2 border dark:border-gray-600 bg-white dark:bg-[#ff953e] rounded-lg'
|
||||||
|
}>
|
||||||
|
<DarkModeButton cRef={darkModeRef} className='group-hover:text-white' />{' '}
|
||||||
|
{isDarkMode ? locale.MENU.LIGHT_MODE : locale.MENU.DARK_MODE}
|
||||||
</button>
|
</button>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一个简单的按钮
|
* 一个简单的按钮
|
||||||
*/
|
*/
|
||||||
function Button({ title, url }) {
|
function Button({ title, url }) {
|
||||||
return <Link href={url} className={'duration-200 hover:text-white hover:shadow-md flex cursor-pointer justify-between items-center px-2 py-2 border dark:border-gray-600 bg-white hover:bg-blue-600 dark:bg-[#1e1e1e] rounded-lg'}>
|
return (
|
||||||
{title}
|
<Link
|
||||||
|
href={url}
|
||||||
|
className={
|
||||||
|
'duration-200 hover:text-white hover:shadow-md flex cursor-pointer justify-between items-center px-2 py-2 border dark:border-gray-600 bg-white hover:bg-blue-600 dark:bg-[#1e1e1e] rounded-lg'
|
||||||
|
}>
|
||||||
|
{title}
|
||||||
</Link>
|
</Link>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,13 @@ const TagItemMini = ({ tag, selected = false }) => {
|
|||||||
key={tag}
|
key={tag}
|
||||||
href={selected ? '/' : `/tag/${encodeURIComponent(tag.name)}`}
|
href={selected ? '/' : `/tag/${encodeURIComponent(tag.name)}`}
|
||||||
passHref
|
passHref
|
||||||
className={'cursor-pointer inline-block hover:text-white hover:bg-indigo-600 dark:hover:bg-yellow-600 px-2 py-1 rounded-2xl dark:text-white duration-200 text-sm whitespace-nowrap ' }>
|
className={
|
||||||
<div className='font-light flex items-center'><HashTag className='text-gray-500 stroke-2 mr-0.5 w-3 h-3'/> {tag.name + (tag.count ? `(${tag.count})` : '')} </div>
|
'cursor-pointer inline-block hover:text-white hover:bg-indigo-600 dark:hover:bg-yellow-600 px-2 py-1 rounded-2xl dark:text-white duration-200 text-sm whitespace-nowrap '
|
||||||
|
}>
|
||||||
|
<div className='font-light flex items-center'>
|
||||||
|
<HashTag className='stroke-2 mr-0.5 w-3 h-3' />{' '}
|
||||||
|
{tag.name + (tag.count ? `(${tag.count})` : '')}{' '}
|
||||||
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user