Skip to content

Commit

Permalink
refactor: opt post
Browse files Browse the repository at this point in the history
  • Loading branch information
guanbinrui committed Dec 11, 2024
1 parent 27452f9 commit f9f7f5b
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 146 deletions.
107 changes: 58 additions & 49 deletions src/components/NFTs/NFTPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<BasePreviewContent
image={nft.image_url}
icon={
isPoap ? (
<PoapIcon width={24} height={24} />
) : chainId ? (
<ChainIcon className="rounded-full" size={24} chainId={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 ? (
<>
<CalendarIcon className="mr-1 inline-block align-sub" width={15} height={15} />
{formatDate(startDate)} - {formatDate(endDate)}
</>
) : null,
])
: [`#${nft.name}`]
}
bookmarkProps={{ nftId: nft.nft_id, ownerAddress: first(nft.owners)?.owner_address }}
/>
);
});
return (
<BasePreviewContent
image={nft.image_url}
icon={
isPoap ? (
<PoapIcon width={24} height={24} />
) : chainId ? (
<ChainIcon className="rounded-full" size={24} chainId={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 ? (
<>
<CalendarIcon className="mr-1 inline-block align-sub" width={15} height={15} />
{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,
Expand Down
6 changes: 2 additions & 4 deletions src/components/NoSSR.tsx
Original file line number Diff line number Diff line change
@@ -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;
}
6 changes: 3 additions & 3 deletions src/components/Posts/PostLinks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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({
Expand Down Expand Up @@ -95,7 +95,7 @@ export function PostLinks({ post, setContent, isInCompose = false }: Props) {
{data.collection ? <CollectionPreviewer collection={data.collection} /> : null}
</>
);
}
});

export function PostLinksInCompose({
type,
Expand Down
185 changes: 95 additions & 90 deletions src/components/Posts/SinglePost.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,101 +31,106 @@ export interface SinglePostProps extends HTMLProps<HTMLDivElement> {
showChannelTag?: boolean;
header?: ReactNode;
}
export const SinglePost = memo<SinglePostProps>(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<SinglePostProps>(
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 (
<motion.article
initial={!disableAnimate ? { opacity: 0 } : false}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className={classNames(
'cursor-pointer border-b border-line bg-bottom px-3 py-2 md:px-4 md:py-3',
className,
{
'hover:bg-bg': !isDetail,
},
)}
onClick={() => {
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}
<NoSSR>
{!isComment ? <FeedActionType isDetail={isDetail} post={post} listKey={listKey} index={index} /> : null}
</NoSSR>

<PostHeader
isComment={isComment}
post={post}
onClickProfileLink={() => {
if (listKey && !isUndefined(index)) useGlobalState.getState().setScrollIndex(listKey, index);
return (
<motion.article
initial={!disableAnimate ? { opacity: 0 } : false}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className={classNames(
'cursor-pointer border-b border-line bg-bottom px-3 py-2 md:px-4 md:py-3',
className,
{
'hover:bg-bg': !isDetail,
},
)}
onClick={() => {
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}
<NoSSR>
{!isComment ? (
<FeedActionType isDetail={isDetail} post={post} listKey={listKey} index={index} />
) : null}
</NoSSR>

<PostBody
post={post}
showMore={showMore}
showTranslate={showTranslate}
isDetail={isDetail}
isComment={isComment}
/>
<NoSSR>
{showPostAction ? (
<PostActions
post={post}
disabled={post.isHidden}
showChannelTag={!isComment && !isChannelPage && showChannelTag}
onSetScrollIndex={() => {
if (listKey && !isUndefined(index))
useGlobalState.getState().setScrollIndex(listKey, index);
}}
/>
) : null}
</NoSSR>
<PostHeader
isComment={isComment}
post={post}
onClickProfileLink={() => {
if (listKey && !isUndefined(index)) useGlobalState.getState().setScrollIndex(listKey, index);
}}
/>

{show ? (
<div className="mt-2 w-full cursor-pointer text-center text-medium font-bold text-highlight">
<div>
<Trans>Show More</Trans>
<PostBody
post={post}
showMore={showMore}
showTranslate={showTranslate}
isDetail={isDetail}
isComment={isComment}
/>
<NoSSR>
{showPostAction ? (
<PostActions
post={post}
disabled={post.isHidden}
showChannelTag={!isComment && !isChannelPage && showChannelTag}
onSetScrollIndex={() => {
if (listKey && !isUndefined(index))
useGlobalState.getState().setScrollIndex(listKey, index);
}}
/>
) : null}
</NoSSR>

{show ? (
<div className="mt-2 w-full cursor-pointer text-center text-medium font-bold text-highlight">
<div>
<Trans>Show More</Trans>
</div>
</div>
</div>
) : null}
</motion.article>
);
});
) : null}
</motion.article>
);
},
(a, b) => a.post.postId === b.post.postId,
);

0 comments on commit f9f7f5b

Please sign in to comment.