From 77d8704d677eb063634b6a23ade8ac7d5c0b29a4 Mon Sep 17 00:00:00 2001 From: Pete Watters <2938440+pete-watters@users.noreply.github.com> Date: Fri, 11 Aug 2023 12:27:48 +0100 Subject: [PATCH] chore: refactor receive modal to share code better --- src/app/components/icons/btc-stamps-icon.tsx | 6 + .../receive/receive-collectible.tsx | 83 -------------- .../pages/receive-tokens/receive-modal.tsx | 108 ------------------ .../components/address-qr-code.tsx | 0 .../components/receive-btc-warning.tsx | 0 .../receive/components/receive-item.tsx} | 18 ++- .../receive/components/receive-items.tsx | 18 +++ .../components/receive-tokens.layout.tsx | 0 .../legacy}/receive-tokens.tsx | 2 +- .../receive-btc.tsx | 0 .../receive-collectible-oridinal.tsx | 0 .../receive-collectible-modal.tsx | 18 --- src/app/pages/receive/receive-modal.tsx | 104 +++++++++++++++++ .../receive-stx.tsx | 0 src/app/routes/app-routes.tsx | 14 ++- 15 files changed, 144 insertions(+), 227 deletions(-) create mode 100644 src/app/components/icons/btc-stamps-icon.tsx delete mode 100644 src/app/components/receive/receive-collectible.tsx delete mode 100644 src/app/pages/receive-tokens/receive-modal.tsx rename src/app/pages/{receive-tokens => receive}/components/address-qr-code.tsx (100%) rename src/app/pages/{receive-tokens => receive}/components/receive-btc-warning.tsx (100%) rename src/app/{components/receive/receive-collectible-item.tsx => pages/receive/components/receive-item.tsx} (75%) create mode 100644 src/app/pages/receive/components/receive-items.tsx rename src/app/pages/{receive-tokens => receive}/components/receive-tokens.layout.tsx (100%) rename src/app/pages/{receive-tokens => receive/legacy}/receive-tokens.tsx (93%) rename src/app/pages/{receive-tokens => receive}/receive-btc.tsx (100%) rename src/app/pages/receive/{receive-collectible => }/receive-collectible-oridinal.tsx (100%) delete mode 100644 src/app/pages/receive/receive-collectible/receive-collectible-modal.tsx create mode 100644 src/app/pages/receive/receive-modal.tsx rename src/app/pages/{receive-tokens => receive}/receive-stx.tsx (100%) diff --git a/src/app/components/icons/btc-stamps-icon.tsx b/src/app/components/icons/btc-stamps-icon.tsx new file mode 100644 index 00000000..b70a4537 --- /dev/null +++ b/src/app/components/icons/btc-stamps-icon.tsx @@ -0,0 +1,6 @@ +import BitcoinStampImg from '@assets/images/bitcoin-stamp.png'; +import { Box } from '@stacks/ui'; + +export function BtcStampsIcon() { + return ; +} diff --git a/src/app/components/receive/receive-collectible.tsx b/src/app/components/receive/receive-collectible.tsx deleted file mode 100644 index e9f4e74f..00000000 --- a/src/app/components/receive/receive-collectible.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import toast from 'react-hot-toast'; -import { useLocation, useNavigate } from 'react-router-dom'; - -import BitcoinStampImg from '@assets/images/bitcoin-stamp.png'; -import { Box, Stack, useClipboard } from '@stacks/ui'; -import { HomePageSelectors } from '@tests/selectors/home.selectors'; -import get from 'lodash.get'; - -import { RouteUrls } from '@shared/route-urls'; - -import { useAnalytics } from '@app/common/hooks/analytics/use-analytics'; -import { StxAvatar } from '@app/components/crypto-assets/stacks/components/stx-avatar'; -import { OrdinalIcon } from '@app/components/icons/ordinal-icon'; -import { useZeroIndexTaprootAddress } from '@app/query/bitcoin/ordinals/use-zero-index-taproot-address'; -import { useCurrentAccountNativeSegwitAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks'; -import { useCurrentAccountStxAddressState } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks'; - -import { ReceiveCollectibleItem } from './receive-collectible-item'; - -export function ReceiveCollectible() { - const analytics = useAnalytics(); - const location = useLocation(); - const navigate = useNavigate(); - const accountIndex = get(location.state, 'accountIndex', undefined); - const btcAddressNativeSegwit = useCurrentAccountNativeSegwitAddressIndexZero(); - const btcAddressTaproot = useZeroIndexTaprootAddress(accountIndex); - - // TODO: Reuse later for privacy mode - // const { isLoading, isError, data: btcAddress } = useNextFreshTaprootAddressQuery(accountIndex); - - const stxAddress = useCurrentAccountStxAddressState(); - const { onCopy: onCopyOrdinal } = useClipboard(btcAddressTaproot); - const { onCopy: onCopyBitcoin } = useClipboard(btcAddressNativeSegwit); - const { onCopy: onCopyStacks } = useClipboard(stxAddress); - - function copyBitcoinAddressToClipboard(copyHandler: () => void) { - void analytics.track('select_stamp_to_add_new_collectible'); - toast.success('Copied to clipboard!'); - copyHandler(); - } - - function copyStacksAddressToClipboard(copyHandler: () => void) { - void analytics.track('select_nft_to_add_new_collectible'); - toast.success('Copied to clipboard!'); - copyHandler(); - } - - if (!btcAddressTaproot) return null; - - return ( - - } - dataTestId={HomePageSelectors.ReceiveBtcTaprootQrCodeBtn} - onCopyAddress={() => copyBitcoinAddressToClipboard(onCopyOrdinal)} - onClickQrCode={() => { - void analytics.track('select_inscription_to_add_new_collectible'); - navigate(RouteUrls.ReceiveCollectibleOrdinal, { state: { btcAddressTaproot } }); - }} - title="Ordinal inscription" - /> - - - - } - onCopyAddress={() => copyBitcoinAddressToClipboard(onCopyBitcoin)} - title="Bitcoin Stamp" - /> - } - dataTestId={HomePageSelectors.ReceiveStxQrCodeBtn} - onCopyAddress={() => copyStacksAddressToClipboard(onCopyStacks)} - onClickQrCode={() => navigate(RouteUrls.ReceiveStx)} - title="Stacks NFT" - /> - - ); -} diff --git a/src/app/pages/receive-tokens/receive-modal.tsx b/src/app/pages/receive-tokens/receive-modal.tsx deleted file mode 100644 index 2757bfac..00000000 --- a/src/app/pages/receive-tokens/receive-modal.tsx +++ /dev/null @@ -1,108 +0,0 @@ -import toast from 'react-hot-toast'; -import { FiCopy } from 'react-icons/fi'; -import { useNavigate } from 'react-router-dom'; - -import { Box, Button, Flex, Stack, useClipboard } from '@stacks/ui'; -import { color, truncateMiddle } from '@stacks/ui-utils'; -import { HomePageSelectors } from '@tests/selectors/home.selectors'; - -import { RouteUrls } from '@shared/route-urls'; - -import { useAnalytics } from '@app/common/hooks/analytics/use-analytics'; -import { StxAvatar } from '@app/components/crypto-assets/stacks/components/stx-avatar'; -import { BaseDrawer } from '@app/components/drawer/base-drawer'; -import { BtcIcon } from '@app/components/icons/btc-icon'; -import { Flag } from '@app/components/layout/flag'; -import { QrCodeIcon } from '@app/components/qr-code-icon'; -import { ReceiveCollectible } from '@app/components/receive/receive-collectible'; -import { Caption } from '@app/components/typography'; -import { useCurrentAccountNativeSegwitAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks'; -import { useCurrentAccountStxAddressState } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks'; - -export function ReceiveModal() { - const analytics = useAnalytics(); - const navigate = useNavigate(); - const btcAddress = useCurrentAccountNativeSegwitAddressIndexZero(); - const stxAddress = useCurrentAccountStxAddressState(); - const { onCopy: onCopyBtc } = useClipboard(btcAddress); - const { onCopy: onCopyStacks } = useClipboard(stxAddress); - - function copyToClipboard(copyHandler: () => void) { - void analytics.track('copy_address_to_clipboard'); - toast.success('Copied to clipboard!'); - copyHandler(); - } - return ( - navigate('../')}> - - Tokens - - - } spacing="base"> - - - Bitcoin - {truncateMiddle(btcAddress, 6)} - - - - - - - - - - } spacing="base"> - - - Stacks - {truncateMiddle(stxAddress, 6)} - - - - - - - - - - - Collectibles - - - - - ); -} diff --git a/src/app/pages/receive-tokens/components/address-qr-code.tsx b/src/app/pages/receive/components/address-qr-code.tsx similarity index 100% rename from src/app/pages/receive-tokens/components/address-qr-code.tsx rename to src/app/pages/receive/components/address-qr-code.tsx diff --git a/src/app/pages/receive-tokens/components/receive-btc-warning.tsx b/src/app/pages/receive/components/receive-btc-warning.tsx similarity index 100% rename from src/app/pages/receive-tokens/components/receive-btc-warning.tsx rename to src/app/pages/receive/components/receive-btc-warning.tsx diff --git a/src/app/components/receive/receive-collectible-item.tsx b/src/app/pages/receive/components/receive-item.tsx similarity index 75% rename from src/app/components/receive/receive-collectible-item.tsx rename to src/app/pages/receive/components/receive-item.tsx index 5991a6b3..e71ca066 100644 --- a/src/app/components/receive/receive-collectible-item.tsx +++ b/src/app/pages/receive/components/receive-item.tsx @@ -3,12 +3,11 @@ import { FiCopy } from 'react-icons/fi'; import { Box, Button, ButtonProps, Flex, Stack } from '@stacks/ui'; import { color, truncateMiddle } from '@stacks/ui-utils'; +import { Caption } from '@app/components//typography'; +import { Flag } from '@app/components/layout/flag'; import { QrCodeIcon } from '@app/components/qr-code-icon'; -import { Flag } from '../layout/flag'; -import { Caption } from '../typography'; - -interface ReceiveCollectibleItemProps extends ButtonProps { +interface ReceiveItemProps extends ButtonProps { address: string; dataTestId?: string; icon: React.JSX.Element; @@ -16,15 +15,14 @@ interface ReceiveCollectibleItemProps extends ButtonProps { onClickQrCode?(): void; title: string; } -export function ReceiveCollectibleItem({ +export function ReceiveItem({ address, dataTestId, icon, onCopyAddress, onClickQrCode, title, - ...rest -}: ReceiveCollectibleItemProps) { +}: ReceiveItemProps) { return ( @@ -34,7 +32,7 @@ export function ReceiveCollectibleItem({ - {onClickQrCode && ( @@ -45,9 +43,7 @@ export function ReceiveCollectibleItem({ ml="tight" onClick={onClickQrCode} > - - - + )} diff --git a/src/app/pages/receive/components/receive-items.tsx b/src/app/pages/receive/components/receive-items.tsx new file mode 100644 index 00000000..cf94338f --- /dev/null +++ b/src/app/pages/receive/components/receive-items.tsx @@ -0,0 +1,18 @@ +import { ButtonProps, Stack } from '@stacks/ui'; + +import { Caption } from '@app/components//typography'; + +interface ReceiveItemListProps extends ButtonProps { + children: React.ReactNode; + title?: string; +} +export function ReceiveItemList({ children, title }: ReceiveItemListProps) { + return ( + <> + {title && {title}} + + {children} + + + ); +} diff --git a/src/app/pages/receive-tokens/components/receive-tokens.layout.tsx b/src/app/pages/receive/components/receive-tokens.layout.tsx similarity index 100% rename from src/app/pages/receive-tokens/components/receive-tokens.layout.tsx rename to src/app/pages/receive/components/receive-tokens.layout.tsx diff --git a/src/app/pages/receive-tokens/receive-tokens.tsx b/src/app/pages/receive/legacy/receive-tokens.tsx similarity index 93% rename from src/app/pages/receive-tokens/receive-tokens.tsx rename to src/app/pages/receive/legacy/receive-tokens.tsx index a6d6f0e9..9ccf9888 100644 --- a/src/app/pages/receive-tokens/receive-tokens.tsx +++ b/src/app/pages/receive/legacy/receive-tokens.tsx @@ -6,7 +6,7 @@ import { useCurrentAccountDisplayName } from '@app/common/hooks/account/use-acco import { useAnalytics } from '@app/common/hooks/analytics/use-analytics'; import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks'; -import { ReceiveTokensLayout } from './components/receive-tokens.layout'; +import { ReceiveTokensLayout } from '../components/receive-tokens.layout'; // ts-unused-exports:disable-next-line export function ReceiveTokens() { diff --git a/src/app/pages/receive-tokens/receive-btc.tsx b/src/app/pages/receive/receive-btc.tsx similarity index 100% rename from src/app/pages/receive-tokens/receive-btc.tsx rename to src/app/pages/receive/receive-btc.tsx diff --git a/src/app/pages/receive/receive-collectible/receive-collectible-oridinal.tsx b/src/app/pages/receive/receive-collectible-oridinal.tsx similarity index 100% rename from src/app/pages/receive/receive-collectible/receive-collectible-oridinal.tsx rename to src/app/pages/receive/receive-collectible-oridinal.tsx diff --git a/src/app/pages/receive/receive-collectible/receive-collectible-modal.tsx b/src/app/pages/receive/receive-collectible/receive-collectible-modal.tsx deleted file mode 100644 index 31f0b18c..00000000 --- a/src/app/pages/receive/receive-collectible/receive-collectible-modal.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { useNavigate } from 'react-router-dom'; - -import { Box } from '@stacks/ui'; - -import { BaseDrawer } from '@app/components/drawer/base-drawer'; -import { ReceiveCollectible } from '@app/components/receive/receive-collectible'; - -export function ReceiveCollectibleModal() { - const navigate = useNavigate(); - - return ( - navigate('../')}> - - - - - ); -} diff --git a/src/app/pages/receive/receive-modal.tsx b/src/app/pages/receive/receive-modal.tsx new file mode 100644 index 00000000..cce4224d --- /dev/null +++ b/src/app/pages/receive/receive-modal.tsx @@ -0,0 +1,104 @@ +import toast from 'react-hot-toast'; +import { useLocation, useNavigate } from 'react-router-dom'; + +import { Box, useClipboard } from '@stacks/ui'; +import { HomePageSelectors } from '@tests/selectors/home.selectors'; +import get from 'lodash.get'; + +import { RouteUrls } from '@shared/route-urls'; + +import { useAnalytics } from '@app/common/hooks/analytics/use-analytics'; +import { StxAvatar } from '@app/components/crypto-assets/stacks/components/stx-avatar'; +import { BaseDrawer } from '@app/components/drawer/base-drawer'; +import { BtcIcon } from '@app/components/icons/btc-icon'; +import { BtcStampsIcon } from '@app/components/icons/btc-stamps-icon'; +import { OrdinalIcon } from '@app/components/icons/ordinal-icon'; +import { useZeroIndexTaprootAddress } from '@app/query/bitcoin/ordinals/use-zero-index-taproot-address'; +import { useCurrentAccountNativeSegwitAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks'; +import { useCurrentAccountStxAddressState } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks'; + +import { ReceiveItem } from './components/receive-item'; +import { ReceiveItemList } from './components/receive-items'; + +type ReceiveModal = 'full' | 'collectible'; + +interface ReceiveModalProps { + type?: 'full' | 'collectible'; +} + +export function ReceiveModal({ type = 'full' }: ReceiveModalProps) { + const analytics = useAnalytics(); + const location = useLocation(); + const navigate = useNavigate(); + const btcAddressNativeSegwit = useCurrentAccountNativeSegwitAddressIndexZero(); + const stxAddress = useCurrentAccountStxAddressState(); + const accountIndex = get(location.state, 'accountIndex', undefined); + const btcAddressTaproot = useZeroIndexTaprootAddress(accountIndex); + + const { onCopy: onCopyBtc } = useClipboard(btcAddressNativeSegwit); + const { onCopy: onCopyStx } = useClipboard(stxAddress); + const { onCopy: onCopyOrdinal } = useClipboard(btcAddressTaproot); + + function copyToClipboard(copyHandler: () => void, tracker = 'copy_address_to_clipboard') { + void analytics.track(tracker); + toast.success('Copied to clipboard!'); + copyHandler(); + } + + const title = type === 'full' ? 'Select asset to receive' : 'Add collectible'; + + return ( + navigate('../')}> + + {type === 'full' && ( + + } + dataTestId={HomePageSelectors.ReceiveBtcNativeSegwitQrCodeBtn} + onCopyAddress={() => copyToClipboard(onCopyBtc)} + onClickQrCode={() => navigate(RouteUrls.ReceiveBtc)} + title="Bitcoin" + /> + } + dataTestId={HomePageSelectors.ReceiveStxQrCodeBtn} + onCopyAddress={() => copyToClipboard(onCopyStx)} + onClickQrCode={() => navigate(RouteUrls.ReceiveStx)} + title="Stacks" + /> + + )} + + } + dataTestId={HomePageSelectors.ReceiveBtcTaprootQrCodeBtn} + onCopyAddress={() => + copyToClipboard(onCopyOrdinal, 'select_stamp_to_add_new_collectible') + } + onClickQrCode={() => { + void analytics.track('select_inscription_to_add_new_collectible'); + navigate(RouteUrls.ReceiveCollectibleOrdinal, { state: { btcAddressTaproot } }); + }} + title="Ordinal inscription" + /> + } + onCopyAddress={() => copyToClipboard(onCopyBtc, 'select_stamp_to_add_new_collectible')} + title="Bitcoin Stamp" + /> + } + onCopyAddress={() => copyToClipboard(onCopyStx, 'select_nft_to_add_new_collectible')} + onClickQrCode={() => navigate(RouteUrls.ReceiveStx)} + title="Stacks NFT" + /> + + + + ); +} diff --git a/src/app/pages/receive-tokens/receive-stx.tsx b/src/app/pages/receive/receive-stx.tsx similarity index 100% rename from src/app/pages/receive-tokens/receive-stx.tsx rename to src/app/pages/receive/receive-stx.tsx diff --git a/src/app/routes/app-routes.tsx b/src/app/routes/app-routes.tsx index 964832f0..41b89a82 100644 --- a/src/app/routes/app-routes.tsx +++ b/src/app/routes/app-routes.tsx @@ -35,11 +35,10 @@ import { BackUpSecretKeyPage } from '@app/pages/onboarding/back-up-secret-key/ba import { SignIn } from '@app/pages/onboarding/sign-in/sign-in'; import { WelcomePage } from '@app/pages/onboarding/welcome/welcome'; import { PsbtRequest } from '@app/pages/psbt-request/psbt-request'; -import { ReceiveBtcModal } from '@app/pages/receive-tokens/receive-btc'; -import { ReceiveModal } from '@app/pages/receive-tokens/receive-modal'; -import { ReceiveStxModal } from '@app/pages/receive-tokens/receive-stx'; -import { ReceiveCollectibleModal } from '@app/pages/receive/receive-collectible/receive-collectible-modal'; -import { ReceiveCollectibleOrdinal } from '@app/pages/receive/receive-collectible/receive-collectible-oridinal'; +import { ReceiveBtcModal } from '@app/pages/receive/receive-btc'; +import { ReceiveCollectibleOrdinal } from '@app/pages/receive/receive-collectible-oridinal'; +import { ReceiveModal } from '@app/pages/receive/receive-modal'; +import { ReceiveStxModal } from '@app/pages/receive/receive-stx'; import { RequestError } from '@app/pages/request-error/request-error'; import { RpcGetAddresses } from '@app/pages/rpc-get-addresses/rpc-get-addresses'; import { rpcSendTransferRoutes } from '@app/pages/rpc-send-transfer/rpc-send-transfer.routes'; @@ -213,7 +212,10 @@ function useAppRoutes() { } /> } /> - } /> + } + /> }