LiveEvent.tsx raw

   1  import { Badge } from '@/components/ui/badge'
   2  import { getLiveEventMetadataFromEvent } from '@/lib/event-metadata'
   3  import { useContentPolicy } from '@/providers/ContentPolicyProvider'
   4  import { useScreenSize } from '@/providers/ScreenSizeProvider'
   5  import { Event } from 'nostr-tools'
   6  import { useMemo } from 'react'
   7  import ClientSelect from '../ClientSelect'
   8  import Image from '../Image'
   9  
  10  export default function LiveEvent({ event, className }: { event: Event; className?: string }) {
  11    const { isSmallScreen } = useScreenSize()
  12  
  13    const { autoLoadMedia } = useContentPolicy()
  14    const metadata = useMemo(() => getLiveEventMetadataFromEvent(event), [event])
  15  
  16    const liveStatusComponent =
  17      metadata.status &&
  18      (metadata.status === 'live' ? (
  19        <Badge className="bg-green-400 hover:bg-green-400">live</Badge>
  20      ) : metadata.status === 'ended' ? (
  21        <Badge variant="destructive">ended</Badge>
  22      ) : (
  23        <Badge variant="secondary">{metadata.status}</Badge>
  24      ))
  25  
  26    const titleComponent = <div className="text-xl font-semibold line-clamp-1">{metadata.title}</div>
  27  
  28    const summaryComponent = metadata.summary && (
  29      <div className="text-sm text-muted-foreground line-clamp-4">{metadata.summary}</div>
  30    )
  31  
  32    const tagsComponent = metadata.tags.length > 0 && (
  33      <div className="flex gap-1 flex-wrap">
  34        {metadata.tags.map((tag) => (
  35          <Badge key={tag} variant="secondary">
  36            {tag}
  37          </Badge>
  38        ))}
  39      </div>
  40    )
  41  
  42    if (isSmallScreen) {
  43      return (
  44        <div className={className}>
  45          {metadata.image && autoLoadMedia && (
  46            <Image
  47              image={{ url: metadata.image, pubkey: event.pubkey }}
  48              className="w-full aspect-video"
  49              hideIfError
  50            />
  51          )}
  52          <div className="space-y-1">
  53            {titleComponent}
  54            {liveStatusComponent}
  55            {summaryComponent}
  56            {tagsComponent}
  57            <ClientSelect className="w-full mt-2" event={event} />
  58          </div>
  59        </div>
  60      )
  61    }
  62  
  63    return (
  64      <div className={className}>
  65        <div className="flex gap-4">
  66          {metadata.image && autoLoadMedia && (
  67            <Image
  68              image={{ url: metadata.image, pubkey: event.pubkey }}
  69              className="aspect-[4/3] xl:aspect-video bg-foreground h-44"
  70              hideIfError
  71            />
  72          )}
  73          <div className="flex-1 w-0 space-y-1">
  74            {titleComponent}
  75            {liveStatusComponent}
  76            {summaryComponent}
  77            {tagsComponent}
  78          </div>
  79        </div>
  80        <ClientSelect className="w-full mt-2" event={event} />
  81      </div>
  82    )
  83  }
  84