improve relay icons

This commit is contained in:
hzrd149 2023-06-15 08:49:17 -05:00
parent 214487eae7
commit c3128f1b7d
4 changed files with 68 additions and 21 deletions

View File

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

View File

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

View 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>
</>
);
}

View File

@ -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 ? (