diff --git a/build.gradle b/build.gradle index 85d4e7be0..603221f97 100644 --- a/build.gradle +++ b/build.gradle @@ -44,7 +44,7 @@ buildscript { composeMaterial : '1.4.3', composeCompiler : '1.4.6', composeConstraintLayout: '1.1.0-alpha05', - uiCore : '0.1.2', + uiCore : '0.1.3', soraCard : '0.1.40', lazySodium : '5.0.2', jna : '5.8.0', diff --git a/common/src/main/java/jp/co/soramitsu/common/domain/AssetAmountInputState.kt b/common/src/main/java/jp/co/soramitsu/common/domain/AssetAmountInputState.kt index 5af001a34..1c713ea01 100644 --- a/common/src/main/java/jp/co/soramitsu/common/domain/AssetAmountInputState.kt +++ b/common/src/main/java/jp/co/soramitsu/common/domain/AssetAmountInputState.kt @@ -37,11 +37,10 @@ import java.math.BigDecimal data class AssetAmountInputState( val token: Token, val balance: String, - val amount: BigDecimal, - val initialAmount: BigDecimal? = null, + val amount: BigDecimal? = null, val amountFiat: String, val enabled: Boolean, val readOnly: Boolean = false, val error: Boolean = false, - val errorHint: String = "", + val errorHint: String = "" ) diff --git a/common/src/main/java/jp/co/soramitsu/common/presentation/compose/components/AssetAmount.kt b/common/src/main/java/jp/co/soramitsu/common/presentation/compose/components/AssetAmount.kt index dab7539db..4b5e59a01 100644 --- a/common/src/main/java/jp/co/soramitsu/common/presentation/compose/components/AssetAmount.kt +++ b/common/src/main/java/jp/co/soramitsu/common/presentation/compose/components/AssetAmount.kt @@ -68,9 +68,11 @@ import jp.co.soramitsu.common.R import jp.co.soramitsu.common.domain.AssetAmountInputState import jp.co.soramitsu.common.domain.OptionsProvider import jp.co.soramitsu.common.presentation.compose.TokenIcon +import jp.co.soramitsu.common.util.ext.orZero import jp.co.soramitsu.common.util.ext.testTagAsId import jp.co.soramitsu.ui_core.component.button.properties.Size import jp.co.soramitsu.ui_core.component.input.number.BasicNumberInput +import jp.co.soramitsu.ui_core.component.input.number.DefaultCursorPosition import jp.co.soramitsu.ui_core.resources.Dimens import jp.co.soramitsu.ui_core.theme.borderRadius import jp.co.soramitsu.ui_core.theme.customColors @@ -157,7 +159,8 @@ fun AssetAmountInput( textStyle = MaterialTheme.customTypography.displayS.copy(textAlign = TextAlign.End), enabled = state?.let { it.enabled && !it.readOnly } ?: false, precision = state?.token?.precision ?: OptionsProvider.defaultScale, - initial = state?.initialAmount, + defaultCursorPosition = DefaultCursorPosition.START, + initial = state?.amount, onValueChanged = onAmountChange, focusRequester = focusRequester, textFieldColors = TextFieldDefaults.textFieldColors( @@ -215,8 +218,7 @@ val previewAssetAmountInputState = AssetAmountInputState( token = previewToken, balance = "10.234 ($2.234.23)", amountFiat = "$2.342.12", - amount = BigDecimal.ZERO, - initialAmount = null, + amount = null, enabled = true, error = false, errorHint = "", @@ -237,7 +239,6 @@ private fun PreviewAssetAmountInput() { Button(onClick = { state.value = state.value.copy( amount = bb.value, - initialAmount = bb.value, ) bb.value = bb.value.plus(BigDecimal.ONE) }) { @@ -255,7 +256,7 @@ private fun PreviewAssetAmountInput() { onFocusChange = {}, ) Spacer(modifier = Modifier.size(10.dp)) - Text(text = state.value.amount.toPlainString()) + Text(text = state.value.amount.orZero().toPlainString()) AssetAmountInput( modifier = Modifier, state = previewAssetAmountInputState, diff --git a/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/util/PolkaswapFormulas.kt b/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/util/PolkaswapFormulas.kt index 48cdfa1ab..ca20d0997 100644 --- a/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/util/PolkaswapFormulas.kt +++ b/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/util/PolkaswapFormulas.kt @@ -125,10 +125,9 @@ object PolkaswapFormulas { amount: BigDecimal, percentage: Double, precision: Int, - ): BigDecimal { - return if (percentage == 100.0) amount else amount.safeDivide(Big100, precision) - .multiply(percentage.toBigDecimal()) - } + ): BigDecimal = if (percentage == 100.0) amount else + amount.multiply(percentage.toBigDecimal()) + .safeDivide(Big100, precision) fun calculateOneAmountFromAnother( amount: BigDecimal, diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt index 9fdcbd044..d7cf36c71 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt @@ -163,10 +163,9 @@ class QRCodeFlowViewModel @Inject constructor( nf = numbersFormatter, precision = DEFAULT_TOKEN_PRINT_PRECISION, ), - amount = BigDecimal.ZERO, - initialAmount = null, + amount = null, amountFiat = "", - enabled = false, + enabled = true, ) else _requestTokenScreenState.value.assetAmountInputState!!.copy( token = assetInUse.token, balance = getAssetBalanceText( @@ -381,7 +380,7 @@ class QRCodeFlowViewModel @Inject constructor( _requestTokenScreenState.value.assetAmountInputState?.let { assetAmountInputState -> _requestTokenScreenState.value = _requestTokenScreenState.value.copy( assetAmountInputState = assetAmountInputState.copy( - initialAmount = assetAmountInputState.amount, + amount = assetAmountInputState.amount, ) ) } @@ -417,7 +416,7 @@ class QRCodeFlowViewModel @Inject constructor( .untransformedUserAddress, assetAmountInputState = _requestTokenScreenState.value .assetAmountInputState?.copy( - initialAmount = _requestTokenScreenState.value + amount = _requestTokenScreenState.value .assetAmountInputState?.amount, enabled = false, readOnly = true, diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt index 244238069..cad49af65 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt @@ -162,12 +162,11 @@ class TransferAmountViewModel @AssistedInject constructor( input = AssetAmountInputState( token = asset.token, balance = getAssetBalanceText(asset), - amount = initialSendAmount?.toBigDecimalOrNull() ?: BigDecimal.ZERO, - initialAmount = initialSendAmount?.toBigDecimalOrNull(), + amount = initialSendAmount?.toBigDecimalOrNull(), amountFiat = "", enabled = false, error = false, - errorHint = "", + errorHint = "" ) ) } else { @@ -178,7 +177,7 @@ class TransferAmountViewModel @AssistedInject constructor( amountFiat = asset.token.printFiat( _sendState.value.input?.amount.orZero(), numbersFormatter - ), + ) ) ) } @@ -230,7 +229,7 @@ class TransferAmountViewModel @AssistedInject constructor( _sendState.value = _sendState.value.copy( input = _sendState.value.input?.copy( readOnly = false, - initialAmount = _sendState.value.input?.amount?.nullZero() + amount = _sendState.value.input?.amount?.nullZero() ), ) } @@ -393,7 +392,7 @@ class TransferAmountViewModel @AssistedInject constructor( fun onReviewClick() { _sendState.value = _sendState.value.copy( input = _sendState.value.input?.copy( - initialAmount = _sendState.value.input?.amount.orZero() + amount = _sendState.value.input?.amount.orZero() ) ) } @@ -425,7 +424,6 @@ class TransferAmountViewModel @AssistedInject constructor( _sendState.value = _sendState.value.copy( input = _sendState.value.input?.copy( amount = amount, - initialAmount = amount, amountFiat = _sendState.value.input?.token?.printFiat( amount, numbersFormatter diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt index e5edd7981..dead88b69 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt @@ -186,7 +186,7 @@ class QrCodeFlowViewModelTest { Assert.assertEquals( viewModel.requestTokenScreenState.value.assetAmountInputState?.amount, - viewModel.requestTokenConfirmScreenState.value.assetAmountInputState?.initialAmount + viewModel.requestTokenConfirmScreenState.value.assetAmountInputState?.amount ) } diff --git a/feature_blockexplorer_api/src/main/java/jp/co/soramitsu/feature_blockexplorer_api/data/BlockExplorerManager.kt b/feature_blockexplorer_api/src/main/java/jp/co/soramitsu/feature_blockexplorer_api/data/BlockExplorerManager.kt index 103f1ab8a..5d1723c43 100644 --- a/feature_blockexplorer_api/src/main/java/jp/co/soramitsu/feature_blockexplorer_api/data/BlockExplorerManager.kt +++ b/feature_blockexplorer_api/src/main/java/jp/co/soramitsu/feature_blockexplorer_api/data/BlockExplorerManager.kt @@ -40,6 +40,7 @@ import javax.inject.Singleton import jp.co.soramitsu.common.config.BuildConfigWrapper import jp.co.soramitsu.common.domain.AppStateProvider import jp.co.soramitsu.common.domain.fiatChange +import jp.co.soramitsu.common.logger.FirebaseWrapper import jp.co.soramitsu.core_db.AppDatabase import jp.co.soramitsu.core_db.model.FiatTokenPriceLocal import jp.co.soramitsu.core_db.model.ReferralLocal @@ -72,7 +73,7 @@ class BlockExplorerManager @Inject constructor( assetsInfo = it } - private suspend fun getAssetsInfoInternal(tokenIds: List): List> { + private suspend fun getAssetsInfoInternal(tokenIds: List): List> = runCatching { val selected = soraConfigManager.getSelectedCurrency() val tokens = db.assetDao().getFiatTokenPriceLocal(selected.code) val yesterdayHour = yesterday() @@ -87,7 +88,10 @@ class BlockExplorerManager @Inject constructor( resultList.add(assetInfo.tokenId to BigInteger(assetInfo.liquidity)) } db.assetDao().insertFiatPrice(fiats) - return resultList + resultList + }.getOrElse { + FirebaseWrapper.recordException(it) + emptyList() } suspend fun updatePoolsSbApy() { @@ -113,6 +117,9 @@ class BlockExplorerManager @Inject constructor( db.referralsDao().insertReferrals(it) } } + .onFailure { + FirebaseWrapper.recordException(it) + } } suspend fun getXorPerEurRatio(): Double? = runCatching { diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapSlippageScreen.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapSlippageScreen.kt index db7c75f63..65e8814f5 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapSlippageScreen.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapSlippageScreen.kt @@ -32,16 +32,17 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_polkaswap_impl.presentation.screens.swap +import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable @@ -50,12 +51,15 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardType -import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import java.math.BigDecimal import java.text.DecimalFormatSymbols import java.util.Locale import jp.co.soramitsu.common.R @@ -63,10 +67,8 @@ import jp.co.soramitsu.ui_core.component.button.FilledButton import jp.co.soramitsu.ui_core.component.button.properties.Order import jp.co.soramitsu.ui_core.component.button.properties.Size import jp.co.soramitsu.ui_core.component.card.ContentCard -import jp.co.soramitsu.ui_core.component.input.InputText -import jp.co.soramitsu.ui_core.component.input.InputTextState -import jp.co.soramitsu.ui_core.component.input.number.CurrencyGroupingVisualTransformationSuffix -import jp.co.soramitsu.ui_core.component.input.number.onDecimalChanged +import jp.co.soramitsu.ui_core.component.input.number.BasicNumberInput +import jp.co.soramitsu.ui_core.component.input.number.CurrencyGroupingVisualTransformation import jp.co.soramitsu.ui_core.resources.Dimens import jp.co.soramitsu.ui_core.theme.borderRadius import jp.co.soramitsu.ui_core.theme.customColors @@ -82,14 +84,46 @@ internal fun SwapSlippageScreen( value: Double, onDone: (Double) -> Unit, ) { - val curValue = remember { mutableStateOf(TextFieldValue(value.toString())) } + var currentValueLocalStorage by remember { mutableStateOf(value) } val desc = remember { mutableStateOf(null) } + val frontrun = stringResource(id = R.string.polkaswap_slippage_frontrun) val fail = stringResource(id = R.string.polkaswap_slippage_mayfail) - val decimalFormatSymbols = remember { DecimalFormatSymbols(Locale.getDefault()) } + + val focused = remember { mutableStateOf(false) } + + val focusRequester = remember { + FocusRequester() + } + val visualTransformation = - remember { CurrencyGroupingVisualTransformationSuffix(decimalFormatSymbols, '%') } - var curDouble by remember { mutableStateOf(value) } + remember(Locale.getDefault()) { + CurrencyGroupingVisualTransformation( + decimalFormatSymbols = DecimalFormatSymbols(Locale.getDefault()), + suffix = "%" + ) + } + + val onValueChangeDecorator: (BigDecimal) -> Unit = remember { + { valueAsBigDecimal -> + val valueAsDouble = valueAsBigDecimal.toDouble() + when { + valueAsDouble < minFail -> { + desc.value = fail + } + valueAsDouble > maxFrontrun -> { + desc.value = frontrun + } + else -> { + desc.value = null + } + } + + // Store inputted value as Double in local storage + currentValueLocalStorage = valueAsDouble + } + } + Column(modifier = Modifier.fillMaxSize()) { ContentCard( modifier = Modifier @@ -103,52 +137,52 @@ internal fun SwapSlippageScreen( .fillMaxWidth() .wrapContentHeight() ) { - InputText( + Column( modifier = Modifier - .background( + .focusRequester(focusRequester) + .onFocusChanged { + focused.value = it.isFocused + }.border( + border = BorderStroke( + width = 1.dp, + color = if (focused.value) MaterialTheme.customColors.fgPrimary + else MaterialTheme.customColors.fgOutline + ), + shape = RoundedCornerShape(MaterialTheme.borderRadius.ml) + ).background( color = MaterialTheme.customColors.bgSurface, shape = RoundedCornerShape(MaterialTheme.borderRadius.ml) - ) - .fillMaxWidth() - .wrapContentHeight(), - maxLines = 1, - visualTransformation = visualTransformation, - singleLine = true, - state = InputTextState(value = curValue.value, descriptionText = desc.value), - onValueChange = { - val result = onDecimalChanged( - it.text, - 2, - decimalFormatSymbols.decimalSeparator, - decimalFormatSymbols.groupingSeparator, - decimalFormatSymbols.minusSign, - ) - if (result != null) { - curValue.value = it.copy(text = result.first) - curDouble = result.second.toDouble() - when { - curDouble < minFail -> { - desc.value = fail - } - curDouble > maxFrontrun -> { - desc.value = frontrun - } - else -> { - desc.value = null - } + ).clip(RoundedCornerShape(MaterialTheme.borderRadius.ml)) + .padding(vertical = Dimens.x1_2, horizontal = Dimens.x2) + .defaultMinSize(minHeight = Dimens.InputHeight) + .wrapContentHeight() + .fillMaxWidth(), + ) { + BasicNumberInput( + modifier = Modifier, + textStyle = MaterialTheme.customTypography.textM, + initial = value.toBigDecimal(), // input value is used; no locally stored data!!! + precision = 2, + enabled = true, + visualTransformation = visualTransformation, + onValueChanged = onValueChangeDecorator, + onKeyboardDone = remember { + { + // Get locally stored value and make coerceIn + onDone(currentValueLocalStorage.coerceIn(min, max)) } } - }, - keyboardActions = KeyboardActions( - onDone = { - onDone(curDouble.coerceIn(min, max)) - } - ), - keyboardOptions = KeyboardOptions.Default.copy( - imeAction = ImeAction.Done, - keyboardType = KeyboardType.Decimal - ), - ) + ) + + val currentDescriptionValue = desc.value + + if (currentDescriptionValue != null) + Text( + text = currentDescriptionValue, + color = MaterialTheme.customColors.fgSecondary, + style = MaterialTheme.customTypography.textXS + ) + } Text( modifier = Modifier .padding(Dimens.x2) @@ -165,7 +199,8 @@ internal fun SwapSlippageScreen( order = Order.PRIMARY, text = stringResource(id = R.string.common_done), onClick = { - onDone(curDouble.coerceIn(min, max)) + // Get locally stored value and make coerceIn + onDone(currentValueLocalStorage.coerceIn(min, max)) }, ) } diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt index 39bf766dc..ab27b7d36 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt @@ -51,6 +51,7 @@ import jp.co.soramitsu.common.util.NumbersFormatter import jp.co.soramitsu.common.util.ext.isZero import jp.co.soramitsu.common.util.ext.lazyAsync import jp.co.soramitsu.common.util.ext.nullZero +import jp.co.soramitsu.common.util.ext.orZero import jp.co.soramitsu.common.view.ViewHelper import jp.co.soramitsu.common_wallet.domain.model.LiquidityData import jp.co.soramitsu.common_wallet.domain.model.WithDesired @@ -400,7 +401,6 @@ class LiquidityAddViewModel @AssistedInject constructor( _addState.value = _addState.value.copy( assetState2 = _addState.value.assetState2?.copy( amount = it, - initialAmount = it, amountFiat = _addState.value.assetState2?.token?.printFiat( it, numbersFormatter @@ -413,7 +413,6 @@ class LiquidityAddViewModel @AssistedInject constructor( _addState.value = _addState.value.copy( assetState1 = _addState.value.assetState1?.copy( amount = it, - initialAmount = it, amountFiat = _addState.value.assetState1?.token?.printFiat( it, numbersFormatter @@ -509,10 +508,10 @@ class LiquidityAddViewModel @AssistedInject constructor( val list = assets.filter { it.token.id in bases && it.token.id != addToken2 } _addState.value = _addState.value.copy( assetState1 = _addState.value.assetState1?.copy( - initialAmount = _addState.value.assetState1?.amount?.nullZero(), + amount = _addState.value.assetState1?.amount?.nullZero() ), assetState2 = _addState.value.assetState2?.copy( - initialAmount = _addState.value.assetState2?.amount?.nullZero(), + amount = _addState.value.assetState2?.amount?.nullZero() ), ) _searchTokenFilter.value = _searchTokenFilter.value.copy( @@ -550,10 +549,10 @@ class LiquidityAddViewModel @AssistedInject constructor( } _addState.value = _addState.value.copy( assetState1 = _addState.value.assetState1?.copy( - initialAmount = _addState.value.assetState1?.amount?.nullZero(), + amount = _addState.value.assetState1?.amount?.nullZero() ), assetState2 = _addState.value.assetState2?.copy( - initialAmount = _addState.value.assetState2?.amount?.nullZero(), + amount = _addState.value.assetState2?.amount?.nullZero() ), ) _searchTokenFilter.value = _searchTokenFilter.value.copy( @@ -571,7 +570,7 @@ class LiquidityAddViewModel @AssistedInject constructor( assetState1 = state.copy( token = a.token, balance = getAssetBalanceText(a), - amountFiat = a.token.printFiat(state.amount, numbersFormatter), + amountFiat = a.token.printFiat(state.amount.orZero(), numbersFormatter) ), ) hasXorReminderWarningBeenChecked = false @@ -587,7 +586,7 @@ class LiquidityAddViewModel @AssistedInject constructor( assetState2 = state?.copy( token = a.token, balance = getAssetBalanceText(a), - amountFiat = a.token.printFiat(state.amount, numbersFormatter), + amountFiat = a.token.printFiat(state.amount.orZero(), numbersFormatter) ) ?: buildInitialAssetState(a), ) @@ -612,7 +611,7 @@ class LiquidityAddViewModel @AssistedInject constructor( _addState.value = _addState.value.copy( assetState1 = _addState.value.assetState1?.copy( balance = getAssetBalanceText(asset), - token = asset.token, + token = asset.token ) ) } @@ -716,10 +715,10 @@ class LiquidityAddViewModel @AssistedInject constructor( fun onSlippageClick() { _addState.value = _addState.value.copy( assetState1 = _addState.value.assetState1?.copy( - initialAmount = _addState.value.assetState1?.amount?.nullZero(), + amount = _addState.value.assetState1?.amount?.nullZero(), ), assetState2 = _addState.value.assetState2?.copy( - initialAmount = _addState.value.assetState2?.amount?.nullZero(), + amount = _addState.value.assetState2?.amount?.nullZero(), ), ) } @@ -736,8 +735,8 @@ class LiquidityAddViewModel @AssistedInject constructor( amountFiat = _addState.value.assetState1?.token?.printFiat( value, numbersFormatter - ).orEmpty() - ) + ).orEmpty(), + ), ) amount1Flow.value = value } @@ -749,7 +748,7 @@ class LiquidityAddViewModel @AssistedInject constructor( amountFiat = _addState.value.assetState2?.token?.printFiat( value, numbersFormatter - ).orEmpty() + ).orEmpty(), ) ) amount2Flow.value = value @@ -784,7 +783,6 @@ class LiquidityAddViewModel @AssistedInject constructor( assetState1 = _addState.value.assetState1?.copy( amountFiat = tokenFrom.printFiat(amount, numbersFormatter), amount = amount, - initialAmount = amount, ) ) amount1Flow.value = amount @@ -799,7 +797,6 @@ class LiquidityAddViewModel @AssistedInject constructor( assetState2 = _addState.value.assetState2?.copy( amountFiat = tokenTo.printFiat(amount, numbersFormatter), amount = amount, - initialAmount = amount, ) ) amount2Flow.value = amount @@ -878,8 +875,7 @@ class LiquidityAddViewModel @AssistedInject constructor( private fun buildInitialAssetState(a: Asset) = AssetAmountInputState( token = a.token, balance = getAssetBalanceText(a), - amount = BigDecimal.ZERO, - initialAmount = null, + amount = null, amountFiat = "", enabled = true, ) diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityremove/LiquidityRemoveViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityremove/LiquidityRemoveViewModel.kt index 1c7e2e73b..53b6ae5c4 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityremove/LiquidityRemoveViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityremove/LiquidityRemoveViewModel.kt @@ -198,8 +198,7 @@ class LiquidityRemoveViewModel @AssistedInject constructor( assetState1 = AssetAmountInputState( token = asset1.token, balance = getAssetBalanceText(asset1), - amount = BigDecimal.ZERO, - initialAmount = null, + amount = null, amountFiat = "", enabled = true, ), @@ -210,8 +209,7 @@ class LiquidityRemoveViewModel @AssistedInject constructor( assetState2 = AssetAmountInputState( token = asset2.token, balance = getAssetBalanceText(asset2), - amount = BigDecimal.ZERO, - initialAmount = null, + amount = null, amountFiat = "", enabled = true, ), @@ -428,10 +426,10 @@ class LiquidityRemoveViewModel @AssistedInject constructor( fun onSlippageClick() { removeState = removeState.copy( assetState1 = removeState.assetState1?.copy( - initialAmount = removeState.assetState1?.amount?.nullZero(), + amount = removeState.assetState1?.amount?.nullZero(), ), assetState2 = removeState.assetState2?.copy( - initialAmount = removeState.assetState2?.amount?.nullZero(), + amount = removeState.assetState2?.amount?.nullZero(), ), ) } @@ -445,11 +443,11 @@ class LiquidityRemoveViewModel @AssistedInject constructor( fun onAmount1Change(value: BigDecimal) { removeState = removeState.copy( assetState1 = removeState.assetState1?.copy( - amount = value, amountFiat = removeState.assetState1?.token?.printFiat( value, numbersFormatter - ).orEmpty() + ).orEmpty(), + amount = value ) ) amount1Flow.value = value @@ -458,11 +456,11 @@ class LiquidityRemoveViewModel @AssistedInject constructor( fun onAmount2Change(value: BigDecimal) { removeState = removeState.copy( assetState2 = removeState.assetState2?.copy( - amount = value, amountFiat = removeState.assetState2?.token?.printFiat( value, numbersFormatter - ).orEmpty() + ).orEmpty(), + amount = value ) ) amount2Flow.value = value @@ -493,12 +491,12 @@ class LiquidityRemoveViewModel @AssistedInject constructor( poolDataUsable?.let { poolData -> val firstAmountMin = PolkaswapFormulas.calculateMinAmount( - fromToken.amount, + fromToken.amount.orZero(), removeState.slippage ) val secondAmountMin = PolkaswapFormulas.calculateMinAmount( - toToken.amount, + toToken.amount.orZero(), removeState.slippage ) val desired = @@ -623,11 +621,10 @@ class LiquidityRemoveViewModel @AssistedInject constructor( shareOfPool = newPoolShare, ) ) - if (amount1.compareTo(removeState.assetState1?.amount) != 0) { + if (amount1.compareTo(removeState.assetState1?.amount.orZero()) != 0) { removeState = removeState.copy( assetState1 = removeState.assetState1?.copy( amount = amount1, - initialAmount = amount1, amountFiat = removeState.assetState1?.token?.printFiat( amount1, numbersFormatter @@ -635,11 +632,10 @@ class LiquidityRemoveViewModel @AssistedInject constructor( ) ) } - if (amount2.compareTo(removeState.assetState2?.amount) != 0) { + if (amount2.compareTo(removeState.assetState2?.amount.orZero()) != 0) { removeState = removeState.copy( assetState2 = removeState.assetState2?.copy( amount = amount2, - initialAmount = amount2, amountFiat = removeState.assetState2?.token?.printFiat( amount2, numbersFormatter @@ -691,7 +687,7 @@ class LiquidityRemoveViewModel @AssistedInject constructor( val result = assetsInteractor.isNotEnoughXorLeftAfterTransaction( networkFeeInXor = networkFee.orZero(), - xorChange = if (assetState1.token.id == SubstrateOptionsProvider.feeAssetId) -assetState1.amount else null, + xorChange = if (assetState1.token.id == SubstrateOptionsProvider.feeAssetId) -assetState1.amount.orZero() else null, ) removeState = removeState.copy( diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt index 230102682..c17decfc6 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt @@ -285,8 +285,7 @@ class SwapViewModel @AssistedInject constructor( tokenFromState = AssetAmountInputState( token = assetFrom.token, balance = getAssetBalanceText(assetFrom), - amount = BigDecimal.ZERO, - initialAmount = null, + amount = null, amountFiat = "", enabled = false, ), @@ -300,8 +299,7 @@ class SwapViewModel @AssistedInject constructor( tokenToState = AssetAmountInputState( token = assetTo.token, balance = getAssetBalanceText(assetTo), - amount = BigDecimal.ZERO, - initialAmount = null, + amount = null, amountFiat = "", enabled = false, ), @@ -400,10 +398,10 @@ class SwapViewModel @AssistedInject constructor( fun onSlippageClick() { _swapMainState.value = _swapMainState.value.copy( tokenFromState = _swapMainState.value.tokenFromState?.copy( - initialAmount = _swapMainState.value.tokenFromState?.amount?.nullZero(), + amount = _swapMainState.value.tokenFromState?.amount?.nullZero(), ), tokenToState = _swapMainState.value.tokenToState?.copy( - initialAmount = _swapMainState.value.tokenToState?.amount?.nullZero(), + amount = _swapMainState.value.tokenToState?.amount?.nullZero(), ), ) } @@ -412,10 +410,10 @@ class SwapViewModel @AssistedInject constructor( _swapMainState.value = _swapMainState.value.copy( selectMarketState = _swapMainState.value.market to availableMarkets, tokenFromState = _swapMainState.value.tokenFromState?.copy( - initialAmount = _swapMainState.value.tokenFromState?.amount?.nullZero(), + amount = _swapMainState.value.tokenFromState?.amount?.nullZero(), ), tokenToState = _swapMainState.value.tokenToState?.copy( - initialAmount = _swapMainState.value.tokenToState?.amount?.nullZero(), + amount = _swapMainState.value.tokenToState?.amount?.nullZero(), ), ) } @@ -430,10 +428,10 @@ class SwapViewModel @AssistedInject constructor( ) _swapMainState.value = _swapMainState.value.copy( tokenFromState = _swapMainState.value.tokenFromState?.copy( - initialAmount = _swapMainState.value.tokenFromState?.amount?.nullZero(), + amount = _swapMainState.value.tokenFromState?.amount?.nullZero(), ), tokenToState = _swapMainState.value.tokenToState?.copy( - initialAmount = _swapMainState.value.tokenToState?.amount?.nullZero(), + amount = _swapMainState.value.tokenToState?.amount?.nullZero(), ), ) } @@ -449,10 +447,10 @@ class SwapViewModel @AssistedInject constructor( ) _swapMainState.value = _swapMainState.value.copy( tokenFromState = _swapMainState.value.tokenFromState?.copy( - initialAmount = _swapMainState.value.tokenFromState?.amount?.nullZero(), + amount = _swapMainState.value.tokenFromState?.amount?.nullZero(), ), tokenToState = _swapMainState.value.tokenToState?.copy( - initialAmount = _swapMainState.value.tokenToState?.amount?.nullZero(), + amount = _swapMainState.value.tokenToState?.amount?.nullZero(), ), ) } @@ -465,7 +463,7 @@ class SwapViewModel @AssistedInject constructor( val change = if (tokenFromState.token.id == SubstrateOptionsProvider.feeAssetId) { tokenFromState.amount } else if (tokenToState.token.id == SubstrateOptionsProvider.feeAssetId) { - -tokenToState.amount + -tokenToState.amount.orZero() } else { null } val result = assetsInteractor.isNotEnoughXorLeftAfterTransaction( networkFeeInXor = networkFee.orZero(), @@ -502,10 +500,10 @@ class SwapViewModel @AssistedInject constructor( desired = if (desired == WithDesired.INPUT) WithDesired.OUTPUT else WithDesired.INPUT _swapMainState.value = _swapMainState.value.copy( tokenFromState = _swapMainState.value.tokenToState?.copy( - initialAmount = _swapMainState.value.tokenToState?.amount?.nullZero() + amount = _swapMainState.value.tokenToState?.amount?.nullZero(), ), tokenToState = _swapMainState.value.tokenFromState?.copy( - initialAmount = _swapMainState.value.tokenFromState?.amount?.nullZero() + amount = _swapMainState.value.tokenFromState?.amount?.nullZero(), ), ) setSwapButtonLoading(true) @@ -519,8 +517,7 @@ class SwapViewModel @AssistedInject constructor( tokenToState = AssetAmountInputState( token = token, balance = getAssetBalanceText(asset), - amount = amountTo, - initialAmount = amountTo.nullZero(), + amount = amountTo.nullZero(), amountFiat = token.printFiat(amountTo, numbersFormatter), enabled = true, ) @@ -533,8 +530,7 @@ class SwapViewModel @AssistedInject constructor( tokenFromState = AssetAmountInputState( token = token, balance = getAssetBalanceText(asset), - amount = amountFrom, - initialAmount = amountFrom.nullZero(), + amount = amountFrom.nullZero(), amountFiat = token.printFiat(amountFrom, numbersFormatter), enabled = _swapMainState.value.tokenToState != null, ) @@ -714,7 +710,6 @@ class SwapViewModel @AssistedInject constructor( numbersFormatter ), amount = it, - initialAmount = it, ) ) } else { @@ -725,7 +720,6 @@ class SwapViewModel @AssistedInject constructor( numbersFormatter ), amount = it, - initialAmount = it, ) ) } @@ -827,7 +821,7 @@ class SwapViewModel @AssistedInject constructor( amountFiat = _swapMainState.value.tokenFromState?.token?.printFiat( value, numbersFormatter - ).orEmpty() + ).orEmpty(), ) ) fromAmountOnEach() @@ -925,12 +919,12 @@ class SwapViewModel @AssistedInject constructor( fromState.token, toState.token, desired, - if (desired == WithDesired.INPUT) fromState.amount else toState.amount, + if (desired == WithDesired.INPUT) fromState.amount.orZero() else toState.amount.orZero(), details.minmax, details.networkFee, details.liquidityFee, details.dex.dexId, - if (desired == WithDesired.OUTPUT) fromState.amount else toState.amount, + if (desired == WithDesired.OUTPUT) fromState.amount.orZero() else toState.amount.orZero(), ) } catch (t: Throwable) { onError(t) @@ -981,7 +975,6 @@ class SwapViewModel @AssistedInject constructor( tokenFromState = _swapMainState.value.tokenFromState?.copy( amountFiat = fromAsset.token.printFiat(amount, numbersFormatter), amount = amount, - initialAmount = amount, ) ) desired = WithDesired.INPUT diff --git a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt index 0d1ba71fb..de953617c 100644 --- a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt +++ b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt @@ -312,7 +312,7 @@ class SwapViewModelTest { viewModel.toAssetSelected(assetsListItems.last().tokenId) advanceUntilIdle() viewModel.fromInputPercentClicked(50) - assertEquals(BigDecimal(50.0).setScale(19), viewModel.swapMainState.value.tokenFromState?.amount) + assertEquals(BigDecimal(50.0).setScale(18), viewModel.swapMainState.value.tokenFromState?.amount) } @Test @@ -324,7 +324,7 @@ class SwapViewModelTest { viewModel.toAssetSelected(assetsListItems.last().tokenId) advanceUntilIdle() viewModel.fromInputPercentClicked(50) - assertEquals(BigDecimal(8.0).setScale(19), viewModel.swapMainState.value.tokenFromState?.amount) + assertEquals(BigDecimal(8.0).setScale(18), viewModel.swapMainState.value.tokenFromState?.amount) } @Test @@ -336,7 +336,7 @@ class SwapViewModelTest { viewModel.toAssetSelected(assetsListItems.last().tokenId) advanceUntilIdle() viewModel.fromInputPercentClicked(50) - assertEquals(BigDecimal(25).setScale(19), viewModel.swapMainState.value.tokenFromState?.amount) + assertEquals(BigDecimal(25).setScale(18), viewModel.swapMainState.value.tokenFromState?.amount) } @Test diff --git a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt index cc34a84ec..8e6311278 100644 --- a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt +++ b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt @@ -39,7 +39,6 @@ import io.mockk.mockkObject import io.mockk.mockkStatic import jp.co.soramitsu.common.R import jp.co.soramitsu.common.domain.CoroutineManager -import jp.co.soramitsu.common.domain.PoolDex import jp.co.soramitsu.common.domain.Token import jp.co.soramitsu.common.domain.iconUri import jp.co.soramitsu.common.logger.FirebaseWrapper @@ -49,7 +48,6 @@ import jp.co.soramitsu.common.util.ext.equalTo import jp.co.soramitsu.common_wallet.domain.model.LiquidityData import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter -import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PoolsInteractor import jp.co.soramitsu.feature_polkaswap_impl.presentation.screens.liquidityadd.LiquidityAddViewModel import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletInteractor