From af973af93e02b354359a9b9fe221e4d4459b44cf Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Mon, 18 Sep 2023 16:21:48 -0500 Subject: [PATCH] make list card component more compact hide empty lists events created by other clients only show list favorite button for people lists --- src/helpers/nostr/lists.ts | 6 ++++ src/hooks/use-favorite-lists.ts | 2 ++ src/hooks/use-user-lists.ts | 9 +++-- src/views/lists/components/list-card.tsx | 36 ++++++++++--------- .../lists/components/list-favorite-button.tsx | 6 ++++ src/views/user/lists.tsx | 22 ++++++++---- 6 files changed, 57 insertions(+), 24 deletions(-) diff --git a/src/helpers/nostr/lists.ts b/src/helpers/nostr/lists.ts index 8f8e8c228..49230a2f9 100644 --- a/src/helpers/nostr/lists.ts +++ b/src/helpers/nostr/lists.ts @@ -18,6 +18,12 @@ export function getListName(event: NostrEvent) { ); } +export function isJunkList(event: NostrEvent) { + const name = event.tags.find(isDTag)?.[1]; + if (!name) return false; + if (event.kind !== PEOPLE_LIST_KIND) return false; + return /^(chats\/([0-9a-f]{64}|null)|notifications)\/lastOpened$/.test(name); +} export function isSpecialListKind(kind: number) { return kind === Kind.Contacts || kind === PIN_LIST_KIND || kind === MUTE_LIST_KIND; } diff --git a/src/hooks/use-favorite-lists.ts b/src/hooks/use-favorite-lists.ts index 19fac6f62..f9e3b4774 100644 --- a/src/hooks/use-favorite-lists.ts +++ b/src/hooks/use-favorite-lists.ts @@ -9,6 +9,8 @@ export default function useFavoriteLists() { const account = useCurrentAccount(); const favoriteList = useReplaceableEvent( account ? { kind: 30078, pubkey: account.pubkey, identifier: FAVORITE_LISTS_IDENTIFIER } : undefined, + [], + true, ); const lists = useReplaceableEvents(favoriteList ? getCoordinatesFromList(favoriteList).map((a) => a.coordinate) : []); diff --git a/src/hooks/use-user-lists.ts b/src/hooks/use-user-lists.ts index a7d8916a1..a36d21e98 100644 --- a/src/hooks/use-user-lists.ts +++ b/src/hooks/use-user-lists.ts @@ -1,10 +1,15 @@ -import { NOTE_LIST_KIND, PEOPLE_LIST_KIND } from "../helpers/nostr/lists"; +import { useCallback } from "react"; +import { NOTE_LIST_KIND, PEOPLE_LIST_KIND, isJunkList } from "../helpers/nostr/lists"; import { useReadRelayUrls } from "./use-client-relays"; import useSubject from "./use-subject"; import useTimelineLoader from "./use-timeline-loader"; +import { NostrEvent } from "../types/nostr-event"; export default function useUserLists(pubkey?: string, additionalRelays: string[] = []) { const readRelays = useReadRelayUrls(additionalRelays); + const eventFilter = useCallback((event: NostrEvent) => { + return !isJunkList(event); + }, []); const timeline = useTimelineLoader( `${pubkey}-lists`, readRelays, @@ -12,7 +17,7 @@ export default function useUserLists(pubkey?: string, additionalRelays: string[] authors: pubkey ? [pubkey] : [], kinds: [PEOPLE_LIST_KIND, NOTE_LIST_KIND], }, - { enabled: !!pubkey }, + { enabled: !!pubkey, eventFilter }, ); return useSubject(timeline.timeline); diff --git a/src/views/lists/components/list-card.tsx b/src/views/lists/components/list-card.tsx index fe8463a4f..2caf47ac3 100644 --- a/src/views/lists/components/list-card.tsx +++ b/src/views/lists/components/list-card.tsx @@ -55,20 +55,11 @@ function ListCardRender({ event, ...props }: Omit & { eve {getListName(event)} - - - - + + + - - - Created by: - - - - - Updated: - + {people.length > 0 && ( <> People ({people.length}): @@ -83,7 +74,7 @@ function ListCardRender({ event, ...props }: Omit & { eve <> Notes ({notes.length}): - {notes.map(({ id, relay }) => ( + {notes.slice(0, 4).map(({ id, relay }) => ( ))} @@ -92,11 +83,24 @@ function ListCardRender({ event, ...props }: Omit & { eve {references.length > 0 && ( <> References ({references.length}) + + {references.slice(0, 3).map(({ url, petname }) => ( + + {petname || url} + + ))} + )} - - + + Created by: + + + + + + ); diff --git a/src/views/lists/components/list-favorite-button.tsx b/src/views/lists/components/list-favorite-button.tsx index 0ab8e5d78..351fb440e 100644 --- a/src/views/lists/components/list-favorite-button.tsx +++ b/src/views/lists/components/list-favorite-button.tsx @@ -10,6 +10,7 @@ import NostrPublishAction from "../../../classes/nostr-publish-action"; import clientRelaysService from "../../../services/client-relays"; import replaceableEventLoaderService from "../../../services/replaceable-event-requester"; import useFavoriteLists, { FAVORITE_LISTS_IDENTIFIER } from "../../../hooks/use-favorite-lists"; +import { NOTE_LIST_KIND, isSpecialListKind } from "../../../helpers/nostr/lists"; export default function ListFavoriteButton({ list, @@ -22,6 +23,11 @@ export default function ListFavoriteButton({ const isFavorite = favoriteList?.tags.some((t) => t[1] === coordinate); const [loading, setLoading] = useState(false); + if (isSpecialListKind(list.kind)) return null; + + // NOTE: dont show favorite button for note lists + if (list.kind === NOTE_LIST_KIND) return null; + const handleClick = async () => { const prev: DraftNostrEvent = favoriteList || { kind: 30078, diff --git a/src/views/user/lists.tsx b/src/views/user/lists.tsx index 03ac94e2d..0faa00674 100644 --- a/src/views/user/lists.tsx +++ b/src/views/user/lists.tsx @@ -1,25 +1,35 @@ +import { useCallback } from "react"; import { useOutletContext } from "react-router-dom"; -import { Divider, Flex, Heading, SimpleGrid } from "@chakra-ui/react"; +import { Divider, Heading, SimpleGrid } from "@chakra-ui/react"; import { useAdditionalRelayContext } from "../../providers/additional-relay-context"; import useTimelineLoader from "../../hooks/use-timeline-loader"; import useSubject from "../../hooks/use-subject"; -import { MUTE_LIST_KIND, NOTE_LIST_KIND, PEOPLE_LIST_KIND, PIN_LIST_KIND } from "../../helpers/nostr/lists"; +import { MUTE_LIST_KIND, NOTE_LIST_KIND, PEOPLE_LIST_KIND, PIN_LIST_KIND, isJunkList } from "../../helpers/nostr/lists"; import { getEventUID } from "../../helpers/nostr/events"; import ListCard from "../lists/components/list-card"; import IntersectionObserverProvider from "../../providers/intersection-observer"; import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback"; import { Kind } from "nostr-tools"; import VerticalPageLayout from "../../components/vertical-page-layout"; +import { NostrEvent } from "../../types/nostr-event"; export default function UserListsTab() { const { pubkey } = useOutletContext() as { pubkey: string }; const readRelays = useAdditionalRelayContext(); - const timeline = useTimelineLoader(pubkey + "-lists", readRelays, { - authors: [pubkey], - kinds: [PEOPLE_LIST_KIND, NOTE_LIST_KIND], - }); + const eventFilter = useCallback((event: NostrEvent) => { + return !isJunkList(event); + }, []); + const timeline = useTimelineLoader( + pubkey + "-lists", + readRelays, + { + authors: [pubkey], + kinds: [PEOPLE_LIST_KIND, NOTE_LIST_KIND], + }, + { eventFilter }, + ); const lists = useSubject(timeline.timeline); const callback = useTimelineCurserIntersectionCallback(timeline);