a tool for shared writing and social publishing
at feature/reader 124 lines 3.6 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 let isLocked = useEntity(props.entityID, "block/is-locked")?.data.value; 22 23 let entity_set = useEntitySetContext(); 24 let [urlValue, setUrlValue] = useState(""); 25 26 let submit = async () => { 27 if (!rep) return; 28 let entity = props.entityID; 29 30 let blueskyPostBlock = await addBlueskyPostBlock(urlValue, entity, rep); 31 if (blueskyPostBlock === false) { 32 let rect = document 33 .getElementById("bluesky-post-block-submit") 34 ?.getBoundingClientRect(); 35 smoker({ 36 error: true, 37 text: "post not found!", 38 position: { 39 x: (rect && rect.left + 12) || 0, 40 y: (rect && rect.top) || 0, 41 }, 42 }); 43 } 44 }; 45 let smoker = useSmoker(); 46 function errorSmokers(x: number, y: number) { 47 if (!urlValue || urlValue === "") { 48 smoker({ 49 error: true, 50 text: "no url!", 51 position: { 52 x: x, 53 y: y, 54 }, 55 }); 56 return; 57 } 58 if (!isUrl(urlValue) || !urlValue.includes("bsky.app")) { 59 smoker({ 60 error: true, 61 text: "invalid bluesky url!", 62 position: { 63 x: x, 64 y: y, 65 }, 66 }); 67 return; 68 } 69 } 70 71 return ( 72 <form 73 onSubmit={(e) => { 74 e.preventDefault(); 75 let rect = document 76 .getElementById("bluesky-post-block-submit") 77 ?.getBoundingClientRect(); 78 79 rect && errorSmokers(rect.left + 12, rect.top); 80 submit(); 81 }} 82 > 83 <div className={`max-w-sm flex gap-2 rounded-md text-secondary`}> 84 {/* TODO: bsky icon? */} 85 <BlockBlueskySmall 86 className={`shrink-0 ${isSelected ? "text-tertiary" : "text-border"} `} 87 /> 88 <Separator /> 89 <Input 90 type="text" 91 className="w-full grow border-none outline-hidden bg-transparent " 92 placeholder="bsky.app/post-url" 93 value={urlValue} 94 disabled={isLocked} 95 onChange={(e) => setUrlValue(e.target.value)} 96 onKeyDown={(e) => { 97 if (e.key === "Enter") { 98 submit(); 99 } 100 if ( 101 e.key === "Backspace" && 102 !e.currentTarget.value && 103 urlValue !== "" 104 ) { 105 e.preventDefault(); 106 } 107 }} 108 /> 109 <button 110 type="submit" 111 id="bluesky-post-block-submit" 112 className={`p-1 ${isSelected && !isLocked ? "text-accent-contrast" : "text-border"}`} 113 onMouseDown={(e) => { 114 e.preventDefault(); 115 errorSmokers(e.clientX + 12, e.clientY); 116 submit(); 117 }} 118 > 119 <CheckTiny /> 120 </button> 121 </div> 122 </form> 123 ); 124};