Skip to content

Commit

Permalink
chore(wallet-mobile): added helpers to handle info
Browse files Browse the repository at this point in the history
  • Loading branch information
stackchain committed May 4, 2024
1 parent 3015ccb commit 85a80e4
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 19 deletions.
10 changes: 3 additions & 7 deletions apps/wallet-mobile/src/components/AmountItem/AmountItem.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {useTheme} from '@yoroi/theme'
import {Balance} from '@yoroi/types'
import {Portfolio} from '@yoroi/types'
import {Swap} from '@yoroi/types'
import * as React from 'react'
import {StyleSheet, View, ViewProps} from 'react-native'
Expand All @@ -8,17 +8,15 @@ import {usePriceImpactRiskTheme} from '../../features/Swap/common/helpers'
import {SwapPriceImpactRisk} from '../../features/Swap/common/types'
import {isEmptyString} from '../../utils'
import {YoroiWallet} from '../../yoroi-wallets/cardano/types'
import {useTokenInfo} from '../../yoroi-wallets/hooks'
import {Quantities} from '../../yoroi-wallets/utils'
import {Boundary, Icon, Spacer, Text, TokenIcon, TokenIconPlaceholder} from '..'
import {PairedBalance} from '../PairedBalance/PairedBalance'

export type AmountItemProps = {
wallet: YoroiWallet
amount: Balance.Amount
amount: Portfolio.Token.Amount
style?: ViewProps['style']
isPrivacyOff?: boolean
status?: string
inWallet?: boolean
variant?: 'swap'
priceImpactRisk?: SwapPriceImpactRisk
Expand All @@ -36,10 +34,8 @@ export const AmountItem = ({
orderType,
}: AmountItemProps) => {
const {styles, colors} = useStyles()
const {quantity, tokenId} = amount
const tokenInfo = useTokenInfo({wallet, tokenId})

const isPrimary = tokenInfo.id === wallet.primaryTokenInfo.id
const isPrimary = amount.info.nature === 'primary'
const name = tokenInfo.ticker ?? tokenInfo.name
const nameLabel = isEmptyString(name) ? '-' : name
const detail = isPrimary ? tokenInfo.description : tokenInfo.fingerprint
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ export const buildPortfolioBalanceManager = ({
network: Chain.Network
}) => {
const primaryTokenInfo = network === Chain.Network.Main ? primaryTokenInfoMainnet : primaryTokenInfoAnyTestnet
const storage = mountMMKVStorage<Portfolio.Token.Id>({path: `/`, id: `${network}.balance-manager`})
const walletStorage = storage.join(`${walletId}/`)
const balanceStorageMounted = walletStorage.join('secondaries/')
const primaryBreakdownStorageMounted = walletStorage.join('primary/')
const rootStorage = mountMMKVStorage<Portfolio.Token.Id>({path: `/`, id: `${network}.balance-manager`})
const walletStorage = rootStorage.join(`${walletId}/`)
const walletBalanceStorage = walletStorage.join('secondaries/')
const walletPrimaryBreakdownStorage = walletStorage.join('primary/')

const balanceStorage = portfolioBalanceStorageMaker({
balanceStorage: observableStorageMaker(balanceStorageMounted),
primaryBreakdownStorage: observableStorageMaker(primaryBreakdownStorageMounted),
balanceStorage: observableStorageMaker(walletBalanceStorage),
primaryBreakdownStorage: observableStorageMaker(walletPrimaryBreakdownStorage),
primaryTokenId: primaryTokenInfo.id,
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ export const usePortfolioTokenManager = ({network}: {network: Chain.Network}) =>
}

export const buildPortfolioTokenManager = ({network}: {network: Chain.Network}) => {
const storage = mountMMKVStorage<Portfolio.Token.Id>({path: '/', id: `${network}.token-manager`})
const tokenDiscoveryStorageMounted = storage.join('token-discovery/')
const tokenInfoStorageMounted = storage.join('token-info/')
const rootStorage = mountMMKVStorage<Portfolio.Token.Id>({path: '/', id: `${network}.token-manager`})
const appTokenDiscoveryStorage = rootStorage.join('token-discovery/')
const appTokenInfoStorage = rootStorage.join('token-info/')

const tokenStorage = portfolioTokenStorageMaker({
tokenDiscoveryStorage: observableStorageMaker(tokenDiscoveryStorageMounted),
tokenInfoStorage: observableStorageMaker(tokenInfoStorageMounted),
tokenDiscoveryStorage: observableStorageMaker(appTokenDiscoveryStorage),
tokenInfoStorage: observableStorageMaker(appTokenInfoStorage),
})
const api = portfolioApiMaker({
network,
Expand Down
27 changes: 26 additions & 1 deletion packages/common/src/utils/strings.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {asConcatenedString} from './strings'
import {asConcatenedString, truncateString} from './strings'

describe('asConcatenedString', () => {
it('should return undefined for null input', () => {
Expand All @@ -23,3 +23,28 @@ describe('asConcatenedString', () => {
expect(asConcatenedString(['h', 'e', 'l', 'l', 'o'])).toBe('hello')
})
})

describe('truncateString', () => {
it('should return the original string if its length is less than or equal to maxLength', () => {
const value = 'hello'
const maxLength = 10
const result = truncateString({value, maxLength})
expect(result).toBe(value)
})

it('should truncate the string and add separator if its length is greater than maxLength', () => {
const value = 'This is a long string'
const maxLength = 10
const separator = '-'
const result = truncateString({value, maxLength, separator})
expect(result).toBe('This-ring')
})

it('should truncate the string and add separator at the correct position', () => {
const value = 'This is a long string'
const maxLength = 15
const separator = '...'
const result = truncateString({value, maxLength, separator})
expect(result).toBe('This i...string')
})
})
19 changes: 19 additions & 0 deletions packages/common/src/utils/strings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,22 @@ export function asConcatenedString(
if (isArrayOfType(value, isString)) return (value as string[]).join('')
return // TS
}

export function truncateString({
value,
maxLength,
separator = '...',
}: {
value: string
maxLength: number
separator?: string
}): string {
if (value.length <= maxLength) return value

const partLength = Math.floor((maxLength - separator.length) / 2)

const start = value.substring(0, partLength)
const end = value.substring(value.length - partLength)

return `${start}${separator}${end}`
}
77 changes: 77 additions & 0 deletions packages/portfolio/src/helpers/info-extract-name.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import {tokenMocks} from '../adapters/token.mocks'
import {infoExtractName} from './info-extract-name'

describe('infoExtractName', () => {
it('should extract the ticker from FT token', () => {
const result = infoExtractName(tokenMocks.primaryETH.info, {
mode: 'name',
})

expect(result).toBe('ETH')
})

it('should extract the name from FT token when ticker is empty', () => {
const result = infoExtractName(
{
...tokenMocks.primaryETH.info,
ticker: '',
},
{
mode: 'name',
},
)

expect(result).toBe('Ethereum')
})

it('should extract the fingerprint from FT token when ticker/name are empty', () => {
const result = infoExtractName(
{
...tokenMocks.primaryETH.info,
ticker: '',
name: '',
},
{
mode: 'name',
},
)

expect(result).toBe('0x1234567890abcdef')
})

it('should extract the name from NFT token', () => {
const result = infoExtractName(tokenMocks.nftCryptoKitty.info, {
mode: 'name',
})

expect(result).toBe('CryptoKitty #1234')
})

it('should extract the fingerprint from NFT token when name is empty', () => {
const result = infoExtractName(
{
...tokenMocks.nftCryptoKitty.info,
name: '',
},
{
mode: 'name',
},
)

expect(result).toBe('asset1s7nlt...eg483c6wu75')
})

it('should extract the ticker from token', () => {
const result = infoExtractName(tokenMocks.rnftWhatever.info, {
mode: 'currency',
})

expect(result).toBe('Whatever')
})

it('should extract the ticker default', () => {
const result = infoExtractName(tokenMocks.rnftWhatever.info)

expect(result).toBe('Whatever #42')
})
})
26 changes: 26 additions & 0 deletions packages/portfolio/src/helpers/info-extract-name.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {truncateString} from '@yoroi/common'
import {Portfolio} from '@yoroi/types'

// max name length is 50 and ticker is 9 in CIP26
// if the data is in metadatum there is "no limit"
export function infoExtractName(
info: Portfolio.Token.Info,
{
mode = 'name',
maxLength = mode === 'name' ? 25 : 9,
}: {mode?: 'currency' | 'name'; maxLength?: number} = {},
) {
if (mode === 'name') {
if (info.type === Portfolio.Token.Type.FT) {
return truncateString({
value: info.ticker || info.name || info.fingerprint,
maxLength,
})
} else {
// NFTs without names usually are the "header" of collection
return truncateString({value: info.name || info.fingerprint, maxLength})
}
}

return truncateString({value: info.ticker, maxLength})
}

0 comments on commit 85a80e4

Please sign in to comment.