V2.0 重新排班

This commit is contained in:
tangly1024
2021-12-17 13:49:17 +08:00
parent 67c0959485
commit 9c38dae8aa
28 changed files with 215 additions and 77 deletions

View File

@@ -45,11 +45,11 @@ export default function ArticleDetail ({ post, blockMap, recommendPosts, prev, n
<Progress targetRef={targetRef} />
<div id="article-wrapper" ref={targetRef} className="flex-grow">
<div className="max-w-5xl mx-auto mt-16 xl:mt-32 w-screen md:w-full">
<div className="max-w-5xl mx-auto w-screen md:w-full ">
<article
itemScope
itemType="https://schema.org/Movie"
className="duration-300 hover:shadow-2xl pt-10 animate__fadeIn animate__animated subpixel-antialiased lg:pt-32 lg:px-52 px-5 py-2 dark:border-gray-700 bg-white dark:bg-gray-900"
className="rounded-xl shadow-md duration-300 hover:shadow-2xl animate__fadeIn animate__animated subpixel-antialiased lg:pt-32 py-10 lg:px-52 px-5 dark:border-gray-700 bg-white dark:bg-gray-900"
>
{post.type && !post.type.includes('Page') && post?.page_cover && (
<>
@@ -150,7 +150,7 @@ export default function ArticleDetail ({ post, blockMap, recommendPosts, prev, n
<section className="md:flex md:justify-between">
{post.tagItems && (
<div className="flex flex-nowrap leading-8 p-1 py-4 overflow-x-auto">
<div className="hidden md:block dark:text-gray-300">
<div className="hidden md:block dark:text-gray-300 whitespace-nowrap">
{locale.COMMON.TAGS}
</div>
{post.tagItems.map(tag => (
@@ -167,7 +167,7 @@ export default function ArticleDetail ({ post, blockMap, recommendPosts, prev, n
</article>
{/* 评论互动 */}
<div className="my-10 w-screen md:w-full overflow-x-auto dark:border-gray-700 bg-white dark:bg-gray-700">
<div className="mt-5 shadow-lg rounded-xl w-screen md:w-full overflow-x-auto dark:border-gray-700 bg-white dark:bg-gray-700">
<Comment frontMatter={post} />
</div>
</div>

View File

@@ -11,7 +11,7 @@ export default function BlogAround ({ prev, next }) {
if (!prev || !next) {
return <></>
}
return <section className='text-gray-800 mb-8 lg:mb-32 border-t dark:text-gray-300 px-5 flex flex-wrap lg:flex-nowrap lg:space-x-10 justify-between py-2'>
return <section className='text-gray-800 mb-8 lg:mb-32 border-t dark:text-gray-300 flex flex-wrap lg:flex-nowrap lg:space-x-10 justify-between py-2'>
<Link href={`/article/${prev.slug}`} passHref>
<a className='text-sm py-3 text-blue-500 hover:underline cursor-pointer'>
<FontAwesomeIcon icon={faAngleDoubleLeft} className='mr-1' />{prev.title}

View File

@@ -8,8 +8,8 @@ import TagItemMini from './TagItemMini'
const BlogPostCard = ({ post, tags }) => {
return (
<div key={post.id} className='flex md:flex-row flex-col-reverse justify-between hover:shadow-2xl shadow-md mb-14 duration-300 rounded-xl
w-full bg-white dark:bg-gray-800 dark:hover:bg-gray-700 dark:border-gray-600'>
<div key={post.id} className='flex md:flex-row flex-col-reverse justify-between hover:shadow-2xl shadow-md mb-8 duration-300 rounded-xl
w-full mx-2 bg-white dark:bg-gray-800 dark:hover:bg-gray-700 dark:border-gray-600'>
<div className='p-8 flex flex-col justify-between w-full'>
<Link href={`${BLOG.path}/article/${post.slug}`} passHref>
@@ -41,7 +41,7 @@ const BlogPostCard = ({ post, tags }) => {
{post?.page_cover && (
<Link href={`${BLOG.path}/article/${post.slug}`} passHref>
<div className='h-60 w-full md:max-w-sm relative rounded-t-xl md:rounded-t-none md:rounded-r-xl md:h-full duration-200 cursor-pointer transform overflow-hidden'>
<div className='h-60 w-full md:max-w-sm relative rounded-t-xl md:rounded-t-none md:rounded-r-xl md:h-full duration-200 cursor-pointer transform overflow-hidden'>
<Image className='hover:scale-105 transform duration-500 rounded-t-xl md:rounded-t-none md:rounded-r-xl' src={post?.page_cover} alt={post.title} layout='fill' objectFit='cover' loading='lazy' />
</div>
</Link>

View File

@@ -5,10 +5,8 @@
* @constructor
*/
const BlogPostListEmpty = ({ currentSearch }) => {
return <div className='min-h-screen flex justify-center mx-auto'>
<div className='text-center my-auto'>
return <div className='flex items-center justify-center min-h-screen mx-auto md:-mt-20'>
<p className='text-gray-500 dark:text-gray-300'>没有找到文章 {(currentSearch && <div>{currentSearch}</div>)}</p>
</div>
</div>
}
export default BlogPostListEmpty

View File

@@ -51,7 +51,7 @@ const BlogPostListScroll = ({ posts = [], tags, currentSearch, currentCategory,
if (!postsToShow || postsToShow.length === 0) {
return <BlogPostListEmpty currentSearch={currentSearch} />
} else {
return <div id='post-list-wrapper' className='mt-20 mx-2 lg:mx-20 xl:mx-52' ref={targetRef}>
return <div id='post-list-wrapper' className='mt-20 md:mt-0' ref={targetRef}>
{/* 文章列表 */}
<div className='flex flex-wrap'>

View File

@@ -4,21 +4,21 @@ import Link from 'next/link'
import React from 'react'
const CategoryGroup = ({ currentCategory, categories }) => {
return <div className='mt-3'>
<div id='category-list' className='dark:border-gray-600 dark:bg-gray-900 flex flex-wrap'>
return <>
<div id='category-list' className='dark:border-gray-600 dark:bg-gray-800 flex flex-wrap'>
{Object.keys(categories).map(category => {
const selected = currentCategory === category
return <Link key={category} href={`/category/${category}`} passHref>
<a className={(selected
? 'bg-gray-200 dark:bg-black text-black dark:text-white'
: 'dark:text-gray-400 text-gray-500') +
' duration-300 hover:text-blue-500 dark:hover:text-blue-400 hover:underline px-5 cursor-pointer pt-2 font-light'}>
<FontAwesomeIcon icon={selected ? faFolderOpen : faFolder} className={`${selected ? 'text-black dark:text-white' : 'text-gray-400'} mr-2`} />{category}({categories[category]})
? 'hover:text-white bg-blue-500 dark:bg-black text-white '
: 'dark:text-gray-400 text-gray-500 hover:text-blue-500 ') +
' text-sm w-full items-center duration-300 dark:hover:text-blue-400 hover:underline px-5 cursor-pointer py-1 font-light'}>
<FontAwesomeIcon icon={selected ? faFolderOpen : faFolder} className={`${selected ? 'text-white' : 'text-gray-400'} mr-2`} />{category}({categories[category]})
</a>
</Link>
})}
</div>
</div>
</>
}
export default CategoryGroup

View File

@@ -11,7 +11,7 @@ const CategoryList = ({ currentCategory, categories }) => {
const { locale } = useGlobal()
return <ul className='flex py-1 space-x-3'>
<li className='w-16 py-2 dark:text-gray-200'><FontAwesomeIcon className='mr-2' icon={faThList} />{locale.COMMON.CATEGORY}</li>
<li className='w-16 py-2 dark:text-gray-200 whitespace-nowrap'><FontAwesomeIcon className='mr-2' icon={faThList} />{locale.COMMON.CATEGORY}</li>
{Object.keys(categories).map(category => {
const selected = category === currentCategory
return (

View File

@@ -31,10 +31,10 @@ const LatestPostsGroup = ({ posts, sliceCount = 5 }) => {
const selected = currentPath === `${BLOG.path}/article/${post.slug}`
return (
<Link key={post.id} title={post.title} href={`${BLOG.path}/article/${post.slug}`} passHref>
<a className={(selected ? 'bg-gray-200 dark:bg-black ' : '') + ' my-1 px-5 flex font-light justify-between'}>
<a className={(selected ? 'bg-blue-500 dark:bg-black ' : '') + ' my-1 px-5 flex font-light justify-between'}>
<div className={ 'text-xs py-1 flex w-40 overflow-x-hidden whitespace-nowrap overflow-hidden ' +
'hover:text-blue-500 dark:hover:text-blue-400 cursor-pointer hover:underline ' +
(selected ? 'dark:text-white text-black ' : 'text-gray-500 dark:text-gray-300')
(selected ? 'text-white ' : 'text-gray-500 dark:text-gray-300')
}>
{post.title}
</div>

View File

@@ -2,7 +2,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faSpinner } from '@fortawesome/free-solid-svg-icons'
export default function LoadingCover () {
return (<div id="loading-cover" className={'bg-white dark:bg-gray-800 dark:text-white text-black animate__animated animate__fadeIn flex-grow flex flex-col justify-center z-10 w-full h-screen container mx-auto'}>
return (<div id="loading-cover" className={'md:-mt-20 dark:text-white text-black animate__animated animate__fadeIn flex-grow flex flex-col justify-center z-10 w-full h-screen container mx-auto'}>
<div className="mx-auto">
<FontAwesomeIcon icon={faSpinner} spin size='2x'/>
</div>

View File

@@ -23,14 +23,14 @@ const MenuButtonGroup = ({ allowCollapse = false }) => {
// { id: 9, icon: 'faTelegram', name: 'Telegram', to: 'https://t.me/tangly_1024', show: true }
]
return <nav id='nav'>
<div className='leading-8 text-gray-500 dark:text-gray-400'>
<div className='leading-8 text-gray-500 dark:text-gray-400 '>
{links.map(link => {
if (link.show) {
const selected = (router.pathname === link.to) || (router.asPath === link.to)
return <Link key={link.id + link.icon} title={link.to} href={link.to} >
<a className={'py-2 px-5 text-lg hover:bg-blue-400 hover:text-white hover:shadow-lg cursor-pointer duration-100 font-light flex flex-nowrap items-center ' +
<a className={'py-1 px-5 mx-2 hover:bg-blue-400 hover:text-white hover:shadow-lg cursor-pointer duration-100 font-light flex flex-nowrap items-center ' +
(selected ? 'bg-blue-500 text-white ' : ' ')} >
<div className='my-auto justify-center flex'>
<div className='my-auto justify-center flex '>
<FontAwesomeIcon icon={link.icon} />
</div>
<div className={'ml-4'}>{link.name}</div>

View File

@@ -43,8 +43,8 @@ const ShareBar = ({ post }) => {
return <>
<div
className='py-2 text-gray-500 text-center space-x-2 flex inline-block my-1 dark:text-gray-200 overflow-visible'>
<div className='hidden md:block text-gray-800 dark:text-gray-300 mr-2 my-2'>{locale.COMMON.SHARE}:</div>
className='py-2 text-gray-500 text-center space-x-2 flex my-1 dark:text-gray-200 overflow-visible'>
<div className='hidden md:block text-gray-800 dark:text-gray-300 mr-2 my-2 whitespace-nowrap'>{locale.COMMON.SHARE}:</div>
<div className='text-3xl cursor-pointer'>
<a className='text-blue-700' href={`https://www.facebook.com/sharer.php?u=${shareUrl}`} >
<FontAwesomeIcon icon={faFacebookSquare}/>

101
components/SideArea.js Normal file
View File

@@ -0,0 +1,101 @@
import React from 'react'
import MenuButtonGroup from '@/components/MenuButtonGroup'
import InfoCard from '@/components/InfoCard'
import TagGroups from '@/components/TagGroups'
import LatestPostsGroup from '@/components/LatestPostsGroup'
import CategoryGroup from '@/components/CategoryGroup'
import SearchInput from '@/components/SearchInput'
import Link from 'next/link'
import { useGlobal } from '@/lib/global'
import Toc from '@/components/Toc'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faAngleDoubleRight, faArchive, faTags, faThList } from '@fortawesome/free-solid-svg-icons'
/**
* 侧边平铺
* @param tags
* @param currentTag
* @param post
* @param posts
* @param categories
* @param currentCategory
* @param currentSearch
* @returns {JSX.Element}
* @constructor
*/
const SideArea = ({ title, tags, currentTag, post, posts, categories, currentCategory, currentSearch }) => {
const { locale } = useGlobal()
return <aside id='sidebar' className='w-72 z-10 scroll-hidden h-full'>
<section className='hidden lg:block bg-white dark:bg-gray-800 rounded-xl py-8 shadow-lg'>
<InfoCard />
</section>
<div className={(!post ? 'sticky top-2' : '') + ' pb-4'}>
{/* <hr className='dark:border-gray-700 mt-5 py-1' /> */}
<section className='hidden lg:block mt-5 py-4 rounded-xl shadow-lg bg-white dark:bg-gray-800'>
<MenuButtonGroup allowCollapse={true} />
<div className='px-5 pt-2'>
<SearchInput currentTag={currentTag} currentSearch={currentSearch} />
</div>
</section>
{/* 最新文章 */}
{posts && (
<section className='rounded-xl shadow-lg py-4 mt-5 bg-white dark:bg-gray-800'>
<div className='text-sm pb-2 px-5 flex flex-nowrap justify-between'>
<div className='font-light text-gray-600 dark:text-gray-200'><FontAwesomeIcon icon={faArchive} className='mr-2' />{locale.COMMON.LATEST_POSTS}</div>
</div>
<LatestPostsGroup posts={posts} />
</section>
)}
{/* 分类 */}
{categories && (
<section className='rounded-xl shadow-lg py-4 mt-5 bg-white dark:bg-gray-800'>
<div className='text-sm px-5 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>
<a className='text-gray-400 hover:text-black dark:text-gray-400 dark:hover:text-white hover:underline cursor-pointer'>
{locale.COMMON.MORE} <FontAwesomeIcon icon={faAngleDoubleRight} />
</a>
</Link>
</div>
<CategoryGroup currentCategory={currentCategory} categories={categories} />
</section>
)}
{/* 标签云 */}
{tags && (
<section className='rounded-xl shadow-lg py-4 mt-5 bg-white dark:bg-gray-800'>
<div className='text-sm pb-1 px-5 flex flex-nowrap justify-between font-light dark:text-gray-200'>
<div className='text-gray-600 dark:text-gray-200'><FontAwesomeIcon icon={faTags} className='mr-2'/>{locale.COMMON.TAGS}</div>
<Link href='/tag' passHref>
<a className='text-gray-400 hover:text-black dark:hover:text-white hover:underline cursor-pointer'>
{locale.COMMON.MORE} <FontAwesomeIcon icon={faAngleDoubleRight} />
</a>
</Link>
</div>
<div className='px-5 pt-2'>
<TagGroups tags={tags} currentTag={currentTag} />
</div>
</section>
)}
</div>
{post && (
<section id='left-toc' className='sticky pb-20 top-0 pt-2 rounded-xl shadow-lg bg-white dark:bg-gray-800'>
<div className='border-b text-2xl bg-white text-black 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>
)}
{/* <section id='blank' className='bg-white dark:bg-gray-800 py-20' /> */}
</aside>
}
export default SideArea

View File

@@ -0,0 +1,45 @@
import React, { useImperativeHandle, useState } from 'react'
import SideArea from './SideArea'
/**
* 侧边栏抽屉面板,可以从侧面拉出
* @returns {JSX.Element}
* @constructor
*/
const SideAreaDrawer = ({ post, currentTag, cRef, tags, posts, categories, currentCategory }) => {
// 暴露给父组件 通过cRef.current.handleMenuClick 调用
useImperativeHandle(cRef, () => {
return {
handleSwitchSideDrawerVisible: () => switchSideDrawerVisible()
}
})
const [isShow, changeHiddenStatus] = useState(false)
// 点击按钮更改侧边抽屉状态
const switchSideDrawerVisible = () => {
const showStatus = !isShow
changeHiddenStatus(showStatus)
if (window) {
const sideBarDrawer = window.document.getElementById('sidebar-drawer')
const sideBarDrawerBackground = window.document.getElementById('sidebar-drawer-background')
if (showStatus) {
sideBarDrawer.classList.replace('-ml-72', 'ml-2')
sideBarDrawerBackground.classList.replace('hidden', 'block')
} else {
sideBarDrawer.classList.replace('ml-2', '-ml-72')
sideBarDrawerBackground.classList.replace('block', 'hidden')
}
}
}
return <>
<div id='sidebar-drawer' className='-ml-72 flex flex-col duration-300 fixed h-full left-0 overflow-y-scroll scroll-hidden top-0 z-50'>
<SideArea tags={tags} post={post} posts={posts} categories={categories} currentCategory={currentCategory} />
</div>
{/* 背景蒙版 */}
<div id='sidebar-drawer-background'
className='hidden fixed top-0 left-0 z-30 w-full h-full bg-black bg-opacity-30'
onClick={switchSideDrawerVisible} />
</>
}
export default SideAreaDrawer

View File

@@ -8,20 +8,20 @@
const StickyBar = ({ children }) => {
if (!children) return <></>
return (
<div id='sticky-bar' className='fixed lg:top-0 top-14 duration-500 z-10 w-full border-b dark:border-gray-600 shadow-inner'>
<div className='bg-white dark:bg-gray-800 flex overflow-x-auto'>
<div className='z-30 sticky left-0 flex'>
<div className='pr-2 bg-white dark:bg-gray-800'/>
<div className='pr-3 -line-x-opacity bg-black'/>
<div id='sticky-bar' className='sticky flex justify-center top-0 duration-500 z-10 w-full'>
<div className='bg-white dark:bg-gray-800 dark:border-gray-600 w-full px-5 rounded-none md:rounded-xl shadow-xl border overflow-x-auto'>
<div className="flex">
<div className='z-30 absolute h-12 left-0 flex'>
<div className='pr-6 md:ml-5 -line-x-opacity'/>
</div>
<div id='tag-container' className="max-w-xs md:max-w-lg xl:max-w-2xl 2xl:max-w-5xl 3xl:max-w-6xl">
{ children }
</div>
<div className='z-30 absolute h-12 right-0 flex'>
<div className='pl-5 md:mr-5 line-x-opacity'/>
</div>
</div>
</div>
<div id='tag-container'>
{ children }
</div>
<div className='z-30 sticky right-0 flex'>
<div className='px-5 line-x-opacity'/>
<div className='px-2 bg-white dark:bg-gray-800'/>
</div>
</div>
</div>
)
}

View File

@@ -14,8 +14,8 @@ const TagList = ({ tags, currentTag }) => {
if (!tags) {
return <></>
}
return <ul className='flex py-1 space-x-3'>
<li className='w-20 py-2 dark:text-gray-200'><FontAwesomeIcon icon={faTags} className='mr-2'/>标签:</li>
return <ul className='flex py-1 space-x-3 overflow-x-scroll w-full'>
<li className='w-20 py-2 dark:text-gray-200 whitespace-nowrap'><FontAwesomeIcon icon={faTags} className='mr-2'/>标签:</li>
{tags.map(tag => {
const selected = tag.name === currentTag
return <TagItem key={tag.name} tag={tag} selected={selected}/>

View File

@@ -17,7 +17,7 @@ const TopNav = ({ tags, currentTag, post, posts, categories, currentCategory })
{/* 导航栏 */}
<div id='sticky-nav' className='flex fixed w-full top-0 z-20 transform duration-500 glassmorphism'>
<div className='w-full flex justify-between items-center p-4 shadow-lg '>
<div className='w-full flex justify-between items-center p-4 shadow'>
{/* 左侧LOGO 标题 */}
<div className='flex flex-none flex-grow-0'>
<div className='relative w-10' ><Image