From 064c6e79236796a4dd4a18528a14a354bc247faa Mon Sep 17 00:00:00 2001 From: codytseng Date: Thu, 18 Dec 2025 16:36:31 +0800 Subject: [PATCH] feat: long form article --- src/components/HighlightButton/index.tsx | 2 +- src/components/Note/LongFormArticle/index.tsx | 112 +++++++++++------- 2 files changed, 67 insertions(+), 47 deletions(-) diff --git a/src/components/HighlightButton/index.tsx b/src/components/HighlightButton/index.tsx index 954294fc..3406be63 100644 --- a/src/components/HighlightButton/index.tsx +++ b/src/components/HighlightButton/index.tsx @@ -47,7 +47,7 @@ export default function HighlightButton({ onHighlight, containerRef }: Highlight // Position button above the selection area, centered horizontally setPosition({ - top: rect.top + scrollTop - 36, // 36px above the selection + top: rect.top + scrollTop - 48, // 48px above the selection left: rect.left + scrollLeft + rect.width / 2 // Center of the selection }) setSelectedText(text) diff --git a/src/components/Note/LongFormArticle/index.tsx b/src/components/Note/LongFormArticle/index.tsx index ce40e915..0b317c91 100644 --- a/src/components/Note/LongFormArticle/index.tsx +++ b/src/components/Note/LongFormArticle/index.tsx @@ -1,10 +1,12 @@ import { SecondaryPageLink, useSecondaryPage } from '@/PageManager' import ImageWithLightbox from '@/components/ImageWithLightbox' +import HighlightButton from '@/components/HighlightButton' +import PostEditor from '@/components/PostEditor' import { getLongFormArticleMetadataFromEvent } from '@/lib/event-metadata' import { toNote, toNoteList, toProfile } from '@/lib/link' import { ExternalLink } from 'lucide-react' import { Event, kinds } from 'nostr-tools' -import { useMemo } from 'react' +import { useMemo, useRef, useState } from 'react' import Markdown from 'react-markdown' import remarkGfm from 'remark-gfm' import NostrNode from './NostrNode' @@ -20,6 +22,14 @@ export default function LongFormArticle({ }) { const { push } = useSecondaryPage() const metadata = useMemo(() => getLongFormArticleMetadataFromEvent(event), [event]) + const contentRef = useRef(null) + const [showHighlightEditor, setShowHighlightEditor] = useState(false) + const [selectedText, setSelectedText] = useState('') + + const handleHighlight = (text: string) => { + setSelectedText(text) + setShowHighlightEditor(true) + } const components = useMemo( () => @@ -74,54 +84,64 @@ export default function LongFormArticle({ /> ) }) as Components, - [] + [event.pubkey] ) return ( -
-

{metadata.title}

- {metadata.summary && ( -
-

{metadata.summary}

-
- )} - {metadata.image && ( - - )} - { - if (url.startsWith('nostr:')) { - return url.slice(6) // Remove 'nostr:' prefix for rendering - } - return url - }} - components={components} + <> +
- {event.content} - - {metadata.tags.length > 0 && ( -
- {metadata.tags.map((tag) => ( -
{ - e.stopPropagation() - push(toNoteList({ hashtag: tag, kinds: [kinds.LongFormArticle] })) - }} - > - #{tag} -
- ))} -
- )} -
+

{metadata.title}

+ {metadata.summary && ( +
+

{metadata.summary}

+
+ )} + {metadata.image && ( + + )} + { + if (url.startsWith('nostr:')) { + return url.slice(6) // Remove 'nostr:' prefix for rendering + } + return url + }} + components={components} + > + {event.content} + + {metadata.tags.length > 0 && ( +
+ {metadata.tags.map((tag) => ( +
{ + e.stopPropagation() + push(toNoteList({ hashtag: tag, kinds: [kinds.LongFormArticle] })) + }} + > + #{tag} +
+ ))} +
+ )} +
+ + + ) }