fix: memoize components to prevent NostrNode

This commit is contained in:
codytseng
2025-08-25 15:52:26 +08:00
parent 9aa63fd11c
commit bd33366342
2 changed files with 48 additions and 49 deletions

View File

@@ -6,7 +6,6 @@ import { Components } from './types'
export default function NostrNode({ rawText, bech32Id }: ComponentProps<Components['nostr']>) {
const { type, id } = useMemo(() => {
if (!bech32Id) return { type: 'invalid', id: '' }
console.log('NostrLink bech32Id:', bech32Id)
try {
const { type } = nip19.decode(bech32Id)
if (type === 'npub') {

View File

@@ -21,42 +21,15 @@ export default function LongFormArticle({
const { push } = useSecondaryPage()
const metadata = useMemo(() => getLongFormArticleMetadataFromEvent(event), [event])
return (
<div
className={`prose prose-zinc max-w-none dark:prose-invert break-words overflow-wrap-anywhere ${className || ''}`}
>
<h1 className="break-words">{metadata.title}</h1>
{metadata.summary && (
<blockquote>
<p className="break-words">{metadata.summary}</p>
</blockquote>
)}
{metadata.image && (
<ImageWithLightbox
image={{ url: metadata.image, pubkey: event.pubkey }}
className="w-full aspect-[3/1] object-cover rounded-lg"
/>
)}
<Markdown
remarkPlugins={[remarkGfm, remarkNostr]}
urlTransform={(url) => {
if (url.startsWith('nostr:')) {
return url.slice(6) // Remove 'nostr:' prefix for rendering
}
return url
}}
components={
{
nostr: (props) => <NostrNode {...props} />,
const components = useMemo(
() =>
({
nostr: ({ rawText, bech32Id }) => <NostrNode rawText={rawText} bech32Id={bech32Id} />,
a: ({ href, children, ...props }) => {
if (!href) {
return <span {...props} className="break-words" />
}
if (
href.startsWith('note1') ||
href.startsWith('nevent1') ||
href.startsWith('naddr1')
) {
if (href.startsWith('note1') || href.startsWith('nevent1') || href.startsWith('naddr1')) {
return (
<SecondaryPageLink
to={toNote(href)}
@@ -91,8 +64,35 @@ export default function LongFormArticle({
p: (props) => <p {...props} className="break-words" />,
div: (props) => <div {...props} className="break-words" />,
code: (props) => <code {...props} className="break-words whitespace-pre-wrap" />
} as Components
}) as Components,
[]
)
return (
<div
className={`prose prose-zinc max-w-none dark:prose-invert break-words overflow-wrap-anywhere ${className || ''}`}
>
<h1 className="break-words">{metadata.title}</h1>
{metadata.summary && (
<blockquote>
<p className="break-words">{metadata.summary}</p>
</blockquote>
)}
{metadata.image && (
<ImageWithLightbox
image={{ url: metadata.image, pubkey: event.pubkey }}
className="w-full aspect-[3/1] object-cover rounded-lg"
/>
)}
<Markdown
remarkPlugins={[remarkGfm, remarkNostr]}
urlTransform={(url) => {
if (url.startsWith('nostr:')) {
return url.slice(6) // Remove 'nostr:' prefix for rendering
}
return url
}}
components={components}
>
{event.content}
</Markdown>