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,6 +1,5 @@
import { toNoteList } from '@/lib/link'
import { SecondaryPageLink } from '@/PageManager'
import { TEmbeddedRenderer } from './types'
export function EmbeddedHashtag({ hashtag }: { hashtag: string }) {
return (
@@ -9,14 +8,7 @@ export function EmbeddedHashtag({ hashtag }: { hashtag: string }) {
to={toNoteList({ hashtag })}
onClick={(e) => e.stopPropagation()}
>
#{hashtag}
{hashtag}
</SecondaryPageLink>
)
}
export const embeddedHashtagRenderer: TEmbeddedRenderer = {
regex: /#([\p{L}\p{N}\p{M}_]+)/gu,
render: (hashtag: string, index: number) => {
return <EmbeddedHashtag key={`hashtag-${index}-${hashtag}`} hashtag={hashtag} />
}
}

View File

@@ -1,5 +1,4 @@
import Username, { SimpleUsername } from '../Username'
import { TEmbeddedRenderer } from './types'
export function EmbeddedMention({ userId }: { userId: string }) {
return (
@@ -10,47 +9,3 @@ export function EmbeddedMention({ userId }: { userId: string }) {
export function EmbeddedMentionText({ userId }: { userId: string }) {
return <SimpleUsername userId={userId} showAt className="inline truncate" withoutSkeleton />
}
export const embeddedNostrNpubRenderer: TEmbeddedRenderer = {
regex: /(nostr:npub1[a-z0-9]{58})/g,
render: (id: string, index: number) => {
const npub1 = id.split(':')[1]
return <EmbeddedMention key={`embedded-nostr-npub-${index}-${npub1}`} userId={npub1} />
}
}
export const embeddedNostrProfileRenderer: TEmbeddedRenderer = {
regex: /(nostr:nprofile1[a-z0-9]+)/g,
render: (id: string, index: number) => {
const nprofile = id.split(':')[1]
return <EmbeddedMention key={`embedded-nostr-profile-${index}-${nprofile}`} userId={nprofile} />
}
}
export const embeddedNpubRenderer: TEmbeddedRenderer = {
regex: /(npub1[a-z0-9]{58})/g,
render: (npub1: string, index: number) => {
return <EmbeddedMention key={`embedded-npub-${index}-${npub1}`} userId={npub1} />
}
}
export const embeddedNostrNpubTextRenderer: TEmbeddedRenderer = {
regex: /(nostr:npub1[a-z0-9]{58})/g,
render: (id: string, index: number) => {
const npub1 = id.split(':')[1]
return <EmbeddedMentionText key={`embedded-nostr-npub-text-${index}-${npub1}`} userId={npub1} />
}
}
export const embeddedNostrProfileTextRenderer: TEmbeddedRenderer = {
regex: /(nostr:nprofile1[a-z0-9]+)/g,
render: (id: string, index: number) => {
const nprofile = id.split(':')[1]
return (
<EmbeddedMentionText
key={`embedded-nostr-profile-text-${index}-${nprofile}`}
userId={nprofile}
/>
)
}
}

View File

@@ -1,5 +1,3 @@
import { TEmbeddedRenderer } from './types'
export function EmbeddedNormalUrl({ url }: { url: string }) {
return (
<a
@@ -13,10 +11,3 @@ export function EmbeddedNormalUrl({ url }: { url: string }) {
</a>
)
}
export const embeddedNormalUrlRenderer: TEmbeddedRenderer = {
regex: /(https?:\/\/[\w\p{L}\p{N}\p{M}&.-/?=#\-@%+_:!~*]+)/gu,
render: (url: string, index: number) => {
return <EmbeddedNormalUrl key={`normal-url-${index}-${url}`} url={url} />
}
}

View File

@@ -1,6 +1,5 @@
import { useSecondaryPage } from '@/PageManager'
import { toRelay } from '@/lib/link'
import { TEmbeddedRenderer } from './types'
export function EmbeddedWebsocketUrl({ url }: { url: string }) {
const { push } = useSecondaryPage()
@@ -17,10 +16,3 @@ export function EmbeddedWebsocketUrl({ url }: { url: string }) {
</span>
)
}
export const embeddedWebsocketUrlRenderer: TEmbeddedRenderer = {
regex: /(wss?:\/\/[\w\p{L}\p{N}\p{M}&.-/?=#\-@%+_:!~*]+)/gu,
render: (url: string, index: number) => {
return <EmbeddedWebsocketUrl key={`websocket-url-${index}-${url}`} url={url} />
}
}

View File

@@ -3,16 +3,3 @@ export * from './EmbeddedMention'
export * from './EmbeddedNormalUrl'
export * from './EmbeddedNote'
export * from './EmbeddedWebsocketUrl'
import reactStringReplace from 'react-string-replace'
import { TEmbeddedRenderer } from './types'
export function embedded(content: string, renderers: TEmbeddedRenderer[]) {
let nodes: React.ReactNode[] = [content]
renderers.forEach((renderer) => {
nodes = reactStringReplace(nodes, renderer.regex, renderer.render)
})
return nodes
}

View File

@@ -1,4 +0,0 @@
export type TEmbeddedRenderer = {
regex: RegExp
render: (match: string, index: number) => JSX.Element
}