feat: add enhanced support for kind:1111 comments
This commit is contained in:
@@ -1,205 +0,0 @@
|
|||||||
import { Separator } from '@/components/ui/separator'
|
|
||||||
import { BIG_RELAY_URLS, ExtendedKind } from '@/constants'
|
|
||||||
import { isCommentEvent, isProtectedEvent } from '@/lib/event'
|
|
||||||
import { generateEventId, tagNameEquals } from '@/lib/tag'
|
|
||||||
import { cn } from '@/lib/utils'
|
|
||||||
import { useNostr } from '@/providers/NostrProvider'
|
|
||||||
import client from '@/services/client.service'
|
|
||||||
import dayjs from 'dayjs'
|
|
||||||
import { Event as NEvent } from 'nostr-tools'
|
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
|
||||||
import ReplyNote from '../ReplyNote'
|
|
||||||
|
|
||||||
const LIMIT = 100
|
|
||||||
|
|
||||||
export default function Nip22ReplyNoteList({
|
|
||||||
event,
|
|
||||||
className
|
|
||||||
}: {
|
|
||||||
event: NEvent
|
|
||||||
className?: string
|
|
||||||
}) {
|
|
||||||
const { t } = useTranslation()
|
|
||||||
const { pubkey, startLogin } = useNostr()
|
|
||||||
const [timelineKey, setTimelineKey] = useState<string | undefined>(undefined)
|
|
||||||
const [until, setUntil] = useState<number | undefined>(() => dayjs().unix())
|
|
||||||
const [replies, setReplies] = useState<NEvent[]>([])
|
|
||||||
const [replyMap, setReplyMap] = useState<
|
|
||||||
Record<string, { event: NEvent; level: number; parent?: NEvent } | undefined>
|
|
||||||
>({})
|
|
||||||
const [loading, setLoading] = useState<boolean>(false)
|
|
||||||
const [highlightReplyId, setHighlightReplyId] = useState<string | undefined>(undefined)
|
|
||||||
const replyRefs = useRef<Record<string, HTMLDivElement | null>>({})
|
|
||||||
const bottomRef = useRef<HTMLDivElement | null>(null)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const handleEventPublished = (data: Event) => {
|
|
||||||
const customEvent = data as CustomEvent<NEvent>
|
|
||||||
const evt = customEvent.detail
|
|
||||||
if (
|
|
||||||
isCommentEvent(evt) &&
|
|
||||||
evt.tags.some(([tagName, tagValue]) => tagName === 'E' && tagValue === event.id)
|
|
||||||
) {
|
|
||||||
onNewReply(evt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
client.addEventListener('eventPublished', handleEventPublished)
|
|
||||||
return () => {
|
|
||||||
client.removeEventListener('eventPublished', handleEventPublished)
|
|
||||||
}
|
|
||||||
}, [event])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (loading) return
|
|
||||||
|
|
||||||
const init = async () => {
|
|
||||||
setLoading(true)
|
|
||||||
setReplies([])
|
|
||||||
|
|
||||||
try {
|
|
||||||
const relayList = await client.fetchRelayList(event.pubkey)
|
|
||||||
const relayUrls = relayList.read.concat(BIG_RELAY_URLS)
|
|
||||||
if (isProtectedEvent(event)) {
|
|
||||||
const seenOn = client.getSeenEventRelayUrls(event.id)
|
|
||||||
relayUrls.unshift(...seenOn)
|
|
||||||
}
|
|
||||||
const { closer, timelineKey } = await client.subscribeTimeline(
|
|
||||||
[
|
|
||||||
{
|
|
||||||
urls: relayUrls.slice(0, 4),
|
|
||||||
filter: {
|
|
||||||
'#E': [event.id],
|
|
||||||
kinds: [ExtendedKind.COMMENT],
|
|
||||||
limit: LIMIT
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
{
|
|
||||||
onEvents: (evts, eosed) => {
|
|
||||||
if (evts.length > 0) {
|
|
||||||
setReplies(evts.reverse())
|
|
||||||
}
|
|
||||||
if (eosed) {
|
|
||||||
setLoading(false)
|
|
||||||
setUntil(evts.length >= LIMIT ? evts[evts.length - 1].created_at - 1 : undefined)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onNew: (evt) => {
|
|
||||||
onNewReply(evt)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
startLogin
|
|
||||||
}
|
|
||||||
)
|
|
||||||
setTimelineKey(timelineKey)
|
|
||||||
return closer
|
|
||||||
} catch {
|
|
||||||
setLoading(false)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const promise = init()
|
|
||||||
return () => {
|
|
||||||
promise.then((closer) => closer?.())
|
|
||||||
}
|
|
||||||
}, [event])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const replyMap: Record<string, { event: NEvent; level: number; parent?: NEvent } | undefined> =
|
|
||||||
{}
|
|
||||||
for (const reply of replies) {
|
|
||||||
const parentEventId = reply.tags.find(tagNameEquals('e'))?.[1]
|
|
||||||
if (parentEventId && parentEventId !== event.id) {
|
|
||||||
const parentReplyInfo = replyMap[parentEventId]
|
|
||||||
const level = parentReplyInfo ? parentReplyInfo.level + 1 : 1
|
|
||||||
replyMap[reply.id] = { event: reply, level, parent: parentReplyInfo?.event }
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
replyMap[reply.id] = { event: reply, level: 1 }
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
setReplyMap(replyMap)
|
|
||||||
}, [replies, event.id])
|
|
||||||
|
|
||||||
const loadMore = useCallback(async () => {
|
|
||||||
if (loading || !until || !timelineKey) return
|
|
||||||
|
|
||||||
setLoading(true)
|
|
||||||
const events = await client.loadMoreTimeline(timelineKey, until, LIMIT)
|
|
||||||
const olderReplies = events.reverse()
|
|
||||||
if (olderReplies.length > 0) {
|
|
||||||
setReplies((pre) => [...olderReplies, ...pre])
|
|
||||||
}
|
|
||||||
setUntil(events.length ? events[events.length - 1].created_at - 1 : undefined)
|
|
||||||
setLoading(false)
|
|
||||||
}, [loading, until, timelineKey])
|
|
||||||
|
|
||||||
const onNewReply = useCallback(
|
|
||||||
(evt: NEvent) => {
|
|
||||||
setReplies((pre) => {
|
|
||||||
if (pre.some((reply) => reply.id === evt.id)) return pre
|
|
||||||
return [...pre, evt]
|
|
||||||
})
|
|
||||||
if (evt.pubkey === pubkey) {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (bottomRef.current) {
|
|
||||||
bottomRef.current.scrollIntoView({ behavior: 'smooth', block: 'nearest' })
|
|
||||||
}
|
|
||||||
highlightReply(evt.id, false)
|
|
||||||
}, 100)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[pubkey]
|
|
||||||
)
|
|
||||||
|
|
||||||
const highlightReply = useCallback((eventId: string, scrollTo = true) => {
|
|
||||||
if (scrollTo) {
|
|
||||||
const ref = replyRefs.current[eventId]
|
|
||||||
if (ref) {
|
|
||||||
ref.scrollIntoView({ behavior: 'smooth', block: 'nearest' })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setHighlightReplyId(eventId)
|
|
||||||
setTimeout(() => {
|
|
||||||
setHighlightReplyId((pre) => (pre === eventId ? undefined : pre))
|
|
||||||
}, 1500)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{(loading || until) && (
|
|
||||||
<div
|
|
||||||
className={`text-sm text-center text-muted-foreground mt-2 ${!loading ? 'hover:text-foreground cursor-pointer' : ''}`}
|
|
||||||
onClick={loadMore}
|
|
||||||
>
|
|
||||||
{loading ? t('loading...') : t('load more older replies')}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{replies.length > 0 && (loading || until) && <Separator className="mt-2" />}
|
|
||||||
<div className={cn('mb-2', className)}>
|
|
||||||
{replies.map((reply) => {
|
|
||||||
const info = replyMap[reply.id]
|
|
||||||
return (
|
|
||||||
<div ref={(el) => (replyRefs.current[reply.id] = el)} key={reply.id}>
|
|
||||||
<ReplyNote
|
|
||||||
event={reply}
|
|
||||||
parentEventId={info?.parent ? generateEventId(info.parent) : undefined}
|
|
||||||
onClickParent={() => info?.parent?.id && highlightReply(info?.parent?.id)}
|
|
||||||
highlight={highlightReplyId === reply.id}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
{replies.length === 0 && !loading && !until && (
|
|
||||||
<div className="text-sm text-center text-muted-foreground">{t('no replies')}</div>
|
|
||||||
)}
|
|
||||||
<div ref={bottomRef} />
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Separator } from '@/components/ui/separator'
|
import { Separator } from '@/components/ui/separator'
|
||||||
import { BIG_RELAY_URLS } from '@/constants'
|
import { BIG_RELAY_URLS, ExtendedKind } from '@/constants'
|
||||||
import {
|
import {
|
||||||
getParentEventTag,
|
getParentEventTag,
|
||||||
getRootEventHexId,
|
getRootEventHexId,
|
||||||
@@ -10,7 +10,7 @@ import { generateEventIdFromETag } from '@/lib/tag'
|
|||||||
import { useSecondaryPage } from '@/PageManager'
|
import { useSecondaryPage } from '@/PageManager'
|
||||||
import { useReply } from '@/providers/ReplyProvider'
|
import { useReply } from '@/providers/ReplyProvider'
|
||||||
import client from '@/services/client.service'
|
import client from '@/services/client.service'
|
||||||
import { Event as NEvent, kinds } from 'nostr-tools'
|
import { Filter, Event as NEvent, kinds } from 'nostr-tools'
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import ReplyNote from '../ReplyNote'
|
import ReplyNote from '../ReplyNote'
|
||||||
@@ -109,17 +109,28 @@ export default function ReplyNoteList({
|
|||||||
const relayUrls = relayList.read.concat(BIG_RELAY_URLS)
|
const relayUrls = relayList.read.concat(BIG_RELAY_URLS)
|
||||||
const seenOn = client.getSeenEventRelayUrls(rootInfo.id)
|
const seenOn = client.getSeenEventRelayUrls(rootInfo.id)
|
||||||
relayUrls.unshift(...seenOn)
|
relayUrls.unshift(...seenOn)
|
||||||
const { closer, timelineKey } = await client.subscribeTimeline(
|
|
||||||
[
|
const filters: (Omit<Filter, 'since' | 'until'> & {
|
||||||
|
limit: number
|
||||||
|
})[] = [
|
||||||
{
|
{
|
||||||
urls: relayUrls.slice(0, 5),
|
|
||||||
filter: {
|
|
||||||
'#e': [rootInfo.id],
|
'#e': [rootInfo.id],
|
||||||
kinds: [kinds.ShortTextNote],
|
kinds: [kinds.ShortTextNote],
|
||||||
limit: LIMIT
|
limit: LIMIT
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
if (event.kind !== kinds.ShortTextNote) {
|
||||||
|
filters.push({
|
||||||
|
'#E': [rootInfo.id],
|
||||||
|
kinds: [ExtendedKind.COMMENT],
|
||||||
|
limit: LIMIT
|
||||||
|
})
|
||||||
}
|
}
|
||||||
],
|
const { closer, timelineKey } = await client.subscribeTimeline(
|
||||||
|
filters.map((filter) => ({
|
||||||
|
urls: relayUrls.slice(0, 5),
|
||||||
|
filter
|
||||||
|
})),
|
||||||
{
|
{
|
||||||
onEvents: (evts, eosed) => {
|
onEvents: (evts, eosed) => {
|
||||||
if (evts.length > 0) {
|
if (evts.length > 0) {
|
||||||
|
|||||||
@@ -177,11 +177,12 @@ export async function createCommentDraftEvent(
|
|||||||
const {
|
const {
|
||||||
quoteEventIds,
|
quoteEventIds,
|
||||||
rootEventId,
|
rootEventId,
|
||||||
rootEventKind,
|
rootKind,
|
||||||
rootEventPubkey,
|
rootPubkey,
|
||||||
|
rootUrl,
|
||||||
parentEventId,
|
parentEventId,
|
||||||
parentEventKind,
|
parentKind,
|
||||||
parentEventPubkey
|
parentPubkey
|
||||||
} = await extractCommentMentions(content, parentEvent)
|
} = await extractCommentMentions(content, parentEvent)
|
||||||
const hashtags = extractHashtags(content)
|
const hashtags = extractHashtags(content)
|
||||||
|
|
||||||
@@ -194,17 +195,29 @@ export async function createCommentDraftEvent(
|
|||||||
tags.push(...generateImetaTags(images))
|
tags.push(...generateImetaTags(images))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tags.push(...mentions.filter((pubkey) => pubkey !== parentPubkey).map((pubkey) => ['p', pubkey]))
|
||||||
|
|
||||||
|
if (rootEventId) {
|
||||||
tags.push(
|
tags.push(
|
||||||
...mentions.filter((pubkey) => pubkey !== parentEventPubkey).map((pubkey) => ['p', pubkey])
|
rootPubkey
|
||||||
|
? ['E', rootEventId, client.getEventHint(rootEventId), rootPubkey]
|
||||||
|
: ['E', rootEventId, client.getEventHint(rootEventId)]
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
if (rootPubkey) {
|
||||||
|
tags.push(['P', rootPubkey])
|
||||||
|
}
|
||||||
|
if (rootKind) {
|
||||||
|
tags.push(['K', rootKind.toString()])
|
||||||
|
}
|
||||||
|
if (rootUrl) {
|
||||||
|
tags.push(['I', rootUrl])
|
||||||
|
}
|
||||||
tags.push(
|
tags.push(
|
||||||
...[
|
...[
|
||||||
['E', rootEventId, client.getEventHint(rootEventId), rootEventPubkey],
|
['e', parentEventId, client.getEventHint(parentEventId), parentPubkey],
|
||||||
['K', rootEventKind.toString()],
|
['k', parentKind.toString()],
|
||||||
['P', rootEventPubkey],
|
['p', parentPubkey]
|
||||||
['e', parentEventId, client.getEventHint(parentEventId), parentEventPubkey],
|
|
||||||
['k', parentEventKind.toString()],
|
|
||||||
['p', parentEventPubkey]
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export function isNsfwEvent(event: Event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isReplyNoteEvent(event: Event) {
|
export function isReplyNoteEvent(event: Event) {
|
||||||
|
if (event.kind === ExtendedKind.COMMENT) return true
|
||||||
if (event.kind !== kinds.ShortTextNote) return false
|
if (event.kind !== kinds.ShortTextNote) return false
|
||||||
|
|
||||||
const cache = EVENT_IS_REPLY_NOTE_CACHE.get(event.id)
|
const cache = EVENT_IS_REPLY_NOTE_CACHE.get(event.id)
|
||||||
@@ -64,7 +65,12 @@ export function isSupportedKind(kind: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getParentEventTag(event?: Event) {
|
export function getParentEventTag(event?: Event) {
|
||||||
if (!event) return undefined
|
if (!event || ![kinds.ShortTextNote, ExtendedKind.COMMENT].includes(event.kind)) return undefined
|
||||||
|
|
||||||
|
if (event.kind === ExtendedKind.COMMENT) {
|
||||||
|
return event.tags.find(tagNameEquals('e')) ?? event.tags.find(tagNameEquals('E'))
|
||||||
|
}
|
||||||
|
|
||||||
let tag = event.tags.find(isReplyETag)
|
let tag = event.tags.find(isReplyETag)
|
||||||
if (!tag) {
|
if (!tag) {
|
||||||
const embeddedEventIds = extractEmbeddedEventIds(event)
|
const embeddedEventIds = extractEmbeddedEventIds(event)
|
||||||
@@ -88,7 +94,12 @@ export function getParentEventId(event?: Event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getRootEventTag(event?: Event) {
|
export function getRootEventTag(event?: Event) {
|
||||||
if (!event) return undefined
|
if (!event || ![kinds.ShortTextNote, ExtendedKind.COMMENT].includes(event.kind)) return undefined
|
||||||
|
|
||||||
|
if (event.kind === ExtendedKind.COMMENT) {
|
||||||
|
return event.tags.find(tagNameEquals('E'))
|
||||||
|
}
|
||||||
|
|
||||||
let tag = event.tags.find(isRootETag)
|
let tag = event.tags.find(isRootETag)
|
||||||
if (!tag) {
|
if (!tag) {
|
||||||
const embeddedEventIds = extractEmbeddedEventIds(event)
|
const embeddedEventIds = extractEmbeddedEventIds(event)
|
||||||
@@ -338,12 +349,32 @@ export async function extractRelatedEventIds(content: string, parentEvent?: Even
|
|||||||
|
|
||||||
export async function extractCommentMentions(content: string, parentEvent: Event) {
|
export async function extractCommentMentions(content: string, parentEvent: Event) {
|
||||||
const quoteEventIds: string[] = []
|
const quoteEventIds: string[] = []
|
||||||
const rootEventId = parentEvent.tags.find(tagNameEquals('E'))?.[1] ?? parentEvent.id
|
let rootEventId =
|
||||||
const rootEventKind = parentEvent.tags.find(tagNameEquals('K'))?.[1] ?? parentEvent.kind
|
parentEvent.kind === ExtendedKind.COMMENT
|
||||||
const rootEventPubkey = parentEvent.tags.find(tagNameEquals('P'))?.[1] ?? parentEvent.pubkey
|
? parentEvent.tags.find(tagNameEquals('E'))?.[1]
|
||||||
|
: parentEvent.id
|
||||||
|
let rootKind =
|
||||||
|
parentEvent.kind === ExtendedKind.COMMENT
|
||||||
|
? parentEvent.tags.find(tagNameEquals('K'))?.[1]
|
||||||
|
: parentEvent.kind
|
||||||
|
let rootPubkey =
|
||||||
|
parentEvent.kind === ExtendedKind.COMMENT
|
||||||
|
? parentEvent.tags.find(tagNameEquals('P'))?.[1]
|
||||||
|
: parentEvent.pubkey
|
||||||
|
const rootUrl =
|
||||||
|
parentEvent.kind === ExtendedKind.COMMENT
|
||||||
|
? parentEvent.tags.find(tagNameEquals('I'))?.[1]
|
||||||
|
: undefined
|
||||||
|
|
||||||
|
if (parentEvent.kind === ExtendedKind.COMMENT && !rootEventId) {
|
||||||
|
rootEventId = parentEvent.id
|
||||||
|
rootKind = parentEvent.kind
|
||||||
|
rootPubkey = parentEvent.pubkey
|
||||||
|
}
|
||||||
|
|
||||||
const parentEventId = parentEvent.id
|
const parentEventId = parentEvent.id
|
||||||
const parentEventKind = parentEvent.kind
|
const parentKind = parentEvent.kind
|
||||||
const parentEventPubkey = parentEvent.pubkey
|
const parentPubkey = parentEvent.pubkey
|
||||||
|
|
||||||
const addToSet = (arr: string[], item: string) => {
|
const addToSet = (arr: string[], item: string) => {
|
||||||
if (!arr.includes(item)) arr.push(item)
|
if (!arr.includes(item)) arr.push(item)
|
||||||
@@ -367,11 +398,12 @@ export async function extractCommentMentions(content: string, parentEvent: Event
|
|||||||
return {
|
return {
|
||||||
quoteEventIds,
|
quoteEventIds,
|
||||||
rootEventId,
|
rootEventId,
|
||||||
rootEventKind,
|
rootKind,
|
||||||
rootEventPubkey,
|
rootPubkey,
|
||||||
|
rootUrl,
|
||||||
parentEventId,
|
parentEventId,
|
||||||
parentEventKind,
|
parentKind,
|
||||||
parentEventPubkey
|
parentPubkey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { useSecondaryPage } from '@/PageManager'
|
import { useSecondaryPage } from '@/PageManager'
|
||||||
import ContentPreview from '@/components/ContentPreview'
|
import ContentPreview from '@/components/ContentPreview'
|
||||||
import Nip22ReplyNoteList from '@/components/Nip22ReplyNoteList'
|
|
||||||
import Note from '@/components/Note'
|
import Note from '@/components/Note'
|
||||||
import NoteStats from '@/components/NoteStats'
|
import NoteStats from '@/components/NoteStats'
|
||||||
import PictureNote from '@/components/PictureNote'
|
import PictureNote from '@/components/PictureNote'
|
||||||
@@ -14,7 +13,6 @@ import SecondaryPageLayout from '@/layouts/SecondaryPageLayout'
|
|||||||
import { getParentEventId, getRootEventId, isPictureEvent } from '@/lib/event'
|
import { getParentEventId, getRootEventId, isPictureEvent } from '@/lib/event'
|
||||||
import { toNote } from '@/lib/link'
|
import { toNote } from '@/lib/link'
|
||||||
import { useMuteList } from '@/providers/MuteListProvider'
|
import { useMuteList } from '@/providers/MuteListProvider'
|
||||||
import { kinds } 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 NotFoundPage from '../NotFoundPage'
|
||||||
@@ -22,14 +20,8 @@ import NotFoundPage from '../NotFoundPage'
|
|||||||
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()
|
||||||
const { event, isFetching } = useFetchEvent(id)
|
const { event, isFetching } = useFetchEvent(id)
|
||||||
const parentEventId = useMemo(
|
const parentEventId = useMemo(() => getParentEventId(event), [event])
|
||||||
() => (event?.kind === kinds.ShortTextNote ? getParentEventId(event) : undefined),
|
const rootEventId = useMemo(() => getRootEventId(event), [event])
|
||||||
[event]
|
|
||||||
)
|
|
||||||
const rootEventId = useMemo(
|
|
||||||
() => (event?.kind === kinds.ShortTextNote ? getRootEventId(event) : undefined),
|
|
||||||
[event]
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!event && isFetching) {
|
if (!event && isFetching) {
|
||||||
return (
|
return (
|
||||||
@@ -65,7 +57,7 @@ const NotePage = forwardRef(({ id, index }: { id?: string; index?: number }, ref
|
|||||||
<SecondaryPageLayout ref={ref} index={index} title={t('Note')} displayScrollToTopButton>
|
<SecondaryPageLayout ref={ref} index={index} title={t('Note')} displayScrollToTopButton>
|
||||||
<PictureNote key={`note-${event.id}`} event={event} fetchNoteStats />
|
<PictureNote key={`note-${event.id}`} event={event} fetchNoteStats />
|
||||||
<Separator className="mt-4" />
|
<Separator className="mt-4" />
|
||||||
<Nip22ReplyNoteList key={`nip22-reply-note-list-${event.id}`} event={event} />
|
<ReplyNoteList key={`reply-note-list-${event.id}`} index={index} event={event} />
|
||||||
</SecondaryPageLayout>
|
</SecondaryPageLayout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -86,11 +78,7 @@ const NotePage = forwardRef(({ id, index }: { id?: string; index?: number }, ref
|
|||||||
<NoteStats className="mt-3" event={event} fetchIfNotExisting displayTopZapsAndLikes />
|
<NoteStats className="mt-3" event={event} fetchIfNotExisting displayTopZapsAndLikes />
|
||||||
</div>
|
</div>
|
||||||
<Separator className="mt-4" />
|
<Separator className="mt-4" />
|
||||||
{[kinds.ShortTextNote, kinds.Highlights].includes(event.kind) ? (
|
|
||||||
<ReplyNoteList key={`reply-note-list-${event.id}`} index={index} event={event} />
|
<ReplyNoteList key={`reply-note-list-${event.id}`} index={index} event={event} />
|
||||||
) : (
|
|
||||||
<Nip22ReplyNoteList key={`nip22-reply-note-list-${event.id}`} event={event} />
|
|
||||||
)}
|
|
||||||
</SecondaryPageLayout>
|
</SecondaryPageLayout>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ class ClientService extends EventTarget {
|
|||||||
) {
|
) {
|
||||||
const newEventIdSet = new Set<string>()
|
const newEventIdSet = new Set<string>()
|
||||||
const requestCount = subRequests.length
|
const requestCount = subRequests.length
|
||||||
const threshold = Math.ceil(requestCount / 2)
|
const threshold = Math.floor(requestCount / 2)
|
||||||
let eventIdSet = new Set<string>()
|
let eventIdSet = new Set<string>()
|
||||||
let events: NEvent[] = []
|
let events: NEvent[] = []
|
||||||
let eosedCount = 0
|
let eosedCount = 0
|
||||||
|
|||||||
Reference in New Issue
Block a user