diff --git a/src/components/token/utils.ts b/src/components/token/utils.ts new file mode 100644 index 000000000..23f89e44e --- /dev/null +++ b/src/components/token/utils.ts @@ -0,0 +1,48 @@ +import { ChainID } from 'lib/eoaWallet' + +import { TokenSymbol, getTokenSymbolByChainId } from 'screens/home/TokenImage' +import { TokenOrBitcoinNetwork } from 'shared/types' + +/** + * Sorts balances by symbol in the following order: + * RIF, USDRIF, RBTC, BTC, RDOC and then alphabetically by symbol + * @param balances - array of balances + * @param chainId - chain id (30 or 31) + * @returns sorted array of balances + */ +export const sortBalancesBySymbol = ( + balances: Array, + chainId: ChainID, +): Array => { + const rif = getTokenSymbolByChainId(TokenSymbol.RIF, chainId) + const usdrif = getTokenSymbolByChainId(TokenSymbol.USDRIF, chainId) + const rbtc = getTokenSymbolByChainId(TokenSymbol.RBTC, chainId) + const btc = getTokenSymbolByChainId(TokenSymbol.BTC, chainId) + const rdoc = getTokenSymbolByChainId(TokenSymbol.RDOC, chainId) + + const defaultOrder = [rif, usdrif, rbtc, btc, rdoc] + + return balances.sort((a, b) => { + const symbolA = getTokenSymbolByChainId(a.symbol, chainId) + const symbolB = getTokenSymbolByChainId(b.symbol, chainId) + const indexA = defaultOrder.indexOf(symbolA) + const indexB = defaultOrder.indexOf(symbolB) + + if (indexA !== -1 && indexB !== -1) { + return indexA - indexB + } + if (indexA !== -1) { + return -1 + } + if (indexB !== -1) { + return 1 + } + if (symbolA < symbolB) { + return -1 + } + if (symbolA > symbolB) { + return 1 + } + return 0 + }) +} diff --git a/src/screens/home/PortfolioComponent.tsx b/src/screens/home/PortfolioComponent.tsx index 7bff65b7d..d5a50d9e9 100644 --- a/src/screens/home/PortfolioComponent.tsx +++ b/src/screens/home/PortfolioComponent.tsx @@ -1,16 +1,17 @@ -import { BitcoinNetwork } from '@rsksmart/rif-wallet-bitcoin' import { useCallback, useState } from 'react' import { useTranslation } from 'react-i18next' import { ScrollView, StyleProp, View, ViewStyle } from 'react-native' import { PortfolioCard } from 'components/Porfolio/PortfolioCard' +import { sortBalancesBySymbol } from 'components/token/utils' import { getTokenColor } from 'screens/home/tokenColor' import { sharedColors } from 'shared/constants' -import { ITokenWithoutLogo } from 'store/slices/balancesSlice/types' +import { TokenOrBitcoinNetwork } from 'shared/types' +import { getCurrentChainId } from 'storage/ChainStorage' interface Props { setSelectedAddress: (token: string | undefined) => void - balances: Array + balances: Array totalUsdBalance: string selectedAddress?: string showTotalCard?: boolean @@ -24,11 +25,14 @@ export const PortfolioComponent = ({ showTotalCard = true, style, }: Props) => { + const chainId = getCurrentChainId() const { t } = useTranslation() const [isTotalCardSelected, setIsTotalCardSelected] = useState( showTotalCard && !selectedAddress, ) + const usersTokens = sortBalancesBySymbol(balances, chainId) + const handleSelectedAddress = useCallback( (contractAddress: string) => { setIsTotalCardSelected(false) @@ -59,13 +63,9 @@ export const PortfolioComponent = ({ isSelected={isTotalCardSelected} /> )} - {balances.map( + {usersTokens.map( ( - { - contractAddress, - symbol, - balance, - }: ITokenWithoutLogo | BitcoinNetwork, + { contractAddress, symbol, balance }: TokenOrBitcoinNetwork, i: number, ) => { const isSelected = diff --git a/src/screens/home/TokenImage.tsx b/src/screens/home/TokenImage.tsx index 935332930..5e5b3a3b3 100644 --- a/src/screens/home/TokenImage.tsx +++ b/src/screens/home/TokenImage.tsx @@ -8,6 +8,8 @@ import { ViewStyle, } from 'react-native' +import { ChainID } from 'lib/eoaWallet' + import { FrownFaceIcon } from 'components/icons' import { sharedColors } from 'shared/constants' interface Props { @@ -277,3 +279,24 @@ export const getIconSource = ( return undefined } } + +export const getTokenSymbolByChainId = ( + symbol: string | TokenSymbol, + chainId: ChainID, +) => { + const upperSymbol = symbol.toUpperCase() + const isMainnet = chainId === 30 + switch (upperSymbol) { + case 'RIF': + case 'TRIF': + return isMainnet ? TokenSymbol.RIF : TokenSymbol.TRIF + case 'RBTC': + case 'TRBTC': + return isMainnet ? TokenSymbol.RBTC : TokenSymbol.TRBTC + case 'BTC': + case 'BTCT': + return isMainnet ? TokenSymbol.BTC : TokenSymbol.BTCT + default: + return TokenSymbol[upperSymbol as keyof typeof TokenSymbol] || upperSymbol + } +} diff --git a/src/screens/send/SendScreen.tsx b/src/screens/send/SendScreen.tsx index 8b3831cf9..891518bac 100644 --- a/src/screens/send/SendScreen.tsx +++ b/src/screens/send/SendScreen.tsx @@ -59,9 +59,7 @@ export const SendScreen = ({ const balances = Object.values(useAppSelector(selectBalances)) const assets = contact - ? balances.filter(b => - isContactBitcoin ? isAssetBitcoin(b) : !isAssetBitcoin(b), - ) + ? balances.filter(b => isContactBitcoin !== isAssetBitcoin(b)) : balances const contractAddress = route.params?.contractAddress || assets[0] diff --git a/src/shared/types/index.ts b/src/shared/types/index.ts index 0f5206273..dd45ece59 100644 --- a/src/shared/types/index.ts +++ b/src/shared/types/index.ts @@ -1,4 +1,7 @@ -import { SendBitcoinRequest } from '@rsksmart/rif-wallet-bitcoin' +import { + BitcoinNetwork, + SendBitcoinRequest, +} from '@rsksmart/rif-wallet-bitcoin' import { Request } from 'lib/eoaWallet' @@ -6,6 +9,7 @@ import { rootTabsRouteNames, RootTabsScreenProps, } from 'navigation/rootNavigator' +import { ITokenWithoutLogo } from 'store/slices/balancesSlice/types' export interface ErrorWithMessage { message: string @@ -28,3 +32,5 @@ export type ContactWithAddressRequired = Partial> & { export type ActivityMainScreenProps = RootTabsScreenProps + +export type TokenOrBitcoinNetwork = ITokenWithoutLogo | BitcoinNetwork