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 { useEffect, useState } from "react";
|
||||||
import PostCard from "./PostCard/PostCard";
|
import PostCard from "./PostCard/PostCard";
|
||||||
import NewThreadCard from "./PostCard/NewThreadCard";
|
import NewThreadCard from "./PostCard/NewThreadCard";
|
||||||
import { getPow } from "../utils/mine";
|
import { uniqBy } from "../utils/utils"; // Assume getPow is a correct import now
|
||||||
import { Event } from "nostr-tools";
|
|
||||||
import { subGlobalFeed } from "../utils/subscriptions";
|
import { subGlobalFeed } from "../utils/subscriptions";
|
||||||
import { uniqBy } from "../utils/utils";
|
import { verifyPow } from "../utils/mine";
|
||||||
// import PWAInstallPopup from "./Modals/PWACheckModal"; // Removed as it's not being used
|
import { Event } from "nostr-tools";
|
||||||
|
|
||||||
const Home = () => {
|
const useUniqEvents = () => {
|
||||||
// State declarations
|
|
||||||
const [events, setEvents] = useState<Event[]>([]);
|
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(() => {
|
useEffect(() => {
|
||||||
// Subscribe to the global feed
|
const onEvent = (event: Event) => setEvents((prevEvents) => [...prevEvents, event]);
|
||||||
subGlobalFeed(onEvent);
|
const unsubscribe = subGlobalFeed(onEvent);
|
||||||
|
|
||||||
// Event listener to handle difficulty changes
|
return unsubscribe;
|
||||||
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);
|
|
||||||
};
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Get unique events based on id
|
return uniqBy(events, "id");
|
||||||
const uniqEvents = events.length > 0 ? uniqBy(events, "id") : [];
|
};
|
||||||
|
|
||||||
// Filter and sort events
|
const Home = () => {
|
||||||
const filteredEvents = uniqEvents
|
const filterDifficulty = localStorage.getItem("filterDifficulty") || 20;
|
||||||
|
const [sortByTime, setSortByTime] = useState(true);
|
||||||
|
const uniqEvents = useUniqEvents();
|
||||||
|
|
||||||
|
const postEvents = uniqEvents
|
||||||
.filter((event) =>
|
.filter((event) =>
|
||||||
getPow(event.id) > Number(filterDifficulty) &&
|
verifyPow(event) >= Number(filterDifficulty) &&
|
||||||
event.kind === 1 &&
|
event.kind === 1 &&
|
||||||
!event.tags.some((tag) => tag[0] === "e")
|
!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 = () => {
|
const toggleSort = () => {
|
||||||
setSortByTime(prev => !prev);
|
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) => {
|
const getMetadataEvent = (event: Event) => {
|
||||||
return uniqEvents.find((e) => e.pubkey === event.pubkey && e.kind === 0) || null;
|
return uniqEvents.find((e) => e.pubkey === event.pubkey && e.kind === 0) || null;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Count replies for an event
|
|
||||||
const countReplies = (event: Event) => {
|
const countReplies = (event: Event) => {
|
||||||
return uniqEvents.filter((e) => e.tags.some((tag) => tag[0] === "e" && tag[1] === event.id)).length;
|
return uniqEvents.filter((e) => e.tags.some((tag) => tag[0] === "e" && tag[1] === event.id)).length;
|
||||||
};
|
};
|
||||||
@ -88,10 +64,7 @@ const Home = () => {
|
|||||||
onChange={toggleSort}
|
onChange={toggleSort}
|
||||||
/>
|
/>
|
||||||
<div className="block bg-gray-600 w-10 h-6 rounded-full"></div>
|
<div className="block bg-gray-600 w-10 h-6 rounded-full"></div>
|
||||||
<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>
|
||||||
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>
|
||||||
<div className={`ml-3 text-neutral-500 font-medium ${sortByTime ? 'text-neutral-500' : ''}`}>
|
<div className={`ml-3 text-neutral-500 font-medium ${sortByTime ? 'text-neutral-500' : ''}`}>
|
||||||
{sortByTime ? 'Sort by recent' : 'Sort by PoW'}
|
{sortByTime ? 'Sort by recent' : 'Sort by PoW'}
|
||||||
@ -99,7 +72,7 @@ const Home = () => {
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 p-4">
|
<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
|
<PostCard
|
||||||
key={event.id}
|
key={event.id}
|
||||||
event={event}
|
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 CardContainer from "./CardContainer";
|
||||||
import { FolderIcon } from "@heroicons/react/24/outline";
|
import { FolderIcon, CpuChipIcon } from "@heroicons/react/24/outline";
|
||||||
import { parseContent } from "../../utils/content";
|
import { parseContent } from "../../utils/content";
|
||||||
import { Event } from "nostr-tools";
|
import { Event, nip19 } from "nostr-tools";
|
||||||
import { nip19 } from "nostr-tools";
|
|
||||||
import { getMetadata } from "../../utils/utils";
|
import { getMetadata } from "../../utils/utils";
|
||||||
import ContentPreview from "../Modals/TextModal";
|
import ContentPreview from "../Modals/TextModal";
|
||||||
import { renderMedia } from "../../utils/FileUpload";
|
import { renderMedia } from "../../utils/FileUpload";
|
||||||
import { getIconFromHash } from "../../utils/deterministicProfileIcon";
|
import { getIconFromHash } from "../../utils/deterministicProfileIcon";
|
||||||
|
import { verifyPow } from "../../utils/mine";
|
||||||
|
|
||||||
const timeAgo = (unixTime: number) => {
|
const timeAgo = (unixTime: number) => {
|
||||||
const seconds = Math.floor(new Date().getTime() / 1000 - unixTime);
|
const seconds = Math.floor(new Date().getTime() / 1000 - unixTime);
|
||||||
@ -74,15 +74,15 @@ const PostCard = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center ml-auto gap-2.5">
|
<div className="flex items-center ml-auto gap-2.5">
|
||||||
<div className="text-xs text-neutral-600">
|
<div className="inline-flex text-xs text-neutral-600 gap-0.5">
|
||||||
{event.id.match(/^0*([^\0]{2})/)?.[0] || 0}
|
<CpuChipIcon className="h-4 w-4" /> {verifyPow(event)}
|
||||||
</div>
|
</div>
|
||||||
<span className="text-neutral-700">·</span>
|
<span className="text-neutral-700">·</span>
|
||||||
<div className="text-xs font-semibold text-neutral-600">
|
<div className="text-xs font-semibold text-neutral-600">
|
||||||
{timeAgo(event.created_at)}
|
{timeAgo(event.created_at)}
|
||||||
</div>
|
</div>
|
||||||
<span className="text-neutral-700">·</span>
|
<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" />
|
<FolderIcon className="h-4 w-4 text-neutral-600" />
|
||||||
<span className="text-xs text-neutral-600">{replyCount}</span>
|
<span className="text-xs text-neutral-600">{replyCount}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -50,3 +50,19 @@ export function minePow<K extends number>(unsigned: UnsignedEvent<K>, difficulty
|
|||||||
|
|
||||||
return event
|
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