From f9f7f5b6a135ef443d97935019814295001b1989 Mon Sep 17 00:00:00 2001 From: guanbinrui Date: Wed, 11 Dec 2024 17:45:11 +0800 Subject: [PATCH] refactor: opt post --- src/components/NFTs/NFTPreview.tsx | 107 ++++++++-------- src/components/NoSSR.tsx | 6 +- src/components/Posts/PostLinks.tsx | 6 +- src/components/Posts/SinglePost.tsx | 185 ++++++++++++++-------------- 4 files changed, 158 insertions(+), 146 deletions(-) diff --git a/src/components/NFTs/NFTPreview.tsx b/src/components/NFTs/NFTPreview.tsx index 7dad0003d4..0af819e92c 100644 --- a/src/components/NFTs/NFTPreview.tsx +++ b/src/components/NFTs/NFTPreview.tsx @@ -110,57 +110,66 @@ function BasePreviewContent(props: BasePreviewContentProps) { ); } -export const NFTPreviewer = memo(function NFTPreview({ nft }: NFTPreviewProps) { - const chainId = resolveSimpleHashChainId(nft.chain); - const collectionId = nft.collection.collection_id; - const isSolanaChain = isValidSolanaChainId(chainId); +export const NFTPreviewer = memo( + function NFTPreview({ nft }: NFTPreviewProps) { + const chainId = resolveSimpleHashChainId(nft.chain); + const collectionId = nft.collection.collection_id; + const isSolanaChain = isValidSolanaChainId(chainId); - const isPoap = isSameEthereumAddress(nft.contract_address, POAP_CONTRACT_ADDRESS); - const startDate = isPoap - ? nft.extra_metadata?.attributes?.find((attr) => attr.trait_type === 'startDate')?.value - : undefined; - const endDate = isPoap - ? nft.extra_metadata?.attributes?.find((attr) => attr.trait_type === 'endDate')?.value - : undefined; + const isPoap = isSameEthereumAddress(nft.contract_address, POAP_CONTRACT_ADDRESS); + const startDate = isPoap + ? nft.extra_metadata?.attributes?.find((attr) => attr.trait_type === 'startDate')?.value + : undefined; + const endDate = isPoap + ? nft.extra_metadata?.attributes?.find((attr) => attr.trait_type === 'endDate')?.value + : undefined; - return ( - - ) : chainId ? ( - - ) : undefined - } - link={ - chainId ? resolveNftUrl(chainId, nft.contract_address, isSolanaChain ? '0' : nft.token_id) : undefined - } - footer={ - nft.collection?.collection_id - ? { - image: nft.collection.image_url, - name: isPoap ? nft.name : nft.collection.name, - link: isPoap ? undefined : collectionId ? resolveNftUrlByCollection(collectionId) : undefined, - } - : undefined - } - tags={ - isPoap - ? compact([ - startDate && endDate ? ( - <> - - {formatDate(startDate)} - {formatDate(endDate)} - - ) : null, - ]) - : [`#${nft.name}`] - } - bookmarkProps={{ nftId: nft.nft_id, ownerAddress: first(nft.owners)?.owner_address }} - /> - ); -}); + return ( + + ) : chainId ? ( + + ) : undefined + } + link={ + chainId + ? resolveNftUrl(chainId, nft.contract_address, isSolanaChain ? '0' : nft.token_id) + : undefined + } + footer={ + nft.collection?.collection_id + ? { + image: nft.collection.image_url, + name: isPoap ? nft.name : nft.collection.name, + link: isPoap + ? undefined + : collectionId + ? resolveNftUrlByCollection(collectionId) + : undefined, + } + : undefined + } + tags={ + isPoap + ? compact([ + startDate && endDate ? ( + <> + + {formatDate(startDate)} - {formatDate(endDate)} + + ) : null, + ]) + : [`#${nft.name}`] + } + bookmarkProps={{ nftId: nft.nft_id, ownerAddress: first(nft.owners)?.owner_address }} + /> + ); + }, + (a, b) => a.nft.nft_id === b.nft.nft_id, +); export const CollectionPreviewer = memo(function CollectionPreviewer({ collection, diff --git a/src/components/NoSSR.tsx b/src/components/NoSSR.tsx index 80dcc0f065..24d5ef0a42 100644 --- a/src/components/NoSSR.tsx +++ b/src/components/NoSSR.tsx @@ -1,13 +1,11 @@ 'use client'; -import { useMounted } from '@/hooks/useMounted.js'; +import { isServer } from '@tanstack/react-query'; interface NoSSRProps { children: React.ReactNode; } export function NoSSR({ children }: NoSSRProps) { - const mounted = useMounted(); - - return mounted ? children : null; + return isServer ? children : null; } diff --git a/src/components/Posts/PostLinks.tsx b/src/components/Posts/PostLinks.tsx index ca11c99d35..fd9f71b3bb 100644 --- a/src/components/Posts/PostLinks.tsx +++ b/src/components/Posts/PostLinks.tsx @@ -3,7 +3,7 @@ import { useQuery } from '@tanstack/react-query'; import { last } from 'lodash-es'; import { useRouter } from 'next/navigation.js'; -import { useEffect, useMemo } from 'react'; +import { memo, useEffect, useMemo } from 'react'; import { ArticleBody } from '@/components/Article/ArticleBody.js'; import { ActionContainer } from '@/components/Blink/ActionContainer.js'; @@ -33,7 +33,7 @@ interface Props { isInCompose?: boolean; } -export function PostLinks({ post, setContent, isInCompose = false }: Props) { +export const PostLinks = memo(function PostLinks({ post, setContent, isInCompose = false }: Props) { const router = useRouter(); const url = resolveOembedUrl(post); const { isLoading, error, data } = useQuery({ @@ -95,7 +95,7 @@ export function PostLinks({ post, setContent, isInCompose = false }: Props) { {data.collection ? : null} ); -} +}); export function PostLinksInCompose({ type, diff --git a/src/components/Posts/SinglePost.tsx b/src/components/Posts/SinglePost.tsx index cfa4170335..1dc0863eda 100644 --- a/src/components/Posts/SinglePost.tsx +++ b/src/components/Posts/SinglePost.tsx @@ -31,101 +31,106 @@ export interface SinglePostProps extends HTMLProps { showChannelTag?: boolean; header?: ReactNode; } -export const SinglePost = memo(function SinglePost({ - post, - disableAnimate = false, - showMore = false, - isComment = false, - isDetail = false, - showTranslate = false, - showChannelTag = true, - listKey, - index, - className, - header, -}) { - const router = useRouter(); - const pathname = usePathname(); - const isPostPage = isRoutePathname(pathname, '/post/:source'); - const isProfilePage = isRoutePathname(pathname, '/profile/:source'); - const isChannelPage = isRoutePathname(pathname, '/channel/:detail'); - const postLink = getPostUrl(post); - const muted = useIsProfileMuted(post.author.source, post.author.profileId) || post.channel?.blocked; +export const SinglePost = memo( + function SinglePost({ + className, + post, + disableAnimate = false, + showMore = false, + isComment = false, + isDetail = false, + showTranslate = false, + showChannelTag = true, + listKey, + index, + header, + }) { + const router = useRouter(); + const pathname = usePathname(); + const isPostPage = isRoutePathname(pathname, '/post/:source'); + const isProfilePage = isRoutePathname(pathname, '/profile/:source'); + const isChannelPage = isRoutePathname(pathname, '/channel/:detail'); + const postLink = getPostUrl(post); + const muted = useIsProfileMuted(post.author.source, post.author.profileId) || post.channel?.blocked; - const show = useMemo(() => { - if (post.source === Source.Twitter) return false; - if (!post.isThread || isPostPage) return false; - if (post.source === Source.Farcaster && post.stats?.comments === 0) return false; - return true; - }, [post, isPostPage]); + const show = useMemo(() => { + if (post.source === Source.Twitter) return false; + if (!post.isThread || isPostPage) return false; + if (post.source === Source.Farcaster && post.stats?.comments === 0) return false; + return true; + }, [post, isPostPage]); - if (!isProfilePage && !isDetail && muted) return null; + if (!isProfilePage && !isDetail && muted) return null; - const showPostAction = !isDetail && (isProfilePage || !post.isHidden || !muted); + const showPostAction = !isDetail && (isProfilePage || !post.isHidden || !muted); - return ( - { - const selection = window.getSelection(); - if (selection && selection.toString().length !== 0) return; - if (!isPostPage || isComment) { - if (listKey && !isUndefined(index)) useGlobalState.getState().setScrollIndex(listKey, index); - router.push(postLink); - } - return; - }} - > - {header} - - {!isComment ? : null} - - - { - if (listKey && !isUndefined(index)) useGlobalState.getState().setScrollIndex(listKey, index); + return ( + { + const selection = window.getSelection(); + if (selection && selection.toString().length !== 0) return; + if (!isPostPage || isComment) { + if (listKey && !isUndefined(index)) useGlobalState.getState().setScrollIndex(listKey, index); + router.push(postLink); + } + return; }} - /> + > + {header} + + {!isComment ? ( + + ) : null} + - - - {showPostAction ? ( - { - if (listKey && !isUndefined(index)) - useGlobalState.getState().setScrollIndex(listKey, index); - }} - /> - ) : null} - + { + if (listKey && !isUndefined(index)) useGlobalState.getState().setScrollIndex(listKey, index); + }} + /> - {show ? ( -
-
- Show More + + + {showPostAction ? ( + { + if (listKey && !isUndefined(index)) + useGlobalState.getState().setScrollIndex(listKey, index); + }} + /> + ) : null} + + + {show ? ( +
+
+ Show More +
-
- ) : null} - - ); -}); + ) : null} + + ); + }, + (a, b) => a.post.postId === b.post.postId, +);