mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-04-23 23:10:20 +02:00
show list links on musted-by view
This commit is contained in:
parent
eb18421d7c
commit
b69bfa3724
5
.changeset/violet-moles-peel.md
Normal file
5
.changeset/violet-moles-peel.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"nostrudel": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Show list links on muted by view
|
@ -82,13 +82,17 @@ export function ListCardContent({ list, ...props }: Omit<CardProps, "children">
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function createListLink(list: NostrEvent) {
|
||||||
|
const isSpecialList = isSpecialListKind(list.kind);
|
||||||
|
return "/lists/" + (isSpecialList ? createCoordinate(list.kind, list.pubkey) : getSharableEventAddress(list));
|
||||||
|
}
|
||||||
|
|
||||||
function ListCardRender({
|
function ListCardRender({
|
||||||
list,
|
list,
|
||||||
hideCreator = false,
|
hideCreator = false,
|
||||||
...props
|
...props
|
||||||
}: Omit<CardProps, "children"> & { list: NostrEvent; hideCreator?: boolean }) {
|
}: Omit<CardProps, "children"> & { list: NostrEvent; hideCreator?: boolean }) {
|
||||||
const isSpecialList = isSpecialListKind(list.kind);
|
const isSpecialList = isSpecialListKind(list.kind);
|
||||||
const link = isSpecialList ? createCoordinate(list.kind, list.pubkey) : getSharableEventAddress(list);
|
|
||||||
|
|
||||||
// if there is a parent intersection observer, register this card
|
// if there is a parent intersection observer, register this card
|
||||||
const ref = useRef<HTMLDivElement | null>(null);
|
const ref = useRef<HTMLDivElement | null>(null);
|
||||||
@ -101,7 +105,7 @@ function ListCardRender({
|
|||||||
<CardHeader p="4">
|
<CardHeader p="4">
|
||||||
<Flex gap="2" alignItems="center">
|
<Flex gap="2" alignItems="center">
|
||||||
<Heading size="md" isTruncated>
|
<Heading size="md" isTruncated>
|
||||||
<HoverLinkOverlay as={RouterLink} to={`/lists/${link}`}>
|
<HoverLinkOverlay as={RouterLink} to={createListLink(list)}>
|
||||||
{getListName(list)}
|
{getListName(list)}
|
||||||
</HoverLinkOverlay>
|
</HoverLinkOverlay>
|
||||||
</Heading>
|
</Heading>
|
||||||
|
@ -1,26 +1,41 @@
|
|||||||
import { memo, useMemo, useRef } from "react";
|
import { memo, useMemo, useRef } from "react";
|
||||||
import { Flex, Heading, SimpleGrid } from "@chakra-ui/react";
|
import { Flex, Heading, Link, SimpleGrid } from "@chakra-ui/react";
|
||||||
import { useOutletContext } from "react-router-dom";
|
import { Link as RouterLink, useOutletContext } from "react-router-dom";
|
||||||
|
|
||||||
import UserAvatarLink from "../../components/user-avatar-link";
|
import UserAvatarLink from "../../components/user-avatar-link";
|
||||||
import { UserLink } from "../../components/user-link";
|
import { UserLink } from "../../components/user-link";
|
||||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||||
import { MUTE_LIST_KIND, PEOPLE_LIST_KIND } from "../../helpers/nostr/lists";
|
import { MUTE_LIST_KIND, PEOPLE_LIST_KIND, getListName, getPubkeysFromList } from "../../helpers/nostr/lists";
|
||||||
import useSubject from "../../hooks/use-subject";
|
import useSubject from "../../hooks/use-subject";
|
||||||
import IntersectionObserverProvider, { useRegisterIntersectionEntity } from "../../providers/intersection-observer";
|
import IntersectionObserverProvider, { useRegisterIntersectionEntity } from "../../providers/intersection-observer";
|
||||||
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
|
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
|
||||||
import { getEventUID } from "../../helpers/nostr/events";
|
import { getEventUID } from "../../helpers/nostr/events";
|
||||||
import VerticalPageLayout from "../../components/vertical-page-layout";
|
import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||||
|
import { NostrEvent } from "../../types/nostr-event";
|
||||||
|
import SuperMap from "../../classes/super-map";
|
||||||
|
import { createListLink } from "../lists/components/list-card";
|
||||||
|
|
||||||
const User = memo(({ pubkey, listId }: { pubkey: string; listId: string }) => {
|
function ListLink({ list }: { list: NostrEvent }) {
|
||||||
const ref = useRef<HTMLDivElement | null>(null);
|
const ref = useRef<HTMLAnchorElement | null>(null);
|
||||||
useRegisterIntersectionEntity(ref, listId);
|
useRegisterIntersectionEntity(ref, getEventUID(list));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex gap="2" overflow="hidden" ref={ref}>
|
<Link as={RouterLink} ref={ref} color="blue.500" to={createListLink(list)}>
|
||||||
|
{getListName(list)} ({getPubkeysFromList(list).length})
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const User = memo(({ pubkey, lists }: { pubkey: string; lists: NostrEvent[] }) => {
|
||||||
|
return (
|
||||||
|
<Flex gap="2" overflow="hidden">
|
||||||
<UserAvatarLink pubkey={pubkey} noProxy size="sm" />
|
<UserAvatarLink pubkey={pubkey} noProxy size="sm" />
|
||||||
<UserLink pubkey={pubkey} isTruncated />
|
<Flex direction="column">
|
||||||
|
<UserLink pubkey={pubkey} isTruncated fontWeight="bold" />
|
||||||
|
{lists.map((list) => (
|
||||||
|
<ListLink key={list.id} list={list} />
|
||||||
|
))}
|
||||||
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -37,11 +52,11 @@ export default function UserMutedByTab() {
|
|||||||
const lists = useSubject(timeline.timeline);
|
const lists = useSubject(timeline.timeline);
|
||||||
|
|
||||||
const pubkeys = useMemo(() => {
|
const pubkeys = useMemo(() => {
|
||||||
const keys = new Map<string, string>();
|
const dir = new SuperMap<string, NostrEvent[]>(() => []);
|
||||||
for (const list of lists) {
|
for (const list of lists) {
|
||||||
keys.set(list.pubkey, getEventUID(list));
|
dir.get(list.pubkey).push(list);
|
||||||
}
|
}
|
||||||
return Array.from(keys).map((a) => ({ pubkey: a[0], listId: a[1] }));
|
return Array.from(dir).map((a) => ({ pubkey: a[0], lists: a[1] }));
|
||||||
}, [lists]);
|
}, [lists]);
|
||||||
|
|
||||||
const callback = useTimelineCurserIntersectionCallback(timeline);
|
const callback = useTimelineCurserIntersectionCallback(timeline);
|
||||||
@ -49,9 +64,9 @@ export default function UserMutedByTab() {
|
|||||||
return (
|
return (
|
||||||
<IntersectionObserverProvider callback={callback}>
|
<IntersectionObserverProvider callback={callback}>
|
||||||
<VerticalPageLayout>
|
<VerticalPageLayout>
|
||||||
<SimpleGrid spacing="2" columns={{ base: 1, md: 2, lg: 3, xl: 4 }}>
|
<SimpleGrid spacing="2" columns={{ base: 1, sm: 2, lg: 3, xl: 4 }}>
|
||||||
{pubkeys.map(({ pubkey, listId }) => (
|
{pubkeys.map(({ pubkey, lists }) => (
|
||||||
<User key={pubkey} pubkey={pubkey} listId={listId} />
|
<User key={pubkey} pubkey={pubkey} lists={lists} />
|
||||||
))}
|
))}
|
||||||
</SimpleGrid>
|
</SimpleGrid>
|
||||||
{pubkeys.length === 0 && (
|
{pubkeys.length === 0 && (
|
||||||
|
Loading…
x
Reference in New Issue
Block a user