import React from 'react' import NostrMentionLink from './NostrMentionLink' import { Tokens } from 'applesauce-content/helpers' // Helper to add timestamps to error logs const ts = () => { const now = new Date() const ms = now.getMilliseconds().toString().padStart(3, '0') return `${now.toLocaleTimeString('en-US', { hour12: false })}.${ms}` } interface RichContentProps { content: string className?: string } /** * Component to render text content with: * - Clickable links * - Resolved nostr mentions (npub, nprofile, note, nevent, naddr) * - Plain text * * Handles both nostr:npub1... and plain npub1... formats */ const RichContent: React.FC = ({ content, className = 'bookmark-content' }) => { try { // Pattern to match: // 1. nostr: URIs (nostr:npub1..., nostr:note1..., etc.) using applesauce Tokens.nostrLink // 2. http(s) URLs const nostrPattern = Tokens.nostrLink const urlPattern = /https?:\/\/[^\s]+/gi const combinedPattern = new RegExp(`(${nostrPattern.source}|${urlPattern.source})`, 'gi') const parts = content.split(combinedPattern) // Helper to check if a string is a nostr identifier (without mutating regex state) const isNostrIdentifier = (str: string): boolean => { const testPattern = new RegExp(nostrPattern.source, nostrPattern.flags) return testPattern.test(str) } return (
{parts.map((part, index) => { // Skip empty or undefined parts if (!part) { return null } // Handle nostr: URIs - Tokens.nostrLink matches both formats if (part.startsWith('nostr:')) { return ( ) } // Handle plain nostr identifiers (Tokens.nostrLink matches these too) if (isNostrIdentifier(part)) { return ( ) } // Handle http(s) URLs if (part.match(/^https?:\/\//)) { return ( {part} ) } // Plain text return {part} })}
) } catch (err) { console.error(`[${ts()}] [npub-resolve] RichContent: Error rendering:`, err) return
Error rendering content
} } export default RichContent