index.tsx raw

   1  import { Skeleton } from '@/components/ui/skeleton'
   2  import { NSFW_DISPLAY_POLICY } from '@/constants'
   3  import { isMentioningMutedUsers, isNsfwEvent } from '@/lib/event'
   4  import { cn } from '@/lib/utils'
   5  import { useContentPolicy } from '@/providers/ContentPolicyProvider'
   6  import { TNavigationColumn } from '@/providers/KeyboardNavigationProvider'
   7  import { useMuteList } from '@/providers/MuteListProvider'
   8  import { Event, kinds } from 'nostr-tools'
   9  import { useMemo } from 'react'
  10  import MainNoteCard from './MainNoteCard'
  11  import RepostNoteCard from './RepostNoteCard'
  12  
  13  export default function NoteCard({
  14    event,
  15    className,
  16    filterMutedNotes = true,
  17    pinned = false,
  18    reposters,
  19    navColumn,
  20    navIndex
  21  }: {
  22    event: Event
  23    className?: string
  24    filterMutedNotes?: boolean
  25    pinned?: boolean
  26    reposters?: string[]
  27    navColumn?: TNavigationColumn
  28    navIndex?: number
  29  }) {
  30    const { mutePubkeySet } = useMuteList()
  31    const { hideContentMentioningMutedUsers, nsfwDisplayPolicy } = useContentPolicy()
  32    const shouldHide = useMemo(() => {
  33      if (filterMutedNotes && mutePubkeySet.has(event.pubkey)) {
  34        return true
  35      }
  36      if (hideContentMentioningMutedUsers && isMentioningMutedUsers(event, mutePubkeySet)) {
  37        return true
  38      }
  39      if (nsfwDisplayPolicy === NSFW_DISPLAY_POLICY.HIDE && isNsfwEvent(event)) {
  40        return true
  41      }
  42      return false
  43    }, [event, filterMutedNotes, mutePubkeySet, nsfwDisplayPolicy])
  44    if (shouldHide) return null
  45  
  46    if (event.kind === kinds.Repost || event.kind === kinds.GenericRepost) {
  47      return (
  48        <RepostNoteCard
  49          event={event}
  50          className={className}
  51          filterMutedNotes={filterMutedNotes}
  52          pinned={pinned}
  53          reposters={reposters}
  54          navColumn={navColumn}
  55          navIndex={navIndex}
  56        />
  57      )
  58    }
  59    return (
  60      <MainNoteCard
  61        event={event}
  62        className={className}
  63        pinned={pinned}
  64        reposters={reposters}
  65        navColumn={navColumn}
  66        navIndex={navIndex}
  67      />
  68    )
  69  }
  70  
  71  export function NoteCardLoadingSkeleton({ className }: { className?: string }) {
  72    return (
  73      <div className={cn('px-4 py-3', className)}>
  74        <div className="flex items-center space-x-2">
  75          <Skeleton className="w-10 h-10 rounded-full" />
  76          <div className={`flex-1 w-0`}>
  77            <div className="py-1">
  78              <Skeleton className="h-4 w-16" />
  79            </div>
  80            <div className="py-0.5">
  81              <Skeleton className="h-4 w-12" />
  82            </div>
  83          </div>
  84        </div>
  85        <div className="pt-2">
  86          <div className="my-1">
  87            <Skeleton className="w-full h-4 my-1 mt-2" />
  88          </div>
  89          <div className="my-1">
  90            <Skeleton className="w-2/3 h-4 my-1" />
  91          </div>
  92        </div>
  93      </div>
  94    )
  95  }
  96