Skip to content

Commit 1e7a30d

Browse files
committed
fix(ocp): prevent excessive cancellation/restart of token-reserves streaming; key balances, mcap, and appreciation at UI
Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent 9668327 commit 1e7a30d

7 files changed

Lines changed: 59 additions & 31 deletions

File tree

apps/flipcash/features/balance/src/main/kotlin/com/flipcash/app/balance/internal/components/BalanceHeader.kt

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.padding
1111
import androidx.compose.material.MaterialTheme
1212
import androidx.compose.material.Text
1313
import androidx.compose.runtime.Composable
14+
import androidx.compose.runtime.key
1415
import androidx.compose.ui.Alignment
1516
import androidx.compose.ui.Modifier
1617
import androidx.compose.ui.draw.alpha
@@ -47,16 +48,18 @@ internal fun BalanceHeader(
4748
CodeCircularProgressIndicator()
4849
}
4950
} else {
50-
Crossfade(balance.nativeAmount) { amount ->
51-
AmountArea(
52-
amountText = amount.formatted(),
53-
isAltCaption = false,
54-
isAltCaptionKinIcon = false,
55-
currencyResId = exchange.getFlagByCurrency(amount.currencyCode.name),
56-
isClickable = true,
57-
textStyle = CodeTheme.typography.displayLarge,
58-
onClick = onClick
59-
)
51+
key(balance.nativeAmount) {
52+
Crossfade(balance.nativeAmount) { amount ->
53+
AmountArea(
54+
amountText = amount.formatted(),
55+
isAltCaption = false,
56+
isAltCaptionKinIcon = false,
57+
currencyResId = exchange.getFlagByCurrency(amount.currencyCode.name),
58+
isClickable = true,
59+
textStyle = CodeTheme.typography.displayLarge,
60+
onClick = onClick
61+
)
62+
}
6063
}
6164

6265
if (appreciation != null) {

apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/internal/components/info/MarketCapSection.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@ import androidx.compose.foundation.layout.fillMaxWidth
2424
import androidx.compose.foundation.layout.height
2525
import androidx.compose.foundation.layout.padding
2626
import androidx.compose.foundation.layout.requiredHeight
27+
import androidx.compose.foundation.layout.size
2728
import androidx.compose.material.MaterialTheme
2829
import androidx.compose.material.Text
2930
import androidx.compose.runtime.Composable
3031
import androidx.compose.runtime.derivedStateOf
3132
import androidx.compose.runtime.getValue
33+
import androidx.compose.runtime.key
3234
import androidx.compose.runtime.mutableStateOf
3335
import androidx.compose.runtime.remember
3436
import androidx.compose.runtime.setValue
@@ -135,6 +137,8 @@ internal fun MarketCapSection(
135137
isVisible = highlightedCapPoint == null,
136138
period = selectedPeriod,
137139
)
140+
} else {
141+
Spacer(Modifier.size(CodeTheme.dimens.grid.x3))
138142
}
139143
}
140144

apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/internal/components/info/TokenBalance.kt

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
1010
import androidx.compose.foundation.layout.padding
1111
import androidx.compose.material.Text
1212
import androidx.compose.runtime.Composable
13+
import androidx.compose.runtime.key
1314
import androidx.compose.runtime.remember
1415
import androidx.compose.ui.Alignment
1516
import androidx.compose.ui.Modifier
@@ -43,22 +44,26 @@ internal fun TokenBalance(
4344
CodeCircularProgressIndicator()
4445
}
4546
} else {
46-
Crossfade(balance) { amount ->
47-
AmountArea(
48-
amountText = amount.formatted(),
49-
isAltCaption = false,
50-
isAltCaptionKinIcon = false,
51-
captionText = null,
52-
currencyResId = exchange.getFlagByCurrency(amount.currencyCode.name),
53-
isClickable = true,
54-
textStyle = CodeTheme.typography.displayLarge,
55-
onClick = onClick
56-
)
47+
key(balance) {
48+
Crossfade(balance) { amount ->
49+
AmountArea(
50+
amountText = amount.formatted(),
51+
isAltCaption = false,
52+
isAltCaptionKinIcon = false,
53+
captionText = null,
54+
currencyResId = exchange.getFlagByCurrency(amount.currencyCode.name),
55+
isClickable = true,
56+
textStyle = CodeTheme.typography.displayLarge,
57+
onClick = onClick
58+
)
59+
}
5760
}
5861

5962
if (appreciation != null) {
60-
Crossfade(appreciation) { amount ->
61-
CurrencyAppreciationLabel(amount)
63+
key(appreciation) {
64+
Crossfade(appreciation) { amount ->
65+
CurrencyAppreciationLabel(amount)
66+
}
6267
}
6368
}
6469
}

apps/flipcash/shared/tokens/src/main/kotlin/SelectTokenViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class SelectTokenViewModel @Inject constructor(
5959
get() = tokens.orEmpty().map { it.balance }.sum()
6060

6161
val aggregateAppreciation: LocalFiat?
62-
get() = tokens?.mapNotNull { it.appreciation }?.sum()
62+
get() = tokens?.map { it.appreciation }?.sum()
6363
}
6464

6565
sealed interface Event {

apps/flipcash/shared/tokens/src/main/kotlin/TokenInfoViewModel.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import kotlinx.coroutines.flow.launchIn
5454
import kotlinx.coroutines.flow.map
5555
import kotlinx.coroutines.flow.mapNotNull
5656
import kotlinx.coroutines.flow.onEach
57+
import kotlinx.coroutines.flow.onStart
5758
import javax.inject.Inject
5859
import kotlin.collections.map
5960

@@ -250,10 +251,16 @@ class TokenInfoViewModel @Inject constructor(
250251
}
251252
}.onEach {
252253
dispatchEvent(Event.OnMarketCapChanged(it))
253-
dispatchEvent(Event.LoadHistoricalDataForPeriod(stateFlow.value.selectedPeriod, evict = true))
254254
}
255255
.launchIn(viewModelScope)
256256

257+
eventFlow
258+
.filterIsInstance<Event.OnMarketCapChanged>()
259+
.map { it.mcap }
260+
.distinctUntilChanged()
261+
.onEach { dispatchEvent(Event.LoadHistoricalDataForPeriod(stateFlow.value.selectedPeriod)) }
262+
.launchIn(viewModelScope)
263+
257264
eventFlow
258265
.filterIsInstance<Event.OpenPurchaseMethods>()
259266
.onEach {

services/opencode/src/main/kotlin/com/getcode/opencode/controllers/TokenController.kt

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import com.getcode.opencode.model.financial.DataSource
2121
import com.getcode.opencode.model.financial.Fiat
2222
import com.getcode.opencode.model.financial.HistoricalMintData
2323
import com.getcode.opencode.model.financial.LocalFiat
24+
import com.getcode.opencode.model.financial.Rate
2425
import com.getcode.opencode.model.financial.Token
2526
import com.getcode.opencode.model.financial.TokenResult
2627
import com.getcode.opencode.model.financial.TokenWithBalance
@@ -527,7 +528,6 @@ class TokenController @Inject constructor(
527528
launchpadMetadata = metadata.launchpadMetadata?.copy(currentCirculatingSupplyQuarks = currentSupply)
528529
)
529530
val tokenBalance = Fiat.tokenBalance(balance, token)
530-
println("balance = ${tokenBalance.decimalValue} for ${token.symbol}")
531531
val appreciation = tokenBalance - Fiat(fiat = usdCostBasis)
532532

533533
return TokenWithBalance(token, tokenBalance, appreciation)
@@ -591,7 +591,8 @@ class TokenController @Inject constructor(
591591

592592
currencyController.streamLiveMintData(
593593
scope = this,
594-
mints = _state.map { it.tokens.keys.toList() },
594+
mints = _state.map { it.tokens.keys.toList() }
595+
.distinctUntilChanged().debounce(300),
595596
tag = "token-reserves"
596597
).filterIsInstance<LiveMintDataResponse.LaunchpadReserveState>()
597598
.collect { response ->
@@ -618,7 +619,16 @@ class TokenController @Inject constructor(
618619
updatedTokens = updatedTokens + (mint to updatedToken)
619620

620621
state.balances[mint]?.let { balance ->
621-
val newBalance = Fiat.tokenBalance(balance.quarks, updatedToken)
622+
val exchangedValue = LocalFiat.valueExchangeIn(
623+
amount = balance,
624+
token = token,
625+
balance = balance,
626+
rate = Rate.oneToOne,
627+
debug = false,
628+
trace = false,
629+
).underlyingTokenAmount
630+
631+
val newBalance = Fiat.tokenBalance(quarks = exchangedValue.quarks, token = token)
622632
updatedBalances = updatedBalances + (mint to newBalance)
623633

624634
trace(
@@ -707,7 +717,6 @@ class TokenController @Inject constructor(
707717
)
708718

709719
val updates = response.accounts.values.mapNotNull { account ->
710-
println("cost basis = ${account.usdCostBasis} for ${account.mint.base58()}")
711720
buildTokenWithBalance(account.mint, account.balance, account.usdCostBasis)
712721
}
713722

services/opencode/src/main/kotlin/com/getcode/opencode/model/financial/Fiat.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ data class Fiat(
5050
estimation: () -> BigDecimal,
5151
tokenMintDecimals: Int,
5252
) : this(
53-
quarks = parseStringToDouble(
53+
fiat = parseStringToDouble(
5454
estimation().toPlainString(),
5555
decimalPlaces = tokenMintDecimals
56-
).let { (it * MULTIPLIER).toLong() },
56+
),
5757
currencyCode = CurrencyCode.USD
5858
)
5959

0 commit comments

Comments
 (0)