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