diff --git a/client/src/components/modals/CardContainer.tsx b/client/src/components/modals/CardContainer.tsx index cfb1290..a54a448 100644 --- a/client/src/components/modals/CardContainer.tsx +++ b/client/src/components/modals/CardContainer.tsx @@ -2,7 +2,7 @@ import { PropsWithChildren } from "react"; export default function CardContainer({ children }: PropsWithChildren) { return ( -
+
{children}
); diff --git a/client/src/components/modals/PostCard.tsx b/client/src/components/modals/PostCard.tsx index 12a4e26..7f2a290 100644 --- a/client/src/components/modals/PostCard.tsx +++ b/client/src/components/modals/PostCard.tsx @@ -88,17 +88,17 @@ const PostCard = ({ ); })}
} -
+
{metadataParsed ? : -
+
}
diff --git a/client/src/components/routes/HashtagPage.tsx b/client/src/components/routes/HashtagPage.tsx index 204d0e8..2cd12b8 100644 --- a/client/src/components/routes/HashtagPage.tsx +++ b/client/src/components/routes/HashtagPage.tsx @@ -1,33 +1,14 @@ import PostCard from "../modals/PostCard"; -import { verifyPow } from "../../utils/mine"; -import { Event } from "nostr-tools"; import NewNoteCard from "../forms/PostFormCard"; import { useParams } from "react-router-dom"; -import { useFetchEvents } from "../../hooks/useFetchEvents"; +import useProcessedEvents from "../../hooks/processedEvents"; const DEFAULT_DIFFICULTY = 0; const HashtagPage = () => { const { id } = useParams(); - const filterDifficulty = localStorage.getItem("filterHashtagDifficulty") || DEFAULT_DIFFICULTY; - const { noteEvents, metadataEvents } = useFetchEvents(id as string, false); - - const postEvents: Event[] = noteEvents - .filter((event) => - verifyPow(event) >= Number(filterDifficulty) && - event.kind !== 0 && - (event.kind !== 1 || !event.tags.some((tag) => tag[0] === "e")) - ) - - let sortedEvents = [...postEvents] - .sort((a, b) => { - // Sort by PoW in descending order - const powDiff = verifyPow(b) - verifyPow(a); - if (powDiff !== 0) return powDiff; - - // If PoW is the same, sort by created_at in descending order - return b.created_at - a.created_at; - }); + const filterDifficulty = DEFAULT_DIFFICULTY; + const { processedEvents } = useProcessedEvents(id as string, filterDifficulty); // Render the component return ( @@ -36,13 +17,14 @@ const HashtagPage = () => {
- {sortedEvents.map((event) => - e.pubkey === event.pubkey && e.kind === 0) || null} - replies={sortedEvents.filter((e) => e.tags.some((tag) => tag[0] === "e" && tag[1] === event.id))} - /> - + {processedEvents.map((event) => + + )}
diff --git a/client/src/components/routes/Home.tsx b/client/src/components/routes/Home.tsx index d5b2888..6197b86 100644 --- a/client/src/components/routes/Home.tsx +++ b/client/src/components/routes/Home.tsx @@ -1,54 +1,23 @@ -import { verifyPow } from "../../utils/mine"; -import { Event } from "nostr-tools"; import NewNoteCard from "../forms/PostFormCard"; import { DEFAULT_DIFFICULTY } from "../../config"; import PostCard from "../modals/PostCard"; -import { useFetchEvents } from "../../hooks/useFetchEvents"; import { useState, useEffect } from "react"; +import useProcessedEvents from "../../hooks/processedEvents"; const Home = () => { - const filterDifficulty = localStorage.getItem("filterDifficulty") || DEFAULT_DIFFICULTY; - const { noteEvents, metadataEvents } = useFetchEvents(); + const filterDifficulty = Number(localStorage.getItem('filterDifficulty')) || DEFAULT_DIFFICULTY; + const { processedEvents } = useProcessedEvents(undefined, filterDifficulty); const [isAnimating, setIsAnimating] = useState(true); // Step 3: Use useEffect to remove the animation class after 3 seconds useEffect(() => { const timer = setTimeout(() => { setIsAnimating(false); - }, 3000); // 3000 milliseconds = 3 seconds + }, 4000); // 3000 milliseconds = 3 seconds return () => clearTimeout(timer); // Cleanup the timer }, []); // Empty dependency array means this effect runs once on mount - - const postEvents: Event[] = noteEvents - .filter((event) => - verifyPow(event) >= Number(filterDifficulty) && - event.kind !== 0 && - (event.kind !== 1 || !event.tags.some((tag) => tag[0] === "e")) - ) - - const postEventsWithReplies = postEvents.map((event) => { - const totalWork = Math.pow(2, verifyPow(event)) - + noteEvents.filter((e) => e.tags.some((tag) => tag[0] === "e" && tag[1] === event.id)) - .reduce((acc, reply) => acc + Math.pow(2, verifyPow(reply)), 0); - return { - postEvent: event, - replies: noteEvents.filter((e) => e.tags.some((tag) => tag[0] === "e" && tag[1] === event.id)), - totalWork: totalWork, // Add total work here - }; - }); - - const sortedEvents = postEventsWithReplies - .sort((a, b) => { - // Sort by total work in descending order - const workDiff = b.totalWork - a.totalWork; - if (workDiff !== 0) return workDiff; - - // If total work is the same, sort by created_at in descending order - return b.postEvent.created_at - a.postEvent.created_at; - }); - // Render the component return (
@@ -56,11 +25,11 @@ const Home = () => {
- {sortedEvents.map((event) => ( + {processedEvents.map((event) => ( e.pubkey === event.postEvent.pubkey && e.kind === 0) || null} + metadata={event.metadataEvent} replies={event.replies} /> ))} diff --git a/client/src/hooks/processedEvents.ts b/client/src/hooks/processedEvents.ts new file mode 100644 index 0000000..7134488 --- /dev/null +++ b/client/src/hooks/processedEvents.ts @@ -0,0 +1,35 @@ +import { useState, useEffect } from 'react'; +import { verifyPow } from '../utils/mine'; +import { useFetchEvents } from './useFetchEvents'; +import { Event } from 'nostr-tools'; + +type ProcessedEvent = { + postEvent: Event; + replies: Event[]; + totalWork: number; + metadataEvent: Event | null; // Added metadataEvent to the type +}; + +const useProcessedEvents = (id?: string, filterDifficulty: number = 0) => { + const { noteEvents, metadataEvents } = useFetchEvents(id, false); // Reintroduced metadataEvents + const [processedEvents, setProcessedEvents] = useState([]); + + useEffect(() => { + const processed = noteEvents + .filter(event => verifyPow(event) >= filterDifficulty && event.kind !== 0) + .filter(event => !(event.kind === 1 && event.tags.some(tag => tag[0] === 'e'))) + .map(event => { + const replies = noteEvents.filter(e => e.tags.some(tag => tag[0] === 'e' && tag[1] === event.id)); + const totalWork = Math.pow(2, verifyPow(event)) + replies.reduce((acc, reply) => acc + Math.pow(2, verifyPow(reply)), 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); + + setProcessedEvents(processed); + }, [noteEvents, metadataEvents, id, filterDifficulty]); // Include metadataEvents in the dependency array + + return { processedEvents }; +}; + +export default useProcessedEvents; \ No newline at end of file