update note replies component

This commit is contained in:
Ren Amamiya 2023-08-26 10:54:06 +07:00
parent bfb7d7915f
commit 0f212828a7
2 changed files with 69 additions and 61 deletions

View File

@ -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 | NDKEventWithReplies[]>(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 (
<div className="mt-5 pb-10">
<div className="flex flex-col">
@ -62,18 +42,6 @@ export function RepliesList({ id }: { id: string }) {
);
}
if (status === 'error') {
return (
<div className="mt-5 pb-10">
<div className="flex flex-col">
<div className="rounded-xl bg-white/10 px-3 py-3">
<p>Error: failed to get replies</p>
</div>
</div>
</div>
);
}
return (
<div className="mt-5 pb-10">
<h5 className="mb-5 text-lg font-semibold text-white">
@ -88,11 +56,7 @@ export function RepliesList({ id }: { id: string }) {
</div>
</div>
) : (
data
.reverse()
.map((event: NDKEventWithReplies) => (
<Reply key={event.id} event={event} root={id} />
))
data.map((event) => <Reply key={event.id} event={event} root={id} />)
)}
</div>
</div>

View File

@ -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,
};