add user likes tab

This commit is contained in:
hzrd149 2023-07-02 10:28:48 -05:00
parent e4b40dda68
commit 086279ebdd
4 changed files with 87 additions and 0 deletions

View File

@ -0,0 +1,5 @@
---
"nostrudel": minor
---
Add user likes tab under profile view

View File

@ -34,6 +34,7 @@ import UserMediaTab from "./views/user/media";
import ToolsHomeView from "./views/tools";
import Nip19ToolsView from "./views/tools/nip19";
import UserAboutTab from "./views/user/about";
import UserLikesTab from "./views/user/likes";
const LiveStreamsTab = React.lazy(() => import("./views/streams"));
const StreamView = React.lazy(() => import("./views/streams/stream"));
@ -73,6 +74,7 @@ const router = createHashRouter([
{ path: "notes", element: <UserNotesTab /> },
{ path: "media", element: <UserMediaTab /> },
{ path: "zaps", element: <UserZapsTab /> },
{ path: "likes", element: <UserLikesTab /> },
{ path: "followers", element: <UserFollowersTab /> },
{ path: "following", element: <UserFollowingTab /> },
{ path: "relays", element: <UserRelaysTab /> },

View File

@ -46,6 +46,7 @@ const tabs = [
{ label: "Media", path: "media" },
{ label: "Zaps", path: "zaps" },
{ label: "Following", path: "following" },
{ label: "Likes", path: "likes" },
{ label: "Relays", path: "relays" },
{ label: "Reports", path: "reports" },
{ label: "Followers", path: "followers" },

79
src/views/user/likes.tsx Normal file
View File

@ -0,0 +1,79 @@
import { useRef } from "react";
import { useOutletContext } from "react-router-dom";
import { Box, Flex, SkeletonText, Spacer, Text } from "@chakra-ui/react";
import { Kind } from "nostr-tools";
import { getReferences, truncatedId } from "../../helpers/nostr-event";
import { useTimelineLoader } from "../../hooks/use-timeline-loader";
import { NostrEvent } from "../../types/nostr-event";
import { useAdditionalRelayContext } from "../../providers/additional-relay-context";
import { useReadRelayUrls } from "../../hooks/use-client-relays";
import TimelineActionAndStatus from "../../components/timeline-action-and-status";
import useSubject from "../../hooks/use-subject";
import IntersectionObserverProvider, { useRegisterIntersectionEntity } from "../../providers/intersection-observer";
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
import useSingleEvent from "../../hooks/use-single-event";
import { Note } from "../../components/note";
import { TrustProvider } from "../../providers/trust";
import { UserAvatar } from "../../components/user-avatar";
import { UserLink } from "../../components/user-link";
import { NoteMenu } from "../../components/note/note-menu";
const Like = ({ event }: { event: NostrEvent }) => {
const ref = useRef<HTMLDivElement | null>(null);
useRegisterIntersectionEntity(ref, event.id);
const contextRelays = useAdditionalRelayContext();
const readRelays = useReadRelayUrls(contextRelays);
const refs = getReferences(event);
const eventId: string | undefined = refs.events[0];
const { event: note } = useSingleEvent(eventId, readRelays);
var content = <></>;
if (!note) return <SkeletonText />;
if (note.kind === Kind.Text) {
content = (
<>
<Flex gap="2" mb="2">
<UserAvatar pubkey={event.pubkey} size="xs" />
<Text>
<UserLink pubkey={event.pubkey} /> {event.content === "+" ? "liked" : "reacted with " + event.content}
</Text>
<Spacer />
<NoteMenu event={event} aria-label="Note menu" variant="ghost" size="xs" />
</Flex>
<Note key={note.id} event={note} maxHeight={1200} />
</>
);
} else content = <>Unknown note type {note.kind}</>;
return <Box ref={ref}>{content}</Box>;
};
export default function UserLikesTab() {
const { pubkey } = useOutletContext() as { pubkey: string };
const contextRelays = useAdditionalRelayContext();
const readRelays = useReadRelayUrls(contextRelays);
const timeline = useTimelineLoader(`${truncatedId(pubkey)}-likes`, readRelays, { authors: [pubkey], kinds: [7] });
const lines = useSubject(timeline.timeline);
const scrollBox = useRef<HTMLDivElement | null>(null);
const callback = useTimelineCurserIntersectionCallback(timeline);
return (
<IntersectionObserverProvider callback={callback} root={scrollBox}>
<TrustProvider trust>
<Flex direction="column" gap="2" p="2" pb="8" h="full" overflowY="auto" ref={scrollBox}>
{lines.map((event) => (
<Like event={event} />
))}
<TimelineActionAndStatus timeline={timeline} />
</Flex>
</TrustProvider>
</IntersectionObserverProvider>
);
}