clean up feeds

This commit is contained in:
smolgrrr 2024-08-25 23:34:49 +10:00
parent 3ef3310a33
commit 6319fb659b
5 changed files with 56 additions and 70 deletions

View File

@ -2,7 +2,7 @@ import { PropsWithChildren } from "react";
export default function CardContainer({ children }: PropsWithChildren) {
return (
<div className="card break-inside-avoid mb-1 h-min">
<div className="card break-inside-avoid mb-3 h-min">
<div className="card-body">{children}</div>
</div>
);

View File

@ -88,17 +88,17 @@ const PostCard = ({
);
})}
</div>}
<div className={`flex justify-between items-center ${type !== "OP" ? 'hover:cursor-pointer' : ''}`} onClick={handleClick}>
<div className={`pt-3 flex justify-between items-center ${type !== "OP" ? 'hover:cursor-pointer' : ''}`} onClick={handleClick}>
{metadataParsed ?
<img
key={key}
className={`h-5 w-5 rounded-full`}
className={`h-7 w-7 rounded-full overflow-hidden`}
src={metadataParsed?.picture ?? icon}
alt=""
loading="lazy"
decoding="async" />
:
<div className={`h-4 w-4 ${icon} rounded-full`} />
<div className={`h-6 w-6 ${icon} rounded-full`} />
}
<div className="flex items-center ml-auto gap-2.5">
<div className={`inline-flex text-xs ${verifyPow(parsedEvent) === 0 ? 'text-neutral-600' : 'text-sky-800'} gap-0.5`}>

View File

@ -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 = () => {
<NewNoteCard hashtag={id as string} />
</div>
<div className="grid grid-cols-1 max-w-xl mx-auto gap-1 px-4">
{sortedEvents.map((event) =>
<PostCard
event={event}
metadata={metadataEvents.find((e) => 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) =>
<PostCard
key={event.postEvent.id}
event={event.postEvent}
metadata={event.metadataEvent}
replies={event.replies}
/>
)}
</div>
</main>

View File

@ -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 (
<main className="text-white mb-20">
@ -56,11 +25,11 @@ const Home = () => {
<NewNoteCard />
</div>
<div className={`grid grid-cols-1 max-w-xl mx-auto gap-1 px-4 ${isAnimating ? 'animate-pulse' : ''}`}>
{sortedEvents.map((event) => (
{processedEvents.map((event) => (
<PostCard
key={event.postEvent.id}
event={event.postEvent}
metadata={metadataEvents.find((e) => e.pubkey === event.postEvent.pubkey && e.kind === 0) || null}
metadata={event.metadataEvent}
replies={event.replies}
/>
))}

View File

@ -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<ProcessedEvent[]>([]);
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;