fixes for dvm feed layout

This commit is contained in:
hzrd149
2024-09-17 19:05:05 -05:00
parent 656bcbb4fe
commit 54f50df015
3 changed files with 57 additions and 33 deletions

View File

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

View File

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

View File

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