mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-04-09 20:29:17 +02:00
Show multiple pubkeys on badge award event
This commit is contained in:
parent
c3de4371c8
commit
054e3f2c57
5
.changeset/polite-points-retire.md
Normal file
5
.changeset/polite-points-retire.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"nostrudel": patch
|
||||
---
|
||||
|
||||
Show multiple pubkeys on badge award event
|
@ -1,4 +1,5 @@
|
||||
import { NostrEvent, isATag, isPTag } from "../../types/nostr-event";
|
||||
import { getPubkeysFromList } from "./lists";
|
||||
|
||||
export const PROFILE_BADGES_IDENTIFIER = "profile_badges";
|
||||
|
||||
@ -30,9 +31,7 @@ export function getBadgeThumbnails(event: NostrEvent) {
|
||||
}
|
||||
|
||||
export function getBadgeAwardPubkey(event: NostrEvent) {
|
||||
const pubkey = event.tags.find(isPTag)?.[1];
|
||||
if (!pubkey) throw new Error("Missing pubkey");
|
||||
return pubkey;
|
||||
return getPubkeysFromList(event);
|
||||
}
|
||||
export function getBadgeAwardBadge(event: NostrEvent) {
|
||||
const badgeCord = event.tags.find(isATag)?.[1];
|
||||
|
@ -6,7 +6,7 @@ import { ArrowLeftSIcon } from "../../components/icons";
|
||||
import { useDeleteEventContext } from "../../providers/delete-event-provider";
|
||||
import useReplaceableEvent from "../../hooks/use-replaceable-event";
|
||||
import { EventRelays } from "../../components/note/note-relays";
|
||||
import { getBadgeDescription, getBadgeImage, getBadgeName } from "../../helpers/nostr/badges";
|
||||
import { getBadgeAwardPubkey, getBadgeDescription, getBadgeImage, getBadgeName } from "../../helpers/nostr/badges";
|
||||
import BadgeMenu from "./components/badge-menu";
|
||||
import BadgeAwardCard from "./components/award-card";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
@ -45,60 +45,62 @@ function BadgeDetailsPage({ badge }: { badge: NostrEvent }) {
|
||||
|
||||
const isAuthor = account?.pubkey === badge.pubkey;
|
||||
return (
|
||||
<IntersectionObserverProvider callback={callback}>
|
||||
<VerticalPageLayout>
|
||||
<Flex gap="2" alignItems="center" wrap="wrap">
|
||||
<Button onClick={() => navigate(-1)} leftIcon={<ArrowLeftSIcon />}>
|
||||
Back
|
||||
<VerticalPageLayout>
|
||||
<Flex gap="2" alignItems="center" wrap="wrap">
|
||||
<Button onClick={() => navigate(-1)} leftIcon={<ArrowLeftSIcon />}>
|
||||
Back
|
||||
</Button>
|
||||
|
||||
<UserAvatarLink pubkey={badge.pubkey} size="sm" />
|
||||
<UserLink fontWeight="bold" pubkey={badge.pubkey} />
|
||||
<Text>|</Text>
|
||||
<Heading size="md">{getBadgeName(badge)}</Heading>
|
||||
|
||||
<Spacer />
|
||||
|
||||
<EventRelays event={badge} />
|
||||
|
||||
{isAuthor && (
|
||||
<Button colorScheme="red" onClick={() => deleteEvent(badge).then(() => navigate("/lists"))}>
|
||||
Delete
|
||||
</Button>
|
||||
)}
|
||||
<BadgeMenu aria-label="More options" badge={badge} />
|
||||
</Flex>
|
||||
|
||||
<UserAvatarLink pubkey={badge.pubkey} size="sm" />
|
||||
<UserLink fontWeight="bold" pubkey={badge.pubkey} />
|
||||
<Text>|</Text>
|
||||
<Flex direction={{ base: "column", lg: "row" }} gap="2">
|
||||
{image && <Image src={image.src} maxW="3in" mr="2" mb="2" mx={{ base: "auto", lg: "initial" }} />}
|
||||
<Flex direction="column" gap="2">
|
||||
<Heading size="md">{getBadgeName(badge)}</Heading>
|
||||
|
||||
<Spacer />
|
||||
|
||||
<EventRelays event={badge} />
|
||||
|
||||
{isAuthor && (
|
||||
<Button colorScheme="red" onClick={() => deleteEvent(badge).then(() => navigate("/lists"))}>
|
||||
Delete
|
||||
</Button>
|
||||
)}
|
||||
<BadgeMenu aria-label="More options" badge={badge} />
|
||||
<Text>
|
||||
Created by: <UserAvatarLink pubkey={badge.pubkey} size="xs" />{" "}
|
||||
<UserLink fontWeight="bold" pubkey={badge.pubkey} />
|
||||
</Text>
|
||||
<Text>
|
||||
Last Updated: <Timestamp timestamp={badge.created_at} />
|
||||
</Text>
|
||||
{description && <Text pb="2">{description}</Text>}
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
<Flex direction={{ base: "column", lg: "row" }} gap="2">
|
||||
{image && <Image src={image.src} maxW="3in" mr="2" mb="2" mx={{ base: "auto", lg: "initial" }} />}
|
||||
<Flex direction="column" gap="2">
|
||||
<Heading size="md">{getBadgeName(badge)}</Heading>
|
||||
<Text>
|
||||
Created by: <UserAvatarLink pubkey={badge.pubkey} size="xs" />{" "}
|
||||
<UserLink fontWeight="bold" pubkey={badge.pubkey} />
|
||||
</Text>
|
||||
<Text>
|
||||
Last Updated: <Timestamp timestamp={badge.created_at} />
|
||||
</Text>
|
||||
{description && <Text pb="2">{description}</Text>}
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
{awards.length > 0 && (
|
||||
<>
|
||||
{awards.length > 0 && (
|
||||
<>
|
||||
<IntersectionObserverProvider callback={callback}>
|
||||
<Heading size="md">Awarded to</Heading>
|
||||
<Divider />
|
||||
<SimpleGrid columns={{ base: 1, lg: 2, xl: 3 }} spacing="2">
|
||||
{awards.map((award) => (
|
||||
<ErrorBoundary>
|
||||
<BadgeAwardCard award={award} />
|
||||
</ErrorBoundary>
|
||||
<>
|
||||
{getBadgeAwardPubkey(award).map(({ pubkey }) => (
|
||||
<BadgeAwardCard award={award} pubkey={pubkey} />
|
||||
))}
|
||||
</>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
</>
|
||||
)}
|
||||
</VerticalPageLayout>
|
||||
</IntersectionObserverProvider>
|
||||
</IntersectionObserverProvider>
|
||||
</>
|
||||
)}
|
||||
</VerticalPageLayout>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,23 @@
|
||||
import { useRef } from "react";
|
||||
import { Card, CardBody, CardProps, Flex, Heading } from "@chakra-ui/react";
|
||||
|
||||
import { UserAvatar } from "../../../components/user-avatar";
|
||||
import { UserDnsIdentityIcon } from "../../../components/user-dns-identity-icon";
|
||||
import { NostrEvent } from "../../../types/nostr-event";
|
||||
import { getBadgeAwardPubkey } from "../../../helpers/nostr/badges";
|
||||
import { UserLink } from "../../../components/user-link";
|
||||
import { useRegisterIntersectionEntity } from "../../../providers/intersection-observer";
|
||||
import { getEventUID } from "../../../helpers/nostr/events";
|
||||
|
||||
export default function BadgeAwardCard({ award, ...props }: Omit<CardProps, "children"> & { award: NostrEvent }) {
|
||||
const pubkey = getBadgeAwardPubkey(award);
|
||||
export default function BadgeAwardCard({
|
||||
pubkey,
|
||||
award,
|
||||
...props
|
||||
}: Omit<CardProps, "children"> & { award: NostrEvent; pubkey: string }) {
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
useRegisterIntersectionEntity(ref, getEventUID(award));
|
||||
|
||||
return (
|
||||
<Card {...props}>
|
||||
<Card {...props} ref={ref}>
|
||||
<CardBody p="2" display="flex" alignItems="center" overflow="hidden" gap="2">
|
||||
<UserAvatar pubkey={pubkey} />
|
||||
<Flex direction="column" flex={1} overflow="hidden">
|
||||
|
Loading…
x
Reference in New Issue
Block a user