@@ -2,12 +2,15 @@ package com.gemwallet.features.asset.presents.chart
22
33import androidx.compose.foundation.clickable
44import androidx.compose.foundation.combinedClickable
5+ import androidx.compose.foundation.layout.Column
6+ import androidx.compose.foundation.layout.defaultMinSize
57import androidx.compose.foundation.layout.padding
68import androidx.compose.foundation.lazy.LazyColumn
79import androidx.compose.foundation.lazy.LazyListScope
810import androidx.compose.foundation.lazy.itemsIndexed
911import androidx.compose.runtime.Composable
1012import androidx.compose.runtime.getValue
13+ import androidx.compose.ui.Alignment
1114import androidx.compose.ui.Modifier
1215import androidx.compose.ui.platform.LocalClipboard
1316import androidx.compose.ui.platform.LocalContext
@@ -18,21 +21,29 @@ import androidx.compose.ui.unit.dp
1821import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
1922import androidx.lifecycle.compose.collectAsStateWithLifecycle
2023import com.gemwallet.android.domains.asset.chain
24+ import com.gemwallet.android.domains.percentage.formatAsPercentage
25+ import com.gemwallet.android.domains.price.getPriceState
2126import com.gemwallet.android.model.compactFormatter
2227import com.gemwallet.android.ui.R
2328import com.gemwallet.android.ui.components.clipboard.setPlainText
2429import com.gemwallet.android.ui.components.image.AsyncImage
2530import com.gemwallet.android.ui.components.list_item.Badge
31+ import com.gemwallet.android.ui.components.list_item.ListItem
32+ import com.gemwallet.android.ui.components.list_item.ListItemSupportText
33+ import com.gemwallet.android.ui.components.list_item.ListItemTitleText
2634import com.gemwallet.android.ui.components.list_item.SubheaderItem
35+ import com.gemwallet.android.ui.components.list_item.color
2736import com.gemwallet.android.ui.components.list_item.property.DataBadgeChevron
2837import com.gemwallet.android.ui.components.list_item.property.PropertyDataText
2938import com.gemwallet.android.ui.components.list_item.property.PropertyItem
3039import com.gemwallet.android.ui.components.list_item.property.PropertyTitleText
40+ import com.gemwallet.android.ui.components.list_item.property.itemsPositioned
3141import com.gemwallet.android.ui.components.screen.LoadingScene
3242import com.gemwallet.android.ui.components.screen.Scene
3343import com.gemwallet.android.ui.models.ListPosition
3444import com.gemwallet.android.ui.open
3545import com.gemwallet.android.ui.theme.trailingIconMedium
46+ import com.gemwallet.features.asset.viewmodels.chart.models.AllTimeUIModel
3647import com.gemwallet.features.asset.viewmodels.chart.models.AssetMarketUIModel
3748import com.gemwallet.features.asset.viewmodels.chart.models.MarketInfoUIModel
3849import com.gemwallet.features.asset.viewmodels.chart.viewmodels.AssetChartViewModel
@@ -41,6 +52,8 @@ import com.wallet.core.primitives.AssetId
4152import com.wallet.core.primitives.AssetMarket
4253import com.wallet.core.primitives.Currency
4354import uniffi.gemstone.Explorer
55+ import java.text.DateFormat
56+ import java.util.Date
4457
4558@Composable
4659fun AssetChartScene (
@@ -109,47 +122,89 @@ private fun LazyListScope.links(links: List<AssetMarketUIModel.Link>) {
109122}
110123
111124private fun LazyListScope.assetMarket (currency : Currency , asset : Asset , marketInfo : AssetMarket ? , explorerName : String ) {
112- val items = marketInfo?.let {
113- mutableListOf<MarketInfoUIModel >().apply {
114- it.marketCap?.let {
115- add(
116- MarketInfoUIModel (
117- type = MarketInfoUIModel .MarketInfoTypeUIModel .MarketCap ,
118- value = currency.compactFormatter(it),
119- badge = marketInfo.marketCapRank?.takeIf { it > 0 }
120- .let { " #${marketInfo.marketCapRank} " }
121- )
125+ marketInfo ? : return
126+ val marketItems = mutableListOf<MarketInfoUIModel >().apply {
127+ marketInfo.marketCap?.let {
128+ add(
129+ MarketInfoUIModel (
130+ type = MarketInfoUIModel .MarketInfoTypeUIModel .MarketCap ,
131+ value = currency.compactFormatter(it),
132+ badge = marketInfo.marketCapRank?.takeIf { it > 0 }
133+ .let { " #${marketInfo.marketCapRank} " }
122134 )
123- }
124- it.circulatingSupply?. let {
125- add(
126- MarketInfoUIModel (
127- type = MarketInfoUIModel . MarketInfoTypeUIModel . CirculatingSupply ,
128- value = currency.compactFormatter(it) ,
129- )
135+ )
136+ }
137+ marketInfo.marketCapFdv?. let {
138+ add (
139+ MarketInfoUIModel (
140+ type = MarketInfoUIModel . MarketInfoTypeUIModel . FDV ,
141+ value = currency.compactFormatter(it),
130142 )
131- }
132- it.totalSupply?.let {
133- add(
134- MarketInfoUIModel (
135- type = MarketInfoUIModel .MarketInfoTypeUIModel .TotalSupply ,
136- value = currency.compactFormatter(it),
137- )
143+ )
144+ }
145+ }
146+
147+ val supplyItems = mutableListOf<MarketInfoUIModel >().apply {
148+ marketInfo.circulatingSupply?.let {
149+ add(
150+ MarketInfoUIModel (
151+ type = MarketInfoUIModel .MarketInfoTypeUIModel .CirculatingSupply ,
152+ value = currency.compactFormatter(it),
138153 )
139- }
140- asset.id.tokenId?. let {
141- add(
142- MarketInfoUIModel (
143- type = MarketInfoUIModel . MarketInfoTypeUIModel . Contract ,
144- value = it ,
145- )
154+ )
155+ }
156+ marketInfo.totalSupply?. let {
157+ add (
158+ MarketInfoUIModel (
159+ type = MarketInfoUIModel . MarketInfoTypeUIModel . TotalSupply ,
160+ value = currency.compactFormatter(it),
146161 )
147- }
162+ )
163+ }
164+
165+ marketInfo.maxSupply?.let {
166+ add(
167+ MarketInfoUIModel (
168+ type = MarketInfoUIModel .MarketInfoTypeUIModel .MaxSupply ,
169+ value = currency.compactFormatter(it),
170+ )
171+ )
148172 }
149- } ? : emptyList()
150- itemsIndexed(items) { index, item ->
151- val position = ListPosition .getPosition(index, items.size)
173+ asset.id.tokenId?.let {
174+ add(
175+ MarketInfoUIModel (
176+ type = MarketInfoUIModel .MarketInfoTypeUIModel .Contract ,
177+ value = it,
178+ )
179+ )
180+ }
181+ }
182+
183+ val allTime = mutableListOf<AllTimeUIModel >().apply {
184+ if (marketInfo.allTimeHigh != null && marketInfo.allTimeHighDate != null && marketInfo.allTimeHighChangePercentage != null ) {
185+ add(
186+ AllTimeUIModel .High (marketInfo.allTimeHighDate!! , marketInfo.allTimeHigh!! , marketInfo.allTimeHighChangePercentage!! )
187+ )
188+ }
189+ if (marketInfo.allTimeLow != null && marketInfo.allTimeLowDate != null && marketInfo.allTimeLowChangePercentage != null ) {
190+ add(
191+ AllTimeUIModel .Low (marketInfo.allTimeLowDate!! , marketInfo.allTimeLow!! , marketInfo.allTimeLowChangePercentage!! )
192+ )
193+ }
194+ }
195+
196+ marketProperties(asset, explorerName, marketItems)
197+ marketProperties(asset, explorerName, supplyItems)
198+ allTimeProperties(asset, currency, allTime)
199+ }
200+
201+ private fun LazyListScope.marketProperties (asset : Asset , explorerName : String , items : List <MarketInfoUIModel >) {
202+ itemsPositioned(items) { position, item ->
152203 when (item.type) {
204+ MarketInfoUIModel .MarketInfoTypeUIModel .FDV ,
205+ MarketInfoUIModel .MarketInfoTypeUIModel .CirculatingSupply ,
206+ MarketInfoUIModel .MarketInfoTypeUIModel .TotalSupply ,
207+ MarketInfoUIModel .MarketInfoTypeUIModel .MaxSupply -> PropertyItem (item.type.label, item.value, listPosition = position)
153208 MarketInfoUIModel .MarketInfoTypeUIModel .MarketCap -> PropertyItem (
154209 title = {
155210 PropertyTitleText (
@@ -160,8 +215,6 @@ private fun LazyListScope.assetMarket(currency: Currency, asset: Asset, marketIn
160215 data = { PropertyDataText (item.value) },
161216 listPosition = position
162217 )
163- MarketInfoUIModel .MarketInfoTypeUIModel .CirculatingSupply -> PropertyItem (item.type.label, item.value, listPosition = position)
164- MarketInfoUIModel .MarketInfoTypeUIModel .TotalSupply -> PropertyItem (item.type.label, item.value, listPosition = position)
165218 MarketInfoUIModel .MarketInfoTypeUIModel .Contract -> {
166219 val context = LocalContext .current
167220 val clipboardManager = LocalClipboard .current.nativeClipboard
@@ -178,7 +231,9 @@ private fun LazyListScope.assetMarket(currency: Currency, asset: Asset, marketIn
178231 title = { PropertyTitleText (R .string.asset_contract) },
179232 data = {
180233 PropertyDataText (
181- modifier = Modifier .weight(1f ).padding(top = 0 .dp, bottom = 2 .dp),
234+ modifier = Modifier
235+ .weight(1f )
236+ .padding(top = 0 .dp, bottom = 2 .dp),
182237 text = item.value,
183238 )
184239 },
@@ -187,4 +242,30 @@ private fun LazyListScope.assetMarket(currency: Currency, asset: Asset, marketIn
187242 }
188243 }
189244 }
245+ }
246+
247+ private fun LazyListScope.allTimeProperties (asset : Asset , currency : Currency , items : List <AllTimeUIModel >) {
248+ val dateFormat = DateFormat .getDateInstance(DateFormat .MEDIUM )
249+
250+ itemsPositioned(items) { position, item ->
251+ val title = when (item) {
252+ is AllTimeUIModel .High -> R .string.asset_all_time_high
253+ is AllTimeUIModel .Low -> R .string.asset_all_time_low
254+ }
255+ ListItem (
256+ listPosition = position,
257+ title = @Composable { ListItemTitleText (stringResource(title)) },
258+ subtitle = { ListItemSupportText (dateFormat.format(Date (item.date))) },
259+ trailing = {
260+ Column (
261+ modifier = Modifier .defaultMinSize(40 .dp),
262+ horizontalAlignment = Alignment .End
263+ ) {
264+ ListItemTitleText (currency.compactFormatter(item.value))
265+ ListItemSupportText (item.percentage.formatAsPercentage(), color = item.percentage.getPriceState().color())
266+ }
267+ },
268+ )
269+ }
270+
190271}
0 commit comments