@@ -4,16 +4,10 @@ import {
44} from '@avalabs/avalanche-module'
55import { TokenUnit } from '@avalabs/core-utils-sdk'
66import { PChainBalance , XChainBalances } from '@avalabs/glacier-sdk'
7- import {
8- Icons ,
9- SPRING_LINEAR_TRANSITION ,
10- Text ,
11- useTheme ,
12- View
13- } from '@avalabs/k2-alpine'
7+ import { SPRING_LINEAR_TRANSITION , Text , View } from '@avalabs/k2-alpine'
8+ import { BalanceText } from 'common/components/BalanceText'
149import { CollapsibleTabs } from 'common/components/CollapsibleTabs'
1510import { getListItemEnteringAnimation } from 'common/utils/animations'
16- import { UNKNOWN_AMOUNT } from 'consts/amount'
1711import React , { FC , useCallback , useMemo } from 'react'
1812import Animated from 'react-native-reanimated'
1913import {
@@ -22,9 +16,6 @@ import {
2216 LocalTokenWithBalance
2317} from 'store/balance'
2418import { xpChainToken } from 'utils/units/knownTokens'
25- import { BalanceText } from 'common/components/BalanceText'
26- import { useFormatCurrency } from 'common/hooks/useFormatCurrency'
27- import { LogoWithNetwork } from './LogoWithNetwork'
2819
2920type PChainBalanceType = keyof PChainBalance
3021type XChainBalanceType = keyof XChainBalances
@@ -34,35 +25,6 @@ interface Props {
3425}
3526
3627const TokenDetail : FC < Props > = ( { token } ) : React . JSX . Element => {
37- const {
38- theme : { colors }
39- } = useTheme ( )
40- const { formatCurrency } = useFormatCurrency ( )
41-
42- const assetTypes = useMemo ( ( ) => {
43- if ( token && isTokenWithBalancePVM ( token ) ) {
44- return Object . keys ( token . balancePerType )
45- . sort ( ( a , b ) => {
46- return Number (
47- ( token . balancePerType [ b as PChainBalanceType ] ?? 0n ) -
48- ( token . balancePerType [ a as PChainBalanceType ] ?? 0n )
49- )
50- } )
51- . filter ( k => ( token . balancePerType [ k as PChainBalanceType ] ?? 0 ) > 0 )
52- }
53- if ( token && isTokenWithBalanceAVM ( token ) ) {
54- return Object . keys ( token . balancePerType )
55- . sort ( ( a , b ) => {
56- return Number (
57- ( token . balancePerType [ b as XChainBalanceType ] ?? 0n ) -
58- ( token . balancePerType [ a as XChainBalanceType ] ?? 0n )
59- )
60- } )
61- . filter ( k => ( token . balancePerType [ k as XChainBalanceType ] ?? 0 ) > 0 )
62- }
63- return [ ]
64- } , [ token ] )
65-
6628 const getBalanceAndAssetName = useCallback (
6729 ( item : string ) => {
6830 const balance =
@@ -82,129 +44,153 @@ const TokenDetail: FC<Props> = ({ token }): React.JSX.Element => {
8244 [ token ]
8345 )
8446
47+ const data = useMemo ( ( ) => {
48+ const isPChainToken = token && isTokenWithBalancePVM ( token )
49+ const isXChainToken = token && isTokenWithBalanceAVM ( token )
50+
51+ if ( isPChainToken ) {
52+ return [
53+ ...Object . keys ( token . balancePerType ) . sort ( ( a , b ) => {
54+ return Number (
55+ ( token . balancePerType [ b as PChainBalanceType ] ?? 0n ) -
56+ ( token . balancePerType [ a as PChainBalanceType ] ?? 0n )
57+ )
58+ } ) ,
59+ 'Total'
60+ ]
61+ }
62+
63+ if ( isXChainToken ) {
64+ return [
65+ ...Object . keys ( token . balancePerType ) . sort ( ( a , b ) => {
66+ return Number (
67+ ( token . balancePerType [ b as XChainBalanceType ] ?? 0n ) -
68+ ( token . balancePerType [ a as XChainBalanceType ] ?? 0n )
69+ )
70+ } ) ,
71+ 'Total'
72+ ]
73+ }
74+ return [ ]
75+ } , [ token ] )
76+
77+ const totalBalance = useMemo ( ( ) => {
78+ return data
79+ . filter ( item => item !== 'Total' )
80+ . reduce ( ( acc , item ) => {
81+ const { balance } = getBalanceAndAssetName ( item )
82+ if ( balance ) {
83+ const balanceUnit = new TokenUnit (
84+ balance ,
85+ xpChainToken . maxDecimals ,
86+ xpChainToken . symbol
87+ )
88+ return acc . add ( balanceUnit )
89+ }
90+ return acc
91+ } , new TokenUnit ( 0n , xpChainToken . maxDecimals , xpChainToken . symbol ) )
92+ } , [ data , getBalanceAndAssetName ] )
93+
8594 const renderItem = useCallback (
86- ( { item } : { item : string } ) : React . JSX . Element => {
95+ ( { item, index } : { item : string ; index : number } ) : React . JSX . Element => {
8796 const { balance, assetName } = getBalanceAndAssetName ( item )
8897
8998 const balanceInAvax = balance
9099 ? new TokenUnit ( balance , xpChainToken . maxDecimals , xpChainToken . symbol )
91100 : undefined
101+
102+ const formattedBalanceInAvax =
103+ balanceInAvax ?. toDisplay ( {
104+ fixedDp : 2 ,
105+ asNumber : true
106+ } ) ?? 0
107+
92108 const formattedBalance =
93- balanceInAvax && token ?. priceInCurrency
94- ? formatCurrency ( {
95- amount : balanceInAvax
96- . mul ( token . priceInCurrency )
97- . toDisplay ( { fixedDp : 2 , asNumber : true } )
98- } )
99- : UNKNOWN_AMOUNT
109+ totalBalance ?. toDisplay ( {
110+ fixedDp : 2 ,
111+ asNumber : true
112+ } ) ?? 0
113+
114+ const title = item === 'Total' ? 'Total balance' : assetName
115+ const value = item === 'Total' ? formattedBalance : formattedBalanceInAvax
116+ const isFirst = index === 0
117+ const isLast = index === data . length - 1
100118
101- const isAvailableBalanceType =
102- item === 'unlockedUnstaked' || item === 'unlocked'
119+ const containerSx = {
120+ paddingHorizontal : 16 ,
121+ backgroundColor : '$surfaceSecondary' ,
122+ ...( isFirst && { borderTopLeftRadius : 16 , borderTopRightRadius : 16 } ) ,
123+ ...( isLast && {
124+ borderBottomLeftRadius : 16 ,
125+ borderBottomRightRadius : 16
126+ } )
127+ }
103128
104129 return (
105- < View
106- sx = { {
107- borderRadius : 18 ,
108- paddingLeft : 16 ,
109- paddingRight : 12 ,
110- paddingVertical : 12 ,
111- flexDirection : 'row' ,
112- alignItems : 'center' ,
113- backgroundColor : '$surfaceSecondary' ,
114- marginBottom : 12
115- } } >
116- { token && isAvailableBalanceType ? (
117- < LogoWithNetwork
118- token = { token }
119- outerBorderColor = { colors . $surfaceSecondary }
120- />
121- ) : (
122- < View
123- sx = { {
124- width : 36 ,
125- height : 36 ,
126- borderRadius : 18 ,
127- justifyContent : 'center' ,
128- alignItems : 'center' ,
129- overflow : 'hidden' ,
130- backgroundColor : '$borderPrimary' ,
131- borderColor : '$borderPrimary'
132- } } >
133- < Icons . Custom . Psychiatry
134- width = { 24 }
135- height = { 24 }
136- color = { colors . $textPrimary }
137- />
138- </ View >
139- ) }
130+ < View sx = { containerSx } >
140131 < View
141132 sx = { {
142- flexGrow : 1 ,
143- marginHorizontal : 12 ,
133+ borderBottomWidth : isLast ? 0 : 1 ,
134+ borderBottomColor : '$borderPrimary' ,
144135 flexDirection : 'row' ,
145- justifyContent : 'space-between'
136+ justifyContent : 'space-between' ,
137+ alignItems : 'center' ,
138+ height : 48
146139 } } >
147- < View
140+ < Text variant = "subtitle2" numberOfLines = { 1 } sx = { { fontSize : 16 } } >
141+ { title }
142+ </ Text >
143+ < BalanceText
144+ variant = "subtitle2"
145+ numberOfLines = { 1 }
148146 sx = { {
149- flexShrink : 1
147+ color : '$textSecondary' ,
148+ fontSize : 16
150149 } } >
151- < Text variant = "buttonMedium" numberOfLines = { 1 } sx = { { flex : 1 } } >
152- { assetName }
153- </ Text >
154- < BalanceText
155- variant = "body2"
156- sx = { { lineHeight : 16 , flex : 1 } }
157- ellipsizeMode = "tail"
158- isCurrency = { false }
159- maskType = "covered"
160- numberOfLines = { 1 } >
161- { balanceInAvax ?. toDisplay ( ) } { xpChainToken . symbol }
162- </ BalanceText >
163- </ View >
164- < View sx = { { flexDirection : 'row' , alignItems : 'center' , gap : 4 } } >
165- < BalanceText
166- variant = "buttonMedium"
167- numberOfLines = { 1 }
168- sx = { { lineHeight : 18 , marginBottom : 1 } } >
169- { formattedBalance }
170- </ BalanceText >
171- </ View >
150+ { value } { xpChainToken . symbol }
151+ </ BalanceText >
172152 </ View >
173153 </ View >
174154 )
175155 } ,
176- [
177- colors . $textPrimary ,
178- colors . $surfaceSecondary ,
179- getBalanceAndAssetName ,
180- token ,
181- formatCurrency
182- ]
156+ [ getBalanceAndAssetName , totalBalance , data . length ]
183157 )
184158
185- const renderHeader = ( ) : JSX . Element => {
186- return (
187- < Text variant = "heading3" sx = { { marginBottom : 12 } } >
188- Token breakdown
189- </ Text >
190- )
191- }
159+ const renderHeader = useCallback ( ( ) : JSX . Element => {
160+ return < > </ >
161+
162+ // TODO: Add after ledger is implemented
163+ // return (
164+ // <View sx={{ marginTop: 8 }}>
165+ // <GroupList
166+ // data={[
167+ // {
168+ // title:
169+ // 'UTXOs across multiple addresses. View all of your balances and UTXOs',
170+ // leftIcon: <Icons.Action.Info color={colors.$textPrimary} />,
171+ // onPress: () => {
172+ // // console.log('info')
173+ // }
174+ // }
175+ // ]}
176+ // />
177+ // </View>
178+ // )
179+ } , [ ] )
192180
193181 return (
194182 < Animated . View
195183 entering = { getListItemEnteringAnimation ( 5 ) }
196184 layout = { SPRING_LINEAR_TRANSITION } >
197185 < CollapsibleTabs . FlatList
198- style = { {
199- paddingTop : 4
200- } }
201186 contentContainerStyle = { {
202187 paddingHorizontal : 16 ,
203- paddingBottom : 16
188+ paddingBottom : 16 ,
189+ paddingTop : 12
204190 } }
205- data = { assetTypes }
191+ data = { data }
192+ ListHeaderComponent = { renderHeader }
206193 renderItem = { renderItem }
207- ListHeaderComponent = { renderHeader ( ) }
208194 showsVerticalScrollIndicator = { false }
209195 keyExtractor = { item => item }
210196 />
0 commit comments