Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add copy button to some dropdown accounts #7689

Merged
merged 4 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions src/components/Modals/Send/views/Details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
usePrevious,
} from '@chakra-ui/react'
import type { AccountId } from '@shapeshiftoss/caip'
import { fromAssetId } from '@shapeshiftoss/caip'
import { fromAccountId, fromAssetId } from '@shapeshiftoss/caip'
import { CHAIN_NAMESPACE } from '@shapeshiftoss/caip/dist/constants'
import isNil from 'lodash/isNil'
import React, { useCallback, useEffect, useMemo } from 'react'
Expand All @@ -23,6 +23,7 @@ import { useHistory } from 'react-router-dom'
import { AccountCard } from 'components/AccountCard'
import { AccountDropdown } from 'components/AccountDropdown/AccountDropdown'
import { Amount } from 'components/Amount/Amount'
import { InlineCopyButton } from 'components/InlineCopyButton'
import { DialogBackButton } from 'components/Modal/components/DialogBackButton'
import { DialogBody } from 'components/Modal/components/DialogBody'
import { DialogFooter } from 'components/Modal/components/DialogFooter'
Expand All @@ -35,6 +36,7 @@ import { TokenRow } from 'components/TokenRow/TokenRow'
import { useModal } from 'hooks/useModal/useModal'
import { useWallet } from 'hooks/useWallet/useWallet'
import { bnOrZero } from 'lib/bignumber/bignumber'
import { isUtxoAccountId } from 'lib/utils/utxo'
import { selectAssetById } from 'state/slices/selectors'
import { useAppSelector } from 'state/store'

Expand All @@ -54,7 +56,8 @@ const MAX_COSMOS_SDK_MEMO_LENGTH = 256
const controllerRules = {
required: true,
}
const accountDropdownButtonProps = { width: 'full', mb: 2, variant: 'solid' }
const accountDropdownBoxProps = { width: '100%', my: 0, pl: 0 }
const accountDropdownButtonProps = { width: 'full', variant: 'solid' }
const formHelperTextHoverStyle = { color: 'gray.400', transition: '.2s color ease' }

