fix: replies
This commit is contained in:
@@ -11,13 +11,11 @@ export type TNoteStats = {
|
||||
likes: { id: string; pubkey: string; created_at: number; emoji: TEmoji | string }[]
|
||||
reposts: Set<string>
|
||||
zaps: { pr: string; pubkey: string; amount: number; comment?: string }[]
|
||||
replyCount: number
|
||||
updatedAt?: number
|
||||
}
|
||||
|
||||
type TNoteStatsContext = {
|
||||
noteStatsMap: Map<string, Partial<TNoteStats>>
|
||||
updateNoteReplyCount: (noteId: string, replyCount: number) => void
|
||||
addZap: (eventId: string, pr: string, amount: number, comment?: string) => void
|
||||
updateNoteStatsByEvents: (events: Event[]) => void
|
||||
fetchNoteStats: (event: Event) => Promise<Partial<TNoteStats> | undefined>
|
||||
@@ -215,20 +213,6 @@ export function NoteStatsProvider({ children }: { children: React.ReactNode }) {
|
||||
return
|
||||
}
|
||||
|
||||
const updateNoteReplyCount = (noteId: string, replyCount: number) => {
|
||||
setNoteStatsMap((prev) => {
|
||||
const old = prev.get(noteId)
|
||||
if (!old) {
|
||||
prev.set(noteId, { replyCount })
|
||||
return new Map(prev)
|
||||
} else if (old.replyCount === undefined || old.replyCount < replyCount) {
|
||||
prev.set(noteId, { ...old, replyCount })
|
||||
return new Map(prev)
|
||||
}
|
||||
return prev
|
||||
})
|
||||
}
|
||||
|
||||
const addZap = (eventId: string, pr: string, amount: number, comment?: string) => {
|
||||
if (!pubkey) return
|
||||
setNoteStatsMap((prev) => {
|
||||
@@ -247,7 +231,6 @@ export function NoteStatsProvider({ children }: { children: React.ReactNode }) {
|
||||
value={{
|
||||
noteStatsMap,
|
||||
fetchNoteStats,
|
||||
updateNoteReplyCount,
|
||||
addZap,
|
||||
updateNoteStatsByEvents
|
||||
}}
|
||||
|
||||
70
src/providers/ReplyProvider.tsx
Normal file
70
src/providers/ReplyProvider.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
import { getParentEventTag, getRootEventTag } from '@/lib/event'
|
||||
import { Event } from 'nostr-tools'
|
||||
import { createContext, useCallback, useContext, useState } from 'react'
|
||||
|
||||
type TReplyContext = {
|
||||
repliesMap: Map<string, { events: Event[]; eventIdSet: Set<string> }>
|
||||
addReplies: (replies: Event[]) => void
|
||||
}
|
||||
|
||||
const ReplyContext = createContext<TReplyContext | undefined>(undefined)
|
||||
|
||||
export const useReply = () => {
|
||||
const context = useContext(ReplyContext)
|
||||
if (!context) {
|
||||
throw new Error('useReply must be used within a ReplyProvider')
|
||||
}
|
||||
return context
|
||||
}
|
||||
|
||||
export function ReplyProvider({ children }: { children: React.ReactNode }) {
|
||||
const [repliesMap, setRepliesMap] = useState<
|
||||
Map<string, { events: Event[]; eventIdSet: Set<string> }>
|
||||
>(new Map())
|
||||
|
||||
const addReplies = useCallback((replies: Event[]) => {
|
||||
const newReplyIdSet = new Set<string>()
|
||||
const newReplyEventMap = new Map<string, Event[]>()
|
||||
replies.forEach((reply) => {
|
||||
if (newReplyIdSet.has(reply.id)) return
|
||||
newReplyIdSet.add(reply.id)
|
||||
|
||||
const rootETag = getRootEventTag(reply)
|
||||
if (!rootETag) return
|
||||
const rootId = rootETag[1]
|
||||
newReplyEventMap.set(rootId, [...(newReplyEventMap.get(rootId) || []), reply])
|
||||
|
||||
const parentETag = getParentEventTag(reply)
|
||||
if (!parentETag) return
|
||||
const parentId = parentETag[1]
|
||||
newReplyEventMap.set(parentId, [...(newReplyEventMap.get(parentId) || []), reply])
|
||||
})
|
||||
if (newReplyEventMap.size === 0) return
|
||||
|
||||
setRepliesMap((prev) => {
|
||||
for (const [id, newReplyEvents] of newReplyEventMap.entries()) {
|
||||
const replies = prev.get(id) || { events: [], eventIdSet: new Set() }
|
||||
newReplyEvents.forEach((reply) => {
|
||||
if (!replies.eventIdSet.has(reply.id)) {
|
||||
replies.events.push(reply)
|
||||
replies.eventIdSet.add(reply.id)
|
||||
}
|
||||
})
|
||||
replies.events.sort((a, b) => a.created_at - b.created_at)
|
||||
prev.set(id, replies)
|
||||
}
|
||||
return new Map(prev)
|
||||
})
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<ReplyContext.Provider
|
||||
value={{
|
||||
repliesMap,
|
||||
addReplies
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</ReplyContext.Provider>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user