mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-09-27 03:56:44 +02:00
fixes for dvm feed layout
This commit is contained in:
@@ -2,16 +2,30 @@ import React, { useState } from "react";
|
|||||||
import { useAsync } from "react-use";
|
import { useAsync } from "react-use";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { requestProvider } from "webln";
|
import { requestProvider } from "webln";
|
||||||
import { Box, BoxProps, Button, ButtonGroup, IconButton, Text } from "@chakra-ui/react";
|
import {
|
||||||
|
Box,
|
||||||
|
BoxProps,
|
||||||
|
Button,
|
||||||
|
ButtonGroup,
|
||||||
|
CloseButton,
|
||||||
|
Flex,
|
||||||
|
IconButton,
|
||||||
|
Input,
|
||||||
|
Text,
|
||||||
|
useDisclosure,
|
||||||
|
} from "@chakra-ui/react";
|
||||||
|
|
||||||
import { parsePaymentRequest, readablizeSats } from "../../helpers/bolt11";
|
import { parsePaymentRequest, readablizeSats } from "../../helpers/bolt11";
|
||||||
import { CopyToClipboardIcon } from "../icons";
|
import { CopyIconButton } from "../copy-icon-button";
|
||||||
|
import QrCode02 from "../icons/qr-code-02";
|
||||||
|
import QrCodeSvg from "../qr-code/qr-code-svg";
|
||||||
|
|
||||||
export type InvoiceButtonProps = {
|
export type InvoiceButtonProps = {
|
||||||
paymentRequest: string;
|
paymentRequest: string;
|
||||||
};
|
};
|
||||||
export const InlineInvoiceCard = ({ paymentRequest, ...props }: Omit<BoxProps, "children"> & InvoiceButtonProps) => {
|
export const InlineInvoiceCard = ({ paymentRequest, ...props }: Omit<BoxProps, "children"> & InvoiceButtonProps) => {
|
||||||
const { value: invoice, error } = useAsync(async () => parsePaymentRequest(paymentRequest));
|
const { value: invoice, error } = useAsync(async () => parsePaymentRequest(paymentRequest));
|
||||||
|
const more = useDisclosure();
|
||||||
|
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const handleClick = async (event: React.SyntheticEvent) => {
|
const handleClick = async (event: React.SyntheticEvent) => {
|
||||||
@@ -41,17 +55,28 @@ export const InlineInvoiceCard = ({ paymentRequest, ...props }: Omit<BoxProps, "
|
|||||||
const isExpired = dayjs(invoice.expiry).isBefore(dayjs());
|
const isExpired = dayjs(invoice.expiry).isBefore(dayjs());
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Flex
|
||||||
padding="3"
|
padding="3"
|
||||||
borderColor="yellow.300"
|
borderColor="yellow.300"
|
||||||
borderWidth="1px"
|
borderWidth="1px"
|
||||||
borderRadius="md"
|
rounded="md"
|
||||||
display="flex"
|
direction="column"
|
||||||
flexWrap="wrap"
|
position="relative"
|
||||||
gap="4"
|
|
||||||
alignItems="center"
|
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
|
{more.isOpen ? (
|
||||||
|
<>
|
||||||
|
<Box maxW="3in" mx="auto" w="full">
|
||||||
|
<QrCodeSvg content={invoice.paymentRequest} />
|
||||||
|
</Box>
|
||||||
|
<Flex gap="2" mt="2">
|
||||||
|
<Input value={invoice.paymentRequest} userSelect="all" />
|
||||||
|
<CopyIconButton value={invoice.paymentRequest} aria-label="Copy Invoice" />
|
||||||
|
</Flex>
|
||||||
|
<CloseButton onClick={more.onClose} position="absolute" right="2" top="2" />
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<Flex flexWrap="wrap" gap="4" alignItems="center">
|
||||||
<Box flexGrow={1}>
|
<Box flexGrow={1}>
|
||||||
<Text fontWeight="bold">Lightning Invoice</Text>
|
<Text fontWeight="bold">Lightning Invoice</Text>
|
||||||
<Text>{invoice.description}</Text>
|
<Text>{invoice.description}</Text>
|
||||||
@@ -61,17 +86,15 @@ export const InlineInvoiceCard = ({ paymentRequest, ...props }: Omit<BoxProps, "
|
|||||||
{isExpired ? "Expired" : "Expires"}: {dayjs(invoice.expiry).fromNow()}
|
{isExpired ? "Expired" : "Expires"}: {dayjs(invoice.expiry).fromNow()}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
<ButtonGroup>
|
<ButtonGroup variant="outline">
|
||||||
<IconButton
|
<CopyIconButton value={invoice.paymentRequest} aria-label="Copy Invoice" />
|
||||||
icon={<CopyToClipboardIcon />}
|
<IconButton icon={<QrCode02 boxSize={6} />} onClick={more.onToggle} aria-label="Show QrCode" />
|
||||||
title="Copy to clipboard"
|
<Button as="a" onClick={handleClick} isLoading={loading} href={`lightning:${paymentRequest}`}>
|
||||||
aria-label="copy invoice"
|
|
||||||
variant="outline"
|
|
||||||
/>
|
|
||||||
<Button as="a" variant="outline" onClick={handleClick} isLoading={loading} href={`lightning:${paymentRequest}`}>
|
|
||||||
⚡ Pay {invoice.amount ? readablizeSats(invoice.amount / 1000) + " sats" : ""}
|
⚡ Pay {invoice.amount ? readablizeSats(invoice.amount / 1000) + " sats" : ""}
|
||||||
</Button>
|
</Button>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</Box>
|
</Flex>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -73,7 +73,7 @@ export default function FeedStatus({ chain, pointer }: { chain: ChainedDVMJob[];
|
|||||||
const response = lastJob.responses.find((r) => r.pubkey === pointer.pubkey);
|
const response = lastJob.responses.find((r) => r.pubkey === pointer.pubkey);
|
||||||
if (response?.result) return <NextPageButton pointer={pointer} chain={chain} />;
|
if (response?.result) return <NextPageButton pointer={pointer} chain={chain} />;
|
||||||
|
|
||||||
const cardProps = { minW: "2xl", mx: "auto" };
|
const cardProps = { w: "full", maxW: "2xl", mx: "auto", overflow: "hidden" };
|
||||||
const cardHeader = (
|
const cardHeader = (
|
||||||
<CardHeader p="4" alignItems="center" display="flex" gap="2">
|
<CardHeader p="4" alignItems="center" display="flex" gap="2">
|
||||||
<DVMAvatarLink pointer={pointer} w="12" />
|
<DVMAvatarLink pointer={pointer} w="12" />
|
||||||
@@ -109,7 +109,7 @@ export default function FeedStatus({ chain, pointer }: { chain: ChainedDVMJob[];
|
|||||||
);
|
);
|
||||||
case "processing":
|
case "processing":
|
||||||
return (
|
return (
|
||||||
<Alert status="info" w="auto" {...cardProps}>
|
<Alert status="info" {...cardProps}>
|
||||||
<AlertIcon boxSize={8} />
|
<AlertIcon boxSize={8} />
|
||||||
<Box>
|
<Box>
|
||||||
<AlertTitle>Processing</AlertTitle>
|
<AlertTitle>Processing</AlertTitle>
|
||||||
@@ -119,7 +119,7 @@ export default function FeedStatus({ chain, pointer }: { chain: ChainedDVMJob[];
|
|||||||
);
|
);
|
||||||
case "error":
|
case "error":
|
||||||
return (
|
return (
|
||||||
<Alert status="error" w="auto" {...cardProps}>
|
<Alert status="error" {...cardProps}>
|
||||||
<AlertIcon boxSize={8} />
|
<AlertIcon boxSize={8} />
|
||||||
<Box>
|
<Box>
|
||||||
<AlertTitle>Error!</AlertTitle>
|
<AlertTitle>Error!</AlertTitle>
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import { ChainedDVMJob, getEventIdsFromJobs } from "../../../../helpers/nostr/dvm";
|
|
||||||
import FeedStatus from "./feed-status";
|
import FeedStatus from "./feed-status";
|
||||||
import { AddressPointer } from "nostr-tools/nip19";
|
import { AddressPointer } from "nostr-tools/nip19";
|
||||||
|
|
||||||
|
import { ChainedDVMJob, getEventIdsFromJobs } from "../../../../helpers/nostr/dvm";
|
||||||
import useSingleEvents from "../../../../hooks/use-single-events";
|
import useSingleEvents from "../../../../hooks/use-single-events";
|
||||||
import TimelineItem from "../../../../components/timeline-page/generic-note-timeline/timeline-item";
|
import TimelineItem from "../../../../components/timeline-page/generic-note-timeline/timeline-item";
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user