clean up user reactions view

This commit is contained in:
hzrd149
2023-09-08 11:02:06 -05:00
parent 094a6fb9db
commit 3d5d23407d
3 changed files with 44 additions and 34 deletions

View File

@@ -0,0 +1,5 @@
---
"nostrudel": minor
---
Clean up user reactions view

View File

@@ -1,4 +1,5 @@
import { Card, CardBody, CardHeader, CardProps, Flex, Heading, Link, Text } from "@chakra-ui/react"; import { Box, Card, CardBody, CardHeader, CardProps, Flex, Heading, Link, Text } from "@chakra-ui/react";
import dayjs from "dayjs";
import { getSharableEventAddress } from "../../../helpers/nip19"; import { getSharableEventAddress } from "../../../helpers/nip19";
import { NostrEvent } from "../../../types/nostr-event"; import { NostrEvent } from "../../../types/nostr-event";
@@ -7,11 +8,23 @@ import { UserLink } from "../../user-link";
import { truncatedId } from "../../../helpers/nostr/events"; import { truncatedId } from "../../../helpers/nostr/events";
import { buildAppSelectUrl } from "../../../helpers/nostr/apps"; import { buildAppSelectUrl } from "../../../helpers/nostr/apps";
import { UserDnsIdentityIcon } from "../../user-dns-identity-icon"; import { UserDnsIdentityIcon } from "../../user-dns-identity-icon";
import dayjs from "dayjs"; import { useMemo } from "react";
import { embedEmoji, embedNostrHashtags, embedNostrLinks, embedNostrMentions } from "../../embed-types";
import { EmbedableContent } from "../../../helpers/embeds";
export default function EmbeddedUnknown({ event, ...props }: Omit<CardProps, "children"> & { event: NostrEvent }) { export default function EmbeddedUnknown({ event, ...props }: Omit<CardProps, "children"> & { event: NostrEvent }) {
const address = getSharableEventAddress(event); const address = getSharableEventAddress(event);
const content = useMemo(() => {
let jsx: EmbedableContent = [event.content];
jsx = embedNostrLinks(jsx);
jsx = embedNostrMentions(jsx, event);
jsx = embedNostrHashtags(jsx, event);
jsx = embedEmoji(jsx, event);
return jsx;
}, [event.content]);
return ( return (
<Card {...props}> <Card {...props}>
<CardHeader display="flex" gap="2" alignItems="center" p="2" pb="0" flexWrap="wrap"> <CardHeader display="flex" gap="2" alignItems="center" p="2" pb="0" flexWrap="wrap">
@@ -29,7 +42,7 @@ export default function EmbeddedUnknown({ event, ...props }: Omit<CardProps, "ch
{address && truncatedId(address)} {address && truncatedId(address)}
</Link> </Link>
</Flex> </Flex>
<Text whiteSpace="pre-wrap">{event.content}</Text> <Box whiteSpace="pre-wrap">{content}</Box>
</CardBody> </CardBody>
</Card> </Card>
); );

View File

@@ -1,7 +1,6 @@
import { useRef } from "react"; import { useRef } from "react";
import { useOutletContext } from "react-router-dom"; import { useOutletContext } from "react-router-dom";
import { Box, Flex, SkeletonText, Spacer, Text } from "@chakra-ui/react"; import { Box, Flex, Spacer, Text } from "@chakra-ui/react";
import { Kind } from "nostr-tools";
import { nip25 } from "nostr-tools"; import { nip25 } from "nostr-tools";
import useTimelineLoader from "../../hooks/use-timeline-loader"; import useTimelineLoader from "../../hooks/use-timeline-loader";
@@ -12,43 +11,36 @@ import TimelineActionAndStatus from "../../components/timeline-page/timeline-act
import useSubject from "../../hooks/use-subject"; import useSubject from "../../hooks/use-subject";
import IntersectionObserverProvider, { useRegisterIntersectionEntity } from "../../providers/intersection-observer"; import IntersectionObserverProvider, { useRegisterIntersectionEntity } from "../../providers/intersection-observer";
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback"; 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 { TrustProvider } from "../../providers/trust";
import { UserAvatar } from "../../components/user-avatar"; import { UserAvatar } from "../../components/user-avatar";
import { UserLink } from "../../components/user-link"; import { UserLink } from "../../components/user-link";
import { NoteMenu } from "../../components/note/note-menu"; import { NoteMenu } from "../../components/note/note-menu";
import { EmbedEventPointer } from "../../components/embed-event";
import { embedEmoji } from "../../components/embed-types";
const Reaction = ({ event }: { event: NostrEvent }) => { const Reaction = ({ reaction: reaction }: { reaction: NostrEvent }) => {
const ref = useRef<HTMLDivElement | null>(null); const ref = useRef<HTMLDivElement | null>(null);
useRegisterIntersectionEntity(ref, event.id); useRegisterIntersectionEntity(ref, reaction.id);
const contextRelays = useAdditionalRelayContext(); const pointer = nip25.getReactedEventPointer(reaction);
const readRelays = useReadRelayUrls(contextRelays); if (!pointer) return null;
const pointer = nip25.getReactedEventPointer(event); const decoded = { type: "nevent", data: pointer } as const;
const { event: note } = useSingleEvent(pointer?.id, readRelays);
var content = <></>; return (
if (!note) return <SkeletonText />; <Box ref={ref}>
<Flex gap="2" mb="2">
if (note.kind === Kind.Text) { <UserAvatar pubkey={reaction.pubkey} size="xs" />
content = ( <Text>
<> <UserLink pubkey={reaction.pubkey} /> {reaction.content === "+" ? "liked" : "reacted with "}
<Flex gap="2" mb="2"> {embedEmoji([reaction.content], reaction)}
<UserAvatar pubkey={event.pubkey} size="xs" /> </Text>
<Text> <Spacer />
<UserLink pubkey={event.pubkey} /> {event.content === "+" ? "liked" : "reacted with " + event.content} <NoteMenu event={reaction} aria-label="Note menu" variant="ghost" size="xs" />
</Text> </Flex>
<Spacer /> <EmbedEventPointer pointer={decoded} />
<NoteMenu event={event} aria-label="Note menu" variant="ghost" size="xs" /> </Box>
</Flex> );
<Note key={note.id} event={note} />
</>
);
} else content = <>Unknown note type {note.kind}</>;
return <Box ref={ref}>{content}</Box>;
}; };
export default function UserReactionsTab() { export default function UserReactionsTab() {
@@ -67,7 +59,7 @@ export default function UserReactionsTab() {
<TrustProvider trust> <TrustProvider trust>
<Flex direction="column" gap="2" p="2" pb="8"> <Flex direction="column" gap="2" p="2" pb="8">
{likes.map((event) => ( {likes.map((event) => (
<Reaction event={event} /> <Reaction reaction={event} />
))} ))}
<TimelineActionAndStatus timeline={timeline} /> <TimelineActionAndStatus timeline={timeline} />