better thread filtering

This commit is contained in:
smolgrrr 2024-09-06 18:32:42 +10:00
parent 99337afedd
commit b005c94a1c

View File

@ -8,6 +8,14 @@ import Placeholder from '../modals/Placeholder';
import PostCard from '../modals/PostCard'; import PostCard from '../modals/PostCard';
import { useFetchEvents } from '../../hooks/useFetchEvents'; import { useFetchEvents } from '../../hooks/useFetchEvents';
import ThreadPostModal from '../forms/ThreadPostModal'; import ThreadPostModal from '../forms/ThreadPostModal';
import { verifyPow } from '../../utils/mine';
type ProcessedEvent = {
postEvent: Event;
replies: Event[];
totalWork: number;
metadataEvent: Event | null;
};
const Thread = () => { const Thread = () => {
const { id } = useParams(); const { id } = useParams();
@ -15,7 +23,7 @@ const Thread = () => {
const [visibleReplyEvents, setVisibleReplyEvents] = useState(10); const [visibleReplyEvents, setVisibleReplyEvents] = useState(10);
let decodeResult = nip19.decode(id as string); let decodeResult = nip19.decode(id as string);
let hexID = decodeResult.data 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 // Load cached thread from localStorage
const threadCache = JSON.parse(sessionStorage.getItem("cachedThread") || "[]") const threadCache = JSON.parse(sessionStorage.getItem("cachedThread") || "[]")
@ -55,59 +63,70 @@ const Thread = () => {
if (OPEvent) { if (OPEvent) {
const uniqEvents = uniqBy(prevMentions, "id"); const uniqEvents = uniqBy(prevMentions, "id");
const earlierEvents = uniqEvents const earlierEvents = uniqEvents
.filter(e => .filter(e =>
e.created_at < OPEvent.created_at e.created_at < OPEvent.created_at
) )
const uniqReplyEvents = uniqBy(allEvents, "id"); const uniqReplyEvents = uniqBy(allEvents, "id");
const replyEvents = [...uniqReplyEvents] const replyEvents: ProcessedEvent[] = [...uniqReplyEvents]
.filter(event => .filter(event =>
event.kind === 1 &&
!earlierEvents.map(e => e.id).includes(event.id) && !earlierEvents.map(e => e.id).includes(event.id) &&
(OPEvent ? OPEvent.id !== event.id : true) (OPEvent ? OPEvent.id !== event.id : true)
).sort((a, b) => a.created_at - b.created_at); )
.map(event => {
return ( const pow = verifyPow(event); // Calculate once and reuse
<>
<main className="bg-black text-white min-h-screen"> const replies = noteEvents.filter(e => e.tags.some(tag => tag[0] === 'e' && tag[1] === event.id));
<div className="w-full sm:px-0 sm:max-w-xl mx-auto my-2"> const totalWork = Math.pow(2, pow) + replies.reduce((acc, reply) => {
{earlierEvents const replyPow = reply.id.startsWith('0') ? verifyPow(reply) : 0;
.filter(event => event.kind === 1) return acc + Math.pow(2, replyPow);
.sort((a, b) => a.created_at - b.created_at).map((event, index) => ( }, 0);
<PostCard key={event.id} event={event} metadata={metadataEvents.find((e) => e.pubkey === event.pubkey && e.kind === 0) || null} replies={uniqEvents.filter((e: Event) => e.tags.some((tag) => tag[0] === "e" && tag[1] === event.id))} /> 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
<PostCard key={OPEvent.id} event={OPEvent} metadata={metadataEvents.find((e) => e.pubkey === OPEvent.pubkey && e.kind === 0) || null} replies={replyEvents} type={'OP'}/> })
</div> .sort((a, b) => b.totalWork - a.totalWork || b.postEvent.created_at - a.postEvent.created_at);
<ThreadPostModal OPEvent={OPEvent} />
<div className="col-span-full h-0.5 bg-neutral-900 mb-2"/> {/* This is the white line separator */} return (
<div className="flex justify-center"> <>
<button onClick={() => setShowAllReplies(!showAllReplies)} className="text-neutral-600 text-xs border border-neutral-700 rounded-md px-4 py-2"> <main className="bg-black text-white min-h-screen">
{showAllReplies ? 'Hide 0 PoW Replies' : 'Show All Replies'} <div className="w-full sm:px-0 sm:max-w-xl mx-auto my-2">
</button> {earlierEvents
</div> .filter(event => event.kind === 1)
<div className="grid grid-cols-1 max-w-xl mx-auto gap-1"> .sort((a, b) => a.created_at - b.created_at).map((event, index) => (
<PostCard key={event.id} event={event} metadata={metadataEvents.find((e) => e.pubkey === event.pubkey && e.kind === 0) || null} replies={uniqEvents.filter((e: Event) => e.tags.some((tag) => tag[0] === "e" && tag[1] === event.id))} />
))}
<PostCard key={OPEvent.id} event={OPEvent} metadata={metadataEvents.find((e) => e.pubkey === OPEvent.pubkey && e.kind === 0) || null} replies={replyEvents.map(event => event.replies).flat()} type={'OP'} />
</div>
<ThreadPostModal OPEvent={OPEvent} />
<div className="col-span-full h-0.5 bg-neutral-900 mb-2" /> {/* This is the white line separator */}
<div className="flex justify-center">
<button onClick={() => setShowAllReplies(!showAllReplies)} className="text-neutral-600 text-xs border border-neutral-700 rounded-md px-4 py-2">
{showAllReplies ? 'Hide 0 PoW Replies' : 'Show All Replies'}
</button>
</div>
<div className="grid grid-cols-1 max-w-xl mx-auto gap-1">
{replyEvents.slice(0, visibleReplyEvents) {replyEvents.slice(0, visibleReplyEvents)
.filter((event: Event) => (showAllReplies || event.id.startsWith('0')) && event.tags.some(tag => tag[0] === 'e' && tag[1] === OPEvent.id)) .filter((event) => (showAllReplies || event.totalWork > 1) && event.postEvent.tags.some(tag => tag[0] === 'e' && tag[1] === OPEvent.id))
.map((event: Event) => ( .map((event) => (
<div className={`w-11/12 ${event.tags.find(tag => tag[0] === 'e' && tag[1] !== OPEvent.id) ? 'ml-auto' : 'mr-auto'}`}> <div className={`w-11/12 ${event.postEvent.tags.find(tag => tag[0] === 'e' && tag[1] !== OPEvent.id) ? 'ml-auto' : 'mr-auto'}`}>
<PostCard <PostCard
key={event.id} key={event.postEvent.id}
event={event} event={event.postEvent}
metadata={metadataEvents.find((e) => e.pubkey === event.pubkey && e.kind === 0) || null} metadata={event.metadataEvent}
replies={replyEvents.filter((e: Event) => e.tags.some((tag) => tag[0] === "e" && tag[1] === event.id))} replies={event.replies}
repliedTo={repliedList(event)} repliedTo={repliedList(event.postEvent)}
/> />
</div> </div>
))} ))}
</div> </div>
</main> </main>
</> </>
); );
} }
return ( return (
<> <>
<Placeholder /> <Placeholder />
<div className="col-span-full h-0.5 bg-neutral-900"/> {/* This is the white line separator */} <div className="col-span-full h-0.5 bg-neutral-900" /> {/* This is the white line separator */}
</> </>
); );
}; };