From 0f212828a7ddf93b6807f2d90d780f10552d99cd Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Sat, 26 Aug 2023 10:54:06 +0700 Subject: [PATCH] update note replies component --- src/shared/notes/replies/list.tsx | 86 +++++++++---------------------- src/utils/hooks/useNostr.ts | 44 ++++++++++++++++ 2 files changed, 69 insertions(+), 61 deletions(-) diff --git a/src/shared/notes/replies/list.tsx b/src/shared/notes/replies/list.tsx index 3173cce4..df33bc85 100644 --- a/src/shared/notes/replies/list.tsx +++ b/src/shared/notes/replies/list.tsx @@ -1,56 +1,36 @@ -import { useQuery } from '@tanstack/react-query'; - -import { useNDK } from '@libs/ndk/provider'; +import { NDKKind } from '@nostr-dev-kit/ndk'; +import { useEffect, useState } from 'react'; import { NoteSkeleton, Reply } from '@shared/notes'; +import { useNostr } from '@utils/hooks/useNostr'; import { NDKEventWithReplies } from '@utils/types'; export function RepliesList({ id }: { id: string }) { - const { ndk } = useNDK(); - const { status, data } = useQuery( - ['note-replies', id], - async () => { - try { - const events = await ndk.fetchEvents({ - kinds: [1], + const { fetchAllReplies, sub } = useNostr(); + const [data, setData] = useState(null); + + useEffect(() => { + async function fetchRepliesAndSub() { + const events = await fetchAllReplies(id); + setData(events); + + // subscribe for new replies + sub( + { + kinds: [NDKKind.Text], '#e': [id], - }); + since: Math.floor(Date.now() / 1000), + }, + (event: NDKEventWithReplies) => setData((prev) => [event, ...prev]), + false + ); + } - const array = [...events] as unknown as NDKEventWithReplies[]; + fetchRepliesAndSub(); + }, []); - if (array.length > 0) { - const replies = new Set(); - array.forEach((event) => { - const tags = event.tags.filter((el) => el[0] === 'e' && el[1] !== id); - if (tags.length > 0) { - tags.forEach((tag) => { - const rootIndex = array.findIndex((el) => el.id === tag[1]); - if (rootIndex !== -1) { - const rootEvent = array[rootIndex]; - if (rootEvent && rootEvent.replies) { - rootEvent.replies.push(event); - } else { - rootEvent.replies = [event]; - } - replies.add(event.id); - } - }); - } - }); - const cleanEvents = array.filter((ev) => !replies.has(ev.id)); - return cleanEvents; - } - - return array; - } catch (e) { - throw new Error(e); - } - }, - { enabled: !!ndk } - ); - - if (status === 'loading') { + if (!data) { return (
@@ -62,18 +42,6 @@ export function RepliesList({ id }: { id: string }) { ); } - if (status === 'error') { - return ( -
-
-
-

Error: failed to get replies

-
-
-
- ); - } - return (
@@ -88,11 +56,7 @@ export function RepliesList({ id }: { id: string }) {
) : ( - data - .reverse() - .map((event: NDKEventWithReplies) => ( - - )) + data.map((event) => ) )}
diff --git a/src/utils/hooks/useNostr.ts b/src/utils/hooks/useNostr.ts index 1c335d62..b194cede 100644 --- a/src/utils/hooks/useNostr.ts +++ b/src/utils/hooks/useNostr.ts @@ -18,6 +18,7 @@ import { useStorage } from '@libs/storage/provider'; import { useStronghold } from '@stores/stronghold'; import { nHoursAgo } from '@utils/date'; +import { NDKEventWithReplies } from '@utils/types'; export function useNostr() { const { ndk, relayUrls } = useNDK(); @@ -222,6 +223,48 @@ export function useNostr() { return all as unknown as NDKEvent[]; }; + const fetchAllReplies = async (id: string, data?: NDKEventWithReplies[]) => { + let events = data || null; + const fetcher = NostrFetcher.withCustomPool(ndkAdapter(ndk)); + + if (!data) { + events = (await fetcher.fetchAllEvents( + relayUrls, + { + kinds: [NDKKind.Text], + '#e': [id], + }, + { since: 0 }, + { sort: true } + )) as unknown as NDKEventWithReplies[]; + } + + if (events.length > 0) { + const replies = new Set(); + events.forEach((event) => { + const tags = event.tags.filter((el) => el[0] === 'e' && el[1] !== id); + if (tags.length > 0) { + tags.forEach((tag) => { + const rootIndex = events.findIndex((el) => el.id === tag[1]); + if (rootIndex !== -1) { + const rootEvent = events[rootIndex]; + if (rootEvent && rootEvent.replies) { + rootEvent.replies.push(event); + } else { + rootEvent.replies = [event]; + } + replies.add(event.id); + } + }); + } + }); + const cleanEvents = events.filter((ev) => !replies.has(ev.id)); + return cleanEvents; + } + + return events; + }; + const publish = async ({ content, kind, @@ -270,6 +313,7 @@ export function useNostr() { fetchActivities, fetchNIP04Chats, fetchNIP04Messages, + fetchAllReplies, publish, createZap, };