make list card component more compact

hide empty lists events created by other clients
only show list favorite button for people lists
This commit is contained in:
hzrd149 2023-09-18 16:21:48 -05:00
parent 2d41abf44a
commit af973af93e
6 changed files with 57 additions and 24 deletions

View File

@ -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;
}

View File

@ -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) : []);

View File

@ -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);

View File

@ -55,20 +55,11 @@ function ListCardRender({ event, ...props }: Omit<CardProps, "children"> & { eve
{getListName(event)}
</Link>
</Heading>
<ButtonGroup size="sm" ml="auto">
<ListFavoriteButton list={event} />
<ListMenu list={event} aria-label="list menu" />
</ButtonGroup>
<Link as={RouterLink} to={`/lists/${link}`} ml="auto">
<Timestamp timestamp={event.created_at} />
</Link>
</CardHeader>
<CardBody p="2">
<Flex gap="2">
<Text>Created by:</Text>
<UserAvatarLink pubkey={event.pubkey} size="xs" />
<UserLink pubkey={event.pubkey} isTruncated fontWeight="bold" fontSize="lg" />
</Flex>
<Text>
Updated: <Timestamp timestamp={event.created_at} />
</Text>
<CardBody py="0" px="2">
{people.length > 0 && (
<>
<Text>People ({people.length}):</Text>
@ -83,7 +74,7 @@ function ListCardRender({ event, ...props }: Omit<CardProps, "children"> & { eve
<>
<Text>Notes ({notes.length}):</Text>
<Flex gap="2" overflow="hidden">
{notes.map(({ id, relay }) => (
{notes.slice(0, 4).map(({ id, relay }) => (
<NoteLink key={id} noteId={id} />
))}
</Flex>
@ -92,11 +83,24 @@ function ListCardRender({ event, ...props }: Omit<CardProps, "children"> & { eve
{references.length > 0 && (
<>
<Text>References ({references.length})</Text>
<Flex gap="2" overflow="hidden">
{references.slice(0, 3).map(({ url, petname }) => (
<Link maxW="200" href={url} isExternal whiteSpace="pre" color="blue.500" isTruncated>
{petname || url}
</Link>
))}
</Flex>
</>
)}
</CardBody>
<CardFooter p="2" display="flex" pt="0">
<EventRelays event={event} ml="auto" />
<CardFooter p="2" display="flex" alignItems="center" whiteSpace="pre" gap="2">
<Text>Created by:</Text>
<UserAvatarLink pubkey={event.pubkey} size="xs" />
<UserLink pubkey={event.pubkey} isTruncated fontWeight="bold" fontSize="lg" />
<ButtonGroup size="xs" variant="ghost" ml="auto">
<ListFavoriteButton list={event} />
<ListMenu list={event} aria-label="list menu" />
</ButtonGroup>
</CardFooter>
</Card>
);

View File

@ -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,

View File

@ -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);