import { useSecondaryPage } from '@/PageManager' import ContentPreview from '@/components/ContentPreview' import Note from '@/components/Note' import NoteInteractions from '@/components/NoteInteractions' import StuffStats from '@/components/StuffStats' import UserAvatar from '@/components/UserAvatar' import { Card } from '@/components/ui/card' import { Separator } from '@/components/ui/separator' import { Skeleton } from '@/components/ui/skeleton' import { ExtendedKind } from '@/constants' import { useFetchEvent } from '@/hooks' import { useKeyboardNavigable } from '@/hooks/useKeyboardNavigable' import SecondaryPageLayout from '@/layouts/SecondaryPageLayout' import { getEventKey, getKeyFromTag, getParentBech32Id, getParentTag, getRootBech32Id } from '@/lib/event' import { toExternalContent, toNote } from '@/lib/link' import { tagNameEquals } from '@/lib/tag' import { cn } from '@/lib/utils' import { Ellipsis } from 'lucide-react' import { Event } from 'nostr-tools' import { forwardRef, useCallback, useMemo } from 'react' import { useTranslation } from 'react-i18next' import NotFound from './NotFound' const NotePage = forwardRef(({ id, index }: { id?: string; index?: number }, ref) => { const { t } = useTranslation() const { event, isFetching } = useFetchEvent(id) const parentEventId = useMemo(() => getParentBech32Id(event), [event]) const rootEventId = useMemo(() => getRootBech32Id(event), [event]) const rootITag = useMemo( () => (event?.kind === ExtendedKind.COMMENT ? event.tags.find(tagNameEquals('I')) : undefined), [event] ) const { isFetching: isFetchingRootEvent, event: rootEvent } = useFetchEvent(rootEventId) const { isFetching: isFetchingParentEvent, event: parentEvent } = useFetchEvent(parentEventId) if (!event && isFetching) { return (
) } if (!event) { return ( ) } // Calculate navIndex offset for replies based on how many parent notes exist const hasRootNote = rootEventId && rootEventId !== parentEventId const hasParentNote = !!parentEventId const parentNoteCount = (hasRootNote ? 1 : 0) + (hasParentNote ? 1 : 0) return (
{rootITag && } {hasRootNote && ( )} {hasParentNote && ( )}
) }) NotePage.displayName = 'NotePage' export default NotePage function ExternalRoot({ value }: { value: string }) { const { push } = useSecondaryPage() return (
push(toExternalContent(value))} >
{value}
) } function ParentNote({ event, eventBech32Id, isFetching, isConsecutive = true, navIndex }: { event?: Event eventBech32Id: string isFetching: boolean isConsecutive?: boolean navIndex?: number }) { const { push } = useSecondaryPage() const handleActivate = useCallback(() => { push(toNote(event ?? eventBech32Id)) }, [push, event, eventBech32Id]) const { ref: navRef, isSelected } = useKeyboardNavigable(2, navIndex ?? 0, { meta: { type: 'note', onActivate: handleActivate } }) if (isFetching) { return (
) } return (
{event && }
{isConsecutive ? (
) : ( )}
) } function isConsecutive(rootEvent?: Event, parentEvent?: Event) { if (!rootEvent || !parentEvent) return false const tag = getParentTag(parentEvent) if (!tag) return false return getEventKey(rootEvent) === getKeyFromTag(tag.tag) }