diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/core/history/HistoryHelper.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/core/history/HistoryHelper.kt index 6db587ce3..7ed8e1503 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/core/history/HistoryHelper.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/core/history/HistoryHelper.kt @@ -130,7 +130,15 @@ class HistoryHelper( for (event in events) { val groupKey = getGroupKey(event.timestampForSort) val date = event.timestampForSort - val section = output[groupKey] ?: ActionDateSection(date, DateHelper.formatTransactionsGroupDate(context, date, settingsRepository.getLocale()), mutableListOf()) + val section = output[groupKey] ?: ActionDateSection( + date, + DateHelper.formatTransactionsGroupDate( + context, + date, + settingsRepository.getLocale() + ), + mutableListOf() + ) section.events.add(event) output[groupKey] = section } @@ -283,7 +291,8 @@ class HistoryHelper( val chunkItems = mutableListOf() for ((actionIndex, action) in actions.withIndex()) { val timestamp = if (removeDate) 0 else event.timestamp - val isScam = event.isScam || settingsRepository.isSpamTransaction(wallet.id, event.eventId) + val isScam = + event.isScam || settingsRepository.isSpamTransaction(wallet.id, event.eventId) val item = action( index = actionIndex, @@ -293,16 +302,29 @@ class HistoryHelper( timestamp = timestamp, isScam = isScam ) - chunkItems.add(item.copy( - pending = pending, - position = ListCell.getPosition(actions.size + positionExtra, actionIndex), - fee = if (fee.isPositive) CurrencyFormatter.format(TokenEntity.TON.symbol, fee, TokenEntity.TON.decimals) else null, - feeInCurrency = CurrencyFormatter.formatFiat(currency.code, feeInCurrency), - refund = if (refund.isPositive) CurrencyFormatter.format(TokenEntity.TON.symbol, refund, TokenEntity.TON.decimals) else null, - refundInCurrency = CurrencyFormatter.formatFiat(currency.code, refundInCurrency), - lt = event.lt, - hiddenBalance = hiddenBalances - )) + chunkItems.add( + item.copy( + pending = pending, + position = ListCell.getPosition(actions.size + positionExtra, actionIndex), + fee = if (fee.isPositive) CurrencyFormatter.format( + TokenEntity.TON.symbol, + fee, + TokenEntity.TON.decimals + ) else null, + feeInCurrency = CurrencyFormatter.formatFiat(currency.code, feeInCurrency), + refund = if (refund.isPositive) CurrencyFormatter.format( + TokenEntity.TON.symbol, + refund, + TokenEntity.TON.decimals + ) else null, + refundInCurrency = CurrencyFormatter.formatFiat( + currency.code, + refundInCurrency + ), + lt = event.lt, + hiddenBalance = hiddenBalances + ) + ) } if (chunkItems.size > 0) { @@ -324,30 +346,43 @@ class HistoryHelper( val simplePreview = action.simplePreview val date = DateHelper.formatTransactionTime(timestamp, settingsRepository.getLocale()) - val dateDetails = DateHelper.formatTransactionDetailsTime(timestamp, settingsRepository.getLocale()) + val dateDetails = + DateHelper.formatTransactionDetailsTime(timestamp, settingsRepository.getLocale()) if (action.jettonSwap != null) { val jettonSwap = action.jettonSwap!! val jettonPreview = jettonSwap.jettonPreview!! val token = jettonSwap.jettonPreview!!.address - val symbol = jettonPreview.symbol val amount = Coins.ofNano(jettonSwap.amount, jettonPreview.decimals) - val tonFromJetton = Coins.of(jettonSwap.ton) - val isOut = jettonSwap.amountOut != "" - val value: CharSequence - val value2: CharSequence - val tokenCode: String - if (!isOut) { - tokenCode = TokenEntity.TON.symbol - value = CurrencyFormatter.format(tokenCode, tonFromJetton, 2) - value2 = CurrencyFormatter.format(symbol, amount, 2) - } else { - tokenCode = symbol - value = CurrencyFormatter.format(symbol, amount, 2) - value2 = CurrencyFormatter.format(TokenEntity.TON.symbol, tonFromJetton, 2) - } + val amountIn = if (jettonSwap.tonIn != null) { + CurrencyFormatter.format( + TokenEntity.TON.symbol, + Coins.of(jettonSwap.tonIn!!), + 2 + ).withMinus + } else if (jettonSwap.jettonMasterIn != null) { + CurrencyFormatter.format( + jettonSwap.jettonMasterIn!!.symbol, + Coins.ofNano(jettonSwap.amountIn, jettonSwap.jettonMasterIn!!.decimals), + 2 + ).withMinus + } else "-" + + val amountOut = if (jettonSwap.tonOut != null) { + CurrencyFormatter.format( + TokenEntity.TON.symbol, + Coins.of(jettonSwap.tonOut!!), + 2 + ).withPlus + } else if (jettonSwap.jettonMasterOut != null) { + CurrencyFormatter.format( + jettonSwap.jettonMasterOut!!.symbol, + Coins.ofNano(jettonSwap.amountOut, jettonSwap.jettonMasterOut!!.decimals), + 2 + ).withPlus + } else "-" val rates = ratesRepository.getRates(currency, token) val inCurrency = rates.convert(token, amount) @@ -359,11 +394,12 @@ class HistoryHelper( action = ActionType.Swap, title = simplePreview.name, subtitle = jettonSwap.router.getNameOrAddress(wallet.testnet, true), - value = value.withPlus, - value2 = value2.withMinus, - tokenCode = tokenCode, - coinIconUrl = jettonSwap.jettonMasterIn?.image ?: TokenEntity.TON.imageUri.toString(), - coinIconUrl2 = jettonSwap.jettonMasterOut?.image ?: TokenEntity.TON.imageUri.toString(), + value = amountOut, + value2 = amountIn, + coinIconUrl = jettonSwap.jettonMasterIn?.image + ?: TokenEntity.TON.imageUri.toString(), + coinIconUrl2 = jettonSwap.jettonMasterOut?.image + ?: TokenEntity.TON.imageUri.toString(), timestamp = timestamp, date = date, dateDetails = dateDetails, @@ -681,7 +717,10 @@ class HistoryHelper( ) } else if (action.auctionBid != null) { val auctionBid = action.auctionBid!! - val subtitle = auctionBid.nft?.title?.max24 ?: auctionBid.bidder.getNameOrAddress(wallet.testnet, true) + val subtitle = auctionBid.nft?.title?.max24 ?: auctionBid.bidder.getNameOrAddress( + wallet.testnet, + true + ) val amount = Coins.ofNano(auctionBid.amount.value) val tokenCode = auctionBid.amount.tokenName @@ -705,7 +744,17 @@ class HistoryHelper( wallet = wallet, ) } else if (action.type == Action.Type.unknown) { - return createUnknown(index, txId, action, date, timestamp, simplePreview, dateDetails, isScam, wallet) + return createUnknown( + index, + txId, + action, + date, + timestamp, + simplePreview, + dateDetails, + isScam, + wallet + ) } else if (action.withdrawStake != null) { val withdrawStake = action.withdrawStake!! @@ -830,7 +879,17 @@ class HistoryHelper( wallet = wallet, ) } else { - return createUnknown(index, txId, action, date, timestamp, simplePreview, dateDetails, isScam, wallet) + return createUnknown( + index, + txId, + action, + date, + timestamp, + simplePreview, + dateDetails, + isScam, + wallet + ) } } diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/recharge/BatteryRechargeViewModel.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/recharge/BatteryRechargeViewModel.kt index 97665975e..4aee9a4ca 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/recharge/BatteryRechargeViewModel.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/recharge/BatteryRechargeViewModel.kt @@ -283,8 +283,8 @@ class BatteryRechargeViewModel( val batteryMaxInputAmount = rechargeMethod.fromTon(api.config.batteryMaxInputAmount) val amount = _selectedPackTypeFlow.value?.let { packType -> - Coins.of(RechargePackEntity.getTonAmount(api.config.batteryMeanFees, packType)) - } ?: Coins.of(_amountFlow.value) + rechargeMethod.fromTon(RechargePackEntity.getTonAmount(api.config.batteryMeanFees, packType)) + } ?: Coins.of(_amountFlow.value, token.decimals) if (amount > batteryMaxInputAmount) { _eventFlow.tryEmit( @@ -333,6 +333,8 @@ class BatteryRechargeViewModel( null } + Log.d("BatteryRechargeViewModel", "amount=$amount") + val jettonPayload = TonTransferHelper.jetton( coins = amount.toGrams(), toAddress = AddrStd.parse(fundReceiver), @@ -358,7 +360,7 @@ class BatteryRechargeViewModel( } }.catch { _eventFlow.tryEmit(BatteryRechargeEvent.Error) - }.flowOn(Dispatchers.IO).launchIn(viewModelScope) + }.take(1).flowOn(Dispatchers.IO).launchIn(viewModelScope) private fun uiItemsPacks( packs: List, diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/recharge/list/holder/CustomAmountHolder.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/recharge/list/holder/CustomAmountHolder.kt index 761db2ebb..a0fb949f7 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/recharge/list/holder/CustomAmountHolder.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/recharge/list/holder/CustomAmountHolder.kt @@ -23,5 +23,6 @@ class CustomAmountHolder( titleView.text = getString(Localization.battery_other_title) subtitleView.text = getString(Localization.battery_other_subtitle) radioView.checked = item.selected + radioView.setOnClickListener { onCustomAmountSelect() } } } \ No newline at end of file diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/recharge/list/holder/RechargePackHolder.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/recharge/list/holder/RechargePackHolder.kt index ff1f7c200..12115727f 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/recharge/list/holder/RechargePackHolder.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/recharge/list/holder/RechargePackHolder.kt @@ -51,6 +51,7 @@ class RechargePackHolder( radioView.checked = item.selected radioView.isEnabled = item.isEnabled + radioView.setOnClickListener { onPackSelect(item.packType) } } diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/refill/BatteryRefillScreen.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/refill/BatteryRefillScreen.kt index 83607aa1d..a318c769a 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/refill/BatteryRefillScreen.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/refill/BatteryRefillScreen.kt @@ -39,7 +39,6 @@ class BatteryRefillScreen(wallet: WalletEntity) : BaseHolderWalletScreen.ChildLi setHeaderBackground(R.drawable.bg_page_gradient) setActionIcon(UIKitIcon.ic_close_16) { finish() } setAdapter(adapter) - updateListPadding(top = requireContext().getDimensionPixelSize(R.dimen.barHeight)) if (initialPromo != null) { viewModel.applyPromo(initialPromo!!, true) } diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/refill/BatteryRefillViewModel.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/refill/BatteryRefillViewModel.kt index 0b1141b36..0770c6466 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/refill/BatteryRefillViewModel.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/refill/BatteryRefillViewModel.kt @@ -27,11 +27,7 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flowOn -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.take import kotlinx.coroutines.launch -import uikit.extensions.collectFlow import java.net.URLEncoder class BatteryRefillViewModel( @@ -68,13 +64,15 @@ class BatteryRefillViewModel( uiItems.add(Item.Space) } - if (!api.config.disableBatteryCryptoRecharge) { + val rechargeMethodsItems = uiItemsRechargeMethods(wallet) + + if (!api.config.disableBatteryCryptoRecharge && rechargeMethodsItems.isNotEmpty()) { uiItems.addAll(uiItemsRechargeMethods(wallet)) + uiItems.add(Item.Space) } val tonProofToken = accountRepository.requestTonProofToken(wallet) ?: "" - uiItems.add(Item.Space) uiItems.add( Item.Refund( wallet = wallet, @@ -134,7 +132,9 @@ class BatteryRefillViewModel( ) ) } - uiItems.add(Item.Gift(wallet, position = ListCell.Position.LAST)) + if (uiItems.isNotEmpty()) { + uiItems.add(Item.Gift(wallet, position = ListCell.Position.LAST)) + } return uiItems.toList() } @@ -177,8 +177,14 @@ class BatteryRefillViewModel( } } return tokens.filter { token -> - supportTokenAddress.contains(token.address) - }.sortedBy { it.fiat }.reversed() + supportTokenAddress.contains(token.address) && token.balance.value.isPositive + }.sortedWith(compareByDescending { token -> + token.isUsdt // Place USDT at the top + }.thenBy { token -> + token.isTon // Place TON at the end + }.thenByDescending { token -> + token.fiat // Sort by fiat value + }) } fun applyPromo(promo: String, isInitial: Boolean = false) { diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/settings/BatterySettingsScreen.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/settings/BatterySettingsScreen.kt index 0b257b6f5..eb19a2b03 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/settings/BatterySettingsScreen.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/settings/BatterySettingsScreen.kt @@ -32,7 +32,7 @@ class BatterySettingsScreen(wallet: WalletEntity): BaseHolderWalletScreen.ChildL setCloseIcon(UIKitIcon.ic_chevron_left_16) { popBackStack() } setActionIcon(UIKitIcon.ic_close_16) { finish() } setAdapter(adapter) - updateListPadding(top = requireContext().getDimensionPixelSize(R.dimen.barHeight)) + collectFlow(viewModel.titleFlow, ::setTitle) } companion object { diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/settings/BatterySettingsViewModel.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/settings/BatterySettingsViewModel.kt index 45851e6b4..dbb5cb62e 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/settings/BatterySettingsViewModel.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/battery/settings/BatterySettingsViewModel.kt @@ -13,6 +13,7 @@ import com.tonapps.wallet.data.battery.BatteryRepository import com.tonapps.wallet.data.battery.entity.BatteryBalanceEntity import com.tonapps.wallet.data.settings.BatteryTransaction import com.tonapps.wallet.data.settings.SettingsRepository +import com.tonapps.wallet.localization.Localization import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flowOn @@ -27,6 +28,17 @@ class BatterySettingsViewModel( private val api: API, ): BaseWalletVM(app) { + val titleFlow = batteryRepository.balanceUpdatedFlow.map { _ -> + val batteryBalance = getBatteryBalance(wallet) + val hasBalance = batteryBalance.balance.isPositive + + if (hasBalance) { + "" + } else { + getString(Localization.transactions) + } + }.flowOn(Dispatchers.IO) + val uiItemsFlow = batteryRepository.balanceUpdatedFlow.map { _ -> val config = api.config val batteryBalance = getBatteryBalance(wallet)