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