index.tsx raw
1 import { ExtendedKind } from '@/constants'
2 import { isMentioningMutedUsers } from '@/lib/event'
3 import { cn } from '@/lib/utils'
4 import { useContentPolicy } from '@/providers/ContentPolicyProvider'
5 import { useMuteList } from '@/providers/MuteListProvider'
6 import { Event, kinds } from 'nostr-tools'
7 import { useMemo } from 'react'
8 import { useTranslation } from 'react-i18next'
9 import CommunityDefinitionPreview from './CommunityDefinitionPreview'
10 import EmojiPackPreview from './EmojiPackPreview'
11 import FollowPackPreview from './FollowPackPreview'
12 import GroupMetadataPreview from './GroupMetadataPreview'
13 import HighlightPreview from './HighlightPreview'
14 import LiveEventPreview from './LiveEventPreview'
15 import LongFormArticlePreview from './LongFormArticlePreview'
16 import NormalContentPreview from './NormalContentPreview'
17 import PictureNotePreview from './PictureNotePreview'
18 import PollPreview from './PollPreview'
19 import VideoNotePreview from './VideoNotePreview'
20
21 export default function ContentPreview({
22 event,
23 className
24 }: {
25 event?: Event
26 className?: string
27 }) {
28 const { t } = useTranslation()
29 const { mutePubkeySet } = useMuteList()
30 const { hideContentMentioningMutedUsers } = useContentPolicy()
31 const isMuted = useMemo(
32 () => (event ? mutePubkeySet.has(event.pubkey) : false),
33 [mutePubkeySet, event]
34 )
35 const isMentioningMuted = useMemo(
36 () =>
37 hideContentMentioningMutedUsers && event
38 ? isMentioningMutedUsers(event, mutePubkeySet)
39 : false,
40 [event, mutePubkeySet]
41 )
42
43 if (!event) {
44 return <div className={cn('pointer-events-none', className)}>{`[${t('Note not found')}]`}</div>
45 }
46
47 if (isMuted) {
48 return (
49 <div className={cn('pointer-events-none', className)}>[{t('This user has been muted')}]</div>
50 )
51 }
52
53 if (isMentioningMuted) {
54 return (
55 <div className={cn('pointer-events-none', className)}>
56 [{t('This note mentions a user you muted')}]
57 </div>
58 )
59 }
60
61 if (
62 [
63 kinds.ShortTextNote,
64 ExtendedKind.COMMENT,
65 ExtendedKind.VOICE,
66 ExtendedKind.VOICE_COMMENT,
67 ExtendedKind.RELAY_REVIEW
68 ].includes(event.kind)
69 ) {
70 return <NormalContentPreview event={event} className={className} />
71 }
72
73 if (event.kind === kinds.Highlights) {
74 return <HighlightPreview event={event} className={className} />
75 }
76
77 if (event.kind === ExtendedKind.POLL) {
78 return <PollPreview event={event} className={className} />
79 }
80
81 if (event.kind === kinds.LongFormArticle) {
82 return <LongFormArticlePreview event={event} className={className} />
83 }
84
85 if (event.kind === ExtendedKind.VIDEO || event.kind === ExtendedKind.SHORT_VIDEO) {
86 return <VideoNotePreview event={event} className={className} />
87 }
88
89 if (event.kind === ExtendedKind.PICTURE) {
90 return <PictureNotePreview event={event} className={className} />
91 }
92
93 if (event.kind === ExtendedKind.GROUP_METADATA) {
94 return <GroupMetadataPreview event={event} className={className} />
95 }
96
97 if (event.kind === kinds.CommunityDefinition) {
98 return <CommunityDefinitionPreview event={event} className={className} />
99 }
100
101 if (event.kind === kinds.LiveEvent) {
102 return <LiveEventPreview event={event} className={className} />
103 }
104
105 if (event.kind === kinds.Emojisets) {
106 return <EmojiPackPreview event={event} className={className} />
107 }
108
109 if (event.kind === ExtendedKind.FOLLOW_PACK) {
110 return <FollowPackPreview event={event} className={className} />
111 }
112
113 return <div className={className}>[{t('Cannot handle event of kind k', { k: event.kind })}]</div>
114 }
115