diff --git a/.changeset/mighty-pans-reflect.md b/.changeset/mighty-pans-reflect.md
new file mode 100644
index 000000000..6efafbcd4
--- /dev/null
+++ b/.changeset/mighty-pans-reflect.md
@@ -0,0 +1,5 @@
+---
+"nostrudel": minor
+---
+
+Show recent badge awards on badges page
diff --git a/src/hooks/use-user-profile-badges.ts b/src/hooks/use-user-profile-badges.ts
index 2cbd58a80..69a56aee5 100644
--- a/src/hooks/use-user-profile-badges.ts
+++ b/src/hooks/use-user-profile-badges.ts
@@ -23,7 +23,7 @@ export default function useUserProfileBadges(pubkey: string, additionalRelays: s
const badge = badges.find((e) => getEventCoordinate(e) === p.badgeCord);
const award = awardEvents.find((e) => e.id === p.awardEventId);
- if (badge && award) final.push({ badge, award });
+ if (badge && award && badge.pubkey === award.pubkey) final.push({ badge, award });
}
return final;
diff --git a/src/views/badges/badge-details.tsx b/src/views/badges/badge-details.tsx
index ad3e9e14c..5ae194884 100644
--- a/src/views/badges/badge-details.tsx
+++ b/src/views/badges/badge-details.tsx
@@ -19,7 +19,6 @@ import { NostrEvent } from "../../types/nostr-event";
import { getEventCoordinate } from "../../helpers/nostr/events";
import { UserAvatarLink } from "../../components/user-avatar-link";
import { UserLink } from "../../components/user-link";
-import { ErrorBoundary } from "../../components/error-boundary";
import Timestamp from "../../components/timestamp";
import VerticalPageLayout from "../../components/vertical-page-layout";
@@ -70,7 +69,7 @@ function BadgeDetailsPage({ badge }: { badge: NostrEvent }) {
{image && }
-
+
{getBadgeName(badge)}
Created by: {" "}
@@ -79,15 +78,21 @@ function BadgeDetailsPage({ badge }: { badge: NostrEvent }) {
Created:
- {description && {description}}
+ {description && (
+ <>
+
+ Description
+
+ {description}
+ >
+ )}
{awards.length > 0 && (
<>
- Awarded to
-
+ Awarded to
{awards.map((award) => (
<>
diff --git a/src/views/badges/index.tsx b/src/views/badges/index.tsx
index 029bfb3d6..01a99082c 100644
--- a/src/views/badges/index.tsx
+++ b/src/views/badges/index.tsx
@@ -1,12 +1,90 @@
-import { Button, Flex, Image, Link, Spacer } from "@chakra-ui/react";
+import { useRef } from "react";
+import {
+ AvatarGroup,
+ Button,
+ Card,
+ Flex,
+ Heading,
+ Image,
+ Link,
+ LinkBox,
+ LinkOverlay,
+ Spacer,
+ Text,
+} from "@chakra-ui/react";
import { Navigate, Link as RouterLink } from "react-router-dom";
+import { Kind } from "nostr-tools";
-import { useCurrentAccount } from "../../hooks/use-current-account";
import { ExternalLinkIcon } from "../../components/icons";
import VerticalPageLayout from "../../components/vertical-page-layout";
+import useTimelineLoader from "../../hooks/use-timeline-loader";
+import PeopleListProvider, { usePeopleListContext } from "../../providers/people-list-provider";
+import PeopleListSelection from "../../components/people-list-selection/people-list-selection";
+import { useReadRelayUrls } from "../../hooks/use-client-relays";
+import useSubject from "../../hooks/use-subject";
+import { NostrEvent, isPTag } from "../../types/nostr-event";
+import { UserLink } from "../../components/user-link";
+import { UserAvatar } from "../../components/user-avatar";
+import { getBadgeAwardBadge, getBadgeImage, getBadgeName } from "../../helpers/nostr/badges";
+import useReplaceableEvent from "../../hooks/use-replaceable-event";
+import IntersectionObserverProvider, { useRegisterIntersectionEntity } from "../../providers/intersection-observer";
+import { getEventUID } from "../../helpers/nostr/events";
+import { getSharableEventAddress } from "../../helpers/nip19";
+import { UserAvatarLink } from "../../components/user-avatar-link";
+import Timestamp from "../../components/timestamp";
+import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
+
+function BadgeAwardCard({ award }: { award: NostrEvent }) {
+ const badge = useReplaceableEvent(getBadgeAwardBadge(award));
+
+ // if there is a parent intersection observer, register this card
+ const ref = useRef(null);
+ useRegisterIntersectionEntity(ref, badge && getEventUID(badge));
+
+ if (!badge) return null;
+
+ const naddr = getSharableEventAddress(badge);
+ return (
+
+
+
+
+
+ {getBadgeName(badge)}
+
+
+
+
+
+
+
+ Awarded:
+
+
+
+
+ {award.tags.filter(isPTag).map((t) => (
+
+
+
+
+ ))}
+
+
+
+ );
+}
function BadgesPage() {
- const account = useCurrentAccount()!;
+ const { filter, listId } = usePeopleListContext();
+ const readRelays = useReadRelayUrls();
+ const timeline = useTimelineLoader(`${listId}-lists`, readRelays, {
+ ...filter,
+ kinds: [Kind.BadgeAward],
+ });
+
+ const awards = useSubject(timeline.timeline);
+ const callback = useTimelineCurserIntersectionCallback(timeline);
return (
@@ -25,11 +103,25 @@ function BadgesPage() {
Badges
+
+ Recent awards
+
+
+
+ {awards.map((award) => (
+
+ ))}
+
);
}
export default function BadgesView() {
- const account = useCurrentAccount();
- return account ? : ;
+ // const account = useCurrentAccount();
+ // return account ? : ;
+ return (
+
+
+
+ );
}
diff --git a/src/views/user/about/user-profile-badges.tsx b/src/views/user/about/user-profile-badges.tsx
index aef0a987d..2ee5f87f0 100644
--- a/src/views/user/about/user-profile-badges.tsx
+++ b/src/views/user/about/user-profile-badges.tsx
@@ -46,6 +46,7 @@ function Badge({ pubkey, badge, award }: { pubkey: string; badge: NostrEvent; aw
+