export const Details = () => {
Expand Down Expand Up @@ -220,12 +223,20 @@ export const Details = () => {
</DialogTitle>
</DialogHeader>
<DialogBody>
<AccountDropdown
assetId={asset.assetId}
defaultAccountId={accountId}
onChange={handleAccountChange}
buttonProps={accountDropdownButtonProps}
/>
<Box mb={4}>
<InlineCopyButton
isDisabled={!accountId || isUtxoAccountId(accountId)}
value={accountId ? fromAccountId(accountId).account : ''}
>
<AccountDropdown
assetId={asset.assetId}
defaultAccountId={accountId}
onChange={handleAccountChange}
boxProps={accountDropdownBoxProps}
buttonProps={accountDropdownButtonProps}
/>
</InlineCopyButton>
</Box>
<AccountCard
asset={asset}
isLoaded={!balancesLoading}
Expand Down
7 changes: 5 additions & 2 deletions src/features/defi/components/Overview/Overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { Amount } from 'components/Amount/Amount'
import type { AssetDescriptionTeaserProps } from 'components/AssetDescriptionTeaser'
import { AssetDescriptionTeaser } from 'components/AssetDescriptionTeaser'
import { AssetIcon } from 'components/AssetIcon'
import { InlineCopyButton } from 'components/InlineCopyButton'
import { RawText, Text } from 'components/Text'

import type { DefiActionButtonProps } from '../DefiActionButtons'
Expand All @@ -35,6 +36,7 @@ export type AssetWithBalance = {
type OverviewProps = {
accountId?: AccountId | undefined
onAccountIdChange?: (accountId: AccountId) => void
positionAddress?: string | undefined
// The LP asset this opportunity represents
lpAsset?: AssetWithBalance
// The assets underlying the LP one
Expand Down Expand Up @@ -69,6 +71,7 @@ const accountDropdownBoxProps = { px: 0, my: 0, width: 'full' }
export const Overview: React.FC<OverviewProps> = ({
accountId,
onAccountIdChange,
positionAddress,
lpAsset,
underlyingAssetsCryptoPrecision,
rewardAssetsCryptoPrecision,
Expand Down Expand Up @@ -109,15 +112,15 @@ export const Overview: React.FC<OverviewProps> = ({
<Flex flexDir='column' gap={3}>
{onAccountIdChange && (
<>
<Flex gap={4} alignItems='center' width='full' justifyContent='space-between'>
<InlineCopyButton isDisabled={!positionAddress} value={positionAddress ?? ''}>
<AccountDropdown
{...(accountId ? { defaultAccountId: accountId } : {})}
assetId={asset.assetId}
onChange={onAccountIdChange}
buttonProps={accountDropdownButtonProps}
boxProps={accountDropdownBoxProps}
/>
</Flex>
</InlineCopyButton>
<Divider />
</>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ArrowDownIcon, ArrowUpIcon } from '@chakra-ui/icons'
import { Center } from '@chakra-ui/react'
import type { AccountId } from '@shapeshiftoss/caip'
import { toAssetId } from '@shapeshiftoss/caip'
import { fromAccountId, toAssetId } from '@shapeshiftoss/caip'
import { DefiModalContent } from 'features/defi/components/DefiModal/DefiModalContent'
import { Overview } from 'features/defi/components/Overview/Overview'
import type {
Expand Down Expand Up @@ -239,6 +239,7 @@ export const CosmosOverview: React.FC<CosmosOverviewProps> = ({
<Overview
accountId={accountId}
onAccountIdChange={handleAccountIdChange}
positionAddress={accountId ? fromAccountId(accountId).account : undefined}
asset={stakingAsset}
name={opportunityData.name!}
icons={makeOpportunityIcons({ assets, opportunity: opportunityData })}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ArrowDownIcon, ArrowUpIcon } from '@chakra-ui/icons'
import { Center } from '@chakra-ui/react'
import type { AccountId } from '@shapeshiftoss/caip'
import { toAssetId } from '@shapeshiftoss/caip'
import { fromAccountId, toAssetId } from '@shapeshiftoss/caip'
import { DefiModalContent } from 'features/defi/components/DefiModal/DefiModalContent'
import { Overview } from 'features/defi/components/Overview/Overview'
import type {
Expand Down Expand Up @@ -210,6 +210,7 @@ export const FoxFarmingOverview: React.FC<FoxFarmingOverviewProps> = ({
<Overview
accountId={accountId}
onAccountIdChange={handleAccountIdChange}
positionAddress={accountId ? fromAccountId(accountId).account : undefined}
asset={stakingAsset}
name={opportunityData.name ?? ''}
icons={underlyingAssetsIcons}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ export const FoxyOverview: React.FC<FoxyOverviewProps> = ({
<Overview
accountId={accountId}
onAccountIdChange={handleAccountIdChange}
positionAddress={accountId ? fromAccountId(accountId).account : undefined}
asset={rewardAsset}
name='FOX Yieldy'
opportunityFiatBalance={fiatAmountAvailable.toFixed(2)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { thorchainAssetId, toAssetId } from '@shapeshiftoss/caip'
import { SwapperName } from '@shapeshiftoss/swapper'
import type { Asset } from '@shapeshiftoss/types'
import { TxStatus } from '@shapeshiftoss/unchained-client'
import { useQuery } from '@tanstack/react-query'
import BigNumber from 'bignumber.js'
import type { DefiButtonProps } from 'features/defi/components/DefiActionButtons'
import { Overview } from 'features/defi/components/Overview/Overview'
Expand All @@ -28,6 +29,7 @@ import { DefiAction } from 'features/defi/contexts/DefiManagerProvider/DefiCommo
import { useCallback, useEffect, useMemo, useState } from 'react'
import { FaTwitter } from 'react-icons/fa'
import { useTranslate } from 'react-polyglot'
import { reactQueries } from 'react-queries'
import { useIsTradingActive } from 'react-queries/hooks/useIsTradingActive'
import type { AccountDropdownProps } from 'components/AccountDropdown/AccountDropdown'
import { Amount } from 'components/Amount/Amount'
Expand All @@ -36,12 +38,16 @@ import { HelperTooltip } from 'components/HelperTooltip/HelperTooltip'
import { Text } from 'components/Text'
import { useBrowserRouter } from 'hooks/useBrowserRouter/useBrowserRouter'
import { useFeatureFlag } from 'hooks/useFeatureFlag/useFeatureFlag'
import { useWallet } from 'hooks/useWallet/useWallet'
import { bnOrZero } from 'lib/bignumber/bignumber'
import { fromBaseUnit, toBaseUnit } from 'lib/math'
import { useGetThorchainSaversDepositQuoteQuery } from 'lib/utils/thorchain/hooks/useGetThorchainSaversDepositQuoteQuery'
import { formatSecondsToDuration } from 'lib/utils/time'
import type { ThorchainSaversStakingSpecificMetadata } from 'state/slices/opportunitiesSlice/resolvers/thorchainsavers/types'
import { THORCHAIN_SAVERS_DUST_THRESHOLDS_CRYPTO_BASE_UNIT } from 'state/slices/opportunitiesSlice/resolvers/thorchainsavers/utils'
import {
getThorchainSaversPosition,
THORCHAIN_SAVERS_DUST_THRESHOLDS_CRYPTO_BASE_UNIT,
} from 'state/slices/opportunitiesSlice/resolvers/thorchainsavers/utils'
import type { StakingId } from 'state/slices/opportunitiesSlice/types'
import { DefiProvider, DefiType } from 'state/slices/opportunitiesSlice/types'
import {
Expand All @@ -56,9 +62,9 @@ import {
selectEarnUserStakingOpportunityByUserStakingId,
selectFirstAccountIdByChainId,
selectHighestStakingBalanceAccountIdByStakingId,
selectHighestUserCurrencyBalanceAccountByAssetId,
selectMarketDataByAssetIdUserCurrency,
selectOpportunitiesApiQueriesByFilter,
selectPortfolioAccountMetadataByAccountId,
selectStakingOpportunityByFilter,
selectTxsByFilter,
selectUnderlyingStakingAssetsWithBalancesAndIcons,
Expand All @@ -84,6 +90,10 @@ export const ThorchainSaversOverview: React.FC<OverviewProps> = ({
const { chainId, assetReference, assetNamespace } = query
const alertBg = useColorModeValue('gray.200', 'gray.900')

const {
state: { wallet },
} = useWallet()

const assetId = toAssetId({
chainId,
assetNamespace,
Expand Down Expand Up @@ -161,24 +171,6 @@ export const ThorchainSaversOverview: React.FC<OverviewProps> = ({
: undefined,
)

const hasStakedBalance = useMemo(() => {
return bnOrZero(earnOpportunityData?.stakedAmountCryptoBaseUnit).gt(0)
}, [earnOpportunityData?.stakedAmountCryptoBaseUnit])

const highestAssetBalanceFilter = useMemo(
() => ({
assetId,
}),
[assetId],
)
const highestAssetBalanceAccountId = useAppSelector(state =>
selectHighestUserCurrencyBalanceAccountByAssetId(state, highestAssetBalanceFilter),
)

const highestStakedOrAssetBalanceAccountId = hasStakedBalance
? maybeAccountId
: highestAssetBalanceAccountId

const opportunityMetadataFilter = useMemo(() => ({ stakingId: assetId as StakingId }), [assetId])
const opportunityMetadata = useAppSelector(state =>
selectStakingOpportunityByFilter(state, opportunityMetadataFilter),
Expand Down Expand Up @@ -263,6 +255,23 @@ export const ThorchainSaversOverview: React.FC<OverviewProps> = ({
return Math.ceil(diffTime / 1000)
}, [earnOpportunityData])

const accountFilter = useMemo(() => ({ accountId: maybeAccountId }), [maybeAccountId])

const accountMetadata = useAppSelector(state =>
selectPortfolioAccountMetadataByAccountId(state, accountFilter),
)

const { data: fromAddress } = useQuery({
...reactQueries.common.thorchainFromAddress({
accountId: accountId!,
assetId,
wallet: wallet!,
accountMetadata: accountMetadata!,
getPosition: getThorchainSaversPosition,
}),
enabled: Boolean(accountId && wallet && accountMetadata),
})

const makeDefaultMenu = useCallback(
({
isFull,
Expand Down Expand Up @@ -436,11 +445,7 @@ export const ThorchainSaversOverview: React.FC<OverviewProps> = ({

const handleThorchainSaversEmptyClick = useCallback(() => setHideEmptyState(true), [])

if (
(!earnOpportunityData?.isLoaded && highestStakedOrAssetBalanceAccountId) ||
isTradingActiveLoading ||
isMockDepositQuoteLoading
) {
if (!earnOpportunityData?.isLoaded || isTradingActiveLoading || isMockDepositQuoteLoading) {
return (
<Center minW='500px' minH='350px'>
<CircularProgress />
Expand All @@ -452,15 +457,15 @@ export const ThorchainSaversOverview: React.FC<OverviewProps> = ({
return <ThorchainSaversEmpty assetId={assetId} onClick={handleThorchainSaversEmptyClick} />
}

if (!(highestStakedOrAssetBalanceAccountId && opportunityDataFilter)) return null
if (!asset) return null
if (!underlyingAssetsWithBalancesAndIcons) return null
if (!earnOpportunityData) return null

return (
<Overview
accountId={highestStakedOrAssetBalanceAccountId}
accountId={maybeAccountId}
onAccountIdChange={handleAccountIdChange}
positionAddress={fromAddress}
asset={asset}
name={earnOpportunityData.name ?? ''}
opportunityFiatBalance={underlyingAssetsFiatBalanceCryptoPrecision}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ArrowDownIcon, ArrowUpIcon } from '@chakra-ui/icons'
import { Center, CircularProgress } from '@chakra-ui/react'
import type { AccountId } from '@shapeshiftoss/caip'
import { toAssetId } from '@shapeshiftoss/caip'
import { fromAccountId, toAssetId } from '@shapeshiftoss/caip'
import { DefiModalContent } from 'features/defi/components/DefiModal/DefiModalContent'
import { Overview } from 'features/defi/components/Overview/Overview'
import type {
Expand Down Expand Up @@ -140,6 +140,7 @@ export const UniV2Overview: React.FC<UniV2OverviewProps> = ({
<Overview
accountId={accountId}
onAccountIdChange={handleAccountIdChange}
positionAddress={maybeAccountId ? fromAccountId(maybeAccountId).account : undefined}
asset={lpAsset}
icons={earnLpOpportunity.icons}
name={earnLpOpportunity.opportunityName}
Expand Down
31 changes: 23 additions & 8 deletions src/pages/RFOX/components/AddressSelection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { useCallback, useMemo, useState } from 'react'
import { useForm, useFormContext } from 'react-hook-form'
import { useTranslate } from 'react-polyglot'
import { AccountDropdown } from 'components/AccountDropdown/AccountDropdown'
import { InlineCopyButton } from 'components/InlineCopyButton'
import { validateAddress } from 'lib/address/address'
import {
selectAccountIdByAccountNumberAndChainId,
Expand All @@ -28,6 +29,7 @@ import type { AddressSelectionValues } from '../types'

type AddressSelectionProps = {
onRuneAddressChange: (address: string | undefined) => void
selectedAddress: string | undefined
} & (
| {
isNewAddress: boolean
Expand All @@ -54,6 +56,7 @@ const buttonProps = {
export const AddressSelection: FC<AddressSelectionProps> = ({
onRuneAddressChange: handleRuneAddressChange,
isNewAddress,
selectedAddress,
validateIsNewAddress,
}) => {
const translate = useTranslate()
Expand Down Expand Up @@ -180,19 +183,31 @@ export const AddressSelection: FC<AddressSelectionProps> = ({
return undefined
}, [currentRuneAddress, maybeMatchingRuneAccountId])

const maybeSelectedRuneAddress = useMemo(() => {
if (selectedAddress) return selectedAddress
if (maybeDefaultRuneAccountId) return fromAccountId(maybeDefaultRuneAccountId).account

return undefined
}, [maybeDefaultRuneAccountId, selectedAddress])

const accountSelection = useMemo(() => {
if (isManualAddress) return null

return (
<AccountDropdown
defaultAccountId={maybeDefaultRuneAccountId}
assetId={thorchainAssetId}
onChange={handleAccountIdChange}
boxProps={boxProps}
buttonProps={buttonProps}
/>
<InlineCopyButton
isDisabled={!maybeSelectedRuneAddress}
value={maybeSelectedRuneAddress ?? ''}
>
<AccountDropdown
defaultAccountId={maybeDefaultRuneAccountId}
assetId={thorchainAssetId}
onChange={handleAccountIdChange}
boxProps={boxProps}
buttonProps={buttonProps}
/>
</InlineCopyButton>
)
}, [handleAccountIdChange, isManualAddress, maybeDefaultRuneAccountId])
}, [handleAccountIdChange, isManualAddress, maybeDefaultRuneAccountId, maybeSelectedRuneAddress])

const addressSelectionLabel = useMemo(
() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ export const ChangeAddressInput: FC<ChangeAddressRouteProps & ChangeAddressInput
isNewAddress
onRuneAddressChange={handleRuneAddressChange}
validateIsNewAddress={validateIsNewAddress}
selectedAddress={newRuneAddress}
/>
</Skeleton>
</Box>
Expand Down
Loading
Loading