a tool for shared writing and social publishing
at main 122 lines 3.5 kB view raw
1import { useEntitySetContext } from "components/EntitySetProvider"; 2import { generateKeyBetween } from "fractional-indexing"; 3import { useState } from "react"; 4import { useEntity, useReplicache } from "src/replicache"; 5import { useUIState } from "src/useUIState"; 6import { BlockProps } from "../Block"; 7import { v7 } from "uuid"; 8import { useSmoker } from "components/Toast"; 9import { Separator } from "components/Layout"; 10import { Input } from "components/Input"; 11import { isUrl } from "src/utils/isURL"; 12import { addBlueskyPostBlock } from "src/utils/addLinkBlock"; 13import { BlockBlueskySmall } from "components/Icons/BlockBlueskySmall"; 14import { CheckTiny } from "components/Icons/CheckTiny"; 15 16export const BlueskyPostEmpty = (props: BlockProps) => { 17 let { rep } = useReplicache(); 18 let isSelected = useUIState((s) => 19 s.selectedBlocks.find((b) => b.value === props.entityID), 20 ); 21 22 let entity_set = useEntitySetContext(); 23 let [urlValue, setUrlValue] = useState(""); 24 25 let submit = async () => { 26 if (!rep) return; 27 let entity = props.entityID; 28 29 let blueskyPostBlock = await addBlueskyPostBlock(urlValue, entity, rep); 30 if (blueskyPostBlock === false) { 31 let rect = document 32 .getElementById("bluesky-post-block-submit") 33 ?.getBoundingClientRect(); 34 smoker({ 35 error: true, 36 text: "post not found!", 37 position: { 38 x: (rect && rect.left + 12) || 0, 39 y: (rect && rect.top) || 0, 40 }, 41 }); 42 } 43 }; 44 let smoker = useSmoker(); 45 function errorSmokers(x: number, y: number) { 46 if (!urlValue || urlValue === "") { 47 smoker({ 48 error: true, 49 text: "no url!", 50 position: { 51 x: x, 52 y: y, 53 }, 54 }); 55 return; 56 } 57 if (!isUrl(urlValue) || !urlValue.includes("bsky.app")) { 58 smoker({ 59 error: true, 60 text: "invalid bluesky url!", 61 position: { 62 x: x, 63 y: y, 64 }, 65 }); 66 return; 67 } 68 } 69 70 return ( 71 <form 72 onSubmit={(e) => { 73 e.preventDefault(); 74 let rect = document 75 .getElementById("bluesky-post-block-submit") 76 ?.getBoundingClientRect(); 77 78 rect && errorSmokers(rect.left + 12, rect.top); 79 submit(); 80 }} 81 > 82 <div className={`max-w-sm flex gap-2 rounded-md text-secondary`}> 83 {/* TODO: bsky icon? */} 84 <BlockBlueskySmall 85 className={`shrink-0 ${isSelected ? "text-tertiary" : "text-border"} `} 86 /> 87 <Separator /> 88 <Input 89 type="text" 90 className="w-full grow border-none outline-hidden bg-transparent " 91 placeholder="bsky.app/post-url" 92 value={urlValue} 93 onChange={(e) => setUrlValue(e.target.value)} 94 onKeyDown={(e) => { 95 if (e.key === "Enter") { 96 submit(); 97 } 98 if ( 99 e.key === "Backspace" && 100 !e.currentTarget.value && 101 urlValue !== "" 102 ) { 103 e.preventDefault(); 104 } 105 }} 106 /> 107 <button 108 type="submit" 109 id="bluesky-post-block-submit" 110 className={`p-1 ${isSelected ? "text-accent-contrast" : "text-border"}`} 111 onMouseDown={(e) => { 112 e.preventDefault(); 113 errorSmokers(e.clientX + 12, e.clientY); 114 submit(); 115 }} 116 > 117 <CheckTiny /> 118 </button> 119 </div> 120 </form> 121 ); 122};