mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-13 23:16:47 +00:00
图片优化
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
'use client'
|
||||
|
||||
import BLOG from '@/blog.config'
|
||||
import { loadExternalResource } from '@/lib/utils'
|
||||
import { useEffect } from 'react'
|
||||
import { isBrowser, loadExternalResource } from '@/lib/utils'
|
||||
|
||||
/**
|
||||
* 自定义引入外部JS 和 CSS
|
||||
* @returns
|
||||
*/
|
||||
const ExternalScript = () => {
|
||||
useEffect(() => {
|
||||
if (isBrowser()) {
|
||||
// 静态导入本地自定义样式
|
||||
loadExternalResource(BLOG.FONT_AWESOME, 'css')
|
||||
loadExternalResource('/css/custom.css', 'css')
|
||||
@@ -30,10 +31,9 @@ const ExternalScript = () => {
|
||||
}
|
||||
// 渲染所有字体
|
||||
BLOG.FONT_URL?.forEach(e => {
|
||||
loadExternalResource(e, 'css')
|
||||
loadExternalResource(e, 'font')
|
||||
})
|
||||
}, [])
|
||||
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
@@ -28,9 +28,9 @@ const MyApp = ({ Component, pageProps }) => {
|
||||
|
||||
return (
|
||||
<GlobalContextProvider>
|
||||
<ExternalScript />
|
||||
<Component {...pageProps}/>
|
||||
<ExternalPlugins {...pageProps} />
|
||||
<ExternalScript />
|
||||
</GlobalContextProvider>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import BLOG from '@/blog.config'
|
||||
import CONFIG from '../config'
|
||||
import Link from 'next/link'
|
||||
import TwikooCommentCount from '@/components/TwikooCommentCount'
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
|
||||
const BlogPostCard = ({ post }) => {
|
||||
const showPageCover = CONFIG.POST_LIST_COVER && post?.pageCoverThumbnail
|
||||
@@ -41,7 +42,7 @@ const BlogPostCard = ({ post }) => {
|
||||
{showPageCover && (
|
||||
<div className="md:w-5/12 w-full overflow-hidden p-1">
|
||||
<Link href={`${BLOG.SUB_PATH}/${post.slug}`} passHref legacyBehavior>
|
||||
<div className='h-44 bg-center bg-cover hover:scale-110 duration-200' style={{ backgroundImage: `url('${post?.pageCoverThumbnail}')` }} />
|
||||
<LazyImage src={post?.pageCoverThumbnail} className='h-44 bg-center bg-cover hover:scale-110 duration-200' />
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -2,6 +2,7 @@ import Link from 'next/link'
|
||||
import CONFIG from '../config'
|
||||
import BLOG from '@/blog.config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
|
||||
/**
|
||||
* 关联推荐文章
|
||||
@@ -35,8 +36,8 @@ export default function ArticleRecommend({ recommendPosts, siteInfo }) {
|
||||
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
|
||||
{recommendPosts.map(post => {
|
||||
const headerImage = post?.pageCoverThumbnail
|
||||
? `url("${post.pageCoverThumbnail}")`
|
||||
: `url("${siteInfo?.pageCover}")`
|
||||
? post.pageCoverThumbnail
|
||||
: siteInfo?.pageCover
|
||||
|
||||
return (
|
||||
(<Link
|
||||
@@ -46,15 +47,13 @@ export default function ArticleRecommend({ recommendPosts, siteInfo }) {
|
||||
passHref
|
||||
className="flex h-40 cursor-pointer overflow-hidden rounded-2xl">
|
||||
|
||||
<div
|
||||
className="h-full w-full bg-cover bg-center bg-no-repeat hover:scale-110 transform duration-200"
|
||||
style={{ backgroundImage: headerImage }}
|
||||
>
|
||||
<div className="flex items-center justify-center bg-black bg-opacity-70 hover:bg-opacity-30 w-full h-full duration-300 ">
|
||||
<div className="text-lg px-4 font-bold text-white text-center shadow-text">
|
||||
<div className="h-full w-full relative group">
|
||||
<div className="flex items-center justify-center w-full h-full duration-300 ">
|
||||
<div className="z-10 text-lg px-4 font-bold text-white text-center shadow-text select-none">
|
||||
{post.title}
|
||||
</div>
|
||||
</div>
|
||||
<LazyImage src={headerImage} className='absolute top-0 w-full h-full object-cover object-center group-hover:scale-110 group-hover:brightness-50 transform duration-200'/>
|
||||
</div>
|
||||
|
||||
</Link>)
|
||||
|
||||
@@ -3,6 +3,7 @@ import Link from 'next/link'
|
||||
import BLOG from '@/blog.config'
|
||||
import CONFIG from '../config'
|
||||
import TagItemMini from './TagItemMini'
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
/**
|
||||
* 博客归档列表
|
||||
* @param posts 所有文章
|
||||
@@ -29,13 +30,13 @@ const BlogPostArchive = ({ posts = [], archiveTitle, siteInfo }) => {
|
||||
post.pageCoverThumbnail = siteInfo?.pageCover
|
||||
}
|
||||
const showPageCover = CONFIG.POST_LIST_COVER && post?.pageCoverThumbnail && !showPreview
|
||||
return <div key={post.id} className={'cursor-pointer flex flex-row mb-4 h-20 md:flex-row group w-full dark:border-gray-600 hover:border-indigo-600 dark:hover:border-yellow-600 duration-300 transition-colors justify-between overflow-hidden'}>
|
||||
return <div key={post.id} className={'cursor-pointer flex flex-row mb-4 h-24 md:flex-row group w-full dark:border-gray-600 hover:border-indigo-600 dark:hover:border-yellow-600 duration-300 transition-colors justify-between overflow-hidden'}>
|
||||
|
||||
{/* 图片封面 */}
|
||||
{showPageCover && (
|
||||
<div>
|
||||
<Link href={`${BLOG.SUB_PATH}/${post.slug}`} passHref legacyBehavior>
|
||||
<div className={'rounded-xl bg-center bg-cover w-40 h-20'} style={{ backgroundImage: `url('${post?.pageCoverThumbnail}')` }} />
|
||||
<LazyImage className={'rounded-xl bg-center bg-cover w-40 h-24'} src={post?.pageCoverThumbnail}/>
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
@@ -44,7 +45,7 @@ const BlogPostArchive = ({ posts = [], archiveTitle, siteInfo }) => {
|
||||
<div className={'flex px-2 flex-col justify-between w-full'}>
|
||||
<div>
|
||||
{/* 分类 */}
|
||||
{post?.category && <div className={`flex mb-1 items-center ${showPreview ? 'justify-center' : 'justify-start'} hidden md:block flex-wrap dark:text-gray-500 text-gray-600 `}>
|
||||
{post?.category && <div className={`flex items-center ${showPreview ? 'justify-center' : 'justify-start'} hidden md:block flex-wrap dark:text-gray-500 text-gray-600 `}>
|
||||
<Link passHref href={`/category/${post.category}`}
|
||||
className="cursor-pointer text-xs font-normal menu-link hover:text-indigo-700 dark:text-gray-600 transform">
|
||||
{post.category}
|
||||
@@ -61,9 +62,9 @@ const BlogPostArchive = ({ posts = [], archiveTitle, siteInfo }) => {
|
||||
</div>
|
||||
|
||||
{/* 摘要 */}
|
||||
<p className="line-clamp-2 replace my-3 2xl:my-1 text-gray-700 dark:text-gray-300 text-sm font-light leading-tight">
|
||||
{/* <p className="line-clamp-1 replace my-3 2xl:my-0 text-gray-700 dark:text-gray-300 text-xs font-light leading-tight">
|
||||
{post.summary}
|
||||
</p>
|
||||
</p> */}
|
||||
|
||||
<div className="md:flex-nowrap flex-wrap md:justify-start inline-block">
|
||||
<div>
|
||||
|
||||
@@ -29,7 +29,7 @@ export const MenuItemDrop = ({ link }) => {
|
||||
{/* 子菜单 */}
|
||||
{hasSubMenu && <ul 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`}>
|
||||
{link.subMenus.map((sLink, index) => {
|
||||
return <li key={index} className='cursor-pointer hover:bg-indigo-300 text-gray-900 hover:text-black tracking-widest transition-all duration-200 dark:border-gray-700 py-1 pr-6 pl-3'>
|
||||
return <li 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'>
|
||||
<Link href={sLink.to}>
|
||||
<span className='text-sm text-nowrap font-extralight'>{link?.icon && <i className={sLink?.icon} > </i>}{sLink.title}</span>
|
||||
</Link>
|
||||
|
||||
@@ -12,7 +12,7 @@ const Style = () => {
|
||||
}
|
||||
|
||||
// 公告栏中的字体固定白色
|
||||
#announcement-content .notion{
|
||||
#theme-heo #announcement-content .notion{
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import Link from 'next/link'
|
||||
import CONFIG from '../config'
|
||||
import BLOG from '@/blog.config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
|
||||
/**
|
||||
* 关联推荐文章
|
||||
@@ -13,53 +14,47 @@ export default function ArticleRecommend({ recommendPosts, siteInfo }) {
|
||||
|
||||
if (
|
||||
!CONFIG.ARTICLE_RECOMMEND ||
|
||||
!recommendPosts ||
|
||||
recommendPosts.length === 0
|
||||
!recommendPosts ||
|
||||
recommendPosts.length === 0
|
||||
) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="pt-8">
|
||||
<div className=" mb-2 px-1 flex flex-nowrap justify-between">
|
||||
<div className='dark:text-gray-300'>
|
||||
<i className="mr-2 fas fa-thumbs-up" />
|
||||
{locale.COMMON.RELATE_POSTS}
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
|
||||
{recommendPosts.map(post => {
|
||||
const headerImage = post?.pageCoverThumbnail
|
||||
? `url("${post.pageCoverThumbnail}")`
|
||||
: `url("${siteInfo?.pageCover}")`
|
||||
|
||||
return (
|
||||
(<Link
|
||||
key={post.id}
|
||||
title={post.title}
|
||||
href={`${BLOG.SUB_PATH}/${post.slug}`}
|
||||
passHref
|
||||
className="flex h-40 cursor-pointer overflow-hidden">
|
||||
|
||||
<div
|
||||
className="h-full w-full bg-cover bg-center bg-no-repeat hover:scale-110 transform duration-200"
|
||||
style={{ backgroundImage: headerImage }}
|
||||
>
|
||||
<div className="flex items-center justify-center bg-black bg-opacity-60 hover:bg-opacity-10 w-full h-full duration-300 ">
|
||||
<div className=" text-sm text-white text-center shadow-text">
|
||||
<div>
|
||||
<i className="fas fa-calendar-alt mr-1" />
|
||||
{post.date?.start_date}
|
||||
</div>
|
||||
<div className="">{post.title}</div>
|
||||
</div>
|
||||
<div className="pt-8">
|
||||
<div className=" mb-2 px-1 flex flex-nowrap justify-between">
|
||||
<div className='dark:text-gray-300'>
|
||||
<i className="mr-2 fas fa-thumbs-up" />
|
||||
{locale.COMMON.RELATE_POSTS}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
|
||||
{recommendPosts.map(post => {
|
||||
const headerImage = post?.pageCoverThumbnail
|
||||
? post.pageCoverThumbnail
|
||||
: siteInfo?.pageCover
|
||||
|
||||
</Link>)
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
return (
|
||||
(<Link
|
||||
key={post.id}
|
||||
title={post.title}
|
||||
href={`${BLOG.SUB_PATH}/${post.slug}`}
|
||||
passHref
|
||||
className="flex h-40 cursor-pointer overflow-hidden">
|
||||
|
||||
<div className="h-full w-full relative group">
|
||||
<div className="flex items-center justify-center w-full h-full duration-300 ">
|
||||
<div className="z-10 text-lg px-4 font-bold text-white text-center shadow-text select-none">
|
||||
{post.title}
|
||||
</div>
|
||||
</div>
|
||||
<LazyImage src={headerImage} className='absolute top-0 w-full h-full object-cover object-center group-hover:scale-110 group-hover:brightness-50 transform duration-200' />
|
||||
</div>
|
||||
|
||||
</Link>)
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import React from 'react'
|
||||
import CONFIG from '../config'
|
||||
import { BlogPostCardInfo } from './BlogPostCardInfo'
|
||||
import BLOG from '@/blog.config'
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
// import Image from 'next/image'
|
||||
|
||||
const BlogPostCard = ({ index, post, showSummary, siteInfo }) => {
|
||||
@@ -16,15 +17,14 @@ const BlogPostCard = ({ index, post, showSummary, siteInfo }) => {
|
||||
return (
|
||||
|
||||
<div className={`${CONFIG.POST_LIST_COVER_HOVER_ENLARGE ? ' hover:scale-110 transition-all duration-150' : ''}`} >
|
||||
<div
|
||||
<div key={post.id}
|
||||
data-aos="fade-up"
|
||||
data-aos-easing="ease-in-out"
|
||||
data-aos-duration="800"
|
||||
data-aos-once="false"
|
||||
data-aos-anchor-placement="top-bottom"
|
||||
id='blog-post-card'
|
||||
key={post.id}
|
||||
className={`md:h-56 w-full flex justify-between md:flex-row flex-col-reverse ${CONFIG.POST_LIST_IMG_CROSSOVER && index % 2 === 1 ? 'md:flex-row-reverse' : ''}
|
||||
className={`group md:h-56 w-full flex justify-between md:flex-row flex-col-reverse ${CONFIG.POST_LIST_IMG_CROSSOVER && index % 2 === 1 ? 'md:flex-row-reverse' : ''}
|
||||
overflow-hidden border dark:border-black rounded-xl bg-white dark:bg-hexo-black-gray`}>
|
||||
|
||||
{/* 文字内容 */}
|
||||
@@ -34,7 +34,7 @@ const BlogPostCard = ({ index, post, showSummary, siteInfo }) => {
|
||||
{showPageCover && (
|
||||
<div className="md:w-5/12 overflow-hidden">
|
||||
<Link href={`${BLOG.SUB_PATH}/${post.slug}`} passHref legacyBehavior>
|
||||
<div className='h-56 bg-center bg-cover hover:scale-110 duration-200' style={{ backgroundImage: `url('${post?.pageCoverThumbnail}')` }} />
|
||||
<LazyImage priority={index === 1} src={post?.pageCoverThumbnail} className='h-56 w-full object-cover object-center group-hover:scale-110 duration-500' />
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -5,6 +5,7 @@ import CONFIG from '../config'
|
||||
import NavButtonGroup from './NavButtonGroup'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import BLOG from '@/blog.config'
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
|
||||
let wrapperTop = 0
|
||||
|
||||
@@ -72,8 +73,8 @@ const Hero = props => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id='header-cover' style={{ backgroundImage: `url('${siteInfo?.pageCover}')` }}
|
||||
className={`header-cover bg-center w-full h-screen bg-cover ${CONFIG.HOME_NAV_BACKGROUND_IMG_FIXED ? 'bg-fixed' : ''}`} />
|
||||
<LazyImage id='header-cover' src={siteInfo?.pageCover}
|
||||
className={`header-cover w-full h-screen object-cover object-center ${CONFIG.HOME_NAV_BACKGROUND_IMG_FIXED ? 'fixed' : ''}`} />
|
||||
|
||||
</header>
|
||||
)
|
||||
|
||||
@@ -3,6 +3,7 @@ import TagItemMini from './TagItemMini'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import BLOG from '@/blog.config'
|
||||
import NotionIcon from '@/components/NotionIcon'
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
|
||||
export default function PostHeader({ post, siteInfo }) {
|
||||
const { locale } = useGlobal()
|
||||
@@ -10,14 +11,12 @@ export default function PostHeader({ post, siteInfo }) {
|
||||
if (!post) {
|
||||
return <></>
|
||||
}
|
||||
const headerImage = post?.pageCover ? `url("${post.pageCover}")` : `url("${siteInfo?.pageCover}")`
|
||||
const headerImage = post?.pageCover ? post.pageCover : siteInfo?.pageCover
|
||||
|
||||
return (
|
||||
<div
|
||||
id="header"
|
||||
className="w-full h-96 relative md:flex-shrink-0 overflow-hidden bg-cover bg-center bg-no-repeat z-10"
|
||||
style={{ backgroundImage: headerImage }}
|
||||
>
|
||||
<div id="header" className="w-full h-96 relative md:flex-shrink-0 z-10" >
|
||||
<LazyImage priority={true} src={headerImage} className='w-full h-full object-cover object-center absolute top-0'/>
|
||||
|
||||
<header id='article-header-cover'
|
||||
className="bg-black bg-opacity-70 absolute top-0 w-full h-96 py-10 flex justify-center items-center ">
|
||||
|
||||
|
||||
@@ -59,9 +59,9 @@ const LayoutBase = props => {
|
||||
appear={true}
|
||||
enter="transition ease-in-out duration-700 transform order-first"
|
||||
enterFrom="opacity-0 -translate-y-16"
|
||||
enterTo="opacity-100 translate-y-0"
|
||||
enterTo="opacity-100"
|
||||
leave="transition ease-in-out duration-300 transform"
|
||||
leaveFrom="opacity-100 translate-y-0"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0 translate-y-16"
|
||||
unmount={false}
|
||||
>
|
||||
|
||||
@@ -2,6 +2,7 @@ import Link from 'next/link'
|
||||
import CONFIG from '../config'
|
||||
import BLOG from '@/blog.config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
|
||||
/**
|
||||
* 关联推荐文章
|
||||
@@ -13,53 +14,53 @@ export default function ArticleRecommend({ recommendPosts, siteInfo }) {
|
||||
|
||||
if (
|
||||
!CONFIG.ARTICLE_RECOMMEND ||
|
||||
!recommendPosts ||
|
||||
recommendPosts.length === 0
|
||||
!recommendPosts ||
|
||||
recommendPosts.length === 0
|
||||
) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="p-2">
|
||||
<div className=" mb-2 px-1 flex flex-nowrap justify-between">
|
||||
<div>
|
||||
<i className="mr-2 fas fa-thumbs-up" />
|
||||
{locale.COMMON.RELATE_POSTS}
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
|
||||
{recommendPosts.map(post => {
|
||||
const headerImage = post?.pageCoverThumbnail
|
||||
? `url("${post.pageCoverThumbnail}")`
|
||||
: `url("${siteInfo?.pageCover}")`
|
||||
|
||||
return (
|
||||
(<Link
|
||||
key={post.id}
|
||||
title={post.title}
|
||||
href={`${BLOG.SUB_PATH}/${post.slug}`}
|
||||
passHref
|
||||
className="flex h-40 cursor-pointer overflow-hidden">
|
||||
|
||||
<div
|
||||
className="h-full w-full bg-cover bg-center bg-no-repeat hover:scale-110 transform duration-200"
|
||||
style={{ backgroundImage: headerImage }}
|
||||
>
|
||||
<div className="flex items-center justify-center bg-black bg-opacity-60 hover:bg-opacity-10 w-full h-full duration-300 ">
|
||||
<div className=" text-sm text-white text-center shadow-text">
|
||||
<div>
|
||||
<i className="fas fa-calendar-alt mr-1" />
|
||||
{post.date?.start_date}
|
||||
</div>
|
||||
<div className="hover:underline">{post.title}</div>
|
||||
</div>
|
||||
<div className="p-2">
|
||||
<div className="mb-2 px-1 flex flex-nowrap justify-between">
|
||||
<div>
|
||||
<i className="mr-2 fas fa-thumbs-up" />
|
||||
{locale.COMMON.RELATE_POSTS}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
|
||||
{recommendPosts.map(post => {
|
||||
const headerImage = post?.pageCoverThumbnail
|
||||
? post.pageCoverThumbnail
|
||||
: siteInfo?.pageCover
|
||||
|
||||
</Link>)
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
return (
|
||||
(<Link
|
||||
key={post.id}
|
||||
title={post.title}
|
||||
href={`${BLOG.SUB_PATH}/${post.slug}`}
|
||||
passHref
|
||||
className="flex h-40 cursor-pointer overflow-hidden">
|
||||
|
||||
<div className="h-full w-full group" >
|
||||
|
||||
<LazyImage src={headerImage} className="h-full w-full object-cover object-center group-hover:scale-110 transform duration-200" />
|
||||
|
||||
<div className="flex items-center justify-center bg-black bg-opacity-60 hover:bg-opacity-10 w-full h-full duration-300 ">
|
||||
<div className="text-sm text-white text-center shadow-text">
|
||||
<div>
|
||||
<i className="fas fa-calendar-alt mr-1" />
|
||||
{post.date?.start_date}
|
||||
</div>
|
||||
<div className="hover:underline">{post.title}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</Link>)
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -22,23 +22,21 @@ const BlogPostCard = ({ index, post, showSummary, siteInfo }) => {
|
||||
data-aos-delay={delay}
|
||||
data-aos-once="true"
|
||||
data-aos-anchor-placement="top-bottom"
|
||||
className="w-full mb-4 overflow-auto shadow-md border dark:border-black rounded-xl bg-white dark:bg-hexo-black-gray">
|
||||
className="w-full mb-4 overflow-hidden shadow-md border dark:border-black rounded-xl bg-white dark:bg-hexo-black-gray">
|
||||
|
||||
{/* 固定高度 ,空白用图片拉升填充 */}
|
||||
<div className="flex flex-col h-80 justify-between">
|
||||
<div className="group flex flex-col h-80 justify-between">
|
||||
|
||||
{/* 头部图片 填充卡片 */}
|
||||
{showPageCover && (
|
||||
<Link href={`${BLOG.SUB_PATH}/${post.slug}`} passHref legacyBehavior>
|
||||
<div
|
||||
className="flex flex-grow w-full relative duration-200 bg-black rounded-t-md cursor-pointer transform overflow-hidden">
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<div className="flex flex-grow w-full relative duration-200 = rounded-t-md cursor-pointer transform overflow-hidden">
|
||||
<LazyImage
|
||||
src={post?.pageCoverThumbnail}
|
||||
alt={post.title}
|
||||
className="opacity-50 h-full w-full hover:scale-125 rounded-t-md transform object-cover duration-500"
|
||||
className="h-full w-full group-hover:scale-125 group-hover:brightness-50 brightness-90 rounded-t-md transform object-cover duration-500"
|
||||
/>
|
||||
<span className='absolute bottom-0 left-0 text-white p-6 text-2xl replace break-words w-full' > {post.title}</span>
|
||||
<div className='absolute bottom-0 left-0 text-white p-6 text-2xl replace break-words w-full shadow-text'>{post.title}</div>
|
||||
</div>
|
||||
</Link>
|
||||
)}
|
||||
|
||||
@@ -4,6 +4,7 @@ import Typed from 'typed.js'
|
||||
import CONFIG from '../config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import BLOG from '@/blog.config'
|
||||
import LazyImage from '@/components/LazyImage'
|
||||
|
||||
let wrapperTop = 0
|
||||
|
||||
@@ -64,8 +65,8 @@ const Hero = props => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id='header-cover' style={{ backgroundImage: `url('${siteInfo?.pageCover}')` }}
|
||||
className={`header-cover bg-center w-full h-screen bg-cover ${CONFIG.HOME_NAV_BACKGROUND_IMG_FIXED ? 'bg-fixed' : ''}`} />
|
||||
<LazyImage priority={true} id='header-cover'src={siteInfo?.pageCover}
|
||||
className={`header-cover object-center w-full h-screen object-cover ${CONFIG.HOME_NAV_BACKGROUND_IMG_FIXED ? 'fixed' : ''}`} />
|
||||
|
||||
</header>
|
||||
)
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
/**
|
||||
* 最新文章列表
|
||||
* @param posts 所有文章数据
|
||||
* @param sliceCount 截取展示的数量 默认6
|
||||
* @constructor
|
||||
*/
|
||||
const LatestPostsGroup = ({ latestPosts, siteInfo }) => {
|
||||
// 获取当前路径
|
||||
const currentPath = useRouter().asPath
|
||||
const { locale } = useGlobal()
|
||||
|
||||
if (!latestPosts) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
return <>
|
||||
<div className=" mb-2 px-1 flex flex-nowrap justify-between">
|
||||
<div>
|
||||
<i className="mr-2 fas fas fa-history" />
|
||||
{locale.COMMON.LATEST_POSTS}
|
||||
</div>
|
||||
</div>
|
||||
{latestPosts.map(post => {
|
||||
const selected = currentPath === `${BLOG.SUB_PATH}/${post.slug}`
|
||||
const headerImage = post?.pageCoverThumbnail
|
||||
? `url("${post.pageCoverThumbnail}")`
|
||||
: `url("${siteInfo?.pageCover}")`
|
||||
|
||||
return (
|
||||
(<Link
|
||||
key={post.id}
|
||||
title={post.title}
|
||||
href={`${BLOG.SUB_PATH}/${post.slug}`}
|
||||
passHref
|
||||
className={'my-2 flex'}>
|
||||
|
||||
<div
|
||||
className="w-20 h-16 bg-cover bg-center bg-no-repeat"
|
||||
style={{ backgroundImage: headerImage }}
|
||||
/>
|
||||
<div
|
||||
className={
|
||||
(selected ? ' text-indigo-400 ' : 'dark:text-gray-400 ') +
|
||||
' text-sm overflow-x-hidden hover:text-indigo-600 px-2 duration-200 w-full rounded ' +
|
||||
'hover:text-white dark:hover:text-indigo-400 cursor-pointer items-center flex'
|
||||
}
|
||||
>
|
||||
<div>
|
||||
<div className='line-clamp-2'>{post.title}</div>
|
||||
<div className="text-gray-500">{post.lastEditedTime}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</Link>)
|
||||
)
|
||||
})}
|
||||
</>
|
||||
}
|
||||
export default LatestPostsGroup
|
||||
@@ -1,60 +0,0 @@
|
||||
import Card from './Card'
|
||||
import CategoryGroup from './CategoryGroup'
|
||||
import LatestPostsGroup from './LatestPostsGroup'
|
||||
import TagGroups from './TagGroups'
|
||||
import Catalog from './Catalog'
|
||||
import { InfoCard } from './InfoCard'
|
||||
import { AnalyticsCard } from './AnalyticsCard'
|
||||
import CONFIG from '../config'
|
||||
import BLOG from '@/blog.config'
|
||||
import dynamic from 'next/dynamic'
|
||||
|
||||
const HexoRecentComments = dynamic(() => import('./HexoRecentComments'))
|
||||
/**
|
||||
* Hexo主题右侧栏
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
export default function SideRight(props) {
|
||||
const {
|
||||
post, currentCategory, categories, latestPosts, tags,
|
||||
currentTag, showCategory, showTag, slot
|
||||
} = props
|
||||
|
||||
return (
|
||||
<div className={'space-y-4 lg:w-80 lg:pt-0 px-2 pt-4'}>
|
||||
<InfoCard {...props} />
|
||||
{CONFIG.WIDGET_ANALYTICS && <AnalyticsCard {...props} />}
|
||||
|
||||
{showCategory && (
|
||||
<Card>
|
||||
<div className='ml-2 mb-1 '>
|
||||
<i className='fas fa-th' /> 分类
|
||||
</div>
|
||||
<CategoryGroup
|
||||
currentCategory={currentCategory}
|
||||
categories={categories}
|
||||
/>
|
||||
</Card>
|
||||
)}
|
||||
{showTag && (
|
||||
<Card>
|
||||
<TagGroups tags={tags} currentTag={currentTag} />
|
||||
</Card>
|
||||
)}
|
||||
{CONFIG.WIDGET_LATEST_POSTS && latestPosts && latestPosts.length > 0 && <Card>
|
||||
<LatestPostsGroup {...props} />
|
||||
</Card>}
|
||||
|
||||
{BLOG.COMMENT_WALINE_SERVER_URL && BLOG.COMMENT_WALINE_RECENT && <HexoRecentComments/>}
|
||||
|
||||
<div className='sticky top-20'>
|
||||
{post && post.toc && post.toc.length > 1 && <Card>
|
||||
<Catalog toc={post.toc} />
|
||||
</Card>}
|
||||
{slot}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { useEffect, useState } from 'react'
|
||||
import Typed from 'typed.js'
|
||||
import CONFIG from '../config'
|
||||
|
||||
let wrapperTop = 0
|
||||
let windowTop = 0
|
||||
let autoScroll = false
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns 头图
|
||||
*/
|
||||
export default function Header(props) {
|
||||
const { siteInfo } = props
|
||||
const [typed, changeType] = useState()
|
||||
useEffect(() => {
|
||||
if (!typed && window && document.getElementById('typed')) {
|
||||
changeType(
|
||||
new Typed('#typed', {
|
||||
strings: CONFIG.HOME_BANNER_Strings,
|
||||
typeSpeed: 200,
|
||||
backSpeed: 100,
|
||||
backDelay: 400,
|
||||
showCursor: true,
|
||||
smartBackspace: true
|
||||
})
|
||||
)
|
||||
}
|
||||
}, [])
|
||||
const { isDarkMode } = useGlobal()
|
||||
|
||||
const autoScrollEnd = () => {
|
||||
if (autoScroll) {
|
||||
windowTop = window.scrollY
|
||||
autoScroll = false
|
||||
}
|
||||
}
|
||||
|
||||
const scrollTrigger = () => {
|
||||
if (
|
||||
(window.scrollY > windowTop) &
|
||||
(window.scrollY < window.innerHeight) &&
|
||||
!autoScroll
|
||||
) {
|
||||
autoScroll = true
|
||||
window.scrollTo({ top: wrapperTop, behavior: 'smooth' })
|
||||
setTimeout(autoScrollEnd, 500)
|
||||
}
|
||||
if (
|
||||
(window.scrollY < windowTop) &
|
||||
(window.scrollY < window.innerHeight) &&
|
||||
!autoScroll
|
||||
) {
|
||||
autoScroll = true
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' })
|
||||
setTimeout(autoScrollEnd, 500)
|
||||
}
|
||||
windowTop = window.scrollY
|
||||
|
||||
updateTopNav()
|
||||
}
|
||||
|
||||
const updateTopNav = () => {
|
||||
if (!isDarkMode) {
|
||||
const stickyNavElement = document.getElementById('sticky-nav')
|
||||
if (window.scrollY < window.innerHeight) {
|
||||
stickyNavElement.classList.add('dark')
|
||||
} else {
|
||||
stickyNavElement.classList.remove('dark')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateHeaderHeight() {
|
||||
setTimeout(() => {
|
||||
const wrapperElement = document.getElementById('wrapper')
|
||||
wrapperTop = wrapperElement.offsetTop
|
||||
}, 500)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
updateHeaderHeight()
|
||||
updateTopNav()
|
||||
window.addEventListener('scroll', scrollTrigger)
|
||||
window.addEventListener('resize', updateHeaderHeight)
|
||||
return () => {
|
||||
window.removeEventListener('scroll', scrollTrigger)
|
||||
window.removeEventListener('resize', updateHeaderHeight)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<header
|
||||
id="header"
|
||||
className="duration-500 md:bg-fixed w-full bg-cover bg-center h-screen bg-black relative z-10"
|
||||
style={{
|
||||
backgroundImage:
|
||||
`linear-gradient(rgba(0, 0, 0, 0.8), rgba(0,0,0,0.2), rgba(0, 0, 0, 0.8) ),url("${siteInfo?.pageCover}")`
|
||||
}}
|
||||
>
|
||||
<div className="absolute flex h-full items-center lg:-mt-14 justify-center w-full text-2xl md:text-4xl text-white">
|
||||
<div id='typed' className='flex text-center font-serif' />
|
||||
</div>
|
||||
<div
|
||||
onClick={() => {
|
||||
window.scrollTo({ top: wrapperTop, behavior: 'smooth' })
|
||||
}}
|
||||
className="cursor-pointer w-full text-center py-4 text-5xl absolute bottom-10 text-white"
|
||||
>
|
||||
<i className='animate-bounce fas fa-angle-down' />
|
||||
</div>
|
||||
</header>
|
||||
)
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
const CONFIG = {
|
||||
|
||||
HOME_BANNER: false, // 首页是否显示大图及标语 [true,false]
|
||||
HOME_BANNER: true, // 首页是否显示大图及标语 [true,false]
|
||||
HOME_BANNER_Strings: ['Hi,我是一个程序员', 'Hi,我是一个打工人', 'Hi,我是一个干饭人', '欢迎来到我的博客🎉'], // 首页大图标语文字
|
||||
|
||||
NAV_TYPE: 'normal', // ['fixed','autoCollapse','normal'] 分别是固定屏幕顶部并始终显示、固定屏幕顶部且滚动时隐藏,不固定屏幕顶部
|
||||
|
||||
@@ -11,7 +11,6 @@ import TopNav from './components/TopNav'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import BLOG from '@/blog.config'
|
||||
import Header from './components/Header'
|
||||
import BlogPostListScroll from './components/BlogPostListScroll'
|
||||
import BlogPostListPage from './components/BlogPostListPage'
|
||||
import StickyBar from './components/StickyBar'
|
||||
@@ -133,7 +132,7 @@ const LayoutBase = (props) => {
|
||||
* @returns
|
||||
*/
|
||||
const LayoutIndex = (props) => {
|
||||
return <LayoutPostList headerSlot={CONFIG.HOME_BANNER && <Header {...props} />} {...props} />
|
||||
return <LayoutPostList {...props} />
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user