Skip to content
This repository was archived by the owner on Mar 26, 2026. It is now read-only.

Commit e1e4b1a

Browse files
committed
update
1 parent 7355b1a commit e1e4b1a

20 files changed

Lines changed: 251 additions & 217 deletions

File tree

data/coordinators/src/androidTest/kotlin/com/gemwallet/android/data/coordinates/perpetuals/GetPerpetualsImplTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ class GetPerpetualsImplTest {
5656
fun testGetPerpetuals_Formatting() = runBlocking {
5757
val result = getPerpetualsImpl.getPerpetuals(null).first()
5858
val item = result[0]
59-
assertEquals("\$95,420.50", item.price.priceValueFormated)
60-
assertEquals("+2.50%", item.price.dayChangePercentageFormatted)
59+
assertEquals("\$95,420.50", item.price.valueFormated)
60+
assertEquals("+2.50%", item.price.changePercentageFormatted)
6161
assertEquals(PriceState.Up, item.price.state)
6262
assertEquals("\$15.00B", item.volume)
6363
}

data/coordinators/src/main/kotlin/com/gemwallet/android/data/coordinates/asset/GetActiveAssetsInfoImpl.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import com.gemwallet.android.data.repositoreis.assets.AssetsRepository
66
import com.gemwallet.android.domains.asset.aggregates.AssetInfoDataAggregate
77
import com.gemwallet.android.domains.asset.getIconUrl
88
import com.gemwallet.android.domains.asset.getSupportIconUrl
9-
import com.gemwallet.android.domains.price.values.PriceableValue
9+
import com.gemwallet.android.domains.price.values.EquivalentValue
1010
import com.gemwallet.android.model.AssetInfo
1111
import com.gemwallet.android.model.format
1212
import com.wallet.core.primitives.AssetId
@@ -55,12 +55,12 @@ class AssetInfoDataAggregateImpl(
5555
override val isZeroBalance: Boolean
5656
get() = assetInfo.balance.totalAmount == 0.0
5757

58-
override val price: PriceableValue?
58+
override val price: EquivalentValue?
5959
get() = assetInfo.price?.price?.let {
60-
PriceableValueImpl(
60+
EquivalentValueImpl(
6161
currency = currency,
62-
priceValue = it.price,
63-
dayChangePercentage = it.priceChangePercentage24h,
62+
value = it.price,
63+
changePercentage = it.priceChangePercentage24h,
6464
)
6565
}
6666

@@ -75,9 +75,9 @@ class AssetInfoDataAggregateImpl(
7575

7676
private val currency: Currency = assetInfo.price?.currency ?: Currency.USD
7777

78-
private class PriceableValueImpl(
78+
private class EquivalentValueImpl(
7979
override val currency: Currency,
80-
override val priceValue: Double?,
81-
override val dayChangePercentage: Double?
82-
) : PriceableValue
80+
override val value: Double?,
81+
override val changePercentage: Double?
82+
) : EquivalentValue
8383
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package com.gemwallet.android.data.coordinates.asset
2+
3+
import com.gemwallet.android.application.assets.coordinators.GetWalletSummary
4+
import com.gemwallet.android.cases.banners.HasMultiSign
5+
import com.gemwallet.android.data.repositoreis.assets.AssetsRepository
6+
import com.gemwallet.android.data.repositoreis.config.UserConfig
7+
import com.gemwallet.android.data.repositoreis.session.SessionRepository
8+
import com.gemwallet.android.domains.price.values.EquivalentValue
9+
import com.gemwallet.android.domains.wallet.aggregates.WalletSummaryAggregate
10+
import com.gemwallet.android.ext.asset
11+
import com.gemwallet.android.ext.isSwapSupport
12+
import com.gemwallet.android.model.format
13+
import com.wallet.core.primitives.Currency
14+
import com.wallet.core.primitives.WalletType
15+
import kotlinx.coroutines.ExperimentalCoroutinesApi
16+
import kotlinx.coroutines.flow.Flow
17+
import kotlinx.coroutines.flow.combine
18+
import kotlinx.coroutines.flow.filterNotNull
19+
import kotlinx.coroutines.flow.flatMapLatest
20+
import java.math.BigDecimal
21+
22+
@OptIn(ExperimentalCoroutinesApi::class)
23+
class GetWalletSummaryImpl(
24+
private val sessionRepository: SessionRepository,
25+
private val assetsRepository: AssetsRepository,
26+
private val hasMultiSign: HasMultiSign,
27+
private val userConfig: UserConfig,
28+
) : GetWalletSummary {
29+
30+
override fun getWalletSummary(): Flow<WalletSummaryAggregate?> {
31+
return combine(
32+
sessionRepository.session(),
33+
assetsRepository.getAssetsInfo(),
34+
sessionRepository.session().filterNotNull().flatMapLatest { hasMultiSign.hasMultiSign(it.wallet) },
35+
userConfig.isHideBalances(),
36+
) { session, assets, hasMultiSign, hideBalances ->
37+
val wallet = session?.wallet ?: return@combine null
38+
val currency = session.currency
39+
40+
val (totalValue, changedValue) = assets.map {
41+
val current = it.balance.fiatTotalAmount.toBigDecimal()
42+
val changed = current * ((it.price?.price?.priceChangePercentage24h ?: 0.0) / 100).toBigDecimal()
43+
Pair(current, changed)
44+
}.fold(Pair(BigDecimal.ZERO, BigDecimal.ZERO)) { acc, pair ->
45+
Pair(acc.first + pair.first, acc.second + pair.second)
46+
}
47+
val changedPercentages = (changedValue.toDouble() / (totalValue.toDouble() / 100.0)).let {
48+
if (it.isNaN()) 0.0 else it
49+
}
50+
val icon = when (wallet.type) {
51+
WalletType.Multicoin -> null
52+
else -> wallet.accounts.firstOrNull()?.chain?.asset()
53+
}
54+
55+
val isSwapEnabled = when (wallet.type) {
56+
WalletType.Multicoin -> true
57+
WalletType.Single,
58+
WalletType.PrivateKey -> wallet.accounts.firstOrNull()?.chain?.isSwapSupport() == true
59+
WalletType.View -> false
60+
}
61+
62+
WalletSummaryAggregateImpl(
63+
walletType = wallet.type,
64+
walletName = wallet.name,
65+
walletIcon = icon,
66+
walletTotalValue = if (hideBalances) "✱✱✱✱✱✱" else currency.format(totalValue, dynamicPlace = true),
67+
changedValue = if (hideBalances) null else object : EquivalentValue {
68+
override val currency: Currency = currency
69+
override val value: Double = changedValue.toDouble()
70+
override val changePercentage: Double = changedPercentages
71+
72+
},
73+
isOperationsAvailable = !hasMultiSign,
74+
isSwapAvailable = isSwapEnabled,
75+
)
76+
}
77+
}
78+
}
79+
80+
class WalletSummaryAggregateImpl(
81+
override val walletType: WalletType,
82+
override val walletName: String,
83+
override val walletIcon: Any?,
84+
override val walletTotalValue: String,
85+
override val changedValue: EquivalentValue?,
86+
override val isOperationsAvailable: Boolean,
87+
override val isSwapAvailable: Boolean,
88+
) : WalletSummaryAggregate

data/coordinators/src/main/kotlin/com/gemwallet/android/data/coordinates/di/AssetModule.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
package com.gemwallet.android.data.coordinates.di
22

33
import com.gemwallet.android.application.assets.coordinators.GetActiveAssetsInfo
4+
import com.gemwallet.android.application.assets.coordinators.GetWalletSummary
5+
import com.gemwallet.android.cases.banners.HasMultiSign
46
import com.gemwallet.android.data.coordinates.asset.GetActiveAssetsInfoImpl
7+
import com.gemwallet.android.data.coordinates.asset.GetWalletSummaryImpl
58
import com.gemwallet.android.data.repositoreis.assets.AssetsRepository
9+
import com.gemwallet.android.data.repositoreis.config.UserConfig
10+
import com.gemwallet.android.data.repositoreis.session.SessionRepository
611
import dagger.Module
712
import dagger.Provides
813
import dagger.hilt.InstallIn
@@ -16,4 +21,18 @@ object AssetModule {
1621
@Singleton
1722
fun provideGetActiveAssetsInfo(assetsRepository: AssetsRepository): GetActiveAssetsInfo =
1823
GetActiveAssetsInfoImpl(assetsRepository)
24+
25+
@Provides
26+
@Singleton
27+
fun provideGetWalletSummary(
28+
sessionRepository: SessionRepository,
29+
assetsRepository: AssetsRepository,
30+
hasMultiSign: HasMultiSign,
31+
userConfig: UserConfig,
32+
): GetWalletSummary = GetWalletSummaryImpl(
33+
sessionRepository = sessionRepository,
34+
assetsRepository = assetsRepository,
35+
hasMultiSign = hasMultiSign,
36+
userConfig = userConfig,
37+
)
1938
}

data/coordinators/src/main/kotlin/com/gemwallet/android/data/coordinates/perpetuals/GetPerpetualsImpl.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package com.gemwallet.android.data.coordinates.perpetuals
22

33
import com.gemwallet.android.application.perpetual.coordinators.GetPerpetuals
44
import com.gemwallet.android.data.repositoreis.perpetual.PerpetualRepository
5-
import com.gemwallet.android.domains.price.values.PriceableValue
5+
import com.gemwallet.android.domains.price.values.EquivalentValue
66
import com.gemwallet.android.model.compactFormatter
77
import com.wallet.core.primitives.Asset
88
import com.wallet.core.primitives.Currency
@@ -22,10 +22,10 @@ class GetPerpetualsImpl @Inject constructor(
2222

2323
class PerpetualDataAggregate(
2424
val data: PerpetualData,
25-
override val price: PriceableValue = object : PriceableValue { // TODO: ???
26-
override val priceValue: Double = data.perpetual.price
25+
override val price: EquivalentValue = object : EquivalentValue { // TODO: ???
26+
override val value: Double = data.perpetual.price
2727
override val currency: Currency = Currency.USD
28-
override val dayChangePercentage: Double = data.perpetual.pricePercentChange24h
28+
override val changePercentage: Double = data.perpetual.pricePercentChange24h
2929
}
3030
) : com.gemwallet.android.domains.perpetual.aggregates.PerpetualDataAggregate {
3131

data/coordinators/src/test/kotlin/com/gemwallet/android/data/coordinates/asset/AssetInfoDataAggregateImplTest.kt

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,10 @@ class AssetInfoDataAggregateImplTest {
168168

169169
assertNotNull(aggregate.price)
170170
assertEquals(Currency.USD, aggregate.price?.currency)
171-
assertEquals(50000.0, aggregate.price?.priceValue)
172-
assertEquals("\$50,000.00", aggregate.price?.priceValueFormated)
173-
assertEquals(-5.000002, aggregate.price?.dayChangePercentage)
174-
assertEquals("-5.00%", aggregate.price?.dayChangePercentageFormatted)
171+
assertEquals(50000.0, aggregate.price?.value)
172+
assertEquals("\$50,000.00", aggregate.price?.valueFormated)
173+
assertEquals(-5.000002, aggregate.price?.changePercentage)
174+
assertEquals("-5.00%", aggregate.price?.changePercentageFormatted)
175175
assertEquals(PriceState.Down, aggregate.price?.state)
176176
}
177177

@@ -183,8 +183,8 @@ class AssetInfoDataAggregateImplTest {
183183
)
184184
val aggregate = AssetInfoDataAggregateImpl(assetInfo, hideBalance = false)
185185

186-
assertEquals(-0.000006, aggregate.price?.dayChangePercentage)
187-
assertEquals("0.00%", aggregate.price?.dayChangePercentageFormatted)
186+
assertEquals(-0.000006, aggregate.price?.changePercentage)
187+
assertEquals("0.00%", aggregate.price?.changePercentageFormatted)
188188
assertEquals(PriceState.None, aggregate.price?.state)
189189
}
190190

@@ -196,8 +196,8 @@ class AssetInfoDataAggregateImplTest {
196196
)
197197
val aggregate = AssetInfoDataAggregateImpl(assetInfo, hideBalance = false)
198198

199-
assertEquals(0.000006, aggregate.price?.dayChangePercentage)
200-
assertEquals("0.00%", aggregate.price?.dayChangePercentageFormatted)
199+
assertEquals(0.000006, aggregate.price?.changePercentage)
200+
assertEquals("0.00%", aggregate.price?.changePercentageFormatted)
201201
assertEquals(PriceState.None, aggregate.price?.state)
202202
}
203203

@@ -211,7 +211,7 @@ class AssetInfoDataAggregateImplTest {
211211
),
212212
hideBalance = false
213213
).let { aggregate ->
214-
assertEquals("-0.06%", aggregate.price?.dayChangePercentageFormatted)
214+
assertEquals("-0.06%", aggregate.price?.changePercentageFormatted)
215215
assertEquals(PriceState.Down, aggregate.price?.state)
216216
}
217217
AssetInfoDataAggregateImpl(
@@ -221,7 +221,7 @@ class AssetInfoDataAggregateImplTest {
221221
),
222222
hideBalance = false
223223
).let { aggregate ->
224-
assertEquals("-0.02%", aggregate.price?.dayChangePercentageFormatted)
224+
assertEquals("-0.02%", aggregate.price?.changePercentageFormatted)
225225
assertEquals(PriceState.Down, aggregate.price?.state)
226226
}
227227

@@ -232,7 +232,7 @@ class AssetInfoDataAggregateImplTest {
232232
),
233233
hideBalance = false
234234
).let { aggregate ->
235-
assertEquals("+0.06%", aggregate.price?.dayChangePercentageFormatted)
235+
assertEquals("+0.06%", aggregate.price?.changePercentageFormatted)
236236
assertEquals(PriceState.Up, aggregate.price?.state)
237237
}
238238

@@ -243,7 +243,7 @@ class AssetInfoDataAggregateImplTest {
243243
),
244244
hideBalance = false
245245
).let { aggregate ->
246-
assertEquals("+0.02%", aggregate.price?.dayChangePercentageFormatted)
246+
assertEquals("+0.02%", aggregate.price?.changePercentageFormatted)
247247
assertEquals(PriceState.Up, aggregate.price?.state)
248248
}
249249
}
@@ -357,7 +357,7 @@ class AssetInfoDataAggregateImplTest {
357357

358358
assertNotNull(aggregate.price)
359359
assertEquals(Currency.EUR, aggregate.price?.currency)
360-
assertEquals(3000.0, aggregate.price?.priceValue)
360+
assertEquals(3000.0, aggregate.price?.value)
361361
}
362362

363363
@Test

features/assets/presents/src/main/kotlin/com/gemwallet/features/assets/views/AssetsScreen.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ fun AssetsScreen(
7070
val importing by viewModel.importInProgress.collectAsStateWithLifecycle()
7171
val pinnedAssets by viewModel.pinnedAssets.collectAsStateWithLifecycle()
7272
val unpinnedAssets by viewModel.unpinnedAssets.collectAsStateWithLifecycle()
73-
val walletInfo by viewModel.walletInfo.collectAsStateWithLifecycle()
73+
// val walletInfo by viewModel.walletInfo.collectAsStateWithLifecycle()
74+
val walletSummary by viewModel.walletSummary.collectAsStateWithLifecycle()
7475
val screenState by viewModel.screenState.collectAsStateWithLifecycle()
7576
val showWelcomeBanner by viewModel.showWelcomeBanner.collectAsStateWithLifecycle()
7677

@@ -79,7 +80,7 @@ fun AssetsScreen(
7980

8081
Scaffold(
8182
modifier = Modifier.fillMaxSize(),
82-
topBar = { AssetsTopBar(walletInfo, onShowWallets, onSearch) },
83+
topBar = { AssetsTopBar(walletSummary, onShowWallets, onSearch) },
8384
containerColor = MaterialTheme.colorScheme.surface,
8485
) {
8586
val pullToRefreshState = rememberPullToRefreshState()
@@ -106,7 +107,7 @@ fun AssetsScreen(
106107
) {
107108
item {
108109
AssetsHead(
109-
walletInfo = walletInfo,
110+
walletSummary = walletSummary,
110111
onSendClick = onSendClick,
111112
onReceiveClick = onReceiveClick,
112113
onBuyClick = onBuyClick,

features/assets/presents/src/main/kotlin/com/gemwallet/features/assets/views/AssetsTopBar.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ import androidx.compose.ui.Modifier
2020
import androidx.compose.ui.platform.testTag
2121
import androidx.compose.ui.text.style.TextOverflow
2222
import androidx.compose.ui.unit.dp
23+
import com.gemwallet.android.domains.wallet.aggregates.WalletSummaryAggregate
2324
import com.gemwallet.android.ui.components.image.AsyncImage
24-
import com.gemwallet.features.assets.viewmodels.model.WalletInfoUIState
2525

2626
@OptIn(ExperimentalMaterial3Api::class)
2727
@Composable
2828
internal fun AssetsTopBar(
29-
walletInfo: WalletInfoUIState,
29+
walletInfo: WalletSummaryAggregate?,
3030
onShowWallets: () -> Unit,
3131
onShowAssetManage: () -> Unit,
3232
) {
@@ -35,10 +35,10 @@ internal fun AssetsTopBar(
3535
Box {
3636
TextButton(onClick = onShowWallets) {
3737
Row(verticalAlignment = Alignment.CenterVertically) {
38-
AsyncImage(model = walletInfo.icon, size = 24.dp)
38+
AsyncImage(model = walletInfo?.walletIcon, size = 24.dp)
3939
Spacer(modifier = Modifier.size(8.dp))
4040
Text(
41-
text = walletInfo.name,
41+
text = walletInfo?.walletName ?: "",
4242
maxLines = 1,
4343
overflow = TextOverflow.Companion.Ellipsis,
4444
color = MaterialTheme.colorScheme.onSurface,

features/assets/presents/src/main/kotlin/com/gemwallet/features/assets/views/components/AssetsHead.kt

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,38 @@
11
package com.gemwallet.features.assets.views.components
22

33
import androidx.compose.runtime.Composable
4+
import com.gemwallet.android.domains.price.PriceState
5+
import com.gemwallet.android.domains.wallet.aggregates.WalletSummaryAggregate
46
import com.gemwallet.android.ui.components.list_head.AmountListHead
57
import com.gemwallet.android.ui.components.list_head.AssetHeadActions
6-
import com.gemwallet.features.assets.viewmodels.model.WalletInfoUIState
78
import com.wallet.core.primitives.AssetId
89

910
@Composable
1011
internal fun AssetsHead(
11-
walletInfo: WalletInfoUIState,
12+
walletSummary: WalletSummaryAggregate?,
1213
onSendClick: () -> Unit,
1314
onReceiveClick: () -> Unit,
1415
onBuyClick: () -> Unit,
1516
onSwapClick: (AssetId?) -> Unit,
1617
onHideBalances: () -> Unit,
1718
) {
19+
walletSummary ?: return // TODO: Amount list head and other should accept nullable values.
20+
1821
AmountListHead(
19-
amount = walletInfo.totalValueFormatted,
20-
changedValue = walletInfo.changedValue,
21-
changedPercentages = walletInfo.changedPercentages,
22-
changeState = walletInfo.priceState,
22+
amount = walletSummary.walletTotalValue,
23+
changedValue = walletSummary.changedValue?.valueFormated,
24+
changedPercentages = walletSummary.changedValue?.changePercentageFormatted,
25+
changeState = walletSummary.changedValue?.state ?: PriceState.None,
2326
onHideBalances = onHideBalances,
2427
actions = {
2528
AssetHeadActions(
26-
walletType = walletInfo.type,
29+
walletType = walletSummary.walletType,
2730
transferEnabled = true,
28-
operationsEnabled = walletInfo.operationsEnabled,
31+
operationsEnabled = walletSummary.isOperationsAvailable,
2932
onTransfer = onSendClick,
3033
onReceive = onReceiveClick,
3134
onBuy = onBuyClick,
32-
onSwap = if (walletInfo.isSwapEnabled) {
35+
onSwap = if (walletSummary.isSwapAvailable) {
3336
{ onSwapClick(null) }
3437
} else null
3538
)

0 commit comments

Comments
 (0)