@@ -36,65 +36,108 @@ export const SelectAssetModal = ({
3636
3737 const [ filter , setFilter ] = useState ( "" ) ;
3838
39- const filteredAssets = useMemo ( ( ) => {
40- return assets . filter (
39+ const { assetsWithBalance , assetsWithoutBalance } = useMemo ( ( ) => {
40+ const filtered = assets . filter (
4141 ( asset ) =>
4242 asset . name . toLowerCase ( ) . indexOf ( filter . toLowerCase ( ) ) >= 0 ||
4343 asset . symbol . toLowerCase ( ) . indexOf ( filter . toLowerCase ( ) ) >= 0
4444 ) ;
45- } , [ assets , filter ] ) ;
45+
46+ const withBalance : Asset [ ] = [ ] ;
47+ const withoutBalance : Asset [ ] = [ ] ;
48+
49+ filtered . forEach ( ( asset ) => {
50+ const tokenAddress =
51+ ibcTransfer === "deposit" ? asset . base : ( asset as NamadaAsset ) . address ;
52+
53+ const balance = balances ?. [ tokenAddress ] ;
54+ const hasBalance = balance && balance [ 0 ] . gt ( 0 ) ;
55+
56+ if ( hasBalance ) {
57+ withBalance . push ( asset ) ;
58+ } else {
59+ withoutBalance . push ( asset ) ;
60+ }
61+ } ) ;
62+
63+ return {
64+ assetsWithBalance : withBalance ,
65+ assetsWithoutBalance : withoutBalance ,
66+ } ;
67+ } , [ assets , filter , balances , ibcTransfer ] ) ;
68+
69+ const renderAssetItem = ( asset : Asset ) : JSX . Element => {
70+ // Fpr IbcTransfer(Deposits), we consider base denom as a token address.
71+ const tokenAddress =
72+ ibcTransfer === "deposit" ? asset . base : ( asset as NamadaAsset ) . address ;
73+
74+ const disabled =
75+ ! namTransfersEnabled && asset . address === nativeTokenAddress ;
76+
77+ return (
78+ < li key = { asset . base } className = "text-sm" >
79+ < button
80+ onClick = { ( ) => {
81+ onSelect ( tokenAddress ) ;
82+ onClose ( ) ;
83+ } }
84+ className = { twMerge (
85+ clsx (
86+ "text-left px-4 py-2.5" ,
87+ "w-full rounded-sm border border-transparent" ,
88+ "hover:border-neutral-400 transition-colors duration-150" ,
89+ { "pointer-events-none opacity-50" : disabled }
90+ )
91+ ) }
92+ disabled = { disabled }
93+ >
94+ < TokenCard
95+ asset = { asset }
96+ address = { tokenAddress }
97+ disabled = { disabled }
98+ balance = { balances ?. [ tokenAddress ] }
99+ />
100+ </ button >
101+ </ li >
102+ ) ;
103+ } ;
104+
105+ const hasAnyAssets =
106+ assetsWithBalance . length > 0 || assetsWithoutBalance . length > 0 ;
46107
47108 return (
48109 < SelectModal title = "Select Asset" onClose = { onClose } >
49110 < ConnectedWalletInfo walletAddress = { walletAddress } />
50111 < div className = "my-4" >
51112 < Search placeholder = "Search asset" onChange = { setFilter } />
52113 </ div >
53- < Stack
54- as = "ul"
55- gap = { 0 }
56- className = "max-h-[400px] overflow-auto dark-scrollbar pb-4 mr-[-0.5rem]"
57- >
58- { filteredAssets . map ( ( asset ) => {
59- // Fpr IbcTransfer(Deposits), we consider base denom as a token address.
60- const tokenAddress =
61- ibcTransfer === "deposit" ?
62- asset . base
63- : ( asset as NamadaAsset ) . address ;
64-
65- const disabled =
66- ! namTransfersEnabled && asset . address === nativeTokenAddress ;
67- return (
68- < li key = { asset . base } className = "text-sm" >
69- < button
70- onClick = { ( ) => {
71- onSelect ( tokenAddress ) ;
72- onClose ( ) ;
73- } }
74- className = { twMerge (
75- clsx (
76- "text-left px-4 py-2.5" ,
77- "w-full rounded-sm border border-transparent" ,
78- "hover:border-neutral-400 transition-colors duration-150" ,
79- { "pointer-events-none opacity-50" : disabled }
80- )
81- ) }
82- disabled = { disabled }
83- >
84- < TokenCard
85- asset = { asset }
86- address = { tokenAddress }
87- disabled = { disabled }
88- balance = { balances ?. [ tokenAddress ] }
89- />
90- </ button >
91- </ li >
92- ) ;
93- } ) }
94- { filteredAssets . length === 0 && (
95- < p className = "py-2 font-light" > There are no available assets</ p >
114+ < div className = "max-h-[400px] overflow-auto dark-scrollbar pb-4 mr-[-0.5rem]" >
115+ { assetsWithBalance . length > 0 && (
116+ < >
117+ < h3 className = "text-xs font-medium text-neutral-500 px-4 py-2 uppercase tracking-wide" >
118+ Your tokens
119+ </ h3 >
120+ < Stack as = "ul" gap = { 0 } >
121+ { assetsWithBalance . map ( renderAssetItem ) }
122+ </ Stack >
123+ </ >
124+ ) }
125+
126+ { assetsWithoutBalance . length > 0 && (
127+ < >
128+ < h3 className = "text-xs font-medium text-neutral-500 px-4 py-2 mt-4 uppercase tracking-wide" >
129+ All tokens
130+ </ h3 >
131+ < Stack as = "ul" gap = { 0 } >
132+ { assetsWithoutBalance . map ( renderAssetItem ) }
133+ </ Stack >
134+ </ >
96135 ) }
97- </ Stack >
136+
137+ { ! hasAnyAssets && (
138+ < p className = "py-2 px-4 font-light" > There are no available assets</ p >
139+ ) }
140+ </ div >
98141 </ SelectModal >
99142 ) ;
100143} ;
0 commit comments