add PoW sorted feed

This commit is contained in:
smolgrrr 2023-09-15 17:06:37 +10:00
parent 7989c20c1a
commit d754c20158
6 changed files with 82 additions and 24 deletions

View File

@ -3,14 +3,8 @@ import { relayInit } from 'nostr-tools';
import PostCard from './PostCard/PostCard'; import PostCard from './PostCard/PostCard';
import Header from './Header/Header'; import Header from './Header/Header';
import NewThreadCard from './PostCard/NewThreadCard'; import NewThreadCard from './PostCard/NewThreadCard';
import { getPow } from '../utils/mine';
// Define the Event interface import { Event } from 'nostr-tools';
interface Event {
id: string;
content: string;
created_at: number;
// Add other fields if necessary
}
const relay = relayInit('wss://nostr.lu.ke'); const relay = relayInit('wss://nostr.lu.ke');
@ -24,14 +18,16 @@ const Home = () => {
const eventList = await relay.list([ const eventList = await relay.list([
{ {
ids: ['00'],
kinds: [1], kinds: [1],
limit: 10, limit: 200,
}, },
]); ]);
// Filter events with a difficulty greater than 10
const filteredEvents = eventList.filter(event => getPow(event.id) > 2);
// Assuming eventList is of type Event[] // Assuming eventList is of type Event[]
setEvents(eventList); setEvents(filteredEvents);
}); });
relay.on('error', () => { relay.on('error', () => {
@ -46,8 +42,8 @@ const Home = () => {
<main className="bg-black text-white min-h-screen"> <main className="bg-black text-white min-h-screen">
<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">
<NewThreadCard /> <NewThreadCard />
{events.sort((a, b) => a.created_at - b.created_at).map((event, index) => ( {events.sort((a, b) => b.created_at - a.created_at).map((event, index) => (
<PostCard key={index} content={event.content} /> <PostCard key={index} event={event}/>
))} ))}
</div> </div>
</main> </main>

View File

@ -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 bg-gradient-to-r from-black to-neutral-950 shadow-lg shadow-black"> <div className="card bg-gradient-to-r from-black to-neutral-900 shadow-lg shadow-black">
<div className="card-body p-4">{children}</div> <div className="card-body p-4">{children}</div>
</div> </div>
); );

View File

@ -2,10 +2,12 @@ import CardContainer from './CardContainer';
import { ArrowUpTrayIcon } from '@heroicons/react/24/outline'; import { ArrowUpTrayIcon } from '@heroicons/react/24/outline';
import { useState } from 'react'; import { useState } from 'react';
import { generatePrivateKey, getPublicKey, finishEvent, relayInit} from 'nostr-tools'; import { generatePrivateKey, getPublicKey, finishEvent, relayInit} from 'nostr-tools';
import { minePow } from '../../func/mine'; import { minePow } from '../../utils/mine';
const difficulty = 10 const difficulty = 10
export const relay = relayInit('wss://nostr.lu.ke')
const NewThreadCard = () => { const NewThreadCard = () => {
const [comment, setComment] = useState(""); const [comment, setComment] = useState("");
@ -14,7 +16,6 @@ const NewThreadCard = () => {
let sk = generatePrivateKey() let sk = generatePrivateKey()
let pk = getPublicKey(sk) let pk = getPublicKey(sk)
const relay = relayInit('wss://nostr.lu.ke')
relay.on('connect', () => { relay.on('connect', () => {
console.log(`connected to ${relay.url}`) console.log(`connected to ${relay.url}`)
}) })

View File

@ -1,4 +1,7 @@
import CardContainer from './CardContainer'; import CardContainer from './CardContainer';
import { FolderIcon } from '@heroicons/react/24/outline';
import { parseContent } from '../../utils/content';
import { Event } from 'nostr-tools';
const colorCombos = [ const colorCombos = [
'from-red-400 to-yellow-500', 'from-red-400 to-yellow-500',
@ -22,9 +25,33 @@ function getRandomElement(array: string[]): string {
const index = Math.floor(Math.random() * array.length); const index = Math.floor(Math.random() * array.length);
return array[index]; return array[index];
} }
const randomCombo = getRandomElement(colorCombos); const timeAgo = (unixTime: number) => {
const seconds = Math.floor((new Date().getTime() / 1000) - unixTime);
const PostCard = ({ content }: { content: string }) => { if (seconds < 60) return `now`;
const minutes = Math.floor(seconds / 60);
if (minutes < 60) return `${minutes}m`;
const hours = Math.floor(minutes / 60);
if (hours < 24) return `${hours}h`;
const days = Math.floor(hours / 24);
return `${days} days ago`;
};
const PostCard = ({ event}: { event: Event }) => {
// Replace 10 with the actual number of comments for each post
const numberOfComments = 10;
const { comment, file } = parseContent(event);
// const replyList = await relay.list([
// {
// kinds: [1],
// limit: 200,
// },
// ]);
return ( return (
<> <>
@ -32,14 +59,26 @@ const PostCard = ({ content }: { content: string }) => {
<div className="flex flex-col"> <div className="flex flex-col">
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">
<div className="flex items-center"> <div className="flex items-center">
<div className={`h-6 w-6 bg-gradient-to-r ${getRandomElement(colorCombos)} rounded-full`} /> <div className={`h-5 w-5 bg-gradient-to-r ${getRandomElement(colorCombos)} rounded-full`} />
<div className="ml-2 text-lg font-semibold">Anonymous</div> <div className="ml-2 text-md font-semibold">Anonymous</div>
</div>
<div className="flex items-center ml-auto">
<div className="text-xs font-semibold text-gray-500 mr-2">{timeAgo(event.created_at)}</div>
<FolderIcon className="h-5 w-5 mr-1 text-gray-500" />
<span className="text-xs text-gray-500">{numberOfComments}</span>
</div> </div>
<div className="text-sm font-semibold">1 day ago</div>
</div> </div>
<div className="mr-2 flex flex-col break-words"> <div className="mr-2 flex flex-col break-words">
{content} {comment}
</div> </div>
{file !== "" && (
<div className="file">
<img
src={file}
loading="lazy"
/>
</div>
)}
</div> </div>
</CardContainer> </CardContainer>
</> </>

View File

@ -0,0 +1,22 @@
import { Event } from 'nostr-tools'
function extractMediaUrl(content: string){
const regex = /(https?:\/\/\S+\.(?:jpg|png|jpeg|gif|mp4|webm|mov|webp))/i;
const match = content.match(regex);
if (match) {
return match[0];
} else {
return '' ;
}
}
export function parseContent(event: Event) {
const file = extractMediaUrl(event.content) as string;
const contentWithoutFile = event.content.replace(file, '');
return {
comment: contentWithoutFile.trim(),
file
};
}