diff --git a/themes/magzine/components/CategoryItem.js b/themes/magzine/components/CategoryItem.js index 44fd3845..f4cff30b 100644 --- a/themes/magzine/components/CategoryItem.js +++ b/themes/magzine/components/CategoryItem.js @@ -7,9 +7,9 @@ export default function CategoryItem({ selected, category, categoryCount }) { passHref className={ (selected - ? ' bg-gray-600 text-white ' + ? 'bg-gray-600 text-white ' : 'dark:text-gray-400 text-gray-900 ') + - 'text-sm hover:underline flex text-md items-center duration-300 cursor-pointer py-1 whitespace-nowrap' + 'text-sm font-semibold hover:underline flex text-md items-center duration-300 cursor-pointer py-1 whitespace-nowrap' }>
{category} {categoryCount && `(${categoryCount})`} diff --git a/themes/magzine/components/PostGroupLatest.js b/themes/magzine/components/PostGroupLatest.js index 8731e7d6..55909552 100644 --- a/themes/magzine/components/PostGroupLatest.js +++ b/themes/magzine/components/PostGroupLatest.js @@ -12,7 +12,7 @@ import { useRouter } from 'next/router' * @constructor */ const PostGroupLatest = props => { - const { latestPosts } = props + const { latestPosts, vertical } = props // 获取当前路径 const currentPath = useRouter().asPath const { locale, siteInfo } = useGlobal() @@ -23,12 +23,12 @@ const PostGroupLatest = props => { return ( <> {/* 标题 */} -
+
{locale.COMMON.LATEST_POSTS}
{/* 文章列表 */} -
+
{latestPosts.map(post => { const selected = currentPath === `${siteConfig('SUB_PATH', '')}/${post.slug}` diff --git a/themes/magzine/components/PostItemCard.js b/themes/magzine/components/PostItemCard.js index f25874d3..ae77cfcb 100644 --- a/themes/magzine/components/PostItemCard.js +++ b/themes/magzine/components/PostItemCard.js @@ -2,6 +2,7 @@ import LazyImage from '@/components/LazyImage' import NotionIcon from '@/components/NotionIcon' import { siteConfig } from '@/lib/config' import { useGlobal } from '@/lib/global' +import { formatDateFmt } from '@/lib/utils/formatDate' import Link from 'next/link' import CategoryItem from './CategoryItem' @@ -14,19 +15,19 @@ const PostItemCard = ({ post }) => { const cover = post?.pageCoverThumbnail || siteInfo?.pageCover return (
-
+
{siteConfig('MAGZINE_POST_LIST_COVER') && (
@@ -39,7 +40,7 @@ const PostItemCard = ({ post }) => { href={post?.href} passHref className={ - 'text-lg cursor-pointer hover:underline leading-tight text-gray-700 dark:text-gray-300 hover:text-gray-500 dark:hover:text-gray-400' + 'text-xl cursor-pointer hover:underline leading-tight text-gray-700 dark:text-gray-300 hover:text-gray-500 dark:hover:text-gray-400' }>

{siteConfig('POST_TITLE_ICON') && ( @@ -49,7 +50,9 @@ const PostItemCard = ({ post }) => {

-
{post.date?.start_date}
+
+ {formatDateFmt(post.publishDate, 'yyyy-MM')} +
) diff --git a/themes/magzine/components/PostItemCardSimple.js b/themes/magzine/components/PostItemCardSimple.js index 3cf8a1ec..36fa00b9 100644 --- a/themes/magzine/components/PostItemCardSimple.js +++ b/themes/magzine/components/PostItemCardSimple.js @@ -1,6 +1,5 @@ import NotionIcon from '@/components/NotionIcon' import { siteConfig } from '@/lib/config' -import { useGlobal } from '@/lib/global' import Link from 'next/link' import CategoryItem from './CategoryItem' @@ -10,12 +9,10 @@ import CategoryItem from './CategoryItem' * @returns */ const PostItemCardSimple = ({ post, showSummary }) => { - const showPreview = siteConfig('MAGZINE_POST_LIST_PREVIEW') && post.blockMap - const { locale } = useGlobal() return (
+ className='lg:mb-6 max-w-screen-2xl border-t border-gray-300 mr-8 py-2 gap-y-3 flex flex-col dark:border-gray-800 '>
{siteConfig('MAGZINE_POST_LIST_CATEGORY') && ( @@ -35,7 +32,7 @@ const PostItemCardSimple = ({ post, showSummary }) => { -
{post.date?.start_date}
+
{post.date?.start_date}
) } diff --git a/themes/magzine/components/PostListHorizontal.js b/themes/magzine/components/PostListHorizontal.js index 5318cf3e..640c733a 100644 --- a/themes/magzine/components/PostListHorizontal.js +++ b/themes/magzine/components/PostListHorizontal.js @@ -1,6 +1,7 @@ import Link from 'next/link' import PostItemCard from './PostItemCard' import PostListEmpty from './PostListEmpty' +import Swiper from './Swiper' /** * 博文水平列表 @@ -15,22 +16,34 @@ const PostListHorizontal = ({ title, href, posts, hasBg }) => { } return ( -
+
{/* 标题 */}

{title}

- - 查看全部 - - + {href && ( + + 查看全部 + + + )}
{/* 列表 */} -
    +
      {posts?.map((p, index) => { return })}
    +
    + + {href && ( + + 查看全部 + + + )} +
) diff --git a/themes/magzine/components/PostListRecommend.js b/themes/magzine/components/PostListRecommend.js index 04a4f811..0ee0208e 100644 --- a/themes/magzine/components/PostListRecommend.js +++ b/themes/magzine/components/PostListRecommend.js @@ -1,6 +1,7 @@ import { siteConfig } from '@/lib/config' import PostItemCard from './PostItemCard' import PostListEmpty from './PostListEmpty' +import Swiper from './Swiper' /** * 博文水平列表 @@ -25,11 +26,14 @@ const PostListRecommend = ({ latestPosts, allNavPages }) => {

{title}

{/* 列表 */} -
    - {recommendPosts?.map(p => { - return +
      + {recommendPosts?.map((p, index) => { + return })}
    +
    + +
) diff --git a/themes/magzine/components/Swiper.js b/themes/magzine/components/Swiper.js new file mode 100644 index 00000000..ac5decde --- /dev/null +++ b/themes/magzine/components/Swiper.js @@ -0,0 +1,137 @@ +import { useRef, useState } from 'react' +import PostItemCard from './PostItemCard' + +const Swiper = ({ posts }) => { + const [currentIndex, setCurrentIndex] = useState(0) + const containerRef = useRef(null) + + // 用于记录触摸开始和结束的水平位置 + const touchStartPos = useRef({ x: 0, y: 0 }) + const touchEndPos = useRef({ x: 0, y: 0 }) + const isHorizontalSwipe = useRef(false) + + const handleTouchStart = e => { + // 记录初始触摸位置 + touchStartPos.current = { + x: e.touches[0].clientX, + y: e.touches[0].clientY + } + isHorizontalSwipe.current = false // 重置滑动方向标志 + } + + const handleTouchMove = e => { + const touch = e.touches[0] + const deltaX = touch.clientX - touchStartPos.current.x + const deltaY = touch.clientY - touchStartPos.current.y + + // 判断是否为水平滑动(避免垂直滑动干扰) + if (!isHorizontalSwipe.current) { + isHorizontalSwipe.current = Math.abs(deltaX) > Math.abs(deltaY) + } + + // 如果是水平滑动,阻止垂直滚动 + if (isHorizontalSwipe.current) { + e.preventDefault() // 阻止垂直方向的默认滚动行为 + } + } + + const handleTouchEnd = e => { + if (isHorizontalSwipe.current) { + // 记录触摸结束位置 + touchEndPos.current = { + x: e.changedTouches[0].clientX, + y: e.changedTouches[0].clientY + } + + // 计算滑动距离 + const deltaX = touchEndPos.current.x - touchStartPos.current.x + + // 如果滑动距离足够大,则决定滑动到下一张或上一张卡片 + const swipeThreshold = 50 // 设置滑动的阈值 + if (deltaX > swipeThreshold) { + goToPrevious() // 向右滑动,上一张 + } else if (deltaX < -swipeThreshold) { + goToNext() // 向左滑动,下一张 + } else { + // 滑动距离不够,回到当前卡片 + scrollToCard(currentIndex) + } + } + } + + const goToPrevious = () => { + const newIndex = currentIndex === 0 ? posts.length - 1 : currentIndex - 1 + setCurrentIndex(newIndex) + scrollToCard(newIndex) + } + + const goToNext = () => { + const newIndex = currentIndex === posts.length - 1 ? 0 : currentIndex + 1 + setCurrentIndex(newIndex) + scrollToCard(newIndex) + } + + const scrollToCard = index => { + const container = containerRef.current + if (!container) return + + const cardWidth = container.scrollWidth / posts.length + container.scrollTo({ + left: index * cardWidth, + behavior: 'smooth' + }) + } + + const handleIndicatorClick = index => { + setCurrentIndex(index) + scrollToCard(index) + } + + return ( +
+ {/* 左侧点击区域 */} +
+ + {/* 右侧点击区域 */} +
+ + {/* Swiper Container */} +
+
+ {posts.map((item, index) => ( +
+ +
+ ))} +
+
+ + {/* Indicator Dots */} +
+ {posts.map((_, index) => ( + + ))} +
+
+ ) +} + +export default Swiper diff --git a/themes/magzine/index.js b/themes/magzine/index.js index 387ef437..d8b9c3b5 100644 --- a/themes/magzine/index.js +++ b/themes/magzine/index.js @@ -178,7 +178,7 @@ const LayoutSlug = props => { {/* 文章区块分为三列 */}
-
+
@@ -231,7 +231,7 @@ const LayoutSlug = props => { {/* 最新文章区块 */}
- +
{/* 文章分类区块 */}