a tool for shared writing and social publishing
at main 85 lines 3.0 kB view raw
1import { useEntitySetContext } from "components/EntitySetProvider"; 2import { useEffect } from "react"; 3import { useEntity } from "src/replicache"; 4import { useUIState } from "src/useUIState"; 5import { BlockProps, BlockLayout } from "../Block"; 6import { elementId } from "src/utils/elementId"; 7import { focusBlock } from "src/utils/focusBlock"; 8import { AppBskyFeedDefs } from "@atproto/api"; 9import { PostNotAvailable } from "./BlueskyEmbed"; 10import { BlueskyPostEmpty } from "./BlueskyEmpty"; 11 12import { BskyPostContent } from "app/lish/[did]/[publication]/[rkey]/BskyPostContent"; 13import { PostView } from "@atproto/api/dist/client/types/app/bsky/feed/defs"; 14 15export const BlueskyPostBlock = (props: BlockProps & { preview?: boolean }) => { 16 let { permissions } = useEntitySetContext(); 17 let isSelected = useUIState((s) => 18 s.selectedBlocks.find((b) => b.value === props.entityID), 19 ); 20 let post = useEntity(props.entityID, "block/bluesky-post")?.data.value; 21 let clientHost = useEntity(props.entityID, "bluesky-post/host")?.data.value; 22 23 useEffect(() => { 24 if (props.preview) return; 25 let input = document.getElementById(elementId.block(props.entityID).input); 26 if (isSelected) { 27 input?.focus(); 28 } else input?.blur(); 29 }, [isSelected, props.entityID, props.preview]); 30 31 switch (true) { 32 case !post: 33 if (!permissions.write) return null; 34 return ( 35 <label 36 id={props.preview ? undefined : elementId.block(props.entityID).input} 37 className={` 38 w-full h-[104px] p-2 39 text-tertiary hover:text-accent-contrast hover:cursor-pointer 40 flex flex-auto gap-2 items-center justify-center hover:border-2 border-dashed rounded-lg 41 ${isSelected ? "border-2 border-tertiary" : "border border-border"} 42 ${props.pageType === "canvas" && "bg-bg-page"}`} 43 onMouseDown={() => { 44 focusBlock( 45 { type: props.type, value: props.entityID, parent: props.parent }, 46 { type: "start" }, 47 ); 48 }} 49 > 50 <BlueskyPostEmpty {...props} /> 51 </label> 52 ); 53 54 case AppBskyFeedDefs.isBlockedPost(post) || 55 AppBskyFeedDefs.isBlockedAuthor(post) || 56 AppBskyFeedDefs.isNotFoundPost(post): 57 return ( 58 <BlockLayout isSelected={!!isSelected} className="w-full"> 59 <PostNotAvailable /> 60 </BlockLayout> 61 ); 62 63 case AppBskyFeedDefs.isThreadViewPost(post): 64 let postView = post.post as PostView; 65 66 return ( 67 <BlockLayout 68 isSelected={!!isSelected} 69 hasBackground="page" 70 borderOnHover 71 className="blueskyPostBlock sm:px-3! sm:py-2! px-2! py-1!" 72 > 73 <BskyPostContent 74 post={postView} 75 parent={undefined} 76 showBlueskyLink={true} 77 showEmbed={true} 78 avatarSize="large" 79 className="text-sm text-secondary " 80 clientHost={clientHost} 81 /> 82 </BlockLayout> 83 ); 84 } 85};