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