mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-04-10 21:00:17 +02:00
add user likes tab
This commit is contained in:
parent
e4b40dda68
commit
086279ebdd
5
.changeset/tough-buttons-speak.md
Normal file
5
.changeset/tough-buttons-speak.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"nostrudel": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Add user likes tab under profile view
|
@ -34,6 +34,7 @@ import UserMediaTab from "./views/user/media";
|
|||||||
import ToolsHomeView from "./views/tools";
|
import ToolsHomeView from "./views/tools";
|
||||||
import Nip19ToolsView from "./views/tools/nip19";
|
import Nip19ToolsView from "./views/tools/nip19";
|
||||||
import UserAboutTab from "./views/user/about";
|
import UserAboutTab from "./views/user/about";
|
||||||
|
import UserLikesTab from "./views/user/likes";
|
||||||
|
|
||||||
const LiveStreamsTab = React.lazy(() => import("./views/streams"));
|
const LiveStreamsTab = React.lazy(() => import("./views/streams"));
|
||||||
const StreamView = React.lazy(() => import("./views/streams/stream"));
|
const StreamView = React.lazy(() => import("./views/streams/stream"));
|
||||||
@ -73,6 +74,7 @@ const router = createHashRouter([
|
|||||||
{ path: "notes", element: <UserNotesTab /> },
|
{ path: "notes", element: <UserNotesTab /> },
|
||||||
{ path: "media", element: <UserMediaTab /> },
|
{ path: "media", element: <UserMediaTab /> },
|
||||||
{ path: "zaps", element: <UserZapsTab /> },
|
{ path: "zaps", element: <UserZapsTab /> },
|
||||||
|
{ path: "likes", element: <UserLikesTab /> },
|
||||||
{ path: "followers", element: <UserFollowersTab /> },
|
{ path: "followers", element: <UserFollowersTab /> },
|
||||||
{ path: "following", element: <UserFollowingTab /> },
|
{ path: "following", element: <UserFollowingTab /> },
|
||||||
{ path: "relays", element: <UserRelaysTab /> },
|
{ path: "relays", element: <UserRelaysTab /> },
|
||||||
|
@ -46,6 +46,7 @@ const tabs = [
|
|||||||
{ label: "Media", path: "media" },
|
{ label: "Media", path: "media" },
|
||||||
{ label: "Zaps", path: "zaps" },
|
{ label: "Zaps", path: "zaps" },
|
||||||
{ label: "Following", path: "following" },
|
{ label: "Following", path: "following" },
|
||||||
|
{ label: "Likes", path: "likes" },
|
||||||
{ label: "Relays", path: "relays" },
|
{ label: "Relays", path: "relays" },
|
||||||
{ label: "Reports", path: "reports" },
|
{ label: "Reports", path: "reports" },
|
||||||
{ label: "Followers", path: "followers" },
|
{ label: "Followers", path: "followers" },
|
||||||
|
79
src/views/user/likes.tsx
Normal file
79
src/views/user/likes.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user