index.tsx raw
1 import {
2 EmbeddedHashtagParser,
3 EmbeddedUrlParser,
4 EmbeddedWebsocketUrlParser,
5 parseContent
6 } from '@/lib/content-parser'
7 import { cn } from '@/lib/utils'
8 import { useMemo } from 'react'
9 import { EmbeddedHashtag, EmbeddedLNInvoice, EmbeddedWebsocketUrl } from '../Embedded'
10 import ImageGallery from '../ImageGallery'
11 import MediaPlayer from '../MediaPlayer'
12 import WebPreview from '../WebPreview'
13 import XEmbeddedPost from '../XEmbeddedPost'
14 import YoutubeEmbeddedPlayer from '../YoutubeEmbeddedPlayer'
15
16 export default function ExternalContent({
17 content,
18 className,
19 mustLoadMedia
20 }: {
21 content?: string
22 className?: string
23 mustLoadMedia?: boolean
24 }) {
25 const nodes = useMemo(() => {
26 if (!content) return []
27
28 return parseContent(content, [
29 EmbeddedUrlParser,
30 EmbeddedWebsocketUrlParser,
31 EmbeddedHashtagParser
32 ])
33 }, [content])
34
35 if (!nodes || nodes.length === 0) {
36 return null
37 }
38
39 const node = nodes[0]
40
41 if (node.type === 'text') {
42 return (
43 <div className={cn('text-wrap break-words whitespace-pre-wrap', className)}>{content}</div>
44 )
45 }
46
47 if (node.type === 'url') {
48 return <WebPreview url={node.data} className={className} mustLoad={mustLoadMedia} />
49 }
50
51 if (node.type === 'x-post') {
52 return (
53 <XEmbeddedPost
54 url={node.data}
55 className={className}
56 mustLoad={mustLoadMedia}
57 embedded={false}
58 />
59 )
60 }
61
62 if (node.type === 'youtube') {
63 return <YoutubeEmbeddedPlayer url={node.data} className={className} mustLoad={mustLoadMedia} />
64 }
65
66 if (node.type === 'image' || node.type === 'images') {
67 const data = Array.isArray(node.data) ? node.data : [node.data]
68 return (
69 <ImageGallery
70 className={className}
71 images={data.map((url) => ({ url }))}
72 mustLoad={mustLoadMedia}
73 />
74 )
75 }
76
77 if (node.type === 'media') {
78 return <MediaPlayer className={className} src={node.data} mustLoad={mustLoadMedia} />
79 }
80
81 if (node.type === 'invoice') {
82 return <EmbeddedLNInvoice invoice={node.data} className={className} />
83 }
84
85 if (node.type === 'websocket-url') {
86 return <EmbeddedWebsocketUrl url={node.data} />
87 }
88
89 if (node.type === 'hashtag') {
90 return <EmbeddedHashtag hashtag={node.data} />
91 }
92
93 return null
94 }
95