diff --git a/src/components/common/DisqusComments.tsx b/src/components/common/DisqusComments.tsx index f27d893..2231e31 100644 --- a/src/components/common/DisqusComments.tsx +++ b/src/components/common/DisqusComments.tsx @@ -1,29 +1,53 @@ 'use client'; -// src/components/DisqusComments.tsx -import { useEffect } from 'react'; +import { useEffect, useState, useRef } from 'react'; export default function DisqusComments({ disqusShortname, }: { disqusShortname: string; }) { + const [loadDisqus, setLoadDisqus] = useState(false); + const disqusReference = useRef(null); + useEffect(() => { - const disqusScript = document.createElement('script'); - disqusScript.src = `https://${disqusShortname}.disqus.com/embed.js`; - disqusScript.dataset.timestamp = `${Date.now()}`; - (document.head || document.body).append(disqusScript); + const observer = new IntersectionObserver( + (entries) => { + if (entries[0].isIntersecting) { + setLoadDisqus(true); // Observer is triggered + observer.disconnect(); // Disconnect observer + } + }, + { threshold: 0.1 } + ); + + if (disqusReference.current) { + observer.observe(disqusReference.current); + } return () => { - // Clean up the script if the component is unmounted - if (disqusScript.parentNode) { - disqusScript.remove(); - } + observer.disconnect(); }; - }, [disqusShortname]); + }, []); + + useEffect(() => { + if (loadDisqus) { + const disqusScript = document.createElement('script'); + disqusScript.src = `https://${disqusShortname}.disqus.com/embed.js`; + disqusScript.dataset.timestamp = `${Date.now()}`; + (document.head || document.body).append(disqusScript); + + return () => { + if (disqusScript.parentNode) { + disqusScript.remove(); + } + }; + } + }, [loadDisqus, disqusShortname]); return (
); diff --git a/src/components/layout/PostLayout.tsx b/src/components/layout/PostLayout.tsx index 951f252..0d4e362 100644 --- a/src/components/layout/PostLayout.tsx +++ b/src/components/layout/PostLayout.tsx @@ -1,10 +1,11 @@ import Image from 'next/image'; import { FaFolder, FaTags } from 'react-icons/fa6'; +import ItemLinks from './ItemLinks'; + import { getConfig } from '@/services/config'; import DisqusComments from '@/components/common/DisqusComments'; -import ItemLinks from '@/components/layout/ItemLinks'; import '@/styles/codeblock.css'; import '@/styles/postContent.css'; @@ -15,91 +16,158 @@ interface PostLayoutProperties { showThumbnail?: boolean; } -export default function PostLayout({ - post, - showThumbnail = true, -}: PostLayoutProperties) { - const config = getConfig(); - - // if showComments is defined in the frontmatter, use that value, - // otherwise default to true - const showComments: boolean = post.frontmatter.showComments ?? true; - +function PostLayout({ post, showThumbnail = true }: PostLayoutProperties) { return ( -
+
{showThumbnail ? ( -
- {/* Thumbnail masking effect */} - {`Thumbnail - - {/* Mask */} -
- - {/* Title and publishing info */} -
-

{post.frontmatter.title}

-

- {post.frontmatter.author} - - {post.frontmatter.date.split(' ')[0]} -

-
-
+ ) : ( - /* If no thumbnail, display the title at the top */ -
-

{post.frontmatter.title}

- - {(post.frontmatter.title === 'About' || - post.frontmatter.title === 'Friends') ?? ( -

- {post.frontmatter.author} - - {post.frontmatter.date.split(' ')[0]} -

- )} -
+ )} +
- {/* Show categories and tags if any */} - {(post.frontmatter.categories?.length || - post.frontmatter.tags?.length) && ( -
    -
  • - - 分类: - -
  • -
  • - - 标签: - -
  • -
+ + + {post.frontmatter.showComments && ( + )} +
+
+ ); +} - {/* Post content */} -
+ {`Thumbnail +
+ +
+ ); +} + +function TitleHeader({ + title, + author, + date, +}: { + title: string; + author: string; + date: string; +}) { + return ( +
+

{title}

+ {title !== 'About' && title !== 'Friends' && ( + -
- {/* Comment Section */} - {showComments && ( - )} -
+ + ); +} + +function MetaInfo({ + title, + author, + date, + isOverlay, +}: { + title?: string; + author: string; + date: string; + isOverlay?: boolean; +}) { + return ( +
+ {title &&

{title}

} +

+ {author} + + {date.split(' ')[0]} +

+
+ ); +} + +function CategoriesTagsList({ + categories, + tags, +}: { + categories?: string[]; + tags?: string[]; +}) { + if (!categories && !tags) return null; + + return ( + ); } + +function PostContent({ contentHtml }: { contentHtml: string }) { + return ( +
+ ); +} + +export default PostLayout;