mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-09-18 19:41:48 +02:00
fix build
This commit is contained in:
@@ -11,7 +11,12 @@ import ZapModal from "../zap-modal";
|
||||
import { useInvoiceModalContext } from "../../providers/invoice-modal";
|
||||
import useUserLNURLMetadata from "../../hooks/use-user-lnurl-metadata";
|
||||
|
||||
export default function NoteZapButton({ note, ...props }: { note: NostrEvent } & Omit<ButtonProps, "children">) {
|
||||
export default function NoteZapButton({
|
||||
note,
|
||||
allowComment,
|
||||
showEventPreview,
|
||||
...props
|
||||
}: { note: NostrEvent; allowComment?: boolean; showEventPreview?: boolean } & Omit<ButtonProps, "children">) {
|
||||
const account = useCurrentAccount();
|
||||
const { metadata } = useUserLNURLMetadata(note.pubkey);
|
||||
const { requestPay } = useInvoiceModalContext();
|
||||
@@ -40,7 +45,15 @@ export default function NoteZapButton({ note, ...props }: { note: NostrEvent } &
|
||||
{readablizeSats(totalZaps(zaps) / 1000)}
|
||||
</Button>
|
||||
{isOpen && (
|
||||
<ZapModal isOpen={isOpen} onClose={onClose} event={note} onInvoice={handleInvoice} pubkey={note.pubkey} />
|
||||
<ZapModal
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
event={note}
|
||||
onInvoice={handleInvoice}
|
||||
pubkey={note.pubkey}
|
||||
allowComment={allowComment}
|
||||
showEventPreview={showEventPreview}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
@@ -17,7 +17,7 @@ import { UserAvatarLink } from "../user-avatar-link";
|
||||
import { UserLink } from "../user-link";
|
||||
import dayjs from "dayjs";
|
||||
import { DislikeIcon, LightningIcon, LikeIcon } from "../icons";
|
||||
import { parseZapEvent } from "../../helpers/zaps";
|
||||
import { ParsedZap, parseZapEvent } from "../../helpers/zaps";
|
||||
import { readablizeSats } from "../../helpers/bolt11";
|
||||
import useEventReactions from "../../hooks/use-event-reactions";
|
||||
import useEventZaps from "../../hooks/use-event-zaps";
|
||||
@@ -47,33 +47,25 @@ const ReactionEvent = React.memo(({ event }: { event: NostrEvent }) => (
|
||||
</Flex>
|
||||
));
|
||||
|
||||
const ZapEvent = React.memo(({ event }: { event: NostrEvent }) => {
|
||||
const ZapEvent = React.memo(({ zap }: { zap: ParsedZap }) => {
|
||||
const isMobile = useIsMobile();
|
||||
try {
|
||||
const { payment, request } = parseZapEvent(event);
|
||||
|
||||
if (!payment.amount) return null;
|
||||
if (!zap.payment.amount) return null;
|
||||
|
||||
return (
|
||||
<Box borderWidth="1px" borderRadius="lg" py="2" px={isMobile ? "2" : "4"}>
|
||||
<Flex gap="2" justifyContent="space-between">
|
||||
<Box>
|
||||
<UserAvatarLink pubkey={request.pubkey} size="xs" mr="2" />
|
||||
<UserLink pubkey={request.pubkey} />
|
||||
</Box>
|
||||
<Text fontWeight="bold">
|
||||
{readablizeSats(payment.amount / 1000)} <LightningIcon color="yellow.500" />
|
||||
</Text>
|
||||
{/* <Text width="35%" textAlign="right">
|
||||
{dayjs.unix(event.created_at).fromNow()}
|
||||
</Text> */}
|
||||
</Flex>
|
||||
<Text>{request.content}</Text>
|
||||
</Box>
|
||||
);
|
||||
} catch (e) {
|
||||
return <Text>Invalid Zap</Text>;
|
||||
}
|
||||
return (
|
||||
<Box borderWidth="1px" borderRadius="lg" py="2" px={isMobile ? "2" : "4"}>
|
||||
<Flex gap="2" justifyContent="space-between">
|
||||
<Box>
|
||||
<UserAvatarLink pubkey={zap.request.pubkey} size="xs" mr="2" />
|
||||
<UserLink pubkey={zap.request.pubkey} />
|
||||
</Box>
|
||||
<Text fontWeight="bold">
|
||||
{readablizeSats(zap.payment.amount / 1000)} <LightningIcon color="yellow.500" />
|
||||
</Text>
|
||||
</Flex>
|
||||
<Text>{zap.request.content}</Text>
|
||||
</Box>
|
||||
);
|
||||
});
|
||||
|
||||
function sortEvents(a: NostrEvent, b: NostrEvent) {
|
||||
@@ -111,7 +103,10 @@ export default function NoteReactionsModal({
|
||||
</ButtonGroup>
|
||||
{selected === "reactions" &&
|
||||
reactions.sort(sortEvents).map((event) => <ReactionEvent key={event.id} event={event} />)}
|
||||
{selected === "zaps" && zaps.sort(sortEvents).map((event) => <ZapEvent key={event.id} event={event} />)}
|
||||
{selected === "zaps" &&
|
||||
zaps
|
||||
.sort((a, b) => b.request.created_at - a.request.created_at)
|
||||
.map((zap) => <ZapEvent key={zap.request.id} zap={zap} />)}
|
||||
</Flex>
|
||||
</ModalBody>
|
||||
</ModalContent>
|
||||
|
@@ -48,6 +48,8 @@ export type ZapModalProps = Omit<ModalProps, "children"> & {
|
||||
initialComment?: string;
|
||||
initialAmount?: number;
|
||||
onInvoice: (invoice: string) => void;
|
||||
allowComment?: boolean;
|
||||
showEventPreview?: boolean;
|
||||
};
|
||||
|
||||
export default function ZapModal({
|
||||
@@ -58,6 +60,8 @@ export default function ZapModal({
|
||||
initialComment,
|
||||
initialAmount,
|
||||
onInvoice,
|
||||
allowComment = true,
|
||||
showEventPreview = true,
|
||||
...props
|
||||
}: ZapModalProps) {
|
||||
const toast = useToast();
|
||||
@@ -146,15 +150,15 @@ export default function ZapModal({
|
||||
<ModalBody padding="4">
|
||||
<form onSubmit={onSubmitZap}>
|
||||
<Flex gap="4" direction="column">
|
||||
<Flex gap="2" alignItems="center">
|
||||
<Flex gap="2" alignItems="center" overflow="hidden">
|
||||
<UserAvatar pubkey={pubkey} size="md" />
|
||||
<Box>
|
||||
<UserLink pubkey={pubkey} fontWeight="bold" />
|
||||
<Text>{tipAddress}</Text>
|
||||
<Text isTruncated>{tipAddress}</Text>
|
||||
</Box>
|
||||
</Flex>
|
||||
|
||||
{stream && (
|
||||
{showEventPreview && stream && (
|
||||
<Box>
|
||||
<Heading size="sm" mb="2">
|
||||
Stream: {stream.title}
|
||||
@@ -162,9 +166,9 @@ export default function ZapModal({
|
||||
{stream.image && <Image src={stream.image} />}
|
||||
</Box>
|
||||
)}
|
||||
{event && <EmbeddedNote note={event} />}
|
||||
{showEventPreview && event && <EmbeddedNote note={event} />}
|
||||
|
||||
{(canZap || lnurlMetadata?.commentAllowed) && (
|
||||
{allowComment && (canZap || lnurlMetadata?.commentAllowed) && (
|
||||
<Input
|
||||
placeholder="Comment"
|
||||
{...register("comment", { maxLength: lnurlMetadata?.commentAllowed ?? 150 })}
|
||||
|
@@ -16,7 +16,7 @@ export default function ChatMessage({ event, stream }: { event: NostrEvent; stre
|
||||
return (
|
||||
<TrustProvider event={event}>
|
||||
<Box>
|
||||
<NoteZapButton note={event} size="xs" variant="ghost" float="right" ml="2" />
|
||||
<NoteZapButton note={event} size="xs" variant="ghost" float="right" ml="2" allowComment={false} />
|
||||
<Text ref={ref}>
|
||||
<UserAvatar pubkey={event.pubkey} size="xs" display="inline-block" mr="2" />
|
||||
<Text as="span" fontWeight="bold" color={event.pubkey === stream.author ? "rgb(248, 56, 217)" : "cyan"}>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { Box, Button, Flex, Select, Text, useDisclosure } from "@chakra-ui/react";
|
||||
import { Box, Flex, Select, Text } from "@chakra-ui/react";
|
||||
import dayjs from "dayjs";
|
||||
import { useCallback, useMemo, useRef, useState } from "react";
|
||||
import { useOutletContext } from "react-router-dom";
|
||||
@@ -20,7 +20,6 @@ import IntersectionObserverProvider, { useRegisterIntersectionEntity } from "../
|
||||
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
|
||||
|
||||
const Zap = ({ zapEvent }: { zapEvent: NostrEvent }) => {
|
||||
const { isOpen, onToggle } = useDisclosure();
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
useRegisterIntersectionEntity(ref, zapEvent.id);
|
||||
@@ -51,14 +50,9 @@ const Zap = ({ zapEvent }: { zapEvent: NostrEvent }) => {
|
||||
<Text>{readablizeSats(payment.amount / 1000)} sats</Text>
|
||||
</Flex>
|
||||
)}
|
||||
{request.content && (
|
||||
<Button variant="link" onClick={onToggle}>
|
||||
Show message
|
||||
</Button>
|
||||
)}
|
||||
<Text ml="auto">{dayjs.unix(request.created_at).fromNow()}</Text>
|
||||
</Flex>
|
||||
{request.content && isOpen && <Text>{request.content}</Text>}
|
||||
{request.content && <Text>{request.content}</Text>}
|
||||
</Box>
|
||||
);
|
||||
} catch (e) {
|
||||
|
Reference in New Issue
Block a user