This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

semble / src / webapp / components / contentDisplay / richTextRenderer / RichTextRenderer.tsx
2.2 kB 82 lines
1'use client'; 2 3import { RichText } from '@atproto/api'; 4import Link from 'next/link'; 5import { Anchor, AnchorProps, Text, TextProps } from '@mantine/core'; 6import { getDomain } from '@/lib/utils/link'; 7 8interface Props { 9 text: string; 10 linkProps?: Partial<AnchorProps>; 11 textProps?: Partial<TextProps>; 12} 13 14export default function RichTextRenderer({ 15 text, 16 linkProps = {}, 17 textProps = {}, 18}: Props) { 19 const richText = new RichText({ text }); 20 richText.detectFacetsWithoutResolution(); 21 22 return ( 23 <Text span {...textProps}> 24 {Array.from(richText.segments()).map((segment, i) => { 25 // Mentions 26 if (segment.isMention()) { 27 return ( 28 <Anchor 29 key={`mention-${i}`} 30 href={`/profile/${segment.text.slice(1)}`} 31 c={linkProps.c || 'blue'} 32 fw={linkProps.fw || 500} 33 onClick={(e) => e.stopPropagation()} 34 {...linkProps} 35 > 36 {segment.text} 37 </Anchor> 38 ); 39 } 40 41 // Links 42 if (segment.isLink() && segment.link?.uri) { 43 return ( 44 <Anchor 45 key={`link-${i}`} 46 href={segment.link.uri} 47 c={linkProps.c || 'blue'} 48 fw={linkProps.fw || 500} 49 target="_blank" 50 onClick={(e) => e.stopPropagation()} 51 {...linkProps} 52 > 53 {getDomain(segment.link.uri)} 54 </Anchor> 55 ); 56 } 57 58 // Hashtags 59 if (segment.isTag()) { 60 const encodedTag = encodeURIComponent(segment.tag?.tag || ''); 61 return ( 62 <Anchor 63 key={`tag-${i}`} 64 component={Link} 65 c={linkProps.c || 'blue'} 66 fw={linkProps.fw || 500} 67 href={`https://bsky.app/hashtag/${encodedTag}`} 68 target="_blank" 69 onClick={(e) => e.stopPropagation()} 70 {...linkProps} 71 > 72 {segment.text} 73 </Anchor> 74 ); 75 } 76 77 // Plain text 78 return <span key={`text-${i}`}>{segment.text}</span>; 79 })} 80 </Text> 81 ); 82}