mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-04-24 07:20:17 +02:00
Show label for paid relays
This commit is contained in:
parent
03d84eb1cd
commit
ce550f588c
5
.changeset/three-chairs-mix.md
Normal file
5
.changeset/three-chairs-mix.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"nostrudel": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Show label for paid relays
|
@ -10,6 +10,7 @@ export type RelayInformationDocument = {
|
|||||||
supported_nips?: number[];
|
supported_nips?: number[];
|
||||||
software: string;
|
software: string;
|
||||||
version: string;
|
version: string;
|
||||||
|
payments_url?: string
|
||||||
};
|
};
|
||||||
|
|
||||||
async function fetchInfo(relay: string) {
|
async function fetchInfo(relay: string) {
|
||||||
|
@ -7,6 +7,8 @@ import {
|
|||||||
CardFooter,
|
CardFooter,
|
||||||
CardHeader,
|
CardHeader,
|
||||||
CardProps,
|
CardProps,
|
||||||
|
Checkbox,
|
||||||
|
CheckboxProps,
|
||||||
Flex,
|
Flex,
|
||||||
Heading,
|
Heading,
|
||||||
IconButton,
|
IconButton,
|
||||||
@ -17,24 +19,21 @@ import {
|
|||||||
ModalContent,
|
ModalContent,
|
||||||
ModalHeader,
|
ModalHeader,
|
||||||
ModalOverlay,
|
ModalOverlay,
|
||||||
ModalProps,
|
Tag,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { Link as RouterLink } from "react-router-dom";
|
import { Link as RouterLink } from "react-router-dom";
|
||||||
import { useRelayInfo } from "../../../hooks/use-relay-info";
|
import { useRelayInfo } from "../../../hooks/use-relay-info";
|
||||||
import { RelayFavicon } from "../../../components/relay-favicon";
|
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 { UserLink } from "../../../components/user-link";
|
||||||
import { UserAvatar } from "../../../components/user-avatar";
|
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 clientRelaysService from "../../../services/client-relays";
|
||||||
import { RelayMode } from "../../../classes/relay";
|
import { RelayMode } from "../../../classes/relay";
|
||||||
import { UserDnsIdentityIcon } from "../../../components/user-dns-identity-icon";
|
import { UserDnsIdentityIcon } from "../../../components/user-dns-identity-icon";
|
||||||
import { useCurrentAccount } from "../../../hooks/use-current-account";
|
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 styled from "@emotion/styled";
|
||||||
import { PropsWithChildren, useCallback } from "react";
|
import { PropsWithChildren, useCallback } from "react";
|
||||||
import RawJson from "../../../components/debug-modals/raw-json";
|
import RawJson from "../../../components/debug-modals/raw-json";
|
||||||
@ -68,6 +67,8 @@ export function RelayMetadata({ url }: { url: string }) {
|
|||||||
<UserDnsIdentityIcon pubkey={info.pubkey} onlyIcon />
|
<UserDnsIdentityIcon pubkey={info.pubkey} onlyIcon />
|
||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
|
<Metadata name="Software">{info?.software}</Metadata>
|
||||||
|
<Metadata name="Version">{info?.version}</Metadata>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -75,9 +76,9 @@ export function RelayMetadata({ url }: { url: string }) {
|
|||||||
export function RelayJoinAction({ url, ...props }: { url: string } & Omit<ButtonProps, "children" | "onClick">) {
|
export function RelayJoinAction({ url, ...props }: { url: string } & Omit<ButtonProps, "children" | "onClick">) {
|
||||||
const account = useCurrentAccount();
|
const account = useCurrentAccount();
|
||||||
const clientRelays = useClientRelays();
|
const clientRelays = useClientRelays();
|
||||||
const joined = clientRelays.some((r) => r.url === url);
|
const relayConfig = clientRelays.find((r) => r.url === url);
|
||||||
|
|
||||||
return joined ? (
|
return relayConfig ? (
|
||||||
<Button
|
<Button
|
||||||
colorScheme="red"
|
colorScheme="red"
|
||||||
variant="outline"
|
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">) {
|
export function RelayDebugButton({ url, ...props }: { url: string } & Omit<IconButtonProps, "icon" | "aria-label">) {
|
||||||
const { info } = useRelayInfo(url);
|
const { info } = useRelayInfo(url);
|
||||||
const debugModal = useDisclosure();
|
const debugModal = useDisclosure();
|
||||||
@ -162,6 +183,7 @@ export function RelayShareButton({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function RelayCard({ url, ...props }: { url: string } & Omit<CardProps, "children">) {
|
export default function RelayCard({ url, ...props }: { url: string } & Omit<CardProps, "children">) {
|
||||||
|
const { info } = useRelayInfo(url);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Card variant="outline" {...props}>
|
<Card variant="outline" {...props}>
|
||||||
@ -169,6 +191,11 @@ export default function RelayCard({ url, ...props }: { url: string } & Omit<Card
|
|||||||
<RelayFavicon relay={url} size="xs" />
|
<RelayFavicon relay={url} size="xs" />
|
||||||
<Heading size="md" isTruncated>
|
<Heading size="md" isTruncated>
|
||||||
<RouterLink to={`/r/${encodeURIComponent(url)}`}>{url}</RouterLink>
|
<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>
|
</Heading>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardBody px="2" py="0" display="flex" flexDirection="column" gap="2">
|
<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>
|
</CardBody>
|
||||||
<CardFooter p="2" as={Flex} gap="2">
|
<CardFooter p="2" as={Flex} gap="2">
|
||||||
<RelayJoinAction url={url} size="sm" />
|
<RelayJoinAction url={url} size="sm" />
|
||||||
|
<RelayModeAction url={url} />
|
||||||
|
|
||||||
<RelayShareButton relay={url} ml="auto" size="sm" />
|
<RelayShareButton relay={url} ml="auto" size="sm" />
|
||||||
<RelayDebugButton url={url} size="sm" title="Show raw NIP-11 metadata" />
|
<RelayDebugButton url={url} size="sm" title="Show raw NIP-11 metadata" />
|
||||||
|
@ -9,6 +9,7 @@ import {
|
|||||||
TabPanel,
|
TabPanel,
|
||||||
TabPanels,
|
TabPanels,
|
||||||
Tabs,
|
Tabs,
|
||||||
|
Tag,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
|
|
||||||
@ -30,6 +31,19 @@ function RelayPage({ relay }: { relay: string }) {
|
|||||||
<Flex gap="2" alignItems="center" wrap="wrap" justifyContent="space-between">
|
<Flex gap="2" alignItems="center" wrap="wrap" justifyContent="space-between">
|
||||||
<Heading isTruncated size={{ base: "md", sm: "lg" }}>
|
<Heading isTruncated size={{ base: "md", sm: "lg" }}>
|
||||||
{relay}
|
{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>
|
</Heading>
|
||||||
<ButtonGroup size={["sm", "md"]}>
|
<ButtonGroup size={["sm", "md"]}>
|
||||||
<RelayDebugButton url={relay} ml="auto" />
|
<RelayDebugButton url={relay} ml="auto" />
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { useOutletContext, Link as RouterLink } from "react-router-dom";
|
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 { useUserRelays } from "../../hooks/use-user-relays";
|
||||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||||
import { truncatedId } from "../../helpers/nostr/event";
|
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 { RelayDebugButton, RelayJoinAction, RelayMetadata, RelayShareButton } from "../relays/components/relay-card";
|
||||||
import IntersectionObserverProvider from "../../providers/intersection-observer";
|
import IntersectionObserverProvider from "../../providers/intersection-observer";
|
||||||
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
|
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
|
||||||
|
import { useRelayInfo } from "../../hooks/use-relay-info";
|
||||||
|
|
||||||
function Relay({ url, reviews }: { url: string; reviews: NostrEvent[] }) {
|
function Relay({ url, reviews }: { url: string; reviews: NostrEvent[] }) {
|
||||||
|
const { info } = useRelayInfo(url);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex p="2" gap="2" direction="column">
|
<Flex p="2" gap="2" direction="column">
|
||||||
<Flex gap="2" alignItems="center">
|
<Flex gap="2" alignItems="center">
|
||||||
<RelayFavicon relay={url} size="xs" />
|
<RelayFavicon relay={url} size="xs" />
|
||||||
<Heading size="md" isTruncated>
|
<Heading size="md" isTruncated>
|
||||||
<RouterLink to={`/r/${encodeURIComponent(url)}`}>{url}</RouterLink>
|
<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>
|
</Heading>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
<RelayDebugButton url={url} size="sm" />
|
<RelayDebugButton url={url} size="sm" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user