index.tsx raw
1 import {
2 EmbeddedEmojiParser,
3 EmbeddedHashtagParser,
4 EmbeddedMentionParser,
5 EmbeddedUrlParser,
6 EmbeddedWebsocketUrlParser,
7 parseContent
8 } from '@/lib/content-parser'
9 import { TEmoji } from '@/types'
10 import { useMemo } from 'react'
11 import { EmbeddedHashtag, EmbeddedMention, EmbeddedWebsocketUrl } from '../Embedded'
12 import Emoji from '../Emoji'
13 import ExternalLink from '../ExternalLink'
14
15 export default function ProfileAbout({
16 about,
17 emojis,
18 className
19 }: {
20 about?: string
21 emojis?: TEmoji[]
22 className?: string
23 }) {
24 const aboutNodes = useMemo(() => {
25 if (!about) return null
26
27 const nodes = parseContent(about, [
28 EmbeddedMentionParser,
29 EmbeddedWebsocketUrlParser,
30 EmbeddedUrlParser,
31 EmbeddedHashtagParser,
32 EmbeddedEmojiParser
33 ])
34
35 // Create emoji map for quick lookup
36 const emojiMap = new Map<string, TEmoji>()
37 emojis?.forEach((emoji) => {
38 emojiMap.set(emoji.shortcode, emoji)
39 })
40
41 return nodes.map((node, index) => {
42 if (node.type === 'url') {
43 return <ExternalLink key={index} url={node.data} />
44 }
45 if (node.type === 'websocket-url') {
46 return <EmbeddedWebsocketUrl key={index} url={node.data} />
47 }
48 if (node.type === 'hashtag') {
49 return <EmbeddedHashtag key={index} hashtag={node.data} />
50 }
51 if (node.type === 'mention') {
52 return <EmbeddedMention key={index} userId={node.data.split(':')[1]} />
53 }
54 if (node.type === 'emoji') {
55 const shortcode = node.data.split(':')[1]
56 const emoji = emojiMap.get(shortcode)
57 if (!emoji) return node.data
58 return <Emoji classNames={{ img: 'mb-1' }} emoji={emoji} key={index} />
59 }
60 return node.data
61 })
62 }, [about, emojis])
63
64 return <div className={className}>{aboutNodes}</div>
65 }
66