Skip to content

Commit 561cd42

Browse files
committed
fix(tokens): stabilize token list sort order
Sort by rounded nativeAmount with deterministic address tiebreaker to prevent visual rearranging from sub-cent rate and supply fluctuations. - Remove stateFlow from combine to eliminate feedback loop - Move rate dispatch to separate observer - Sort by nativeAmount.rounded() so tokens within the same display cent compare equal and fall through to the address tiebreaker Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent dc90a6a commit 561cd42

1 file changed

Lines changed: 12 additions & 4 deletions

File tree

apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/ui/SelectTokenViewModel.kt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import com.getcode.opencode.model.financial.TokenWithLocalizedBalance
2121
import com.getcode.opencode.model.financial.sum
2222
import com.getcode.opencode.model.financial.toFiat
2323
import com.getcode.solana.keys.Mint
24+
import com.getcode.solana.keys.base58
2425
import com.getcode.util.resources.ResourceHelper
2526
import com.flipcash.libs.coroutines.DispatcherProvider
2627
import com.getcode.view.BaseViewModel
@@ -94,16 +95,19 @@ class SelectTokenViewModel @Inject constructor(
9495
.onEach { dispatchEvent(Event.OnDiscoveryEnabled(it)) }
9596
.launchIn(viewModelScope)
9697

98+
exchange.observePreferredRate()
99+
.distinctUntilChanged()
100+
.onEach { dispatchEvent(Event.OnRateChanged(it)) }
101+
.launchIn(viewModelScope)
102+
97103
eventFlow
98104
.filterIsInstance<Event.OnPurposeChanged>()
99105
.map { it.purpose }
100106
.flatMapLatest { purpose ->
101107
combine(
102-
stateFlow,
103108
tokenCoordinator.tokenBalances,
104109
exchange.observePreferredRate()
105-
) { state, balances, rate ->
106-
dispatchEvent(Event.OnRateChanged(rate))
110+
) { balances, rate ->
107111
balances
108112
.map {
109113
val balance = LocalFiat(
@@ -138,6 +142,7 @@ class SelectTokenViewModel @Inject constructor(
138142
it.token.name
139143
}
140144
}
145+
141146
TokenPurpose.Select -> it.token.name
142147
TokenPurpose.Withdraw -> {
143148
if (it.token.address == Mint.usdf) {
@@ -149,7 +154,10 @@ class SelectTokenViewModel @Inject constructor(
149154
}
150155
)
151156
}
152-
.sortedWith(compareByDescending { item -> item.balance.nativeAmount })
157+
.sortedWith(
158+
compareByDescending<TokenWithLocalizedBalance> { it.balance.nativeAmount.rounded() }
159+
.thenBy { it.token.address.base58() }
160+
)
153161
.filter {
154162
val hasBalance = it.balance.nativeAmount.hasDisplayableValue
155163
when (purpose) {

0 commit comments

Comments
 (0)