mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-04-11 05:09:36 +02:00
improve relay icons
This commit is contained in:
parent
214487eae7
commit
c3128f1b7d
@ -89,7 +89,7 @@ export const Note = React.memo(({ event, maxHeight, variant = "outline" }: NoteP
|
||||
target="_blank"
|
||||
/>
|
||||
)}
|
||||
<NoteRelays event={event} size="sm" variant="link" />
|
||||
<NoteRelays event={event} />
|
||||
<NoteMenu event={event} size="sm" variant="link" aria-label="More Options" />
|
||||
</CardFooter>
|
||||
</Card>
|
||||
|
@ -1,28 +1,18 @@
|
||||
import { memo } from "react";
|
||||
import { IconButton, IconButtonProps, Flex, useDisclosure } from "@chakra-ui/react";
|
||||
import { IconButtonProps } from "@chakra-ui/react";
|
||||
import { getEventRelays } from "../../services/event-relays";
|
||||
import { NostrEvent } from "../../types/nostr-event";
|
||||
import { RelayIcon } from "../icons";
|
||||
import { RelayFavicon } from "../relay-favicon";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import { RelayIconStack } from "../relay-icon-stack";
|
||||
import { useIsMobile } from "../../hooks/use-is-mobile";
|
||||
|
||||
export type NoteRelaysProps = Omit<IconButtonProps, "icon" | "aria-label"> & {
|
||||
export type NoteRelaysProps = {
|
||||
event: NostrEvent;
|
||||
};
|
||||
|
||||
export const NoteRelays = memo(({ event, ...props }: NoteRelaysProps) => {
|
||||
export const NoteRelays = memo(({ event }: NoteRelaysProps) => {
|
||||
const isMobile = useIsMobile();
|
||||
const eventRelays = useSubject(getEventRelays(event.id));
|
||||
const { isOpen, onOpen } = useDisclosure();
|
||||
|
||||
return isOpen || !isMobile ? (
|
||||
<Flex alignItems="center" gap="-4">
|
||||
{eventRelays.map((url) => (
|
||||
<RelayFavicon key={url} relay={url} size="2xs" title={url} />
|
||||
))}
|
||||
</Flex>
|
||||
) : (
|
||||
<IconButton icon={<RelayIcon />} size="xs" aria-label="Relays" onClick={onOpen} variant="link" />
|
||||
);
|
||||
return <RelayIconStack relays={eventRelays} direction="row-reverse" maxRelays={isMobile ? 4 : undefined} />;
|
||||
});
|
||||
|
56
src/components/relay-icon-stack.tsx
Normal file
56
src/components/relay-icon-stack.tsx
Normal file
@ -0,0 +1,56 @@
|
||||
import {
|
||||
Avatar,
|
||||
Box,
|
||||
Flex,
|
||||
FlexProps,
|
||||
IconButton,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
ModalContent,
|
||||
ModalHeader,
|
||||
ModalOverlay,
|
||||
Text,
|
||||
useDisclosure,
|
||||
} from "@chakra-ui/react";
|
||||
import { RelayFavicon } from "./relay-favicon";
|
||||
import relayScoreboardService from "../services/relay-scoreboard";
|
||||
|
||||
export function RelayIconStack({ relays, maxRelays, ...props }: { relays: string[]; maxRelays?: number } & FlexProps) {
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
|
||||
const topRelays = relayScoreboardService.getRankedRelays(relays);
|
||||
const clamped = maxRelays ? topRelays.slice(0, maxRelays) : topRelays;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex alignItems="center" gap="-4" overflow="hidden" cursor="pointer" onClick={onOpen} {...props}>
|
||||
{clamped.map((url) => (
|
||||
<RelayFavicon key={url} relay={url} size="2xs" title={url} />
|
||||
))}
|
||||
{clamped.length !== topRelays.length && (
|
||||
<Text mx="1" fontSize="sm" lineHeight={0}>
|
||||
+{topRelays.length - clamped.length}
|
||||
</Text>
|
||||
)}
|
||||
</Flex>
|
||||
<Modal isOpen={isOpen} onClose={onClose}>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader>Relays</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody>
|
||||
<Flex direction="column" gap="1">
|
||||
{topRelays.map((url) => (
|
||||
<Flex key={url}>
|
||||
<RelayFavicon relay={url} size="2xs" mr="2" />
|
||||
<Text>{url}</Text>
|
||||
</Flex>
|
||||
))}
|
||||
</Flex>
|
||||
</ModalBody>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { Box, Button, Flex, FormControl, FormLabel, Spinner, Switch, useDisclosure } from "@chakra-ui/react";
|
||||
import { Button, Flex, FormControl, FormLabel, Spinner, Switch, useDisclosure } from "@chakra-ui/react";
|
||||
import { useOutletContext } from "react-router-dom";
|
||||
import { Note } from "../../components/note";
|
||||
import RepostNote from "../../components/repost-note";
|
||||
@ -8,10 +8,11 @@ import userTimelineService from "../../services/user-timeline";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import { useMount, useUnmount } from "react-use";
|
||||
import { RelayIconStack } from "../../components/relay-icon-stack";
|
||||
|
||||
const UserNotesTab = () => {
|
||||
const { pubkey } = useOutletContext() as { pubkey: string };
|
||||
const contextRelays = useAdditionalRelayContext();
|
||||
const readRelays = useAdditionalRelayContext();
|
||||
|
||||
const { isOpen: showReplies, onToggle: toggleReplies } = useDisclosure();
|
||||
const { isOpen: hideReposts, onToggle: toggleReposts } = useDisclosure();
|
||||
@ -22,8 +23,8 @@ const UserNotesTab = () => {
|
||||
const loading = useSubject(timeline.loading);
|
||||
|
||||
useEffect(() => {
|
||||
timeline.setRelays(contextRelays);
|
||||
}, [timeline, contextRelays.join("|")]);
|
||||
timeline.setRelays(readRelays);
|
||||
}, [timeline, readRelays.join("|")]);
|
||||
|
||||
useMount(() => timeline.open());
|
||||
useUnmount(() => timeline.close());
|
||||
@ -45,7 +46,7 @@ const UserNotesTab = () => {
|
||||
<FormLabel htmlFor="reposts" mb="0">
|
||||
Reposts
|
||||
</FormLabel>
|
||||
<Box flexGrow={1} />
|
||||
<RelayIconStack ml="auto" relays={readRelays} direction="row-reverse" mr="4" maxRelays={4} />
|
||||
</FormControl>
|
||||
{filteredEvents.map((event) =>
|
||||
event.kind === 6 ? (
|
||||
|
Loading…
x
Reference in New Issue
Block a user