mirror of
https://github.com/smolgrrr/TAO.git
synced 2024-09-20 09:21:25 +00:00
start cleaning up
This commit is contained in:
parent
f9c07267b2
commit
3a1ca92d30
@ -1,72 +1,48 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import PostCard from "./PostCard/PostCard";
|
||||
import NewThreadCard from "./PostCard/NewThreadCard";
|
||||
import { getPow } from "../utils/mine";
|
||||
import { Event } from "nostr-tools";
|
||||
import { uniqBy } from "../utils/utils"; // Assume getPow is a correct import now
|
||||
import { subGlobalFeed } from "../utils/subscriptions";
|
||||
import { uniqBy } from "../utils/utils";
|
||||
// import PWAInstallPopup from "./Modals/PWACheckModal"; // Removed as it's not being used
|
||||
import { verifyPow } from "../utils/mine";
|
||||
import { Event } from "nostr-tools";
|
||||
|
||||
const Home = () => {
|
||||
// State declarations
|
||||
const useUniqEvents = () => {
|
||||
const [events, setEvents] = useState<Event[]>([]);
|
||||
const [filterDifficulty, setFilterDifficulty] = useState(localStorage.getItem("filterDifficulty") || "20");
|
||||
const [sortByTime, setSortByTime] = useState(true);
|
||||
// const [inBrowser, setInBrowser] = useState(false); // Removed as it's not being used
|
||||
|
||||
// Function to handle new events
|
||||
const onEvent = (event: Event) => {
|
||||
setEvents((prevEvents) => [...prevEvents, event]);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// Subscribe to the global feed
|
||||
subGlobalFeed(onEvent);
|
||||
const onEvent = (event: Event) => setEvents((prevEvents) => [...prevEvents, event]);
|
||||
const unsubscribe = subGlobalFeed(onEvent);
|
||||
|
||||
// Event listener to handle difficulty changes
|
||||
const handleDifficultyChange = (event: any) => {
|
||||
const { filterDifficulty } = event.detail;
|
||||
setFilterDifficulty(filterDifficulty);
|
||||
};
|
||||
|
||||
// Attach event listener
|
||||
window.addEventListener("difficultyChanged", handleDifficultyChange);
|
||||
|
||||
// Cleanup listener on component unmount
|
||||
return () => {
|
||||
window.removeEventListener("difficultyChanged", handleDifficultyChange);
|
||||
};
|
||||
return unsubscribe;
|
||||
}, []);
|
||||
|
||||
// Get unique events based on id
|
||||
const uniqEvents = events.length > 0 ? uniqBy(events, "id") : [];
|
||||
return uniqBy(events, "id");
|
||||
};
|
||||
|
||||
// Filter and sort events
|
||||
const filteredEvents = uniqEvents
|
||||
const Home = () => {
|
||||
const filterDifficulty = localStorage.getItem("filterDifficulty") || 20;
|
||||
const [sortByTime, setSortByTime] = useState(true);
|
||||
const uniqEvents = useUniqEvents();
|
||||
|
||||
const postEvents = uniqEvents
|
||||
.filter((event) =>
|
||||
getPow(event.id) > Number(filterDifficulty) &&
|
||||
verifyPow(event) >= Number(filterDifficulty) &&
|
||||
event.kind === 1 &&
|
||||
!event.tags.some((tag) => tag[0] === "e")
|
||||
)
|
||||
|
||||
const sortedEvents = [...postEvents].sort((a, b) =>
|
||||
sortByTime ? b.created_at - a.created_at : verifyPow(b) - verifyPow(a)
|
||||
);
|
||||
|
||||
const toggleSort = () => {
|
||||
setSortByTime(prev => !prev);
|
||||
};
|
||||
|
||||
// Events sorted by time
|
||||
const eventsSortedByTime = [...filteredEvents].sort((a, b) => b.created_at - a.created_at);
|
||||
|
||||
// Events sorted by PoW (assuming `getPow` returns a numerical representation of the PoW)
|
||||
const eventsSortedByPow = [...filteredEvents].sort((a, b) => getPow(b.id) - getPow(a.id));
|
||||
|
||||
const displayedEvents = sortByTime ? eventsSortedByTime : eventsSortedByPow;
|
||||
|
||||
// Get metadata for an event
|
||||
const getMetadataEvent = (event: Event) => {
|
||||
return uniqEvents.find((e) => e.pubkey === event.pubkey && e.kind === 0) || null;
|
||||
};
|
||||
|
||||
// Count replies for an event
|
||||
const countReplies = (event: Event) => {
|
||||
return uniqEvents.filter((e) => e.tags.some((tag) => tag[0] === "e" && tag[1] === event.id)).length;
|
||||
};
|
||||
@ -88,10 +64,7 @@ const Home = () => {
|
||||
onChange={toggleSort}
|
||||
/>
|
||||
<div className="block bg-gray-600 w-10 h-6 rounded-full"></div>
|
||||
<div
|
||||
className={`dot absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition ${sortByTime ? 'transform translate-x-full bg-blue-400' : ''
|
||||
}`}
|
||||
></div>
|
||||
<div className={`dot absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition ${sortByTime ? 'transform translate-x-full bg-blue-400' : '' }`} ></div>
|
||||
</div>
|
||||
<div className={`ml-3 text-neutral-500 font-medium ${sortByTime ? 'text-neutral-500' : ''}`}>
|
||||
{sortByTime ? 'Sort by recent' : 'Sort by PoW'}
|
||||
@ -99,7 +72,7 @@ const Home = () => {
|
||||
</label>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 p-4">
|
||||
{displayedEvents.map((event) => (
|
||||
{sortedEvents.map((event) => (
|
||||
<PostCard
|
||||
key={event.id}
|
||||
event={event}
|
||||
|
@ -1,21 +0,0 @@
|
||||
// PWAInstallPopup.tsx
|
||||
import React, { useState, useEffect } from 'react';
|
||||
|
||||
interface PWAInstallPopupProps {
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
const PWAInstallPopup: React.FC<PWAInstallPopupProps> = ({ onClose }) => {
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 flex items-center justify-center z-50">
|
||||
<div className="bg-white p-4 rounded shadow-lg">
|
||||
<h1 className="text-lg font-semibold mb-2">Install Our PWA</h1>
|
||||
<p className="mb-4">Click "Install" to add this app to your home screen and enjoy a full-screen experience!</p>
|
||||
<button className="bg-gray-200 px-4 py-2 rounded" onClick={onClose}>Close</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PWAInstallPopup;
|
@ -1,12 +1,12 @@
|
||||
import CardContainer from "./CardContainer";
|
||||
import { FolderIcon } from "@heroicons/react/24/outline";
|
||||
import { FolderIcon, CpuChipIcon } from "@heroicons/react/24/outline";
|
||||
import { parseContent } from "../../utils/content";
|
||||
import { Event } from "nostr-tools";
|
||||
import { nip19 } from "nostr-tools";
|
||||
import { Event, nip19 } from "nostr-tools";
|
||||
import { getMetadata } from "../../utils/utils";
|
||||
import ContentPreview from "../Modals/TextModal";
|
||||
import { renderMedia } from "../../utils/FileUpload";
|
||||
import { getIconFromHash } from "../../utils/deterministicProfileIcon";
|
||||
import { verifyPow } from "../../utils/mine";
|
||||
|
||||
const timeAgo = (unixTime: number) => {
|
||||
const seconds = Math.floor(new Date().getTime() / 1000 - unixTime);
|
||||
@ -74,15 +74,15 @@ const PostCard = ({
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center ml-auto gap-2.5">
|
||||
<div className="text-xs text-neutral-600">
|
||||
{event.id.match(/^0*([^\0]{2})/)?.[0] || 0}
|
||||
<div className="inline-flex text-xs text-neutral-600 gap-0.5">
|
||||
<CpuChipIcon className="h-4 w-4" /> {verifyPow(event)}
|
||||
</div>
|
||||
<span className="text-neutral-700">·</span>
|
||||
<div className="text-xs font-semibold text-neutral-600">
|
||||
{timeAgo(event.created_at)}
|
||||
</div>
|
||||
<span className="text-neutral-700">·</span>
|
||||
<div className="inline-flex items-center gap-1.5">
|
||||
<div className="inline-flex items-center gap-1">
|
||||
<FolderIcon className="h-4 w-4 text-neutral-600" />
|
||||
<span className="text-xs text-neutral-600">{replyCount}</span>
|
||||
</div>
|
||||
|
@ -49,4 +49,20 @@ export function minePow<K extends number>(unsigned: UnsignedEvent<K>, difficulty
|
||||
}
|
||||
|
||||
return event
|
||||
}
|
||||
|
||||
/** Verify POW difficulty for a NOSTR event. */
|
||||
export function verifyPow(event: Event): number {
|
||||
const hash = getEventHash(event)
|
||||
const count = getPow(hash)
|
||||
|
||||
// Extract the target difficulty level from the tags
|
||||
const nonceTag = event.tags.find(tag => tag[0] === 'nonce');
|
||||
if (!nonceTag || nonceTag.length < 3) {
|
||||
return 0 // Without specifying target difficulty, there is no PROOF of work
|
||||
}
|
||||
const targetDifficulty = parseInt(nonceTag[2], 10);
|
||||
|
||||
// The proof-of-work is the minimum of actual hash result and target
|
||||
return Math.min(count, targetDifficulty)
|
||||
}
|
Loading…
Reference in New Issue
Block a user