You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

103 lines
3.5 KiB

import { useSecondaryPage } from '@/PageManager'
import {
extractImageInfosFromEventTags,
getParentEventId,
getUsingClient,
isPictureEvent,
isSupportedKind
} from '@/lib/event'
import { toNote } from '@/lib/link'
import { useScreenSize } from '@/providers/ScreenSizeProvider'
import { Event, kinds } from 'nostr-tools'
import { useMemo } from 'react'
import Content from '../Content'
import { FormattedTimestamp } from '../FormattedTimestamp'
import ImageGallery from '../ImageGallery'
import Nip05 from '../Nip05'
import NoteOptions from '../NoteOptions'
import ParentNotePreview from '../ParentNotePreview'
import TranslateButton from '../TranslateButton'
import UserAvatar from '../UserAvatar'
import Username from '../Username'
import Highlight from './Highlight'
import IValue from './IValue'
import { UnknownNote } from './UnknownNote'
export default function Note({
event,
size = 'normal',
className,
hideParentNotePreview = false
}: {
event: Event
size?: 'normal' | 'small'
className?: string
hideParentNotePreview?: boolean
}) {
const { push } = useSecondaryPage()
const { isSmallScreen } = useScreenSize()
const parentEventId = useMemo(
() => (hideParentNotePreview ? undefined : getParentEventId(event)),
[event, hideParentNotePreview]
)
const imageInfos = useMemo(
() => (isPictureEvent(event) ? extractImageInfosFromEventTags(event) : []),
[event]
)
const usingClient = useMemo(() => getUsingClient(event), [event])
return (
<div className={className}>
<div className="flex justify-between items-start gap-2">
<div className="flex items-center space-x-2 flex-1">
<UserAvatar userId={event.pubkey} size={size === 'small' ? 'medium' : 'normal'} />
<div className="flex-1 w-0">
<div className="flex gap-2 items-baseline">
<Username
userId={event.pubkey}
className={`font-semibold flex truncate ${size === 'small' ? 'text-sm' : ''}`}
skeletonClassName={size === 'small' ? 'h-3' : 'h-4'}
/>
{usingClient && size === 'normal' && (
<span className="text-sm text-muted-foreground shrink-0">using {usingClient}</span>
)}
</div>
<div className="flex items-baseline gap-1 text-sm text-muted-foreground">
<Nip05 pubkey={event.pubkey} append="·" />
<FormattedTimestamp
timestamp={event.created_at}
className="shrink-0"
short={isSmallScreen}
/>
</div>
</div>
</div>
<div className="flex items-center">
<TranslateButton event={event} className={size === 'normal' ? '' : 'pr-0'} />
{size === 'normal' && (
<NoteOptions event={event} className="py-1 shrink-0 [&_svg]:size-5" />
)}
</div>
</div>
{parentEventId && (
<ParentNotePreview
eventId={parentEventId}
className="mt-2"
onClick={(e) => {
e.stopPropagation()
push(toNote(parentEventId))
}}
/>
)}
<IValue event={event} className="mt-2" />
{event.kind === kinds.Highlights ? (
<Highlight className="mt-2" event={event} />
) : isSupportedKind(event.kind) ? (
<Content className="mt-2" event={event} />
) : (
<UnknownNote className="mt-2" event={event} />
)}
{imageInfos.length > 0 && <ImageGallery images={imageInfos} />}
</div>
)
}