LongFormArticlePreview.tsx raw
1 import { getLongFormArticleMetadataFromEvent } from '@/lib/event-metadata'
2 import { toNoteList } from '@/lib/link'
3 import { useSecondaryPage } from '@/PageManager'
4 import { useContentPolicy } from '@/providers/ContentPolicyProvider'
5 import { useScreenSize } from '@/providers/ScreenSizeProvider'
6 import { Event, kinds } from 'nostr-tools'
7 import { useMemo } from 'react'
8 import Image from '../Image'
9
10 export default function LongFormArticlePreview({
11 event,
12 className
13 }: {
14 event: Event
15 className?: string
16 }) {
17 const { isSmallScreen } = useScreenSize()
18 const { push } = useSecondaryPage()
19 const { autoLoadMedia } = useContentPolicy()
20 const metadata = useMemo(() => getLongFormArticleMetadataFromEvent(event), [event])
21
22 const titleComponent = <div className="text-xl font-semibold line-clamp-2">{metadata.title}</div>
23
24 const tagsComponent = metadata.tags.length > 0 && (
25 <div className="flex gap-1 flex-wrap">
26 {metadata.tags.map((tag) => (
27 <div
28 key={tag}
29 className="flex items-center rounded-full text-xs px-2.5 py-0.5 bg-muted text-muted-foreground max-w-32 cursor-pointer hover:bg-accent hover:text-accent-foreground"
30 onClick={(e) => {
31 e.stopPropagation()
32 push(toNoteList({ hashtag: tag, kinds: [kinds.LongFormArticle] }))
33 }}
34 >
35 #<span className="truncate">{tag}</span>
36 </div>
37 ))}
38 </div>
39 )
40
41 const summaryComponent = metadata.summary && (
42 <div className="text-sm text-muted-foreground line-clamp-4">{metadata.summary}</div>
43 )
44
45 if (isSmallScreen) {
46 return (
47 <div className={className}>
48 {metadata.image && autoLoadMedia && (
49 <Image
50 image={{ url: metadata.image, pubkey: event.pubkey }}
51 className="w-full aspect-video"
52 hideIfError
53 />
54 )}
55 <div className="space-y-1">
56 {titleComponent}
57 {summaryComponent}
58 {tagsComponent}
59 </div>
60 </div>
61 )
62 }
63
64 return (
65 <div className={className}>
66 <div className="flex gap-4">
67 {metadata.image && autoLoadMedia && (
68 <Image
69 image={{ url: metadata.image, pubkey: event.pubkey }}
70 className="aspect-[4/3] xl:aspect-video object-cover bg-foreground h-44"
71 hideIfError
72 />
73 )}
74 <div className="flex-1 w-0 space-y-1">
75 {titleComponent}
76 {summaryComponent}
77 {tagsComponent}
78 </div>
79 </div>
80 </div>
81 )
82 }
83