feat: improve highlight source display and navigation
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
import { useFetchEvent, useTranslatedEvent } from '@/hooks'
|
import { useFetchEvent, useTranslatedEvent } from '@/hooks'
|
||||||
import { createFakeEvent } from '@/lib/event'
|
import { createFakeEvent } from '@/lib/event'
|
||||||
import { toNjump, toNote } from '@/lib/link'
|
import { toNote } from '@/lib/link'
|
||||||
import { isValidPubkey } from '@/lib/pubkey'
|
import { isValidPubkey } from '@/lib/pubkey'
|
||||||
import { generateBech32IdFromATag } from '@/lib/tag'
|
import { generateBech32IdFromATag, generateBech32IdFromETag } from '@/lib/tag'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
import { useSecondaryPage } from '@/PageManager'
|
import { useSecondaryPage } from '@/PageManager'
|
||||||
import { Event } from 'nostr-tools'
|
import { Event } from 'nostr-tools'
|
||||||
@@ -62,7 +62,13 @@ function HighlightSource({ event }: { event: Event }) {
|
|||||||
return sourceTag
|
return sourceTag
|
||||||
}, [event])
|
}, [event])
|
||||||
const { event: referenceEvent } = useFetchEvent(
|
const { event: referenceEvent } = useFetchEvent(
|
||||||
sourceTag && sourceTag[0] === 'e' ? sourceTag[1] : undefined
|
sourceTag
|
||||||
|
? sourceTag[0] === 'e'
|
||||||
|
? generateBech32IdFromETag(sourceTag)
|
||||||
|
: sourceTag[0] === 'a'
|
||||||
|
? generateBech32IdFromATag(sourceTag)
|
||||||
|
: undefined
|
||||||
|
: undefined
|
||||||
)
|
)
|
||||||
const referenceEventId = useMemo(() => {
|
const referenceEventId = useMemo(() => {
|
||||||
if (!sourceTag || sourceTag[0] === 'r') return
|
if (!sourceTag || sourceTag[0] === 'r') return
|
||||||
@@ -110,29 +116,17 @@ function HighlightSource({ event }: { event: Event }) {
|
|||||||
<div className="flex items-center gap-2 text-muted-foreground">
|
<div className="flex items-center gap-2 text-muted-foreground">
|
||||||
<div className="shrink-0">{t('From')}</div>
|
<div className="shrink-0">{t('From')}</div>
|
||||||
{pubkey && <UserAvatar userId={pubkey} size="xSmall" className="cursor-pointer" />}
|
{pubkey && <UserAvatar userId={pubkey} size="xSmall" className="cursor-pointer" />}
|
||||||
{referenceEvent ? (
|
{referenceEventId && (
|
||||||
<div
|
<div
|
||||||
className="truncate underline pointer-events-auto cursor-pointer hover:text-foreground"
|
className="truncate underline pointer-events-auto cursor-pointer hover:text-foreground"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
push(toNote(referenceEvent))
|
push(toNote(referenceEvent ?? referenceEventId))
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ContentPreview event={referenceEvent} />
|
{referenceEvent ? <ContentPreview event={referenceEvent} /> : referenceEventId}
|
||||||
</div>
|
</div>
|
||||||
) : referenceEventId ? (
|
)}
|
||||||
<div className="truncate text-muted-foreground">
|
|
||||||
<a
|
|
||||||
href={toNjump(referenceEventId)}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="underline text-muted-foreground hover:text-foreground"
|
|
||||||
onClick={(e) => e.stopPropagation()}
|
|
||||||
>
|
|
||||||
{toNjump(referenceEventId)}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,13 @@ export function tagNameEquals(tagName: string) {
|
|||||||
|
|
||||||
export function generateBech32IdFromETag(tag: string[]) {
|
export function generateBech32IdFromETag(tag: string[]) {
|
||||||
try {
|
try {
|
||||||
const [, id, relay, , author] = tag
|
const [, id, relay, markerOrPubkey, pubkey] = tag
|
||||||
|
let author: string | undefined
|
||||||
|
if (markerOrPubkey && isValidPubkey(markerOrPubkey)) {
|
||||||
|
author = markerOrPubkey
|
||||||
|
} else if (pubkey && isValidPubkey(pubkey)) {
|
||||||
|
author = pubkey
|
||||||
|
}
|
||||||
return nip19.neventEncode({ id, relays: relay ? [relay] : undefined, author })
|
return nip19.neventEncode({ id, relays: relay ? [relay] : undefined, author })
|
||||||
} catch {
|
} catch {
|
||||||
return undefined
|
return undefined
|
||||||
|
|||||||
13
src/pages/secondary/NotePage/NotFound.tsx
Normal file
13
src/pages/secondary/NotePage/NotFound.tsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import ClientSelect from '@/components/ClientSelect'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
export default function NotFound({ bech32Id }: { bech32Id?: string }) {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="text-muted-foreground w-full h-full flex flex-col items-center justify-center gap-2">
|
||||||
|
<div>{t('Note not found')}</div>
|
||||||
|
<ClientSelect originalNoteId={bech32Id} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -18,7 +18,7 @@ import { Ellipsis } from 'lucide-react'
|
|||||||
import { Event } from 'nostr-tools'
|
import { Event } from 'nostr-tools'
|
||||||
import { forwardRef, useMemo } from 'react'
|
import { forwardRef, useMemo } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import NotFoundPage from '../NotFoundPage'
|
import NotFound from './NotFound'
|
||||||
|
|
||||||
const NotePage = forwardRef(({ id, index }: { id?: string; index?: number }, ref) => {
|
const NotePage = forwardRef(({ id, index }: { id?: string; index?: number }, ref) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
@@ -59,7 +59,13 @@ const NotePage = forwardRef(({ id, index }: { id?: string; index?: number }, ref
|
|||||||
</SecondaryPageLayout>
|
</SecondaryPageLayout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (!event) return <NotFoundPage />
|
if (!event) {
|
||||||
|
return (
|
||||||
|
<SecondaryPageLayout ref={ref} index={index} title={t('Note')} displayScrollToTopButton>
|
||||||
|
<NotFound bech32Id={id} />
|
||||||
|
</SecondaryPageLayout>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SecondaryPageLayout ref={ref} index={index} title={t('Note')} displayScrollToTopButton>
|
<SecondaryPageLayout ref={ref} index={index} title={t('Note')} displayScrollToTopButton>
|
||||||
|
|||||||
Reference in New Issue
Block a user