Skip to content

Commit 90159c0

Browse files
committed
WIP
1 parent 4ee97d6 commit 90159c0

7 files changed

Lines changed: 819 additions & 46 deletions

File tree

packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/_lib/actions.tsx

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,26 @@ import { parseReportForm } from "@/lib/data/db/report-shared";
1313
import { createReport } from "@/lib/data/db/report";
1414
import { getVoteForComment } from "@/lib/data/db/vote";
1515
import { ensureUser } from "@/lib/data/user";
16+
import { createHeadlessEditor } from "@lexical/headless";
17+
import {
18+
SerializedEditorState,
19+
$parseSerializedNode,
20+
LexicalEditor,
21+
$getRoot,
22+
EditorState,
23+
LexicalNode,
24+
$isTextNode,
25+
$isElementNode,
26+
} from "lexical";
1627
import { revalidatePath } from "next/cache";
28+
import { deletePost } from "@/lib/data/atproto/post";
1729

18-
export async function createCommentAction(
19-
input: { parentRkey?: string; postRkey: string; postAuthorDid: DID },
20-
_prevState: unknown,
21-
formData: FormData,
22-
) {
23-
const content = formData.get("comment") as string;
30+
export async function createCommentAction(input: {
31+
parentRkey?: string;
32+
postRkey: string;
33+
postAuthorDid: DID;
34+
content: SerializedEditorState;
35+
}) {
2436
const user = await ensureUser();
2537

2638
const [post, comment] = await Promise.all([
@@ -41,13 +53,15 @@ export async function createCommentAction(
4153
throw new Error(`[naughty] Cannot comment on deleted post. ${user.did}`);
4254
}
4355

44-
const { rkey } = await createComment({
45-
content,
46-
post,
47-
parent: comment,
48-
});
49-
await waitForComment(rkey);
50-
revalidatePath(`/post`);
56+
const state = createHeadlessEditor().parseEditorState(input.content);
57+
58+
// const { rkey } = await createComment({
59+
// content,
60+
// post,
61+
// parent: comment,
62+
// });
63+
// await waitForComment(rkey);
64+
// revalidatePath(`/post`);
5165
}
5266

5367
const MAX_POLLS = 15;
@@ -64,6 +78,28 @@ async function waitForComment(rkey: string) {
6478
}
6579
}
6680

81+
function editorStateToCommentContent(editorState: EditorState) {
82+
return editorState.read(() => {
83+
const root = $getRoot();
84+
root.getChildren().forEach((child) => {});
85+
86+
const text = root.getTextContent();
87+
});
88+
}
89+
90+
function $nodeToFacets(node: LexicalNode) {
91+
if ($isTextNode(node)) {
92+
if (node.hasFormat("bold")) {
93+
return node.selectStart;
94+
}
95+
}
96+
if ($isElementNode(node) && node.isEmpty()) return [];
97+
}
98+
99+
export async function deletePostAction(rkey: string) {
100+
await deletePost(rkey);
101+
}
102+
67103
export async function deleteCommentAction(rkey: string) {
68104
await ensureUser();
69105
await deleteComment(rkey);

packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/_lib/comment-client.tsx

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
AlertDialogTrigger,
1212
} from "@/lib/components/ui/alert-dialog";
1313
import { Button } from "@/lib/components/ui/button";
14-
import { Textarea } from "@/lib/components/ui/textarea";
14+
import { EditableTextArea } from "@/lib/components/ui/textarea";
1515
import { SimpleTooltip } from "@/lib/components/ui/tooltip";
1616
import { useToast } from "@/lib/components/ui/use-toast";
1717
import {
@@ -22,13 +22,7 @@ import {
2222
reportCommentAction,
2323
} from "./actions";
2424
import { ChatBubbleIcon, TrashIcon } from "@radix-ui/react-icons";
25-
import {
26-
useActionState,
27-
useRef,
28-
useState,
29-
useId,
30-
startTransition,
31-
} from "react";
25+
import { useRef, useState, useId, startTransition, useTransition } from "react";
3226
import {
3327
VoteButton,
3428
VoteButtonState,
@@ -44,6 +38,7 @@ import { DeleteButton } from "@/app/(app)/_components/delete-button";
4438
import { cva, VariantProps } from "class-variance-authority";
4539
import { cn } from "@/lib/utils";
4640
import { ShareDropdownButton } from "@/app/(app)/_components/share-button";
41+
import { LexicalEditor } from "lexical";
4742

4843
const commentVariants = cva(undefined, {
4944
variants: {
@@ -226,7 +221,6 @@ export function NewComment({
226221
postRkey,
227222
postAuthorDid,
228223
extraButton,
229-
textAreaRef,
230224
onActionDone,
231225
}: {
232226
parentRkey?: string;
@@ -237,23 +231,28 @@ export function NewComment({
237231
extraButton?: React.ReactNode;
238232
textAreaRef?: React.RefObject<HTMLTextAreaElement>;
239233
}) {
234+
const editorRef = useRef<LexicalEditor | null>(null);
240235
const [input, setInput] = useState("");
241-
const [_, action, isPending] = useActionState(
242-
createCommentAction.bind(null, { parentRkey, postRkey, postAuthorDid }),
243-
undefined,
244-
);
236+
const [isPending, startTransition] = useTransition();
237+
245238
const id = useId();
246239
const textAreaId = `${id}-comment`;
247240

248241
return (
249242
<form
250-
action={action}
251243
onSubmit={(event) => {
252244
event.preventDefault();
253-
startTransition(() => {
254-
action(new FormData(event.currentTarget));
245+
startTransition(async () => {
246+
const state = editorRef.current?.getEditorState().toJSON();
247+
if (!state) throw new Error("Empty comment");
248+
console.log(state);
249+
await createCommentAction({
250+
parentRkey,
251+
postRkey,
252+
postAuthorDid,
253+
content: state,
254+
});
255255
onActionDone?.();
256-
setInput("");
257256
});
258257
}}
259258
aria-busy={isPending}
@@ -271,7 +270,7 @@ export function NewComment({
271270
}}
272271
className="space-y-2"
273272
>
274-
<Textarea
273+
<EditableTextArea
275274
value={input}
276275
onChange={(event) => {
277276
setInput(event.target.value);
@@ -280,10 +279,10 @@ export function NewComment({
280279
// eslint-disable-next-line jsx-a11y/no-autofocus
281280
autoFocus={autoFocus}
282281
name="comment"
283-
ref={textAreaRef}
282+
ref={editorRef}
284283
placeholder="Write a comment..."
285284
disabled={isPending}
286-
className="resize-y flex-1"
285+
className="resize-y flex-1 overflow-auto grow"
287286
/>
288287
<div className="w-full flex justify-between">
289288
<InputLengthIndicator

0 commit comments

Comments
 (0)