diff --git a/client/src/components/routes/Thread.tsx b/client/src/components/routes/Thread.tsx index ad1ef2f..7005675 100644 --- a/client/src/components/routes/Thread.tsx +++ b/client/src/components/routes/Thread.tsx @@ -8,6 +8,14 @@ import Placeholder from '../modals/Placeholder'; import PostCard from '../modals/PostCard'; import { useFetchEvents } from '../../hooks/useFetchEvents'; import ThreadPostModal from '../forms/ThreadPostModal'; +import { verifyPow } from '../../utils/mine'; + +type ProcessedEvent = { + postEvent: Event; + replies: Event[]; + totalWork: number; + metadataEvent: Event | null; + }; const Thread = () => { const { id } = useParams(); @@ -15,7 +23,7 @@ const Thread = () => { const [visibleReplyEvents, setVisibleReplyEvents] = useState(10); let decodeResult = nip19.decode(id as string); let hexID = decodeResult.data as string; - const { noteEvents, metadataEvents } = useFetchEvents(undefined,false,hexID); + const { noteEvents, metadataEvents } = useFetchEvents(undefined, false, hexID); // Load cached thread from localStorage const threadCache = JSON.parse(sessionStorage.getItem("cachedThread") || "[]") @@ -55,59 +63,70 @@ const Thread = () => { if (OPEvent) { const uniqEvents = uniqBy(prevMentions, "id"); const earlierEvents = uniqEvents - .filter(e => - e.created_at < OPEvent.created_at - ) - + .filter(e => + e.created_at < OPEvent.created_at + ) + const uniqReplyEvents = uniqBy(allEvents, "id"); - const replyEvents = [...uniqReplyEvents] + const replyEvents: ProcessedEvent[] = [...uniqReplyEvents] .filter(event => - event.kind === 1 && !earlierEvents.map(e => e.id).includes(event.id) && (OPEvent ? OPEvent.id !== event.id : true) - ).sort((a, b) => a.created_at - b.created_at); - - return ( - <> -
-
- {earlierEvents - .filter(event => event.kind === 1) - .sort((a, b) => a.created_at - b.created_at).map((event, index) => ( - e.pubkey === event.pubkey && e.kind === 0) || null} replies={uniqEvents.filter((e: Event) => e.tags.some((tag) => tag[0] === "e" && tag[1] === event.id))} /> - ))} - e.pubkey === OPEvent.pubkey && e.kind === 0) || null} replies={replyEvents} type={'OP'}/> -
- -
{/* This is the white line separator */} -
- -
-
+ ) + .map(event => { + const pow = verifyPow(event); // Calculate once and reuse + + const replies = noteEvents.filter(e => e.tags.some(tag => tag[0] === 'e' && tag[1] === event.id)); + const totalWork = Math.pow(2, pow) + replies.reduce((acc, reply) => { + const replyPow = reply.id.startsWith('0') ? verifyPow(reply) : 0; + return acc + Math.pow(2, replyPow); + }, 0); + const metadataEvent = metadataEvents.find((e) => e.pubkey === event.pubkey && e.kind === 0) || null; // Find the corresponding metadataEvent + return { postEvent: event, replies, totalWork, metadataEvent }; // Include metadataEvent in the returned object + }) + .sort((a, b) => b.totalWork - a.totalWork || b.postEvent.created_at - a.postEvent.created_at); + + return ( + <> +
+
+ {earlierEvents + .filter(event => event.kind === 1) + .sort((a, b) => a.created_at - b.created_at).map((event, index) => ( + e.pubkey === event.pubkey && e.kind === 0) || null} replies={uniqEvents.filter((e: Event) => e.tags.some((tag) => tag[0] === "e" && tag[1] === event.id))} /> + ))} + e.pubkey === OPEvent.pubkey && e.kind === 0) || null} replies={replyEvents.map(event => event.replies).flat()} type={'OP'} /> +
+ +
{/* This is the white line separator */} +
+ +
+
{replyEvents.slice(0, visibleReplyEvents) - .filter((event: Event) => (showAllReplies || event.id.startsWith('0')) && event.tags.some(tag => tag[0] === 'e' && tag[1] === OPEvent.id)) - .map((event: Event) => ( -
tag[0] === 'e' && tag[1] !== OPEvent.id) ? 'ml-auto' : 'mr-auto'}`}> - e.pubkey === event.pubkey && e.kind === 0) || null} - replies={replyEvents.filter((e: Event) => e.tags.some((tag) => tag[0] === "e" && tag[1] === event.id))} - repliedTo={repliedList(event)} - /> -
- ))} -
-
- - ); + .filter((event) => (showAllReplies || event.totalWork > 1) && event.postEvent.tags.some(tag => tag[0] === 'e' && tag[1] === OPEvent.id)) + .map((event) => ( +
tag[0] === 'e' && tag[1] !== OPEvent.id) ? 'ml-auto' : 'mr-auto'}`}> + +
+ ))} +
+
+ + ); } return ( <> -
{/* This is the white line separator */} +
{/* This is the white line separator */} ); };