From cdfdc715174e3246b216363b0fa07f01e0edf6a3 Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Mon, 9 Oct 2023 16:43:11 -0500 Subject: [PATCH] Show recent badge awards on badges page --- .changeset/mighty-pans-reflect.md | 5 + src/hooks/use-user-profile-badges.ts | 2 +- src/views/badges/badge-details.tsx | 15 ++- src/views/badges/index.tsx | 102 ++++++++++++++++++- src/views/user/about/user-profile-badges.tsx | 1 + 5 files changed, 114 insertions(+), 11 deletions(-) create mode 100644 .changeset/mighty-pans-reflect.md 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 +