feat: enhance post content parsing and rendering (#263)

This commit is contained in:
Cody Tseng
2025-04-10 23:06:28 +08:00
committed by GitHub
parent e9f8b2166e
commit 0569a1dd26
27 changed files with 441 additions and 296 deletions

View File

@@ -1,13 +1,15 @@
import { extractEmbeddedNotesFromContent, extractImagesFromContent } from '@/lib/event'
import {
EmbeddedEventParser,
EmbeddedImageParser,
EmbeddedMentionParser,
EmbeddedVideoParser,
parseContent
} from '@/lib/content-parser'
import { cn } from '@/lib/utils'
import { Event } from 'nostr-tools'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import {
embedded,
embeddedNostrNpubTextRenderer,
embeddedNostrProfileTextRenderer
} from '../Embedded'
import { EmbeddedMentionText } from '../Embedded'
export default function ContentPreview({
event,
@@ -17,24 +19,36 @@ export default function ContentPreview({
className?: string
}) {
const { t } = useTranslation()
const content = useMemo(() => {
if (!event) return `[${t('Not found the note')}]`
const { contentWithoutEmbeddedNotes, embeddedNotes } = extractEmbeddedNotesFromContent(
event.content
)
const { contentWithoutImages, images } = extractImagesFromContent(contentWithoutEmbeddedNotes)
const contents = [contentWithoutImages]
if (images?.length) {
contents.push(`[${t('image')}]`)
}
if (embeddedNotes.length) {
contents.push(`[${t('note')}]`)
}
return embedded(contents.join(' '), [
embeddedNostrProfileTextRenderer,
embeddedNostrNpubTextRenderer
const nodes = useMemo(() => {
if (!event) return [{ type: 'text', data: `[${t('Not found the note')}]` }]
return parseContent(event.content, [
EmbeddedImageParser,
EmbeddedVideoParser,
EmbeddedEventParser,
EmbeddedMentionParser
])
}, [event])
return <div className={cn('pointer-events-none', className)}>{content}</div>
return (
<div className={cn('pointer-events-none', className)}>
{nodes.map((node, index) => {
if (node.type === 'text') {
return node.data
}
if (node.type === 'image' || node.type === 'images') {
return index > 0 ? ` [${t('image')}]` : `[${t('image')}]`
}
if (node.type === 'video') {
return index > 0 ? ` [${t('video')}]` : `[${t('video')}]`
}
if (node.type === 'event') {
return index > 0 ? ` [${t('note')}]` : `[${t('note')}]`
}
if (node.type === 'mention') {
return <EmbeddedMentionText key={index} userId={node.data.split(':')[1]} />
}
})}
</div>
)
}