mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-06-04 20:19:34 +02:00
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:
parent
2d41abf44a
commit
af973af93e
@ -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;
|
||||
}
|
||||
|
@ -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) : []);
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user