import { logContentSpacing, reprString } from '@/lib/content-spacing-debug' import customEmojiService from '@/services/custom-emoji.service' import { emojis, shortcodeToEmoji } from '@tiptap/extension-emoji' import { JSONContent } from '@tiptap/react' import { nip19 } from 'nostr-tools' export function parseEditorJsonToText(node?: JSONContent) { const rawJoined = _parseEditorJsonToText(node) let text = rawJoined.trim() const trace = rawJoined.includes('nostr:') || /npub1|nprofile1/.test(rawJoined) if (trace) { logContentSpacing('parseEditorJsonToText:joined', { beforeTrimRepr: reprString(rawJoined), afterTrimRepr: reprString(text) }) } const regex = /(?:^|\s)(nevent|naddr|nprofile|npub)1[a-zA-Z0-9]+/g text = text.replace(regex, (match) => { const trimmed = match.trim() const leadingSpace = match.startsWith(' ') ? ' ' : '' try { nip19.decode(trimmed) return `${leadingSpace}nostr:${trimmed}` } catch { return match } }) // Ensure space before nostr: when not already preceded by space (fixes "Like:nostr:npub" and "Like:\nnostr:npub") const beforeNostrSpacePass = text text = text.replace(/(.)(?=nostr:)/g, (_, prev) => (prev === ' ' ? prev : prev + ' ')) if (trace) { logContentSpacing('parseEditorJsonToText:after-nostr-prefix-pass', { beforeRepr: reprString(beforeNostrSpacePass), afterRepr: reprString(text) }) } return text } function _parseEditorJsonToText(node?: JSONContent): string { if (!node) return '' if (typeof node === 'string') return node if (node.type === 'text') { return node.text || '' } if (node.type === 'hardBreak') { return '\n' } if (Array.isArray(node.content)) { return ( node.content.map(_parseEditorJsonToText).join('') + (node.type === 'paragraph' ? '\n' : '') ) } switch (node.type) { case 'paragraph': return '\n' case 'mention': return node.attrs ? `nostr:${node.attrs.id}` : '' case 'emoji': return parseEmojiNodeName(node.attrs?.name) default: return '' } } function parseEmojiNodeName(name?: string): string { if (!name) return '' if (customEmojiService.isCustomEmojiId(name)) { const custom = customEmojiService.getEmojiById(name) return custom ? `:${custom.shortcode}:` : `:${name}:` } const native = shortcodeToEmoji(name, emojis) ?? shortcodeToEmoji(name.replace(/\s+/g, '_'), emojis) return native?.emoji ?? `:${name}:` }