From ef574c4d2d3a53938dbad0ec6dbe934fecafd3bb Mon Sep 17 00:00:00 2001 From: smolgrrr Date: Thu, 26 Oct 2023 18:29:14 +1100 Subject: [PATCH] reply tings --- client/src/components/Home.tsx | 2 +- client/src/components/Thread/ReplyCard.tsx | 126 ++++++++++++++++++++ client/src/components/Thread/Thread.tsx | 11 +- client/src/components/Thread/ThreadPost.tsx | 4 +- 4 files changed, 136 insertions(+), 7 deletions(-) create mode 100644 client/src/components/Thread/ReplyCard.tsx diff --git a/client/src/components/Home.tsx b/client/src/components/Home.tsx index fbff3fb..349355d 100644 --- a/client/src/components/Home.tsx +++ b/client/src/components/Home.tsx @@ -23,7 +23,7 @@ const Home = () => { const filteredAndSortedEvents = uniqEvents .filter(event => - getPow(event.id) > 3 && + getPow(event.id) > 20 && event.kind === 1 && !event.tags.some(tag => tag[0] === 'p') ) diff --git a/client/src/components/Thread/ReplyCard.tsx b/client/src/components/Thread/ReplyCard.tsx new file mode 100644 index 0000000..ca952d6 --- /dev/null +++ b/client/src/components/Thread/ReplyCard.tsx @@ -0,0 +1,126 @@ +import CardContainer from '../PostCard/CardContainer' +import { FolderIcon } from '@heroicons/react/24/outline'; +import { parseContent } from '../../utils/content'; +import { Event } from 'nostr-tools'; +import { nip19 } from 'nostr-tools'; +import { useEffect, useState } from 'react'; +import { subNote } from '../../utils/subscriptions'; +import { getMetadata, uniqBy } from '../../utils/utils'; + +const colorCombos = [ + 'from-red-400 to-yellow-500', + 'from-green-400 to-blue-500', + 'from-purple-400 to-pink-500', + 'from-yellow-400 to-orange-500', + 'from-indigo-400 to-purple-500', + 'from-pink-400 to-red-500', + 'from-blue-400 to-indigo-500', + 'from-orange-400 to-red-500', + 'from-teal-400 to-green-500', + 'from-cyan-400 to-teal-500', + 'from-lime-400 to-green-500', + 'from-amber-400 to-orange-500', + 'from-rose-400 to-pink-500', + 'from-violet-400 to-purple-500', + 'from-sky-400 to-cyan-500' +]; + +const getColorFromHash = (id: string, colors: string[]): string => { + // Create a simple hash from the event.id + let hash = 0; + for (let i = 0; i < id.length; i++) { + hash = (hash << 5) - hash + id.charCodeAt(i); + } + + // Use the hash to pick a color from the colors array + const index = Math.abs(hash) % colors.length; + return colors[index]; +}; + +const timeAgo = (unixTime: number) => { + const seconds = Math.floor((new Date().getTime() / 1000) - unixTime); + + 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); + if (days < 7) return `${days}d`; + + const weeks = Math.floor(days / 7); + return `${weeks}w`; +}; + +const ReplyCard = ({ event, metadata, replyCount, repliedTo }: { event: Event, metadata: Event | null, replyCount: number, repliedTo: Event[] }) => { + const { comment, file } = parseContent(event); + const colorCombo = getColorFromHash(event.pubkey, colorCombos); + + let metadataParsed = null; + if (metadata !== null) { + metadataParsed = getMetadata(metadata); + } + + // const replyPubkeys = event.tags.filter(tag => tag[0] === 'p'); + + // const getMetadataEvent = (event: Event) => { + // const metadataEvent = uniqEvents.find(e => e.pubkey === event.pubkey && e.kind === 0); + // if (metadataEvent) { + // return metadataEvent; + // } + // return null; + // } + + return ( + <> + + +
+
+
+ {metadataParsed ? + <> + +
{metadataParsed.name}
+ + : + <> +
+
Anonymous
+ + } +
+
+
{timeAgo(event.created_at)}
+ + {replyCount} +
+
+
+ Reply to: + {uniqBy(repliedTo, 'pubkey').map((event, index) => ( + + ))} +
+
+ {comment} +
+ {file !== "" && ( +
+ +
+ )} +
+
+ + + ); +}; + +export default ReplyCard; \ No newline at end of file diff --git a/client/src/components/Thread/Thread.tsx b/client/src/components/Thread/Thread.tsx index 632b4e4..8dc94d7 100644 --- a/client/src/components/Thread/Thread.tsx +++ b/client/src/components/Thread/Thread.tsx @@ -11,6 +11,7 @@ import { generatePrivateKey, getPublicKey, finishEvent, relayInit } from 'nostr- import { minePow } from '../../utils/mine'; import { publish } from '../../utils/relays'; import ThreadPost from './ThreadPost'; +import ReplyCard from './ReplyCard'; const difficulty = 20 @@ -23,8 +24,6 @@ const Thread = () => { const [showForm, setShowForm] = useState(false); const [postType, setPostType] = useState(""); - - // Define your callback function for subGlobalFeed const onEvent = (event: Event, relay: string) => { setEvents((prevEvents) => [...prevEvents, event]); @@ -80,6 +79,10 @@ const Thread = () => { return uniqEvents.filter(e => e.tags.some(tag => tag[0] === 'e' && tag[1] === event.id)).length; } + const repliedList = (event: Event): Event[] => { + return uniqEvents.filter(e => event.tags.some(tag => tag[0] === 'p' && tag[1] === e.pubkey) && e.kind === 0); + } + if (!uniqEvents[0]) { return ( <> @@ -132,8 +135,8 @@ const Thread = () => { {uniqEvents .slice(1) .filter(event => event.kind === 1) - .sort((a, b) => b.created_at - a.created_at).map((event, index) => ( - + .sort((a, b) => a.created_at - b.created_at).map((event, index) => ( + ))}
diff --git a/client/src/components/Thread/ThreadPost.tsx b/client/src/components/Thread/ThreadPost.tsx index d3293cb..3c14761 100644 --- a/client/src/components/Thread/ThreadPost.tsx +++ b/client/src/components/Thread/ThreadPost.tsx @@ -8,13 +8,12 @@ import NostrImg from '../../utils/ImgUpload'; import { nip19 } from 'nostr-tools'; -const difficulty = 5 +const difficulty = 25 const ThreadPost = ({ state, type }: { state: Boolean, type: String }) => { const { id} = useParams(); const [comment, setComment] = useState(""); const [file, setFile] = useState(""); - const [tags, setTags] = useState([['']]); let decodeResult = nip19.decode(id as string); @@ -23,6 +22,7 @@ const ThreadPost = ({ state, type }: { state: Boolean, type: String }) => { let sk = generatePrivateKey(); let id = decodeResult.data as string + let tags = []; if (type === 'r') { tags.push(["e", id as string]) } else if (type === 'q') {