diff --git a/client/src/components/forms/ThreadPostModal.tsx b/client/src/components/forms/ThreadPostModal.tsx new file mode 100644 index 0000000..add82ad --- /dev/null +++ b/client/src/components/forms/ThreadPostModal.tsx @@ -0,0 +1,63 @@ +import { useState } from "react"; +import { Event } from "nostr-tools" +import { DocumentTextIcon, FolderPlusIcon, DocumentDuplicateIcon, ArrowTopRightOnSquareIcon } from '@heroicons/react/24/outline'; +import NewNoteCard from '../forms/PostFormCard'; +import RepostNote from '../forms/RepostNote'; + +type PostType = "" | "Reply" | "Quote" | undefined; + +const ThreadPostModal = ({ OPEvent }: { OPEvent: Event }) => { + const [showForm, setShowForm] = useState(false); + const [showRepost, setShowRepost] = useState(false); + const [postType, setPostType] = useState(""); + + return ( + <> +
+ { + setShowForm(prevShowForm => !prevShowForm); + setPostType('Reply'); + setShowRepost(false) + }} + /> + { + setShowRepost(prevShowRepost => !prevShowRepost); + setShowForm(false); + }} + /> + { + setShowForm(prevShowForm => !prevShowForm); + setPostType('Quote'); + setShowRepost(false) + }} + /> + + + +
+ {(showForm && postType) && +
+
+ {postType}-post +
+ +
} + {showRepost && OPEvent &&
+
+ Repost note +
+ +
} + + ); +}; + +export default ThreadPostModal; \ No newline at end of file diff --git a/client/src/components/modals/PostCard.tsx b/client/src/components/modals/PostCard.tsx index 0bcc9ac..9139c9c 100644 --- a/client/src/components/modals/PostCard.tsx +++ b/client/src/components/modals/PostCard.tsx @@ -8,6 +8,7 @@ import { verifyPow } from "../../utils/mine"; import { uniqBy } from "../../utils/otherUtils"; import ContentPreview from "./CardModals/TextModal"; import CardContainer from "./CardContainer"; +import { useState, useEffect } from "react"; interface CardProps { key?: string | number; @@ -29,9 +30,16 @@ const PostCard = ({ // const { files } = parseContent(event); const icon = getIconFromHash(event.pubkey); const metadataParsed = metadata ? getMetadata(metadata) : null; + const [relatedEvents, setRelatedEvents] = useState([]); + + useEffect(() => { + const allRelatedEvents = [event, ...(replies || [])]; + setRelatedEvents(allRelatedEvents); + }, [event, replies]); const handleClick = () => { if (type !== "OP") { + localStorage.setItem("cachedThread", JSON.stringify(relatedEvents)); window.location.href = `/thread/${nip19.noteEncode(event.id)}`; } }; diff --git a/client/src/components/routes/Home.tsx b/client/src/components/routes/Home.tsx index f853d5d..1336a1f 100644 --- a/client/src/components/routes/Home.tsx +++ b/client/src/components/routes/Home.tsx @@ -17,7 +17,7 @@ const Home = () => { (event.kind !== 1 || !event.tags.some((tag) => tag[0] === "e" || tag[0] === "a")) ) - let sortedEvents = [...postEvents] + const sortedEvents = postEvents .sort((a, b) => { // Sort by PoW in descending order const powDiff = verifyPow(b) - verifyPow(a); diff --git a/client/src/components/routes/Thread.tsx b/client/src/components/routes/Thread.tsx index 9f4652d..32bfafd 100644 --- a/client/src/components/routes/Thread.tsx +++ b/client/src/components/routes/Thread.tsx @@ -4,41 +4,39 @@ import { Event, nip19 } from "nostr-tools" import { subNotesOnce } from '../../utils/subscriptions'; import { useEffect } from 'react'; import { uniqBy } from '../../utils/otherUtils'; -import { DocumentTextIcon, FolderPlusIcon, DocumentDuplicateIcon, ArrowTopRightOnSquareIcon } from '@heroicons/react/24/outline'; import Placeholder from '../modals/Placeholder'; -import NewNoteCard from '../forms/PostFormCard'; -import RepostNote from '../forms/RepostNote'; import PostCard from '../modals/PostCard'; import { useFetchEvents } from '../../hooks/useFetchEvents'; - -type PostType = "" | "Reply" | "Quote" | undefined; +import ThreadPostModal from '../forms/ThreadPostModal'; const Thread = () => { const { id } = useParams(); - const [showForm, setShowForm] = useState(false); - const [showRepost, setShowRepost] = useState(false); - const [postType, setPostType] = useState(""); const [prevMentions, setPrevMentions] = useState([]); - // const filterDifficulty = useState(localStorage.getItem("filterDifficulty") || "20"); let decodeResult = nip19.decode(id as string); let hexID = decodeResult.data as string; const { noteEvents, metadataEvents } = useFetchEvents(undefined,false,hexID); + // Load cached thread from localStorage + const [threadCache, setThreadCache] = useState( + JSON.parse(localStorage.getItem("cachedThread") || "[]") + ); + // Combine noteEvents and threadCache into a single array + const allEvents = [...noteEvents, ...threadCache]; + const countReplies = (event: Event) => { - return noteEvents.filter(e => e.tags.some(tag => tag[0] === 'e' && tag[1] === event.id)); + return allEvents.filter(e => e.tags.some(tag => tag[0] === 'e' && tag[1] === event.id)); } const repliedList = (event: Event): Event[] => { - return noteEvents.filter(e => event.tags.some(tag => tag[0] === 'p' && tag[1] === e.pubkey)); + return allEvents.filter(e => event.tags.some(tag => tag[0] === 'p' && tag[1] === e.pubkey)); } - // Define your callback function for subGlobalFeed - const onEvent = (event: Event, relay: string) => { + const onEvent = (event: Event) => { setPrevMentions((prevEvents) => [...prevEvents, event]); }; - const OPEvent = noteEvents.find(event => event.id === hexID); + const OPEvent = allEvents.find(event => event.id === hexID); useEffect(() => { if (OPEvent && prevMentions.length == 0) { const OPMentionIDs = OPEvent.tags.filter(tag => tag[0] === 'e').map(tag => tag[1]); @@ -53,7 +51,7 @@ const Thread = () => { e.created_at < OPEvent.created_at ) - const replyEvents = [...noteEvents].slice(1) + const replyEvents = [...allEvents].slice(1) .filter(event => !earlierEvents.map(e => e.id).includes(event.id) && (OPEvent ? OPEvent.id !== event.id : true) @@ -70,49 +68,7 @@ const Thread = () => { ))} e.pubkey === OPEvent.pubkey && e.kind === 0) || null} replies={countReplies(OPEvent)} type={'OP'}/> -
- { - setShowForm(prevShowForm => !prevShowForm); - setPostType('Reply'); - setShowRepost(false) - }} - /> - { - setShowRepost(prevShowRepost => !prevShowRepost); - setShowForm(false); - }} - /> - { - setShowForm(prevShowForm => !prevShowForm); - setPostType('Quote'); - setShowRepost(false) - }} - /> - - - -
- {(showForm && postType) && -
-
- {postType}-post -
- -
} - {showRepost && OPEvent &&
-
- Repost note -
- -
} +
{/* This is the white line separator */}
{replyEvents.map((event, index) => (