([]);
+
+ // Process the content to render mentions, links, etc.
+ useEffect(() => {
+ if (!event || event.kind !== 1) return;
+
+ const processContent = async () => {
+ const text = event.content;
+
+ // Regular expressions for different patterns
+ const urlRegex = /(https?:\/\/[^\s]+)/g;
+ const nostrRegex = /nostr:(npub1|note1|nprofile1|nevent1)([a-z0-9]+)/g;
+ const hashtagRegex = /#(\w+)/g;
+
+ // Split the content by these patterns
+ let lastIndex = 0;
+ const parts: React.ReactNode[] = [];
+
+ // Process URLs
+ const processUrls = () => {
+ text.replace(urlRegex, (match, url, index) => {
+ if (index > lastIndex) {
+ parts.push(text.substring(lastIndex, index));
+ }
+
+ parts.push(
+
+ {url}
+
+ );
+
+ lastIndex = index + match.length;
+ return match;
+ });
+ };
+
+ // Process Nostr references
+ const processNostrRefs = () => {
+ text.replace(nostrRegex, (match, prefix, datastring, index) => {
+ if (index > lastIndex) {
+ parts.push(text.substring(lastIndex, index));
+ }
+
+ try {
+ const nostrId = `${prefix}${datastring}`;
+ const decoded = nip19.decode(nostrId);
+
+ if (decoded.type === 'npub') {
+ const pubkey = decoded.data as string;
+ parts.push(
+
+ );
+ } else if (decoded.type === 'note') {
+ parts.push(
+
+ note
+
+ );
+ } else {
+ // For other types, just show as a link
+ parts.push(
+
+ {match}
+
+ );
+ }
+ } catch (e) {
+ // If decoding fails, just render as text
+ parts.push(match);
+ }
+
+ lastIndex = index + match.length;
+ return match;
+ });
+ };
+
+ // Process hashtags
+ const processHashtags = () => {
+ text.replace(hashtagRegex, (match, tag, index) => {
+ if (index > lastIndex) {
+ parts.push(text.substring(lastIndex, index));
+ }
+
+ parts.push(
+
+ #{tag}
+
+ );
+
+ lastIndex = index + match.length;
+ return match;
+ });
+ };
+
+ // Run all processors
+ processUrls();
+ processNostrRefs();
+ processHashtags();
+
+ // Add any remaining text
+ if (lastIndex < text.length) {
+ parts.push(text.substring(lastIndex));
+ }
+
+ // If no special content was found, just use the plain text
+ if (parts.length === 0) {
+ parts.push(text);
+ }
+
+ setContent(parts);
+ };
+
+ processContent();
+ }, [event]);
+
+ return (
+
+ {content.length > 0 ? content : event.content}
+
+ );
+}
+
+// Helper component to display user mentions
+function NostrMention({ pubkey }: { pubkey: string }) {
+ const author = useAuthor(pubkey);
+ const displayName = author.data?.metadata?.name || pubkey.slice(0, 8);
+
+ return (
+
+ @{displayName}
+
+ );
+}
\ No newline at end of file