From 111eb17c7ba078a9b69400edb39b684d664c0a9d Mon Sep 17 00:00:00 2001 From: John Huang Date: Wed, 15 May 2024 12:58:10 -0400 Subject: [PATCH] Feature/mob 498 integration target leverage (#103) * UX working * Sync up text formatting * Update Abacus * compile issue --- v4/build.gradle | 3 +- .../prices/DydxMarketPricesViewModel.kt | 1 + .../DydxTradeInputTargetLeverageView.kt | 24 ++++--- .../DydxTradeInputTargetLeverageViewModel.kt | 63 +++++++++++++------ .../tradeinput/DydxTradeInputViewModel.kt | 10 ++- 5 files changed, 66 insertions(+), 35 deletions(-) diff --git a/v4/build.gradle b/v4/build.gradle index edb3d2f8..efcbab34 100644 --- a/v4/build.gradle +++ b/v4/build.gradle @@ -78,7 +78,6 @@ subprojects { ignoreFailures = true } } - } // Define versions in a single place @@ -89,7 +88,7 @@ ext { compileSdkVersion = 34 // App dependencies - abacusVersion = '1.7.10' + abacusVersion = '1.7.16' carteraVersion = '0.1.13' kollectionsVersion = '2.0.16' diff --git a/v4/feature/market/src/main/java/exchange/dydx/trading/feature/market/marketinfo/components/prices/DydxMarketPricesViewModel.kt b/v4/feature/market/src/main/java/exchange/dydx/trading/feature/market/marketinfo/components/prices/DydxMarketPricesViewModel.kt index 28e7dd12..505c3e6c 100644 --- a/v4/feature/market/src/main/java/exchange/dydx/trading/feature/market/marketinfo/components/prices/DydxMarketPricesViewModel.kt +++ b/v4/feature/market/src/main/java/exchange/dydx/trading/feature/market/marketinfo/components/prices/DydxMarketPricesViewModel.kt @@ -47,6 +47,7 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.stateIn +import timber.log.Timber import java.time.Instant import java.time.temporal.ChronoUnit import javax.inject.Inject diff --git a/v4/feature/trade/src/main/java/exchange/dydx/trading/feature/trade/tradeinput/DydxTradeInputTargetLeverageView.kt b/v4/feature/trade/src/main/java/exchange/dydx/trading/feature/trade/tradeinput/DydxTradeInputTargetLeverageView.kt index a307b839..81d8d124 100644 --- a/v4/feature/trade/src/main/java/exchange/dydx/trading/feature/trade/tradeinput/DydxTradeInputTargetLeverageView.kt +++ b/v4/feature/trade/src/main/java/exchange/dydx/trading/feature/trade/tradeinput/DydxTradeInputTargetLeverageView.kt @@ -37,7 +37,7 @@ import exchange.dydx.trading.feature.shared.scaffolds.InputFieldScaffold import exchange.dydx.trading.feature.shared.views.HeaderViewCloseBotton import exchange.dydx.trading.feature.shared.views.LabeledTextInput -data class LeverageTextAndValue(val text: String, val value: Double) +data class LeverageTextAndValue(val text: String, val value: String) @Preview @Composable @@ -55,6 +55,7 @@ object DydxTradeInputTargetLeverageView : DydxComponent { val localizer: LocalizerProtocol, val leverageText: String?, val leverageOptions: List?, + val selectAction: ((String) -> Unit)? = null, val closeAction: (() -> Unit)? = null, ) { companion object { @@ -185,7 +186,11 @@ object DydxTradeInputTargetLeverageView : DydxComponent { localizer = MockLocalizer(), label = state?.localizer?.localize("APP.TRADE.TARGET_LEVERAGE"), value = state?.leverageText ?: "", - onValueChanged = {}, + onValueChanged = { + state?.selectAction?.invoke( + it, + ) + }, ), ) } @@ -198,7 +203,7 @@ object DydxTradeInputTargetLeverageView : DydxComponent { state: ViewState? ) { Row( - modifier = Modifier + modifier = modifier .padding( horizontal = ThemeShapes.HorizontalPadding, vertical = 8.dp, @@ -213,7 +218,7 @@ object DydxTradeInputTargetLeverageView : DydxComponent { items = state?.leverageOptions?.map { { modifier -> PlatformPillItem( - modifier = Modifier + modifier = modifier .padding( vertical = 4.dp, horizontal = 8.dp, @@ -234,7 +239,7 @@ object DydxTradeInputTargetLeverageView : DydxComponent { selectedItems = state?.leverageOptions?.map { { modifier -> PlatformPillItem( - modifier = Modifier + modifier = modifier .padding( vertical = 4.dp, horizontal = 8.dp, @@ -254,9 +259,13 @@ object DydxTradeInputTargetLeverageView : DydxComponent { } ?: listOf(), equalWeight = false, currentSelection = state?.leverageOptions?.indexOfFirst { - it.text == state.leverageText + it.value.toDouble() == state.leverageText?.toDouble() + }, + onSelectionChanged = { it -> + state?.leverageOptions?.get(it)?.value?.let { value -> + state.selectAction?.invoke(value) + } }, - onSelectionChanged = {}, ) } } @@ -276,6 +285,7 @@ object DydxTradeInputTargetLeverageView : DydxComponent { text = state?.localizer?.localize("APP.TRADE.CONFIRM_LEVERAGE"), state = PlatformButtonState.Primary, ) { + state?.closeAction?.invoke() } } } diff --git a/v4/feature/trade/src/main/java/exchange/dydx/trading/feature/trade/tradeinput/DydxTradeInputTargetLeverageViewModel.kt b/v4/feature/trade/src/main/java/exchange/dydx/trading/feature/trade/tradeinput/DydxTradeInputTargetLeverageViewModel.kt index babc2cbc..4696ffa0 100644 --- a/v4/feature/trade/src/main/java/exchange/dydx/trading/feature/trade/tradeinput/DydxTradeInputTargetLeverageViewModel.kt +++ b/v4/feature/trade/src/main/java/exchange/dydx/trading/feature/trade/tradeinput/DydxTradeInputTargetLeverageViewModel.kt @@ -4,14 +4,16 @@ import androidx.lifecycle.ViewModel import dagger.hilt.android.lifecycle.HiltViewModel import exchange.dydx.abacus.output.input.TradeInput import exchange.dydx.abacus.protocols.LocalizerProtocol +import exchange.dydx.abacus.state.model.TradeInputField import exchange.dydx.dydxstatemanager.AbacusStateManagerProtocol import exchange.dydx.platformui.components.PlatformInfo import exchange.dydx.trading.common.DydxViewModel import exchange.dydx.trading.common.formatter.DydxFormatter import exchange.dydx.trading.common.navigation.DydxRouter import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.map import javax.inject.Inject @HiltViewModel @@ -22,43 +24,64 @@ class DydxTradeInputTargetLeverageViewModel @Inject constructor( private val formatter: DydxFormatter, val platformInfo: PlatformInfo, ) : ViewModel(), DydxViewModel { + var targetLeverage: MutableStateFlow = MutableStateFlow(null) val state: Flow = - abacusStateManager.state.tradeInput - .map { - createViewState(it) - } + combine( + abacusStateManager.state.tradeInput, + targetLeverage, + ) { selectedSubaccountPosition, marketAndAsset -> + createViewState(selectedSubaccountPosition, marketAndAsset) + } .distinctUntilChanged() - private fun createViewState(tradeInput: TradeInput?): DydxTradeInputTargetLeverageView.ViewState { - val targetLeverage = tradeInput?.targetLeverage ?: 1.0 + private fun createViewState( + tradeInput: TradeInput?, + targetLeverage: String? + ): DydxTradeInputTargetLeverageView.ViewState { val maxLeverage = tradeInput?.options?.maxLeverage ?: 5.0 val leverages = leverageOptions(maxLeverage) return DydxTradeInputTargetLeverageView.ViewState( localizer = localizer, - leverageText = formatter.localFormatted(targetLeverage, 1), + leverageText = targetLeverage ?: ( + tradeInput?.targetLeverage?.let { + "$it" + } + ) ?: "2.0", leverageOptions = leverages, + selectAction = { leverage -> + this.targetLeverage.value = leverage + }, closeAction = { + targetLeverage.let { + abacusStateManager.trade("$it", TradeInputField.targetLeverage) + } router.navigateBack() }, ) } private fun leverageOptions(max: Double): List { + val steps = listOf(1.0, 2.0, 5.0, 10.0) val leverages = mutableListOf() - if (max > 1.0) { - leverages.add(LeverageTextAndValue("1.0", 1.0)) - } - if (max > 2.0) { - leverages.add(LeverageTextAndValue("2.0", 2.0)) - } - if (max > 5.0) { - leverages.add(LeverageTextAndValue("5.0", 2.0)) - } - if (max > 10.0) { - leverages.add(LeverageTextAndValue("10.0", 2.0)) + for (step in steps) { + if (max > step) { + leverages.add(leverageTextAndValue(step)) + } } - leverages.add(LeverageTextAndValue(localizer.localize("APP.GENERAL.MAX"), max)) + leverages.add( + LeverageTextAndValue( + localizer.localize("APP.GENERAL.MAX"), + formatter.raw(max) ?: "", + ), + ) return leverages } + + private fun leverageTextAndValue(value: Double): LeverageTextAndValue { + return LeverageTextAndValue( + formatter.leverage(value, 1) ?: "", + formatter.raw(value) ?: "", + ) + } } diff --git a/v4/feature/trade/src/main/java/exchange/dydx/trading/feature/trade/tradeinput/DydxTradeInputViewModel.kt b/v4/feature/trade/src/main/java/exchange/dydx/trading/feature/trade/tradeinput/DydxTradeInputViewModel.kt index 4101e1c7..afce4d0c 100644 --- a/v4/feature/trade/src/main/java/exchange/dydx/trading/feature/trade/tradeinput/DydxTradeInputViewModel.kt +++ b/v4/feature/trade/src/main/java/exchange/dydx/trading/feature/trade/tradeinput/DydxTradeInputViewModel.kt @@ -71,12 +71,10 @@ class DydxTradeInputViewModel @Inject constructor( ), isIsolatedMarketEnabled = featureFlags.isFeatureEnabled(DydxFeatureFlag.enable_isolated_market), isIsolatedMarketSelected = tradeInput?.marginMode == MarginMode.isolated, - isolatedMarketTargetLeverageText = tradeInput?.targetLeverage?.let { - formatter.leverage( - it, - 2, - ) - } ?: "2x", + isolatedMarketTargetLeverageText = formatter.leverage( + (tradeInput?.targetLeverage ?: 2.0), + 1, + ), orderbookToggleState = orderbookToggleState, requestedBottomSheetState = buttomSheetState, onMarketType = {