diff --git a/src/views/thread/index.tsx b/src/views/thread/index.tsx index 9e04ca5f1..e9e99a7fb 100644 --- a/src/views/thread/index.tsx +++ b/src/views/thread/index.tsx @@ -1,9 +1,10 @@ import { ReactNode } from "react"; -import { Card, Heading, Link, Spinner } from "@chakra-ui/react"; +import { Box, Heading, Link, LinkBox, Spinner, useDisclosure } from "@chakra-ui/react"; import { Link as RouterLink } from "react-router-dom"; import { Thread, ThreadQuery } from "applesauce-core/queries"; import { useStoreQuery } from "applesauce-react/hooks"; -import { nip19 } from "nostr-tools"; +import { EventPointer } from "nostr-tools/nip19"; +import { nip19, NostrEvent } from "nostr-tools"; import ThreadPost from "./components/thread-post"; import VerticalPageLayout from "../../components/vertical-page-layout"; @@ -14,45 +15,79 @@ import useThreadTimelineLoader from "../../hooks/use-thread-timeline-loader"; import useSingleEvent from "../../hooks/use-single-event"; import useParamsEventPointer from "../../hooks/use-params-event-pointer"; import LoadingNostrLink from "../../components/loading-nostr-link"; -import UserName from "../../components/user/user-name"; import UserAvatarLink from "../../components/user/user-avatar-link"; -import { ReplyIcon } from "../../components/icons"; -import TimelineNote from "../../components/note/timeline-note"; import { getSharableEventAddress } from "../../services/relay-hints"; import useMaxPageWidth from "../../hooks/use-max-page-width"; +import { getNip10References } from "applesauce-core/helpers"; +import useEventIntersectionRef from "../../hooks/use-event-intersection-ref"; +import UserLink from "../../components/user/user-link"; +import { ExpandableToggleButton } from "../notifications/components/notification-item"; +import TextNoteContents from "../../components/note/timeline-note/text-note-contents"; +import { TrustProvider } from "../../providers/local/trust-provider"; +import UserDnsIdentityIcon from "../../components/user/user-dns-identity-icon"; +import Timestamp from "../../components/timestamp"; -function CollapsedReplies({ - pointer, - thread, - root, -}: { - pointer: nip19.EventPointer; - thread: Thread; - root: nip19.EventPointer; -}) { - const post = thread.all.get(pointer.id); - if (!post) return ; - - let reply: ReactNode = null; - if (post.refs.reply?.e && post.refs.reply.e.id !== root.id) { - reply = ; - } +function ParentNote({ note, level = 0 }: { note: NostrEvent; level?: number }) { + const ref = useEventIntersectionRef(note); + const more = useDisclosure({ defaultIsOpen: level < 2 }); return ( - <> - {reply} - - - - {root.id !== pointer.id && } - - {post.event.content} + + + + + + + + - - + + {more.isOpen ? ( + +
+ +
+ ) : ( + + {note.content} + + )} + ); } +function Parents({ pointer, thread }: { pointer: nip19.EventPointer; thread: Thread }) { + const posts: ReactNode[] = []; + + let level = 0; + let cursor: EventPointer | undefined = pointer; + while (cursor) { + const post = thread.all.get(cursor.id); + + if (post) { + posts.unshift(); + // attempt to walk up the "e" reply tree + cursor = getNip10References(post.event).reply?.e; + level++; + } else { + // failed to find parent post, append loading and done + posts.unshift(); + cursor = undefined; + } + } + + return <>{posts}; +} + function ThreadPage({ thread, rootPointer, @@ -82,19 +117,22 @@ function ThreadPage({ const grandparentPointer = focusedPost.parent?.refs.reply?.e; + const parent = getNip10References(focusedPost.event).reply?.e; + return ( <> - {rootPointer && focusedPost.refs.reply?.e?.id !== rootPointer.id && ( - + {parent && } + {/* {rootPointer && focusedPost.refs.reply?.e?.id !== rootPointer.id && ( + )} {grandparentPointer && grandparentPointer.id !== rootPointer.id && ( - + )} {focusedPost.parent ? ( ) : ( focusedPost.refs.reply?.e && - )} + )} */} );