Show label for paid relays

This commit is contained in:
hzrd149 2023-08-12 15:56:29 -05:00
parent 03d84eb1cd
commit ce550f588c
5 changed files with 66 additions and 9 deletions

View File

@ -0,0 +1,5 @@
---
"nostrudel": minor
---
Show label for paid relays

View File

@ -10,6 +10,7 @@ export type RelayInformationDocument = {
supported_nips?: number[];
software: string;
version: string;
payments_url?: string
};
async function fetchInfo(relay: string) {

View File

@ -7,6 +7,8 @@ import {
CardFooter,
CardHeader,
CardProps,
Checkbox,
CheckboxProps,
Flex,
Heading,
IconButton,
@ -17,24 +19,21 @@ import {
ModalContent,
ModalHeader,
ModalOverlay,
ModalProps,
Tag,
useDisclosure,
useToast,
} from "@chakra-ui/react";
import { Link as RouterLink } from "react-router-dom";
import { useRelayInfo } from "../../../hooks/use-relay-info";
import { RelayFavicon } from "../../../components/relay-favicon";
import { CodeIcon, ExternalLinkIcon, RepostIcon } from "../../../components/icons";
import { CodeIcon, RepostIcon } from "../../../components/icons";
import { UserLink } from "../../../components/user-link";
import { UserAvatar } from "../../../components/user-avatar";
import { useClientRelays, useReadRelayUrls } from "../../../hooks/use-client-relays";
import { useClientRelays } from "../../../hooks/use-client-relays";
import clientRelaysService from "../../../services/client-relays";
import { RelayMode } from "../../../classes/relay";
import { UserDnsIdentityIcon } from "../../../components/user-dns-identity-icon";
import { useCurrentAccount } from "../../../hooks/use-current-account";
import useSubject from "../../../hooks/use-subject";
import useTimelineLoader from "../../../hooks/use-timeline-loader";
import RelayReviewNote from "./relay-review-note";
import styled from "@emotion/styled";
import { PropsWithChildren, useCallback } from "react";
import RawJson from "../../../components/debug-modals/raw-json";
@ -68,6 +67,8 @@ export function RelayMetadata({ url }: { url: string }) {
<UserDnsIdentityIcon pubkey={info.pubkey} onlyIcon />
</Flex>
)}
<Metadata name="Software">{info?.software}</Metadata>
<Metadata name="Version">{info?.version}</Metadata>
</Box>
);
}
@ -75,9 +76,9 @@ export function RelayMetadata({ url }: { url: string }) {
export function RelayJoinAction({ url, ...props }: { url: string } & Omit<ButtonProps, "children" | "onClick">) {
const account = useCurrentAccount();
const clientRelays = useClientRelays();
const joined = clientRelays.some((r) => r.url === url);
const relayConfig = clientRelays.find((r) => r.url === url);
return joined ? (
return relayConfig ? (
<Button
colorScheme="red"
variant="outline"
@ -99,6 +100,26 @@ export function RelayJoinAction({ url, ...props }: { url: string } & Omit<Button
);
}
export function RelayModeAction({
url,
...props
}: { url: string } & Omit<CheckboxProps, "children" | "isChecked" | "onChange">) {
const clientRelays = useClientRelays();
const relayConfig = clientRelays.find((r) => r.url === url);
return relayConfig ? (
<Checkbox
isChecked={!!(relayConfig.mode & RelayMode.WRITE)}
onChange={(e) => {
clientRelaysService.updateRelay(relayConfig.url, e.target.checked ? RelayMode.WRITE : RelayMode.READ);
}}
{...props}
>
Write
</Checkbox>
) : null;
}
export function RelayDebugButton({ url, ...props }: { url: string } & Omit<IconButtonProps, "icon" | "aria-label">) {
const { info } = useRelayInfo(url);
const debugModal = useDisclosure();
@ -162,6 +183,7 @@ export function RelayShareButton({
}
export default function RelayCard({ url, ...props }: { url: string } & Omit<CardProps, "children">) {
const { info } = useRelayInfo(url);
return (
<>
<Card variant="outline" {...props}>
@ -169,6 +191,11 @@ export default function RelayCard({ url, ...props }: { url: string } & Omit<Card
<RelayFavicon relay={url} size="xs" />
<Heading size="md" isTruncated>
<RouterLink to={`/r/${encodeURIComponent(url)}`}>{url}</RouterLink>
{info?.payments_url && (
<Tag as="a" variant="solid" colorScheme="green" size="sm" ml="2" target="_blank" href={info.payments_url}>
Paid
</Tag>
)}
</Heading>
</CardHeader>
<CardBody px="2" py="0" display="flex" flexDirection="column" gap="2">
@ -176,6 +203,7 @@ export default function RelayCard({ url, ...props }: { url: string } & Omit<Card
</CardBody>
<CardFooter p="2" as={Flex} gap="2">
<RelayJoinAction url={url} size="sm" />
<RelayModeAction url={url} />
<RelayShareButton relay={url} ml="auto" size="sm" />
<RelayDebugButton url={url} size="sm" title="Show raw NIP-11 metadata" />

View File

@ -9,6 +9,7 @@ import {
TabPanel,
TabPanels,
Tabs,
Tag,
useDisclosure,
} from "@chakra-ui/react";
@ -30,6 +31,19 @@ function RelayPage({ relay }: { relay: string }) {
<Flex gap="2" alignItems="center" wrap="wrap" justifyContent="space-between">
<Heading isTruncated size={{ base: "md", sm: "lg" }}>
{relay}
{info?.payments_url && (
<Tag
as="a"
variant="solid"
colorScheme="green"
size={{ base: "sm", md: "lg" }}
ml="2"
target="_blank"
href={info.payments_url}
>
Paid
</Tag>
)}
</Heading>
<ButtonGroup size={["sm", "md"]}>
<RelayDebugButton url={relay} ml="auto" />

View File

@ -1,5 +1,6 @@
import { useOutletContext, Link as RouterLink } from "react-router-dom";
import { Button, Flex, Heading, Spacer, StackDivider, VStack } from "@chakra-ui/react";
import { Button, Flex, Heading, Spacer, StackDivider, Tag, VStack } from "@chakra-ui/react";
import { useUserRelays } from "../../hooks/use-user-relays";
import useTimelineLoader from "../../hooks/use-timeline-loader";
import { truncatedId } from "../../helpers/nostr/event";
@ -11,14 +12,22 @@ import { RelayFavicon } from "../../components/relay-favicon";
import { RelayDebugButton, RelayJoinAction, RelayMetadata, RelayShareButton } from "../relays/components/relay-card";
import IntersectionObserverProvider from "../../providers/intersection-observer";
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
import { useRelayInfo } from "../../hooks/use-relay-info";
function Relay({ url, reviews }: { url: string; reviews: NostrEvent[] }) {
const { info } = useRelayInfo(url);
return (
<Flex p="2" gap="2" direction="column">
<Flex gap="2" alignItems="center">
<RelayFavicon relay={url} size="xs" />
<Heading size="md" isTruncated>
<RouterLink to={`/r/${encodeURIComponent(url)}`}>{url}</RouterLink>
{info?.payments_url && (
<Tag as="a" variant="solid" colorScheme="green" size="sm" ml="2" target="_blank" href={info.payments_url}>
Paid
</Tag>
)}
</Heading>
<Spacer />
<RelayDebugButton url={url} size="sm" />