From c14cc36e5d46715fc11b18a42d6b0092672a7712 Mon Sep 17 00:00:00 2001 From: Tom Sherman Date: Sun, 28 Jul 2024 10:20:38 +0100 Subject: [PATCH] WIP --- .../[postAuthor]/[postRkey]/_lib/actions.tsx | 69 +------------------ .../editor-state-to-comment-content.test.ts | 17 +++++ .../_lib/editor-state-to-comment-content.ts | 55 +++++++++++++++ 3 files changed, 75 insertions(+), 66 deletions(-) create mode 100644 packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/_lib/editor-state-to-comment-content.test.ts create mode 100644 packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/_lib/editor-state-to-comment-content.ts diff --git a/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/_lib/actions.tsx b/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/_lib/actions.tsx index 7a8cf378..282ef4e1 100644 --- a/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/_lib/actions.tsx +++ b/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/_lib/actions.tsx @@ -1,10 +1,6 @@ "use server"; -import { - CommentCollection, - createComment, - deleteComment, -} from "@/lib/data/atproto/comment"; +import { CommentCollection, deleteComment } from "@/lib/data/atproto/comment"; import { DID } from "@/lib/data/atproto/did"; import { deletePost } from "@/lib/data/atproto/post"; import { createVote, deleteVote } from "@/lib/data/atproto/vote"; @@ -13,19 +9,8 @@ import { getPost } from "@/lib/data/db/post"; import { getVoteForComment } from "@/lib/data/db/vote"; import { ensureUser } from "@/lib/data/user"; import { createHeadlessEditor } from "@lexical/headless"; -import { - SerializedEditorState, - $parseSerializedNode, - LexicalEditor, - $getRoot, - EditorState, - LexicalNode, - $isTextNode, - $isElementNode, - RootNode, -} from "lexical"; -import { $dfs } from "@lexical/utils"; -import { revalidatePath } from "next/cache"; +import { SerializedEditorState, RootNode } from "lexical"; +import { editorStateToCommentContent } from "./editor-state-to-comment-content"; export async function createCommentAction(input: { parentRkey?: string; @@ -79,54 +64,6 @@ async function waitForComment(rkey: string) { } } -function editorStateToCommentContent(editorState: EditorState) { - return editorState.read(() => { - const root = $getRoot(); - const content = $nodeToCommentContent(root); - const text = root.getTextContent(); - }); -} - -const FORMATS = ["bold", "italic", "strikethrough"] as const; - -type CommentFacet = - | { - $type: "fyi.frontpage.richtext.facet#format"; - format: (typeof FORMATS)[number]; - } - | { - $type: "fyi.frontpage.richtext.facet#link"; - uri: string; - }; - -type CommentContent = - | string - | { content: CommentContent; facets: CommentFacet[] } - | CommentContent[]; - -function $nodeToCommentContent(node: LexicalNode): CommentContent { - if ($isTextNode(node)) { - console.log("text node", node); - const formats = FORMATS.filter((format) => node.hasFormat(format)); - if (formats.length === 0) { - return node.getTextContent(); - } - - return { - content: node.getTextContent(), - facets: formats.map((format) => ({ - $type: "fyi.frontpage.richtext.facet#format", - format, - })), - }; - } else if ($isElementNode(node)) { - console.log("element node", node); - return node.getChildren().map($nodeToCommentContent); - } else { - throw new Error("Unknown node type"); - } -} - export async function deletePostAction(rkey: string) { await deletePost(rkey); } diff --git a/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/_lib/editor-state-to-comment-content.test.ts b/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/_lib/editor-state-to-comment-content.test.ts new file mode 100644 index 00000000..2eec961c --- /dev/null +++ b/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/_lib/editor-state-to-comment-content.test.ts @@ -0,0 +1,17 @@ +import { createHeadlessEditor } from "@lexical/headless"; +import { $createParagraphNode, $createTextNode, $getRoot } from "lexical"; +import { expect, test } from "vitest"; +import { editorStateToCommentContent } from "./editor-state-to-comment-content"; + +test("simple string", () => { + const editor = createHeadlessEditor(); + editor.update(() => + $getRoot().append( + $createParagraphNode().append($createTextNode("Hello, world!")), + ), + ); + + expect(editorStateToCommentContent(editor.getEditorState())).toEqual( + "Hello, world!", + ); +}); diff --git a/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/_lib/editor-state-to-comment-content.ts b/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/_lib/editor-state-to-comment-content.ts new file mode 100644 index 00000000..ebb0593b --- /dev/null +++ b/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/_lib/editor-state-to-comment-content.ts @@ -0,0 +1,55 @@ +import { + $getRoot, + $isElementNode, + $isTextNode, + EditorState, + LexicalNode, +} from "lexical"; + +export function editorStateToCommentContent(editorState: EditorState) { + return editorState.read(() => { + const root = $getRoot(); + const content = $nodeToCommentContent(root); + return content; + }); +} + +const FORMATS = ["bold", "italic", "strikethrough"] as const; + +type CommentFacet = + | { + $type: "fyi.frontpage.richtext.facet#format"; + format: (typeof FORMATS)[number]; + } + | { + $type: "fyi.frontpage.richtext.facet#link"; + uri: string; + }; + +type CommentContent = + | string + | { content: CommentContent; facets: CommentFacet[] } + | CommentContent[]; + +function $nodeToCommentContent(node: LexicalNode): CommentContent { + if ($isTextNode(node)) { + console.log("text node", node); + const formats = FORMATS.filter((format) => node.hasFormat(format)); + if (formats.length === 0) { + return node.getTextContent(); + } + + return { + content: node.getTextContent(), + facets: formats.map((format) => ({ + $type: "fyi.frontpage.richtext.facet#format", + format, + })), + }; + } else if ($isElementNode(node)) { + console.log("element node", node); + return node.getChildren().map($nodeToCommentContent); + } else { + throw new Error("Unknown node type"); + } +}