tiptap.ts raw

   1  import customEmojiService from '@/services/custom-emoji.service'
   2  import { emojis, shortcodeToEmoji } from '@tiptap/extension-emoji'
   3  import { JSONContent } from '@tiptap/react'
   4  import { nip19 } from 'nostr-tools'
   5  
   6  export function parseEditorJsonToText(node?: JSONContent) {
   7    const text = _parseEditorJsonToText(node)
   8    const regex = /(^|\s+|@)(nostr:)?(nevent|naddr|nprofile|npub)1[a-zA-Z0-9]+/g
   9  
  10    return text.replace(regex, (match, leadingWhitespace) => {
  11      let bech32 = match.trim()
  12      const whitespace = leadingWhitespace || ''
  13  
  14      if (bech32.startsWith('@nostr:')) {
  15        bech32 = bech32.slice(7)
  16      } else if (bech32.startsWith('@')) {
  17        bech32 = bech32.slice(1)
  18      } else if (bech32.startsWith('nostr:')) {
  19        bech32 = bech32.slice(6)
  20      }
  21  
  22      try {
  23        nip19.decode(bech32)
  24        return `${whitespace}nostr:${bech32}`
  25      } catch {
  26        return match
  27      }
  28    }).trim()
  29  }
  30  
  31  function _parseEditorJsonToText(node?: JSONContent): string {
  32    if (!node) return ''
  33  
  34    if (typeof node === 'string') return node
  35  
  36    if (node.type === 'text') {
  37      return node.text || ''
  38    }
  39  
  40    if (node.type === 'hardBreak') {
  41      return '\n'
  42    }
  43  
  44    if (Array.isArray(node.content)) {
  45      return (
  46        node.content.map(_parseEditorJsonToText).join('') + (node.type === 'paragraph' ? '\n' : '')
  47      )
  48    }
  49  
  50    switch (node.type) {
  51      case 'paragraph':
  52        return '\n'
  53      case 'mention':
  54        return node.attrs ? `nostr:${node.attrs.id}` : ''
  55      case 'emoji':
  56        return parseEmojiNodeName(node.attrs?.name)
  57      default:
  58        return ''
  59    }
  60  }
  61  
  62  function parseEmojiNodeName(name?: string): string {
  63    if (!name) return ''
  64    if (customEmojiService.isCustomEmojiId(name)) {
  65      return `:${name}:`
  66    }
  67    const emoji = shortcodeToEmoji(name, emojis)
  68    return emoji ? (emoji.emoji ?? '') : ''
  69  }
  70