Skip to content

Commit

Permalink
chore(portfolio): helpers renamed
Browse files Browse the repository at this point in the history
  • Loading branch information
stackchain committed Apr 30, 2024
1 parent 199b892 commit c3300b0
Show file tree
Hide file tree
Showing 11 changed files with 177 additions and 394 deletions.
@@ -1,4 +1,4 @@
import {amountFormatter, infoExtractName} from '@yoroi/portfolio'
import {amountFormatter, infoExtractName, isNft} from '@yoroi/portfolio'
import {useTheme} from '@yoroi/theme'
import {Portfolio} from '@yoroi/types'
import {Swap} from '@yoroi/types'
Expand Down Expand Up @@ -73,7 +73,7 @@ export const TokenAmountItem = ({
</Middle>

<Right>
{info.type !== Portfolio.Token.Type.NFT && variant !== 'swap' && (
{!isNft(info) && variant !== 'swap' && (
<View testID="tokenAmountText">
{priceImpactRisk === 'moderate' && <Icon.Info size={24} color={priceImpactRiskTextColor} />}

Expand Down
@@ -1,34 +1,32 @@
import {useFocusEffect, useNavigation} from '@react-navigation/native'
import {FlashList} from '@shopify/flash-list'
import {isPrimaryToken} from '@yoroi/portfolio'
import {useTheme} from '@yoroi/theme'
import {targetGetTokenBalanceBreakdown, useTransfer} from '@yoroi/transfer'
import {Balance, Portfolio} from '@yoroi/types'
import React from 'react'
import {StyleSheet, TouchableOpacity, View} from 'react-native'

import {Boundary, Spacer, Text} from '../../../../../components'
import {AmountItem} from '../../../../../components/AmountItem/AmountItem'
import {Spacer, Text} from '../../../../../components'
import {NftImageGallery} from '../../../../../components/NftImageGallery'
import {useMetrics} from '../../../../../metrics/metricsManager'
import {TxHistoryRouteNavigation} from '../../../../../navigation'
import {useSearch, useSearchOnNavBar} from '../../../../../Search/SearchContext'
import {sortTokenInfos} from '../../../../../utils'
import {YoroiWallet} from '../../../../../yoroi-wallets/cardano/types'
import {limitOfSecondaryAmountsPerTx} from '../../../../../yoroi-wallets/contants'
import {useAllTokenInfos, useBalances, useIsWalletEmpty, useNfts} from '../../../../../yoroi-wallets/hooks'
import {Amounts, Quantities} from '../../../../../yoroi-wallets/utils'
import {useBalances, useIsWalletEmpty, useNfts} from '../../../../../yoroi-wallets/hooks'
import {Amounts} from '../../../../../yoroi-wallets/utils'
import {usePortfolioBalances} from '../../../../Portfolio/common/hooks/usePortfolioBalances'
import {usePortfolioPrimaryBreakdown} from '../../../../Portfolio/common/hooks/usePortfolioPrimaryBreakdown'
import {useSelectedWallet} from '../../../../WalletManager/Context'
import {filterByFungibility} from '../../../common/filterByFungibility'
import {filterBySearch} from '../../../common/filterBySearch'
import {useOverridePreviousSendTxRoute} from '../../../common/navigation'
import {NoAssetFoundImage} from '../../../common/NoAssetFoundImage'
import {useStrings} from '../../../common/strings'
import {useSelectedSecondaryAmountsCounter} from '../../../common/useSelectedSecondaryAmountsCounter'
import {useTokenQuantities} from '../../../common/useTokenQuantities'
import {MaxAmountsPerTx} from './Show/MaxAmountsPerTx'
import {usePortfolioPrimaryBreakdown} from '../../../../Portfolio/common/hooks/usePortfolioPrimaryBreakdown'
import {isPrimary, isPrimaryToken} from '@yoroi/portfolio'

export const SelectTokenFromListScreen = () => {
const strings = useStrings()
Expand All @@ -37,14 +35,15 @@ export const SelectTokenFromListScreen = () => {

const wallet = useSelectedWallet()
const balances = usePortfolioBalances({wallet})
const [fungibilityFilter, setFungibilityFilter] = React.useState<keyof typeof balances>('all')
const [fungibilityFilter, setFungibilityFilter] = React.useState<Exclude<keyof typeof balances, 'records'>>('all')
const [isPending, startTransition] = React.useTransition()
const showOnlyNfts = fungibilityFilter === 'nfts'
const filteredBalancesByFungibility = balances[fungibilityFilter]
const withoutSelected = React.useMemo(
() => filteredBalancesByFungibility.filter(filterOutSelected(targets[selectedTargetIndex].entry.amounts)),
[filteredBalancesByFungibility, selectedTargetIndex, targets],
)
const balancesBreakdown =

const counter = withoutSelected.length

Expand Down Expand Up @@ -113,12 +112,12 @@ type ListProps<T> = {
const List = <T,>({showOnlyNfts, isSearching, canAddAmount}: ListProps<T>) => {
const showNftList = showOnlyNfts && !isSearching

if (showNftList) return <NftList canAddAmount={canAddAmount} />
if (showNftList) return <ListSpendableNfts canAddAmount={canAddAmount} />

return <ListAvailableBalances fungibilityFilter={fungibilityFilter} canAddAmount={canAddAmount} />
return <ListSpendableBalances fungibilityFilter={fungibilityFilter} canAddAmount={canAddAmount} />
}

const NftList = ({canAddAmount}: {canAddAmount: boolean}) => {
const ListSpendableNfts = ({canAddAmount}: {canAddAmount: boolean}) => {
const {styles} = useStyles()
const wallet = useSelectedWallet()
const navigation = useNavigation<TxHistoryRouteNavigation>()
Expand Down Expand Up @@ -159,11 +158,11 @@ const NftList = ({canAddAmount}: {canAddAmount: boolean}) => {
)
}

type ListAvailableBalancesProps = {
type ListSpendableBalancesProps = {
canAddAmount: boolean
availableBalances: ReadonlyArray<Portfolio.Token.Amount>
}
const ListAvailableBalances = ({canAddAmount, availableBalances}: ListAvailableBalancesProps) => {
const ListSpendableBalances = ({canAddAmount, availableBalances}: ListSpendableBalancesProps) => {
const {styles} = useStyles()

return (
Expand Down Expand Up @@ -232,31 +231,30 @@ const SelectableAssetItem = ({amount, disabled, wallet}: SelectableAssetItemProp

const isPrimary = isPrimaryToken(amount.info)

const onSelect = () => {
const handleOnSelect = React.useCallback(() => {
tokenSelectedChanged(amount.info.id)
closeSearch()

// if the balance is atomic there is no need to edit the amount
if (tokenInfo.kind === 'ft' && spendable === 1n) {
amountChanged(spendable)
navigation.navigate('send-list-amounts-to-send')
} else if (tokenInfo.kind === 'nft') {
const quantity = Amounts.getAmount(balances, tokenInfo.id).quantity
amountChanged(quantity)
if (spendable === 1n && amount.info.decimals === 0) {
amountChanged({
info: amount.info,
quantity: spendable,
})
navigation.navigate('send-list-amounts-to-send')
} else {
navigation.navigate('send-edit-amount')
}
}
}, [amount.info, amountChanged, closeSearch, navigation, spendable, tokenSelectedChanged])

return (
<TouchableOpacity
style={[styles.item, isPrimary && styles.borderBottom]}
onPress={onSelect}
onPress={handleOnSelect}
testID="selectTokenButton"
disabled={disabled}
>
<AmountItem amount={{tokenId: tokenInfo.id, quantity: spendable}} wallet={wallet} />
<PortfolioAmountItem amount={{info: amount.info, quantity: spendable}} wallet={wallet} />
</TouchableOpacity>
)
}
Expand Down
@@ -0,0 +1,55 @@
import {Transfer} from '@yoroi/types'
import {tokenBalanceMocks} from '@yoroi/portfolio'

import {targetGetUsedByOtherTargets} from './target-get-allocated-in-others'

describe('targetGetUsedByOtherTargets()', () => {
it('should calculate balances breakdown correctly', () => {
const targets: Transfer.Target[] = [
{
receiver: {
resolve: '',
as: 'address',
selectedNameServer: undefined,
addressRecords: undefined,
},
entry: {
address: '',
amounts: {
[tokenBalanceMocks.ftNoTicker.info.id]: {
...tokenBalanceMocks.ftNoTicker,
quantity: 100n,
},
},
},
},
{
receiver: {
resolve: 'address2',
as: 'address',
addressRecords: undefined,
selectedNameServer: undefined,
},
entry: {
address: 'address2',
amounts: {
[tokenBalanceMocks.ftNoTicker.info.id]: {
...tokenBalanceMocks.ftNoTicker,
quantity: 200n,
},
},
},
},
]

const result = targetGetUsedByOtherTargets({targets})

expect(result.size).toEqual(1)
expect(result.get(0)?.get(tokenBalanceMocks.ftNoTicker.info.id)).toEqual({
used: 200n,
})
expect(result.get(0)?.get(tokenBalanceMocks.ftNoTicker.info.id)).toEqual({
used: 100n,
})
})
})
31 changes: 31 additions & 0 deletions packages/transfer/src/helpers/target-get-allocated-in-others.ts
@@ -0,0 +1,31 @@
import {Portfolio, Transfer} from '@yoroi/types'
import {freeze} from 'immer'

import {TransferUsedByOtherTargets} from '../types'
import {targetGetTokenTotalUsedByOthers} from './target-get-token-allocated-to-others'

export function targetGetUsedByOtherTargets({
targets,
}: {
targets: Readonly<Transfer.Targets>
}) {
const usedByOtherTargets: TransferUsedByOtherTargets = new Map()

targets.forEach((target, targetIndex) => {
Object.keys(target.entry.amounts).forEach((untypedTokenId) => {
const tokenId = untypedTokenId as Portfolio.Token.Id
const allocated = targetGetTokenTotalUsedByOthers({
targets,
targetIndex,
tokenId,
})
const currentTarget = usedByOtherTargets.get(targetIndex) ?? new Map()

currentTarget.set(tokenId, {
allocated,
})
})
})

return freeze(usedByOtherTargets, true)
}
@@ -1,8 +1,8 @@
import {tokenBalanceMocks} from '@yoroi/portfolio'
import {targetGetTokenTotalUsedByOthers} from './target-get-token-total-used-by-others'
import {targetGetTokenAllocatedToOthers} from './target-get-token-allocated-to-others'
import {Transfer} from '@yoroi/types'

describe('targetGetTokenTotalUsedByOthers', () => {
describe('targetGetTokenAllocatedToOthers', () => {
it('should return the total amount of tokens used by other targets', () => {
const targets: Transfer.Target[] = [
{
Expand Down Expand Up @@ -40,13 +40,13 @@ describe('targetGetTokenTotalUsedByOthers', () => {
},
},
]
const selectedTargetIndex = 0
const selectedTokenId = tokenBalanceMocks.ftNoTicker.info.id
const targetIndex = 0
const tokenId = tokenBalanceMocks.ftNoTicker.info.id

const totalUsed = targetGetTokenTotalUsedByOthers({
const totalUsed = targetGetTokenAllocatedToOthers({
targets,
selectedTargetIndex,
selectedTokenId,
targetIndex,
tokenId,
})

expect(totalUsed).toBe(200n)
Expand All @@ -72,13 +72,13 @@ describe('targetGetTokenTotalUsedByOthers', () => {
},
},
]
const selectedTargetIndex = 0
const selectedTokenId = tokenBalanceMocks.ftNoTicker.info.id
const targetIndex = 0
const tokenId = tokenBalanceMocks.ftNoTicker.info.id

const totalUsed = targetGetTokenTotalUsedByOthers({
const totalUsed = targetGetTokenAllocatedToOthers({
targets,
selectedTargetIndex,
selectedTokenId,
targetIndex,
tokenId,
})

expect(totalUsed).toBe(0n)
Expand Down Expand Up @@ -121,13 +121,13 @@ describe('targetGetTokenTotalUsedByOthers', () => {
},
},
]
const selectedTargetIndex = 0
const selectedTokenId = 'anyOther.token'
const targetIndex = 0
const tokenId = 'anyOther.token'

const totalUsed = targetGetTokenTotalUsedByOthers({
const totalUsed = targetGetTokenAllocatedToOthers({
targets,
selectedTargetIndex,
selectedTokenId,
targetIndex,
tokenId,
})

expect(totalUsed).toBe(0n)
Expand Down
Expand Up @@ -4,23 +4,22 @@ import {Portfolio, Transfer} from '@yoroi/types'
* @summary Returns the total amount of tokens used by other targets
* @returns BigInt
*/
export function targetGetTokenTotalUsedByOthers({
export function targetGetTokenAllocatedToOthers({
targets,
selectedTargetIndex,
selectedTokenId,
targetIndex,
tokenId,
}: {
targets: Readonly<Transfer.Targets>
selectedTargetIndex: number
selectedTokenId: Portfolio.Token.Id
targetIndex: number
tokenId: Portfolio.Token.Id
}) {
const isNotTheSelectedTarget = (_: Transfer.Target, index: number) =>
index !== selectedTargetIndex
index !== targetIndex

return targets
.filter(isNotTheSelectedTarget)
.reduce(
(acc, target) =>
acc + (target.entry.amounts[selectedTokenId]?.quantity ?? 0n),
(acc, target) => acc + (target.entry.amounts[tokenId]?.quantity ?? 0n),
0n,
)
}

0 comments on commit c3300b0

Please sign in to comment.