a tool for shared writing and social publishing
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};