mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-29 23:16:51 +00:00
Merge branch 'main' of https://github.com/tangly1024/NotionNext
This commit is contained in:
@@ -4,29 +4,33 @@ import CONFIG from '../config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { formatDateFmt } from '@/lib/formatDate'
|
||||
|
||||
export const ArticleInfo = (props) => {
|
||||
/**
|
||||
* 文章描述
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
export default function ArticleInfo (props) {
|
||||
const { post } = props
|
||||
|
||||
const { locale } = useGlobal()
|
||||
|
||||
return (
|
||||
<section className="flex-wrap flex mt-2 text-gray-400 dark:text-gray-400 font-light leading-8">
|
||||
<div>
|
||||
<h2
|
||||
className="blog-item-title mb-5 font-bold text-black text-xl md:text-2xl no-underline">
|
||||
{post?.title}
|
||||
</h2>
|
||||
<section className="mt-2 text-gray-600 dark:text-gray-400 leading-8">
|
||||
<h2
|
||||
className="blog-item-title mb-5 font-bold text-black text-xl md:text-2xl no-underline">
|
||||
{post?.title}
|
||||
</h2>
|
||||
|
||||
{post?.type !== 'Page' && (<>
|
||||
<div className="mb-4 text-sm text-gray-700 dark:text-gray-300">
|
||||
<div className='flex flex-wrap text-gray-700 dark:text-gray-300'>
|
||||
{post?.type !== 'Page' && (
|
||||
<div className="space-x-3 mr-4">
|
||||
<span> <i className="fa-regular fa-user"></i> <a href={siteConfig('SIMPLE_AUTHOR_LINK', null, CONFIG)}>{siteConfig('AUTHOR')}</a></span>
|
||||
<span> - <i className="fa-regular fa-clock"></i> {post?.publishDay}</span>
|
||||
{post?.category && <span> - <i className="fa-regular fa-folder"></i> <a href={`/category/${post?.category}`} className="hover:text-red-400 transition-all duration-200">{post?.category}</a></span>}
|
||||
<span> <i className="fa-regular fa-clock"></i> {post?.publishDay}</span>
|
||||
{post?.category && <span> <i className="fa-regular fa-folder"></i> <a href={`/category/${post?.category}`} className="hover:text-red-400 transition-all duration-200">{post?.category}</a></span>}
|
||||
{post?.tags && post?.tags?.length > 0 && post?.tags.map(t => <span key={t}> / <Link href={`/tag/${t}`}><span className=' hover:text-red-400 transition-all duration-200'>{t}</span></Link></span>)}
|
||||
</div>
|
||||
</>)}
|
||||
</div>)}
|
||||
|
||||
{post?.type !== 'Page' && (<>
|
||||
{post?.type !== 'Page' && (<div className=''>
|
||||
<span>{locale.COMMON.POST_TIME}:
|
||||
<Link
|
||||
href={`/archive#${formatDateFmt(post?.publishDate, 'yyyy-MM')}`}
|
||||
@@ -36,7 +40,7 @@ export const ArticleInfo = (props) => {
|
||||
</Link>
|
||||
</span>
|
||||
<span className='mr-2'>|</span>
|
||||
<span className='mx-2 text-gray-400 dark:text-gray-500'>
|
||||
<span className='mx-2 dark:text-gray-500'>
|
||||
{locale.COMMON.LAST_EDITED_TIME}: {post?.lastEditedDay}
|
||||
</span>
|
||||
<span className='mr-2'>|</span>
|
||||
@@ -45,10 +49,9 @@ export const ArticleInfo = (props) => {
|
||||
|
||||
<span className="mr-2 busuanzi_value_page_pv" />
|
||||
</span>
|
||||
</>)}
|
||||
</div>)}
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import { useEffect, useRef } from 'react'
|
||||
* @param validPassword(bool) 回调函数,校验正确回调入参为true
|
||||
* @returns
|
||||
*/
|
||||
export const ArticleLock = props => {
|
||||
export default function ArticleLock (props) {
|
||||
const { validPassword } = props
|
||||
const { locale } = useGlobal()
|
||||
|
||||
|
||||
@@ -3,43 +3,60 @@ import CONFIG from '../config'
|
||||
import TwikooCommentCount from '@/components/TwikooCommentCount'
|
||||
import { formatDateFmt } from '@/lib/formatDate'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
|
||||
export const BlogItem = props => {
|
||||
const { post } = props
|
||||
const showPageCover = siteConfig('SIMPLE_POST_COVER_ENABLE', false, CONFIG)
|
||||
|
||||
return <div key={post.id} className="h-42 my-6 pb-12 border-b dark:border-gray-800" >
|
||||
{/* 文章标题 */}
|
||||
|
||||
<h2 className="mb-2">
|
||||
<Link
|
||||
href={`${siteConfig('SUB_PATH', '')}/${post.slug}`}
|
||||
className="blog-item-title font-bold text-black text-2xl menu-link">
|
||||
{post.title}
|
||||
</Link>
|
||||
</h2>
|
||||
<div className='flex'>
|
||||
<div className='article-cover h-full'>
|
||||
{/* 图片封面 */}
|
||||
{showPageCover && (
|
||||
<div className="overflow-hidden mr-2 w-56 h-full">
|
||||
<Link href={`${siteConfig('SUB_PATH', '')}/${post.slug}`} passHref legacyBehavior>
|
||||
<LazyImage src={post?.pageCoverThumbnail} className='w-56 h-full object-cover object-center group-hover:scale-110 duration-500' />
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 文章信息 */}
|
||||
|
||||
<div className="mb-5 text-md text-gray-700 dark:text-gray-300 flex-wrap flex leading-6">
|
||||
<div className='space-x-2'>
|
||||
<span> <a href={siteConfig('SIMPLE_AUTHOR_LINK', null, CONFIG)} className='p-1 hover:text-red-400 transition-all duration-200'><i className="fa-regular fa-user"></i> {siteConfig('AUTHOR')}</a></span>
|
||||
<span>
|
||||
<Link className='p-1 hover:text-red-400 transition-all duration-200' href={`/archive#${formatDateFmt(post?.publishDate, 'yyyy-MM')}`}>
|
||||
<i className="fa-regular fa-clock" /> {post.date?.start_date || post.createdTime}
|
||||
<div className='article-info'>
|
||||
<h2 className="mb-2">
|
||||
<Link
|
||||
href={`${siteConfig('SUB_PATH', '')}/${post.slug}`}
|
||||
className="blog-item-title font-bold text-black text-2xl menu-link">
|
||||
{post.title}
|
||||
</Link>
|
||||
</span>
|
||||
<span><TwikooCommentCount post={post} /></span>
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
<div>
|
||||
{post.category && <Link href={`/category/${post.category}`} className='p-1'> <span className="hover:text-red-400 transition-all duration-200"><i className="fa-regular fa-folder mr-0.5"/>{post.category}</span></Link>}
|
||||
{post?.tags && post?.tags?.length > 0 && post?.tags.map(t => <Link key={t} href={`/tag/${t}`} className=' hover:text-red-400 transition-all duration-200'><span > /{t}</span></Link>)}
|
||||
</div>
|
||||
</div>
|
||||
{/* 文章信息 */}
|
||||
|
||||
<div className="text-gray-700 dark:text-gray-300 leading-normal mb-6">
|
||||
{post.summary}
|
||||
{post.summary && <span>...</span>}
|
||||
<div className="mb-5 text-md text-gray-700 dark:text-gray-300 flex-wrap flex leading-6">
|
||||
<div className='space-x-2'>
|
||||
<span> <a href={siteConfig('SIMPLE_AUTHOR_LINK', null, CONFIG)} className='p-1 hover:text-red-400 transition-all duration-200'><i className="fa-regular fa-user"></i> {siteConfig('AUTHOR')}</a></span>
|
||||
<span>
|
||||
<Link className='p-1 hover:text-red-400 transition-all duration-200' href={`/archive#${formatDateFmt(post?.publishDate, 'yyyy-MM')}`}>
|
||||
<i className="fa-regular fa-clock" /> {post.date?.start_date || post.createdTime}
|
||||
</Link>
|
||||
</span>
|
||||
<span><TwikooCommentCount post={post} /></span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{post.category && <Link href={`/category/${post.category}`} className='p-1'> <span className="hover:text-red-400 transition-all duration-200"><i className="fa-regular fa-folder mr-0.5" />{post.category}</span></Link>}
|
||||
{post?.tags && post?.tags?.length > 0 && post?.tags.map(t => <Link key={t} href={`/tag/${t}`} className=' hover:text-red-400 transition-all duration-200'><span > /{t}</span></Link>)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="text-gray-700 dark:text-gray-300 leading-normal mb-6">
|
||||
{post.summary}
|
||||
{post.summary && <span>...</span>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='block'>
|
||||
|
||||
@@ -6,7 +6,12 @@ import { AdSlot } from '@/components/GoogleAdsense'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import CONFIG from '../config'
|
||||
|
||||
export const BlogListPage = props => {
|
||||
/**
|
||||
* 博客列表
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
export default function BlogListPage(props) {
|
||||
const { page = 1, posts, postCount } = props
|
||||
const router = useRouter()
|
||||
const totalPage = Math.ceil(postCount / parseInt(siteConfig('POSTS_PER_PAGE')))
|
||||
|
||||
@@ -4,7 +4,12 @@ import throttle from 'lodash.throttle'
|
||||
import { BlogItem } from './BlogItem'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
|
||||
export const BlogListScroll = props => {
|
||||
/**
|
||||
* 滚动博客列表
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
export default function BlogListScroll (props) {
|
||||
const { posts } = props
|
||||
const { locale } = useGlobal()
|
||||
|
||||
|
||||
@@ -57,31 +57,33 @@ const Catalog = ({ post }) => {
|
||||
}
|
||||
|
||||
return <div className='px-3 '>
|
||||
<div className='dark:text-white'><i className='mr-1 fas fa-stream' />{locale.COMMON.TABLE_OF_CONTENTS}</div>
|
||||
<div className='dark:text-white mb-2'>
|
||||
<i className='mr-1 fas fa-stream' />{locale.COMMON.TABLE_OF_CONTENTS}
|
||||
</div>
|
||||
|
||||
<div className='overflow-y-auto overscroll-none max-h-36 lg:max-h-96 scroll-hidden' ref={tRef}>
|
||||
<nav className='h-full text-black'>
|
||||
{post?.toc?.map((tocItem) => {
|
||||
const id = uuidToId(tocItem.id)
|
||||
return (
|
||||
<a
|
||||
key={id}
|
||||
href={`#${id}`}
|
||||
className={`notion-table-of-contents-item duration-300 transform font-light dark:text-gray-200
|
||||
<div className='overflow-y-auto overscroll-none max-h-36 lg:max-h-96 scroll-hidden' ref={tRef}>
|
||||
<nav className='h-full text-black'>
|
||||
{post?.toc?.map((tocItem) => {
|
||||
const id = uuidToId(tocItem.id)
|
||||
return (
|
||||
<a
|
||||
key={id}
|
||||
href={`#${id}`}
|
||||
className={`notion-table-of-contents-item duration-300 transform dark:text-gray-200
|
||||
notion-table-of-contents-item-indent-level-${tocItem.indentLevel} `}
|
||||
>
|
||||
<span style={{ display: 'inline-block', marginLeft: tocItem.indentLevel * 16 }}
|
||||
className={`${activeSection === id && ' font-bold text-red-500 underline overflow-ellipsis truncate'}`}
|
||||
>
|
||||
{tocItem.text}
|
||||
</span>
|
||||
</a>
|
||||
)
|
||||
})}
|
||||
</nav>
|
||||
>
|
||||
<span style={{ display: 'inline-block', marginLeft: tocItem.indentLevel * 16 }}
|
||||
className={`${activeSection === id && ' font-bold text-red-600 underline overflow-ellipsis truncate'}`}
|
||||
>
|
||||
{tocItem.text}
|
||||
</span>
|
||||
</a>
|
||||
)
|
||||
})}
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
export default Catalog
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import DarkModeButton from '@/components/DarkModeButton'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
|
||||
export const Footer = (props) => {
|
||||
/**
|
||||
* 页脚
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
export default function Footer (props) {
|
||||
const d = new Date()
|
||||
const currentYear = d.getFullYear()
|
||||
const since = siteConfig('SINCE')
|
||||
|
||||
@@ -3,14 +3,15 @@ import Link from 'next/link'
|
||||
import CONFIG from '../config'
|
||||
import SocialButton from './SocialButton'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { compressImage } from '@/lib/notion/mapImage'
|
||||
|
||||
/**
|
||||
* 网站顶部
|
||||
* @returns
|
||||
*/
|
||||
export const Header = (props) => {
|
||||
export default function Header (props) {
|
||||
const { siteInfo } = props
|
||||
const avatar = siteInfo?.icon || siteConfig('AVATAR')
|
||||
const avatar = compressImage(siteInfo?.icon || siteConfig('AVATAR'), 200)
|
||||
|
||||
return (
|
||||
<header className="text-center justify-between items-center px-6 bg-white h-80 dark:bg-black relative z-10">
|
||||
@@ -18,8 +19,8 @@ export const Header = (props) => {
|
||||
<Link href='/'>
|
||||
{/* 可使用一张单图作为logo */}
|
||||
<div className='flex space-x-6'>
|
||||
<div className='hover:rotate-45 hover:scale-125 transform duration-200 cursor-pointer'>
|
||||
<LazyImage src={avatar} className='rounded-full' width={130} height={130} alt={siteConfig('AUTHOR')} />
|
||||
<div className='hover:rotate-45 hover:scale-125 transform duration-200 cursor-pointer justify-center items-center flex'>
|
||||
<LazyImage priority={true} src={avatar} className='rounded-full' width={100} height={100} alt={siteConfig('AUTHOR')} />
|
||||
</div>
|
||||
|
||||
<div className='flex-col flex justify-center'>
|
||||
|
||||
@@ -7,7 +7,7 @@ import { MenuList } from './MenuList'
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
export const NavBar = (props) => {
|
||||
export default function NavBar (props) {
|
||||
const [showSearchInput, changeShowSearchInput] = useState(false)
|
||||
const router = useRouter()
|
||||
|
||||
|
||||
@@ -3,7 +3,12 @@ import Live2D from '@/components/Live2D'
|
||||
import Announcement from './Announcement'
|
||||
import Catalog from './Catalog'
|
||||
|
||||
export const SideBar = (props) => {
|
||||
/**
|
||||
* 侧边栏
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
export default function SideBar (props) {
|
||||
const { notice } = props
|
||||
return (<>
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ import { siteConfig } from '@/lib/config'
|
||||
* @constructor
|
||||
*/
|
||||
const SocialButton = () => {
|
||||
return <div className='w-52 justify-center flex-wrap flex'>
|
||||
<div className='space-x-3 md:text-xl text-3xl text-gray-600 dark:text-gray-400 text-center'>
|
||||
return <div className='w-52 justify-center flex-wrap flex my-2'>
|
||||
<div className='space-x-5 md:text-xl text-3xl text-gray-600 dark:text-gray-400 text-center'>
|
||||
{siteConfig('CONTACT_GITHUB') && <a target='_blank' rel='noreferrer' title={'github'} href={siteConfig('CONTACT_GITHUB')} >
|
||||
<i className='fab fa-github transform hover:scale-125 duration-150'/>
|
||||
</a>}
|
||||
|
||||
@@ -5,11 +5,13 @@ import { siteConfig } from '@/lib/config'
|
||||
* 网站顶部 提示栏
|
||||
* @returns
|
||||
*/
|
||||
export const TopBar = (props) => {
|
||||
if (siteConfig('SIMPLE_TOP_BAR_CONTENT', null, CONFIG)) {
|
||||
export default function TopBar (props) {
|
||||
const content = siteConfig('SIMPLE_TOP_BAR_CONTENT', null, CONFIG)
|
||||
|
||||
if (content) {
|
||||
return <header className="flex justify-center items-center bg-black dark:bg-hexo-black-gray">
|
||||
<div id='top-bar-inner' className='max-w-9/10 w-full z-20'>
|
||||
<div className='text-xs text-center float-left text-white z-50 leading-5 py-2.5' dangerouslySetInnerHTML={{ __html: siteConfig('SIMPLE_TOP_BAR_CONTENT', null, CONFIG) }}/>
|
||||
<div className='text-xs text-center float-left text-white z-50 leading-5 py-2.5' dangerouslySetInnerHTML={{ __html: content }}/>
|
||||
</div>
|
||||
</header>
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ const CONFIG = {
|
||||
|
||||
SIMPLE_POST_AD_ENABLE: process.env.NEXT_PUBLIC_SIMPLE_POST_AD_ENABLE || false, // 文章列表是否插入广告
|
||||
|
||||
SIMPLE_POST_COVER_ENABLE: process.env.NEXT_PUBLIC_SIMPLE_POST_COVER_ENABLE || false, // 是否展示博客封面
|
||||
|
||||
// 菜单配置
|
||||
SIMPLE_MENU_CATEGORY: true, // 显示分类
|
||||
SIMPLE_MENU_TAG: true, // 显示标签
|
||||
|
||||
@@ -1,31 +1,35 @@
|
||||
import CONFIG from './config'
|
||||
import { BlogListPage } from './components/BlogListPage'
|
||||
import { BlogListScroll } from './components/BlogListScroll'
|
||||
import { useEffect } from 'react'
|
||||
import { isBrowser, loadExternalResource } from '@/lib/utils'
|
||||
import BlogArchiveItem from './components/BlogArchiveItem'
|
||||
import { ArticleLock } from './components/ArticleLock'
|
||||
import NotionPage from '@/components/NotionPage'
|
||||
import { ArticleInfo } from './components/ArticleInfo'
|
||||
import Comment from '@/components/Comment'
|
||||
import ArticleAround from './components/ArticleAround'
|
||||
import ShareBar from '@/components/ShareBar'
|
||||
import { AdSlot } from '@/components/GoogleAdsense'
|
||||
import Link from 'next/link'
|
||||
import { TopBar } from './components/TopBar'
|
||||
import { Header } from './components/Header'
|
||||
import { NavBar } from './components/NavBar'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { SideBar } from './components/SideBar'
|
||||
import JumpToTopButton from './components/JumpToTopButton'
|
||||
import { Footer } from './components/Footer'
|
||||
import { isBrowser } from '@/lib/utils'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import SearchInput from './components/SearchInput'
|
||||
import { AdSlot } from '@/components/GoogleAdsense'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { Transition } from '@headlessui/react'
|
||||
import Link from 'next/link'
|
||||
import { Style } from './style'
|
||||
import replaceSearchResult from '@/components/Mark'
|
||||
import CommonHead from '@/components/CommonHead'
|
||||
import WWAds from '@/components/WWAds'
|
||||
import dynamic from 'next/dynamic'
|
||||
import NotionPage from '@/components/NotionPage'
|
||||
// const NotionPage = dynamic(() => import('@/components/NotionPage'), { ssr: false });
|
||||
|
||||
// 主题组件
|
||||
const BlogListScroll = dynamic(() => import('./components/BlogListScroll'), { ssr: false });
|
||||
const BlogArchiveItem = dynamic(() => import('./components/BlogArchiveItem'), { ssr: false });
|
||||
const ArticleLock = dynamic(() => import('./components/ArticleLock'), { ssr: false });
|
||||
const ArticleInfo = dynamic(() => import('./components/ArticleInfo'), { ssr: false });
|
||||
const Comment = dynamic(() => import('@/components/Comment'), { ssr: false });
|
||||
const ArticleAround = dynamic(() => import('./components/ArticleAround'), { ssr: false });
|
||||
const ShareBar = dynamic(() => import('@/components/ShareBar'), { ssr: false });
|
||||
const TopBar = dynamic(() => import('./components/TopBar'), { ssr: false });
|
||||
const Header = dynamic(() => import('./components/Header'), { ssr: false });
|
||||
const NavBar = dynamic(() => import('./components/NavBar'), { ssr: false });
|
||||
const SideBar = dynamic(() => import('./components/SideBar'), { ssr: false });
|
||||
const JumpToTopButton = dynamic(() => import('./components/JumpToTopButton'), { ssr: false });
|
||||
const Footer = dynamic(() => import('./components/Footer'), { ssr: false });
|
||||
const SearchInput = dynamic(() => import('./components/SearchInput'), { ssr: false });
|
||||
const CommonHead = dynamic(() => import('@/components/CommonHead'), { ssr: false });
|
||||
const WWAds = dynamic(() => import('@/components/WWAds'), { ssr: false });
|
||||
const BlogListPage = dynamic(() => import('./components/BlogListPage'), { ssr: false })
|
||||
|
||||
/**
|
||||
* 基础布局
|
||||
@@ -37,9 +41,6 @@ const LayoutBase = props => {
|
||||
const { children, slotTop, meta } = props
|
||||
const { onLoading } = useGlobal()
|
||||
|
||||
if (isBrowser) {
|
||||
loadExternalResource('/css/theme-simple.css', 'css')
|
||||
}
|
||||
return (
|
||||
<div id='theme-simple' className='min-h-screen flex flex-col dark:text-gray-300 bg-white dark:bg-black'>
|
||||
{/* SEO相关 */}
|
||||
|
||||
Reference in New Issue
Block a user