From d89fa44244eabd404ca464d7ab94b80d0675a76b Mon Sep 17 00:00:00 2001 From: highperfocused Date: Wed, 4 Mar 2026 19:01:11 +0100 Subject: [PATCH] fix markdown support in ProfessionalBlogPostForm and Editor components --- src/components/ProfessionalBlogPostForm.tsx | 120 ++++++-------------- src/components/blocks/editor-00/editor.tsx | 18 ++- 2 files changed, 47 insertions(+), 91 deletions(-) diff --git a/src/components/ProfessionalBlogPostForm.tsx b/src/components/ProfessionalBlogPostForm.tsx index 059669b..c4218ec 100644 --- a/src/components/ProfessionalBlogPostForm.tsx +++ b/src/components/ProfessionalBlogPostForm.tsx @@ -1,7 +1,8 @@ import { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { nip19 } from 'nostr-tools'; -import { SerializedEditorState } from 'lexical'; +import { $convertToMarkdownString, TRANSFORMERS } from '@lexical/markdown'; +import { EditorState, SerializedEditorState } from 'lexical'; import { useCurrentUser } from '@/hooks/useCurrentUser'; import { usePublishBlogPost } from '@/hooks/usePublishBlogPost'; import { useLongFormContentNote } from '@/hooks/useLongFormContentNote'; @@ -55,7 +56,8 @@ export function ProfessionalBlogPostForm({ editIdentifier }: ProfessionalBlogPos editIdentifier || '' ); - const [editorState, setEditorState] = useState(initialEditorState); + const [editorSerializedState, setEditorSerializedState] = useState(initialEditorState); + const [markdownContent, setMarkdownContent] = useState(''); const [metadata, setMetadata] = useState({ identifier: '', title: '', @@ -67,66 +69,26 @@ export function ProfessionalBlogPostForm({ editIdentifier }: ProfessionalBlogPos // Load existing post data when editing useEffect(() => { - if (existingPost && editIdentifier) { - const d = existingPost.tags.find(([name]) => name === 'd')?.[1] || ''; - const title = existingPost.tags.find(([name]) => name === 'title')?.[1] || ''; - const summary = existingPost.tags.find(([name]) => name === 'summary')?.[1] || ''; - const image = existingPost.tags.find(([name]) => name === 'image')?.[1] || ''; - const hashtags = existingPost.tags - .filter(([name]) => name === 't') - .map(([, value]) => value) - .join(', '); + if (!existingPost || !editIdentifier) return; - setMetadata({ - identifier: d, - title, - summary, - image, - hashtags, - }); + const d = existingPost.tags.find(([name]) => name === 'd')?.[1] || ''; + const title = existingPost.tags.find(([name]) => name === 'title')?.[1] || ''; + const summary = existingPost.tags.find(([name]) => name === 'summary')?.[1] || ''; + const image = existingPost.tags.find(([name]) => name === 'image')?.[1] || ''; + const hashtags = existingPost.tags + .filter(([name]) => name === 't') + .map(([, value]) => value) + .join(', '); - // Convert markdown content to editor state - // We'll use a simple approach - the editor will handle the markdown - // For now, we'll just set it as the initial state - if (existingPost.content) { - try { - // Create a simple editor state with the markdown content as text - // The Lexical markdown plugin should handle conversion - const contentState = { - root: { - children: [ - { - children: [ - { - detail: 0, - format: 0, - mode: "normal", - style: "", - text: existingPost.content, - type: "text", - version: 1, - }, - ], - direction: "ltr", - format: "", - indent: 0, - type: "paragraph", - version: 1, - }, - ], - direction: "ltr", - format: "", - indent: 0, - type: "root", - version: 1, - }, - } as unknown as SerializedEditorState; - setEditorState(contentState); - } catch (error) { - console.error('Failed to parse existing content:', error); - } - } - } + setMetadata({ + identifier: d, + title, + summary, + image, + hashtags, + }); + + setMarkdownContent(existingPost.content || ''); }, [existingPost, editIdentifier]); const handleMetadataChange = (field: keyof typeof metadata, value: string) => { @@ -145,30 +107,11 @@ export function ProfessionalBlogPostForm({ editIdentifier }: ProfessionalBlogPos } }; - const getMarkdownFromEditor = (): string => { - // Extract text content from the editor state - // In a full implementation, you'd use $convertToMarkdownString with proper transformers - try { - interface EditorNode { - children?: Array<{ text?: string }>; - } - - const root = editorState.root as { children?: EditorNode[] }; - const content = (root.children || []) - .map((child: EditorNode) => { - if (child.children && Array.isArray(child.children)) { - return child.children - .map((textNode) => textNode.text || '') - .join(''); - } - return ''; - }) - .join('\n\n'); - return content; - } catch (error) { - console.error('Failed to extract markdown:', error); - return ''; - } + const handleEditorChange = (nextEditorState: EditorState) => { + nextEditorState.read(() => { + const markdown = $convertToMarkdownString(TRANSFORMERS); + setMarkdownContent(markdown); + }); }; const handleSubmit = async (e: React.FormEvent) => { @@ -184,8 +127,6 @@ export function ProfessionalBlogPostForm({ editIdentifier }: ProfessionalBlogPos return; } - const markdownContent = getMarkdownFromEditor(); - if (!markdownContent.trim()) { alert('Please write some content for your post'); return; @@ -439,8 +380,11 @@ export function ProfessionalBlogPostForm({ editIdentifier }: ProfessionalBlogPos
setEditorState(value)} + key={editIdentifier ? `edit-${editIdentifier}-${existingPost?.id ?? 'loading'}` : 'create-post-editor'} + editorSerializedState={editorSerializedState} + initialMarkdown={editIdentifier ? existingPost?.content || '' : undefined} + onChange={handleEditorChange} + onSerializedChange={(value) => setEditorSerializedState(value)} />

diff --git a/src/components/blocks/editor-00/editor.tsx b/src/components/blocks/editor-00/editor.tsx index 216a355..9fe588d 100644 --- a/src/components/blocks/editor-00/editor.tsx +++ b/src/components/blocks/editor-00/editor.tsx @@ -6,6 +6,7 @@ import { } from "@lexical/react/LexicalComposer" import { OnChangePlugin } from "@lexical/react/LexicalOnChangePlugin" import { EditorState, SerializedEditorState } from "lexical" +import { $convertFromMarkdownString, TRANSFORMERS } from "@lexical/markdown" import { editorTheme } from "@/components/editor/themes/editor-theme" import { TooltipProvider } from "@/components/ui/tooltip" @@ -25,22 +26,33 @@ const editorConfig: InitialConfigType = { export function Editor({ editorState, editorSerializedState, + initialMarkdown, onChange, onSerializedChange, }: { editorState?: EditorState editorSerializedState?: SerializedEditorState + initialMarkdown?: string onChange?: (editorState: EditorState) => void onSerializedChange?: (editorSerializedState: SerializedEditorState) => void }) { + const resolvedInitialEditorState = editorState + ? editorState + : initialMarkdown !== undefined + ? () => { + $convertFromMarkdownString(initialMarkdown, TRANSFORMERS) + } + : editorSerializedState + ? JSON.stringify(editorSerializedState) + : undefined + return (