Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
at main 98 lines 3.1 kB view raw
1import { EyeIcon } from "@heroicons/react/24/outline"; 2import getPostData from "@hey/helpers/getPostData"; 3import getURLs from "@hey/helpers/getURLs"; 4import { isRepost } from "@hey/helpers/postHelpers"; 5import type { AnyPostFragment } from "@hey/indexer"; 6import { getSrc } from "@livepeer/react/external"; 7import { memo } from "react"; 8import Quote from "@/components/Shared/Embed/Quote"; 9import Markup from "@/components/Shared/Markup"; 10import Attachments from "@/components/Shared/Post/Attachments"; 11import Oembed from "@/components/Shared/Post/Oembed"; 12import PostLink from "@/components/Shared/Post/PostLink"; 13import Video from "@/components/Shared/Post/Video"; 14import { H6 } from "@/components/Shared/UI"; 15import cn from "@/helpers/cn"; 16 17interface PostBodyProps { 18 contentClassName?: string; 19 post: AnyPostFragment; 20 quoted?: boolean; 21 showMore?: boolean; 22} 23 24const PostBody = ({ 25 contentClassName = "", 26 post, 27 quoted = false, 28 showMore = false 29}: PostBodyProps) => { 30 const targetPost = isRepost(post) ? post.repostOf : post; 31 const { metadata } = targetPost; 32 33 const filteredContent = getPostData(metadata)?.content || ""; 34 const filteredAttachments = getPostData(metadata)?.attachments || []; 35 const filteredAsset = getPostData(metadata)?.asset; 36 37 const canShowMore = filteredContent?.length > 450 && showMore; 38 const urls = getURLs(filteredContent); 39 const hasURLs = urls.length > 0; 40 41 let content = filteredContent; 42 43 if (canShowMore) { 44 const lines = content?.split("\n"); 45 if (lines && lines.length > 0) { 46 content = lines.slice(0, 5).join("\n"); 47 } 48 } 49 50 // Show live if it's there 51 const showLive = metadata.__typename === "LivestreamMetadata"; 52 // Show attachments if they're there 53 const showAttachments = filteredAttachments.length > 0 || filteredAsset; 54 // Show sharing link 55 const showSharingLink = metadata.__typename === "LinkMetadata"; 56 const showOembed = 57 !showSharingLink && 58 hasURLs && 59 !showLive && 60 !showAttachments && 61 !quoted && 62 !targetPost.quoteOf; 63 64 return ( 65 <div className="break-words"> 66 <Markup 67 className={cn( 68 { "line-clamp-5": canShowMore }, 69 "markup linkify break-words", 70 contentClassName 71 )} 72 mentions={targetPost.mentions} 73 > 74 {content} 75 </Markup> 76 {canShowMore ? ( 77 <H6 className="mt-4 flex items-center space-x-1 text-gray-500 dark:text-gray-200"> 78 <EyeIcon className="size-4" /> 79 <PostLink post={post}>Show more</PostLink> 80 </H6> 81 ) : null} 82 {/* Attachments and Quotes */} 83 {showAttachments ? ( 84 <Attachments asset={filteredAsset} attachments={filteredAttachments} /> 85 ) : null} 86 {showLive ? ( 87 <div className="mt-3"> 88 <Video src={getSrc(metadata.liveUrl || metadata.playbackUrl)} /> 89 </div> 90 ) : null} 91 {showOembed ? <Oembed url={urls[0]} /> : null} 92 {showSharingLink ? <Oembed url={metadata.sharingLink} /> : null} 93 {targetPost.quoteOf ? <Quote post={targetPost.quoteOf} /> : null} 94 </div> 95 ); 96}; 97 98export default memo(PostBody);