feat: improve note details page
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
import { useSecondaryPage } from '@renderer/PageManager'
|
||||
import { toNote } from '@renderer/lib/link'
|
||||
import { formatTimestamp } from '@renderer/lib/timestamp'
|
||||
import { Event } from 'nostr-tools'
|
||||
import Content from '../Content'
|
||||
import NoteStats from '../NoteStats'
|
||||
import UserAvatar from '../UserAvatar'
|
||||
import Username from '../Username'
|
||||
import NoteStats from '../NoteStats'
|
||||
|
||||
export default function Note({
|
||||
event,
|
||||
@@ -33,7 +35,7 @@ export default function Note({
|
||||
</div>
|
||||
</div>
|
||||
{parentEvent && (
|
||||
<div className="text-xs text-muted-foreground truncate mt-2">
|
||||
<div className="text-muted-foreground truncate mt-2">
|
||||
<ParentNote event={parentEvent} />
|
||||
</div>
|
||||
)}
|
||||
@@ -46,8 +48,16 @@ export default function Note({
|
||||
}
|
||||
|
||||
function ParentNote({ event }: { event: Event }) {
|
||||
const { push } = useSecondaryPage()
|
||||
|
||||
return (
|
||||
<div className="flex space-x-1 items-center text-xs rounded-lg border px-1 bg-muted w-fit max-w-full">
|
||||
<div
|
||||
className="flex space-x-1 items-center text-xs rounded-lg px-2 bg-muted w-fit max-w-full hover:text-foreground cursor-pointer"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
push(toNote(event))
|
||||
}}
|
||||
>
|
||||
<div>reply to</div>
|
||||
<UserAvatar userId={event.pubkey} size="tiny" />
|
||||
<div className="truncate">{event.content}</div>
|
||||
|
||||
@@ -26,7 +26,7 @@ export default function ShortTextNoteCard({
|
||||
className={className}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
push(toNote(rootEvent ?? event))
|
||||
push(toNote(event))
|
||||
}}
|
||||
>
|
||||
<Card
|
||||
|
||||
24
src/renderer/src/components/ParentNote/index.tsx
Normal file
24
src/renderer/src/components/ParentNote/index.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import { useSecondaryPage } from '@renderer/PageManager'
|
||||
import { Card } from '@renderer/components/ui/card'
|
||||
import { toNote } from '@renderer/lib/link'
|
||||
import { Event } from 'nostr-tools'
|
||||
import UserAvatar from '../UserAvatar'
|
||||
import Username from '../Username'
|
||||
|
||||
export default function ParentNote({ event }: { event: Event }) {
|
||||
const { push } = useSecondaryPage()
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Card
|
||||
className="flex space-x-1 p-1 items-center hover:bg-muted/50 cursor-pointer text-xs text-muted-foreground hover:text-foreground"
|
||||
onClick={() => push(toNote(event))}
|
||||
>
|
||||
<UserAvatar userId={event.pubkey} size="tiny" />
|
||||
<Username userId={event.pubkey} className="font-semibold" />
|
||||
<div className="truncate">{event.content}</div>
|
||||
</Card>
|
||||
<div className="ml-5 w-px h-2 bg-border" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -48,7 +48,7 @@ export default function ReplyNote({
|
||||
|
||||
function ParentReplyNote({ event }: { event: Event }) {
|
||||
return (
|
||||
<div className="flex space-x-1 items-center text-xs border rounded-lg w-fit px-1 bg-muted max-w-full">
|
||||
<div className="flex space-x-1 items-center text-xs rounded-lg w-fit px-2 bg-muted max-w-full">
|
||||
<div>reply to</div>
|
||||
<UserAvatar userId={event.pubkey} size="tiny" />
|
||||
<div className="truncate">{event.content}</div>
|
||||
|
||||
@@ -56,7 +56,7 @@ export default function ReplyNoteList({ event, className }: { event: Event; clas
|
||||
const onClickParent = (eventId: string) => {
|
||||
const ref = replyRefs.current[eventId]
|
||||
if (ref) {
|
||||
ref.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'nearest' })
|
||||
ref.scrollIntoView({ behavior: 'smooth', block: 'nearest' })
|
||||
}
|
||||
setHighlightReplyId(eventId)
|
||||
setTimeout(() => {
|
||||
|
||||
@@ -13,7 +13,7 @@ const UserAvatarSizeCnMap = {
|
||||
large: 'w-24 h-24',
|
||||
normal: 'w-10 h-10',
|
||||
small: 'w-7 h-7',
|
||||
tiny: 'w-3 h-3'
|
||||
tiny: 'w-4 h-4'
|
||||
}
|
||||
|
||||
export default function UserAvatar({
|
||||
|
||||
@@ -9,15 +9,17 @@ export function isNsfwEvent(event: Event) {
|
||||
}
|
||||
|
||||
export function isReplyNoteEvent(event: Event) {
|
||||
return event.kind === kinds.ShortTextNote && event.tags.some(rootETag)
|
||||
return (
|
||||
event.kind === kinds.ShortTextNote && event.tags.some((tag) => replyETag(tag) || rootETag(tag))
|
||||
)
|
||||
}
|
||||
|
||||
export function getParentEventId(event: Event) {
|
||||
return event.tags.find(replyETag)?.[1]
|
||||
export function getParentEventId(event?: Event) {
|
||||
return event?.tags.find(replyETag)?.[1]
|
||||
}
|
||||
|
||||
export function getRootEventId(event: Event) {
|
||||
return event.tags.find(rootETag)?.[1]
|
||||
export function getRootEventId(event?: Event) {
|
||||
return event?.tags.find(rootETag)?.[1]
|
||||
}
|
||||
|
||||
export function isReplaceable(kind: number) {
|
||||
|
||||
@@ -1,19 +1,25 @@
|
||||
import Note from '@renderer/components/Note'
|
||||
import ParentNote from '@renderer/components/ParentNote'
|
||||
import ReplyNoteList from '@renderer/components/ReplyNoteList'
|
||||
import { Separator } from '@renderer/components/ui/separator'
|
||||
import { useFetchEventById } from '@renderer/hooks'
|
||||
import SecondaryPageLayout from '@renderer/layouts/SecondaryPageLayout'
|
||||
import { getParentEventId, getRootEventId } from '@renderer/lib/event'
|
||||
import { Event } from 'nostr-tools'
|
||||
|
||||
export default function NotePage({ event }: { event?: Event }) {
|
||||
const parentEvent = useFetchEventById(getParentEventId(event))
|
||||
const rootEvent = useFetchEventById(getRootEventId(event))
|
||||
|
||||
if (!event) return null
|
||||
|
||||
return (
|
||||
<SecondaryPageLayout titlebarContent="note">
|
||||
{event && (
|
||||
<>
|
||||
<Note key={`note-${event.id}`} event={event} fetchNoteStats />
|
||||
<Separator className="mt-2" />
|
||||
<ReplyNoteList key={`reply-note-list-${event.id}`} event={event} />
|
||||
</>
|
||||
)}
|
||||
{rootEvent && <ParentNote key={`root-note-${event.id}`} event={rootEvent} />}
|
||||
{parentEvent && <ParentNote key={`parent-note-${event.id}`} event={parentEvent} />}
|
||||
<Note key={`note-${event.id}`} event={event} fetchNoteStats />
|
||||
<Separator className="my-2" />
|
||||
<ReplyNoteList key={`reply-note-list-${event.id}`} event={event} />
|
||||
</SecondaryPageLayout>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user