import { MentionNote, useArk, useSuggestion, useWidget } from "@lume/ark"; import { CancelIcon, LoaderIcon } from "@lume/icons"; import { WIDGET_KIND } from "@lume/utils"; import { NDKKind } from "@nostr-dev-kit/ndk"; import CharacterCount from "@tiptap/extension-character-count"; import Image from "@tiptap/extension-image"; import Mention from "@tiptap/extension-mention"; import Placeholder from "@tiptap/extension-placeholder"; import { EditorContent, useEditor } from "@tiptap/react"; import StarterKit from "@tiptap/starter-kit"; import { convert } from "html-to-text"; import { nip19 } from "nostr-tools"; import { useLayoutEffect, useRef, useState } from "react"; import { useNavigate, useSearchParams } from "react-router-dom"; import { toast } from "sonner"; import { MediaUploader, MentionPopup } from "./components"; export function NewPostScreen() { const ark = useArk(); const { addWidget } = useWidget(); const { suggestion } = useSuggestion(); const [loading, setLoading] = useState(false); const [height, setHeight] = useState(0); const [searchParams, setSearchParams] = useSearchParams(); const navigate = useNavigate(); const containerRef = useRef(null); const editor = useEditor({ extensions: [ StarterKit.configure(), Placeholder.configure({ placeholder: "Sharing some thoughts..." }), Image.configure({ HTMLAttributes: { class: "rounded-lg w-full object-cover h-auto max-h-[400px] border border-neutral-200 dark:border-neutral-800 outline outline-1 outline-offset-0 outline-neutral-300 dark:outline-neutral-700", }, }), CharacterCount.configure(), Mention.configure({ suggestion, // eslint-disable-next-line @typescript-eslint/no-unused-vars renderLabel({ options, node }) { const npub = nip19.npubEncode(node.attrs.id); return `nostr:${npub}`; }, }), ], content: JSON.parse(localStorage.getItem("editor-post") || "{}"), editorProps: { attributes: { class: "outline-none prose prose-lg prose-neutral max-w-none select-text whitespace-pre-line break-words dark:prose-invert hover:prose-a:text-blue-500", }, }, onUpdate: ({ editor }) => { const jsonContent = JSON.stringify(editor.getJSON()); localStorage.setItem("editor-post", jsonContent); }, }); const submit = async () => { try { if (!ark.ndk.signer) return navigate("/new/privkey"); setLoading(true); // get plaintext content const html = editor.getHTML(); const serializedContent = convert(html, { selectors: [ { selector: "a", options: { linkBrackets: false } }, { selector: "img", options: { linkBrackets: false } }, ], }); // add reply to tags if present const replyTo = searchParams.get("replyTo"); const rootReplyTo = searchParams.get("rootReplyTo"); // publish event const publish = await ark.createEvent({ kind: NDKKind.Text, tags: [], content: serializedContent, replyTo, rootReplyTo, }); if (publish) { toast.success( `Broadcasted to ${publish.seens.length} relays successfully.`, ); // update state setLoading(false); setSearchParams({}); // open new widget with this event id if (!replyTo) { addWidget.mutate({ title: "Thread", content: publish.id, kind: WIDGET_KIND.thread, }); } // reset editor editor.commands.clearContent(); localStorage.setItem("editor-post", "{}"); } } catch (e) { setLoading(false); toast.error(e); } }; useLayoutEffect(() => { setHeight(containerRef.current.clientHeight); }, []); return (