mirror of
https://github.com/smolgrrr/TAO.git
synced 2024-09-20 01:11:25 +00:00
clean up feeds
This commit is contained in:
parent
3ef3310a33
commit
6319fb659b
@ -2,7 +2,7 @@ import { PropsWithChildren } from "react";
|
|||||||
|
|
||||||
export default function CardContainer({ children }: PropsWithChildren) {
|
export default function CardContainer({ children }: PropsWithChildren) {
|
||||||
return (
|
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 className="card-body">{children}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -88,17 +88,17 @@ const PostCard = ({
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>}
|
</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 ?
|
{metadataParsed ?
|
||||||
<img
|
<img
|
||||||
key={key}
|
key={key}
|
||||||
className={`h-5 w-5 rounded-full`}
|
className={`h-7 w-7 rounded-full overflow-hidden`}
|
||||||
src={metadataParsed?.picture ?? icon}
|
src={metadataParsed?.picture ?? icon}
|
||||||
alt=""
|
alt=""
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
decoding="async" />
|
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="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`}>
|
<div className={`inline-flex text-xs ${verifyPow(parsedEvent) === 0 ? 'text-neutral-600' : 'text-sky-800'} gap-0.5`}>
|
||||||
|
@ -1,33 +1,14 @@
|
|||||||
import PostCard from "../modals/PostCard";
|
import PostCard from "../modals/PostCard";
|
||||||
import { verifyPow } from "../../utils/mine";
|
|
||||||
import { Event } from "nostr-tools";
|
|
||||||
import NewNoteCard from "../forms/PostFormCard";
|
import NewNoteCard from "../forms/PostFormCard";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { useFetchEvents } from "../../hooks/useFetchEvents";
|
import useProcessedEvents from "../../hooks/processedEvents";
|
||||||
|
|
||||||
const DEFAULT_DIFFICULTY = 0;
|
const DEFAULT_DIFFICULTY = 0;
|
||||||
|
|
||||||
const HashtagPage = () => {
|
const HashtagPage = () => {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const filterDifficulty = localStorage.getItem("filterHashtagDifficulty") || DEFAULT_DIFFICULTY;
|
const filterDifficulty = DEFAULT_DIFFICULTY;
|
||||||
const { noteEvents, metadataEvents } = useFetchEvents(id as string, false);
|
const { processedEvents } = useProcessedEvents(id as string, filterDifficulty);
|
||||||
|
|
||||||
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;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Render the component
|
// Render the component
|
||||||
return (
|
return (
|
||||||
@ -36,11 +17,12 @@ const HashtagPage = () => {
|
|||||||
<NewNoteCard hashtag={id as string} />
|
<NewNoteCard hashtag={id as string} />
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-1 max-w-xl mx-auto gap-1 px-4">
|
<div className="grid grid-cols-1 max-w-xl mx-auto gap-1 px-4">
|
||||||
{sortedEvents.map((event) =>
|
{processedEvents.map((event) =>
|
||||||
<PostCard
|
<PostCard
|
||||||
event={event}
|
key={event.postEvent.id}
|
||||||
metadata={metadataEvents.find((e) => e.pubkey === event.pubkey && e.kind === 0) || null}
|
event={event.postEvent}
|
||||||
replies={sortedEvents.filter((e) => e.tags.some((tag) => tag[0] === "e" && tag[1] === event.id))}
|
metadata={event.metadataEvent}
|
||||||
|
replies={event.replies}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
)}
|
)}
|
||||||
|
@ -1,54 +1,23 @@
|
|||||||
import { verifyPow } from "../../utils/mine";
|
|
||||||
import { Event } from "nostr-tools";
|
|
||||||
import NewNoteCard from "../forms/PostFormCard";
|
import NewNoteCard from "../forms/PostFormCard";
|
||||||
import { DEFAULT_DIFFICULTY } from "../../config";
|
import { DEFAULT_DIFFICULTY } from "../../config";
|
||||||
import PostCard from "../modals/PostCard";
|
import PostCard from "../modals/PostCard";
|
||||||
import { useFetchEvents } from "../../hooks/useFetchEvents";
|
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
|
import useProcessedEvents from "../../hooks/processedEvents";
|
||||||
|
|
||||||
const Home = () => {
|
const Home = () => {
|
||||||
const filterDifficulty = localStorage.getItem("filterDifficulty") || DEFAULT_DIFFICULTY;
|
const filterDifficulty = Number(localStorage.getItem('filterDifficulty')) || DEFAULT_DIFFICULTY;
|
||||||
const { noteEvents, metadataEvents } = useFetchEvents();
|
const { processedEvents } = useProcessedEvents(undefined, filterDifficulty);
|
||||||
const [isAnimating, setIsAnimating] = useState(true);
|
const [isAnimating, setIsAnimating] = useState(true);
|
||||||
|
|
||||||
// Step 3: Use useEffect to remove the animation class after 3 seconds
|
// Step 3: Use useEffect to remove the animation class after 3 seconds
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
setIsAnimating(false);
|
setIsAnimating(false);
|
||||||
}, 3000); // 3000 milliseconds = 3 seconds
|
}, 4000); // 3000 milliseconds = 3 seconds
|
||||||
|
|
||||||
return () => clearTimeout(timer); // Cleanup the timer
|
return () => clearTimeout(timer); // Cleanup the timer
|
||||||
}, []); // Empty dependency array means this effect runs once on mount
|
}, []); // 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
|
// Render the component
|
||||||
return (
|
return (
|
||||||
<main className="text-white mb-20">
|
<main className="text-white mb-20">
|
||||||
@ -56,11 +25,11 @@ const Home = () => {
|
|||||||
<NewNoteCard />
|
<NewNoteCard />
|
||||||
</div>
|
</div>
|
||||||
<div className={`grid grid-cols-1 max-w-xl mx-auto gap-1 px-4 ${isAnimating ? 'animate-pulse' : ''}`}>
|
<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
|
<PostCard
|
||||||
key={event.postEvent.id}
|
key={event.postEvent.id}
|
||||||
event={event.postEvent}
|
event={event.postEvent}
|
||||||
metadata={metadataEvents.find((e) => e.pubkey === event.postEvent.pubkey && e.kind === 0) || null}
|
metadata={event.metadataEvent}
|
||||||
replies={event.replies}
|
replies={event.replies}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
35
client/src/hooks/processedEvents.ts
Normal file
35
client/src/hooks/processedEvents.ts
Normal 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;
|
Loading…
Reference in New Issue
Block a user