diff --git a/src/components/layout/display-mode-context.ts b/src/components/layout/display-mode-context.ts index 04b018ec..5000b996 100644 --- a/src/components/layout/display-mode-context.ts +++ b/src/components/layout/display-mode-context.ts @@ -1,7 +1,7 @@ import { createContext, useContext } from 'react' import type { ReactNode } from 'react' import type { ErrorMessage } from '@joinmarket-webui/joinmarket-api-ts/jm' -import type { Currency } from '@/types/global' +import type { AmountSats, Currency } from '@/types/global' export type JarColor = '#e2b86a' | '#3b5ba9' | '#c94f7c' | '#a67c52' | '#7c3fa6' @@ -19,7 +19,7 @@ export const jarTemplates: Array<{ export interface Jar { name: string color: JarColor - balance: number + balance: AmountSats account?: string } @@ -32,7 +32,7 @@ export interface DisplayModeContextType { formatAmount: (amount: number) => string currencySymbol: (size?: 'sm' | 'lg') => ReactNode jars: Jar[] - totalBalance: number + totalBalance: AmountSats walletName: string | null isLoading: boolean error: Error | ErrorMessage | null diff --git a/src/components/receive/BitcoinQR.tsx b/src/components/receive/BitcoinQR.tsx index 80a1b1e3..b37f7add 100644 --- a/src/components/receive/BitcoinQR.tsx +++ b/src/components/receive/BitcoinQR.tsx @@ -3,16 +3,18 @@ import { DownloadIcon } from 'lucide-react' import QRCode from 'qrcode' import { useTranslation } from 'react-i18next' import { Button } from '@/components/ui/button' -import { satsToBtc } from '@/lib/utils' +import { cn, satsToBtc } from '@/lib/utils' +import type { AmountSats, BitcoinAddress } from '@/types/global' interface BitcoinQRProps { - address: string - amount?: number + className?: string + address: BitcoinAddress + amount?: AmountSats errorCorrectionLevel?: QRCode.QRCodeErrorCorrectionLevel width?: number } -export const BitcoinQR = ({ address, amount, errorCorrectionLevel = 'H', width = 260 }: BitcoinQRProps) => { +export const BitcoinQR = ({ className, address, amount, errorCorrectionLevel = 'H', width = 260 }: BitcoinQRProps) => { const { t } = useTranslation() const [data, setData] = useState() const [image, setImage] = useState() @@ -47,7 +49,10 @@ export const BitcoinQR = ({ address, amount, errorCorrectionLevel = 'H', width = } return ( -
+
{image && ( <> - + {t('receive.button_download_qr')} diff --git a/src/components/receive/Receive.tsx b/src/components/receive/Receive.tsx index a9c05e87..bf77f612 100644 --- a/src/components/receive/Receive.tsx +++ b/src/components/receive/Receive.tsx @@ -1,11 +1,12 @@ -import { useState, useEffect, useCallback, useMemo } from 'react' +import { useState, useEffect, useCallback } from 'react' import { getaddressOptions } from '@joinmarket-webui/joinmarket-api-ts/@tanstack/react-query' import { useQuery } from '@tanstack/react-query' import { Copy, CopyCheck, RefreshCw, Share } from 'lucide-react' import { useTranslation } from 'react-i18next' import { toast } from 'sonner' import { useApiClient } from '@/hooks/useApiClient' -import { btcToSats, satsToBtc, type WalletFileName } from '@/lib/utils' +import { btcToSats, cn, satsToBtc, type WalletFileName } from '@/lib/utils' +import type { AmountSats, BitcoinAddress } from '@/types/global' import { useJamDisplayContext } from '../layout/display-mode-context' import { SelectableJar } from '../ui/SelectableJar' import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '../ui/accordion' @@ -14,6 +15,8 @@ import { Skeleton } from '../ui/skeleton' import { BitcoinAmountInput } from './BitcoinAmountInput' import { BitcoinQR } from './BitcoinQR' +const QRCODE_WIDTH = 320 // "h-[320px] w-[320px]" <- Comment for tailwind importer (ADAPT THE COMMENT IF YOU CHANGE THE VALUE) + interface ReceiveProps { walletFileName: WalletFileName } @@ -21,8 +24,8 @@ interface ReceiveProps { export const Receive = ({ walletFileName }: ReceiveProps) => { const { t } = useTranslation() const [selectedJarIndex, setSelectedJarIndex] = useState(0) - const [amount, setAmount] = useState() - const [bitcoinAddress, setBitcoinAddress] = useState() + const [amount, setAmount] = useState() + const [bitcoinAddress, setBitcoinAddress] = useState() const [copied, setCopied] = useState(false) const { jars, currency, isPrivate, totalBalance, toggleCurrencyUnit } = useJamDisplayContext() @@ -51,10 +54,6 @@ export const Receive = ({ walletFileName }: ReceiveProps) => { } }, [getAddressQuery.error, t]) - const isQrLoading = useMemo(() => { - return getAddressQuery.isFetching - }, [getAddressQuery.isFetching]) - const copyToClipboard = () => { if (bitcoinAddress) { navigator.clipboard.writeText(bitcoinAddress) @@ -140,35 +139,66 @@ export const Receive = ({ walletFileName }: ReceiveProps) => {

{t('receive.subtitle')}

- {isQrLoading ? ( - + {getAddressQuery.isFetching ? ( + ) : bitcoinAddress ? ( - + ) : ( -
+
{t('receive.error_loading_address_failed')}
)} - {isQrLoading ? ( - + {getAddressQuery.isFetching ? ( + ) : ( -

{bitcoinAddress}

+

+ {bitcoinAddress} +

)}
- {'share' in navigator && ( - @@ -205,7 +235,7 @@ export const Receive = ({ walletFileName }: ReceiveProps) => { onChange={handleAmountChange} toggleCurrencyUnit={toggleCurrencyUnit} isPrivate={isPrivate} - disabled={isQrLoading || !bitcoinAddress} + disabled={getAddressQuery.isFetching || !bitcoinAddress} />
diff --git a/src/components/ui/SelectableJar.tsx b/src/components/ui/SelectableJar.tsx index 06b3843a..527a30d2 100644 --- a/src/components/ui/SelectableJar.tsx +++ b/src/components/ui/SelectableJar.tsx @@ -1,11 +1,12 @@ +import type { AmountSats } from '@/types/global' import { CurrencySymbol } from '../CurrencySymbol' import { JarIcon } from './JarIcon' interface SelectableJarProps { name: string color: string - balance: number - totalBalance: number + balance: AmountSats + totalBalance: AmountSats isSelected: boolean onClick: () => void } diff --git a/src/types/global.d.ts b/src/types/global.d.ts index ec8bab4a..c9e8865d 100644 --- a/src/types/global.d.ts +++ b/src/types/global.d.ts @@ -1,5 +1,6 @@ export type Currency = 'sats' | 'btc' export type AmountSats = number +export type BitcoinAddress = string export type Milliseconds = number export type Seconds = number