react-bluesky-embed
Version:
React Bluesky Embed allows you to embed post threads, profiles, and comments in your React application when using Next.js, Create React App, Vite, and more.
1 lines • 6.17 kB
JavaScript
"use client";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import{AppBskyFeedDefs,AppBskyFeedPost}from"@atproto/api";import{useState}from"react";import{Embed}from"./embed.js";import{PostContent}from"./post.js";export const CommentSection=({thread})=>{var _thread_replies;const[,,did,_,rkey]=thread.post.uri.split("/");const postUrl=`https://bsky.app/profile/${did}/post/${rkey}`;const[error,setError]=useState(null);const[visibleCount,setVisibleCount]=useState(4);if(error){return /*#__PURE__*/_jsx("p",{className:"text-center",children:error})}if(!thread){return /*#__PURE__*/_jsx("p",{className:"text-center",children:"Loading comments..."})}const showMore=()=>{setVisibleCount(prevCount=>prevCount+4)};var _thread_replies_sort;const sortedReplies=(_thread_replies_sort=(_thread_replies=thread.replies)==null?void 0:_thread_replies.sort(sortByLikes))!=null?_thread_replies_sort:[];return /*#__PURE__*/_jsxs("div",{children:[/*#__PURE__*/_jsx("h2",{className:"text-xl font-bold",children:"Comments"}),/*#__PURE__*/_jsxs("p",{className:"mt-2 text-sm",children:["Reply on Bluesky"," ",/*#__PURE__*/_jsx("a",{href:postUrl,className:"underline",target:"_blank",rel:"noreferrer noopener",children:"here"})," ","to join the conversation."]}),/*#__PURE__*/_jsx("hr",{className:"my-2"}),/*#__PURE__*/_jsxs("div",{className:"space-y-4",children:[sortedReplies.slice(0,visibleCount).map(reply=>{if(!AppBskyFeedDefs.isThreadViewPost(reply))return null;return /*#__PURE__*/_jsx(Comment,{comment:reply},reply.post.uri)}),visibleCount<sortedReplies.length&&/*#__PURE__*/_jsx("button",{onClick:showMore,className:"w-full text-sm text-blue-400 p-2 px-4 border rounded-lg hover:bg-[#2e3f51] transition",children:"Show more comments"})]})]})};const Comment=({comment})=>{const author=comment.post.author;const avatarClassName="size-6 shrink-0 rounded-full bg-gray-300";if(!AppBskyFeedPost.isRecord(comment.post.record))return null;return /*#__PURE__*/_jsxs("div",{className:"text-base space-y-4",children:[/*#__PURE__*/_jsxs("div",{className:"flex xmax-w-xl flex-col gap-2",children:[/*#__PURE__*/_jsxs("a",{className:"flex flex-row items-center gap-2 hover:underline",href:`https://bsky.app/profile/${author.did}`,target:"_blank",rel:"noreferrer noopener",children:[author.avatar?/*#__PURE__*/_jsx("img",{src:comment.post.author.avatar,alt:"avatar",className:avatarClassName,loading:"lazy"}):/*#__PURE__*/_jsx("div",{className:avatarClassName}),/*#__PURE__*/_jsxs("p",{className:"line-clamp-1",children:[(author.displayName||author.handle)&&/*#__PURE__*/_jsxs(_Fragment,{children:[author.displayName||author.handle," "]}),author.handle&&/*#__PURE__*/_jsxs("span",{className:"text-sm text-textLight dark:text-textDark",children:["@",author.handle]})]})]}),/*#__PURE__*/_jsxs("a",{href:`https://bsky.app/profile/${author.did}/post/${comment.post.uri.split("/").pop()}`,target:"_blank",rel:"noreferrer noopener",className:"flex-1 flex-col flex gap-2",children:[/*#__PURE__*/_jsx(PostContent,{record:comment.post.record,isComment:true}),/*#__PURE__*/_jsx("div",{className:"max-w-xl",children:/*#__PURE__*/_jsx(Embed,{content:comment.post.embed,labels:comment.post.labels},comment.post.uri)}),/*#__PURE__*/_jsx(Actions,{post:comment.post})]})]}),comment.replies&&comment.replies.length>0&&/*#__PURE__*/_jsx("div",{className:"space-y-4 border-l-2 pl-2 dark:hover:border-[#4c6784] hover:border-[#3b5169] transition",children:comment.replies.sort(sortByLikes).map(reply=>{if(!AppBskyFeedDefs.isThreadViewPost(reply))return null;return /*#__PURE__*/_jsx(Comment,{comment:reply},reply.post.uri)})})]})};const Actions=({post})=>{var _post_replyCount,_post_repostCount,_post_likeCount;return /*#__PURE__*/_jsxs("div",{className:"flex w-full max-w-[150px] flex-row items-center justify-between opacity-60",children:[/*#__PURE__*/_jsxs("div",{className:"flex flex-row items-center gap-1.5",children:[/*#__PURE__*/_jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor",className:"size-4",children:/*#__PURE__*/_jsx("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M12 20.25c4.97 0 9-3.694 9-8.25s-4.03-8.25-9-8.25S3 7.444 3 12c0 2.104.859 4.023 2.273 5.48.432.447.74 1.04.586 1.641a4.483 4.483 0 0 1-.923 1.785A5.969 5.969 0 0 0 6 21c1.282 0 2.47-.402 3.445-1.087.81.22 1.668.337 2.555.337Z"})}),/*#__PURE__*/_jsx("p",{className:"text-xs",children:(_post_replyCount=post.replyCount)!=null?_post_replyCount:0})]}),/*#__PURE__*/_jsxs("div",{className:"flex flex-row items-center gap-1.5",children:[/*#__PURE__*/_jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor",className:"size-4",children:/*#__PURE__*/_jsx("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M19.5 12c0-1.232-.046-2.453-.138-3.662a4.006 4.006 0 0 0-3.7-3.7 48.678 48.678 0 0 0-7.324 0 4.006 4.006 0 0 0-3.7 3.7c-.017.22-.032.441-.046.662M19.5 12l3-3m-3 3-3-3m-12 3c0 1.232.046 2.453.138 3.662a4.006 4.006 0 0 0 3.7 3.7 48.656 48.656 0 0 0 7.324 0 4.006 4.006 0 0 0 3.7-3.7c.017-.22.032-.441.046-.662M4.5 12l3 3m-3-3-3 3"})}),/*#__PURE__*/_jsx("p",{className:"text-xs",children:(_post_repostCount=post.repostCount)!=null?_post_repostCount:0})]}),/*#__PURE__*/_jsxs("div",{className:"flex flex-row items-center gap-1.5",children:[/*#__PURE__*/_jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor",className:"size-4",children:/*#__PURE__*/_jsx("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12Z"})}),/*#__PURE__*/_jsx("p",{className:"text-xs",children:(_post_likeCount=post.likeCount)!=null?_post_likeCount:0})]})]})};const sortByLikes=(a,b)=>{if(!AppBskyFeedDefs.isThreadViewPost(a)||!AppBskyFeedDefs.isThreadViewPost(b)){return 0}var _b_post_likeCount,_a_post_likeCount;return((_b_post_likeCount=b.post.likeCount)!=null?_b_post_likeCount:0)-((_a_post_likeCount=a.post.likeCount)!=null?_a_post_likeCount:0)};