Updated on 2026-08-14
This commit is contained in:
commit
f63a05d380
18 changed files with 66 additions and 72 deletions
|
|
@ -1,7 +1,11 @@
|
|||
package com.tangem.tap.common.compose.extensions
|
||||
|
||||
import android.content.Context
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
|
||||
@Composable
|
||||
fun LazyListState.OnBottomReached(loadMoreThreshold: Int, loadMore: () -> Unit) {
|
||||
|
|
@ -17,4 +21,15 @@ fun LazyListState.OnBottomReached(loadMoreThreshold: Int, loadMore: () -> Unit)
|
|||
LaunchedEffect(shouldLoadMore) {
|
||||
if (shouldLoadMore) loadMore()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LazyListState.HideKeyboardOnScroll() {
|
||||
val context = LocalContext.current
|
||||
val view = LocalView.current
|
||||
LaunchedEffect(firstVisibleItemIndex) {
|
||||
val inputMethodManager =
|
||||
context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import com.tangem.common.card.Card
|
|||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.domain.common.TwinCardNumber
|
||||
import com.tangem.operations.pins.CheckUserCodesResponse
|
||||
import com.tangem.tap.common.entities.FiatCurrency
|
||||
import com.tangem.tap.common.redux.NotificationAction
|
||||
import com.tangem.tap.domain.termsOfUse.CardTou
|
||||
import com.tangem.wallet.R
|
||||
|
|
@ -58,4 +59,5 @@ sealed class DetailsAction : Action {
|
|||
}
|
||||
}
|
||||
|
||||
data class ChangeAppCurrency(val fiatCurrency: FiatCurrency) : DetailsAction()
|
||||
}
|
||||
|
|
@ -31,6 +31,9 @@ private fun internalReduce(action: Action, state: AppState): DetailsState {
|
|||
is DetailsAction.ManageSecurity -> {
|
||||
handleSecurityAction(action, detailsState)
|
||||
}
|
||||
is DetailsAction.ChangeAppCurrency ->
|
||||
detailsState.copy(appCurrency = action.fiatCurrency)
|
||||
|
||||
else -> detailsState
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import android.net.Uri
|
|||
import com.tangem.blockchain.common.Wallet
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.tap.common.entities.Button
|
||||
import com.tangem.tap.common.entities.FiatCurrency
|
||||
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsState
|
||||
import com.tangem.tap.store
|
||||
import org.rekotlin.StateType
|
||||
|
|
@ -19,6 +20,7 @@ data class DetailsState(
|
|||
val securityScreenState: SecurityScreenState? = null,
|
||||
val cardTermsOfUseUrl: Uri? = null,
|
||||
val createBackupAllowed: Boolean = false,
|
||||
val appCurrency: FiatCurrency = FiatCurrency.Default
|
||||
) : StateType {
|
||||
|
||||
// if you do not delegate - the application crashes on startup,
|
||||
|
|
|
|||
|
|
@ -116,6 +116,9 @@ class DetailsFragment : Fragment(R.layout.fragment_details), StoreSubscriber<Det
|
|||
}
|
||||
|
||||
tvAppCurrency.show(state.scanResponse?.card?.isMultiwalletAllowed != true)
|
||||
tvAppCurrencyTitle.show(state.scanResponse?.card?.isMultiwalletAllowed != true)
|
||||
tvAppCurrency.text = state.appCurrency.code
|
||||
|
||||
tvAppCurrency.setOnClickListener {
|
||||
store.dispatch(WalletAction.AppCurrencyAction.ChooseAppCurrency)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,7 +128,8 @@ class ReceiptReducer : SendInternalReducer {
|
|||
val totalFiat = amountFiat.plus(feeFiat)
|
||||
ReceiptTokenFiat(
|
||||
amountFiat = amountFiat.scaleToFiat(true).stripZeroPlainString(),
|
||||
feeFiat = feeFiat.scaleToFiat(true).stripZeroPlainString(),
|
||||
feeFiat = feeFiat.scaleToFiat(true)
|
||||
.stripZeroPlainString().addPrecisionSign(),
|
||||
totalFiat = totalFiat.scaleToFiat(true).stripZeroPlainString(),
|
||||
willSentToken = tokensToSend.stripZeroPlainString(),
|
||||
willSentFeeCoin = feeCoin.stripZeroPlainString(),
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.tap.common.compose.extensions.HideKeyboardOnScroll
|
||||
import com.tangem.tap.common.compose.extensions.OnBottomReached
|
||||
import com.tangem.tap.domain.tokens.Currency
|
||||
import com.tangem.tap.features.tokens.redux.ContractAddress
|
||||
|
|
@ -44,6 +45,8 @@ fun ListOfCurrencies(
|
|||
}
|
||||
|
||||
val listState = rememberLazyListState()
|
||||
listState.HideKeyboardOnScroll()
|
||||
listState.OnBottomReached(loadMoreThreshold = 40) { onLoadMore() }
|
||||
|
||||
LazyColumn(
|
||||
state = listState,
|
||||
|
|
@ -67,7 +70,6 @@ fun ListOfCurrencies(
|
|||
)
|
||||
}
|
||||
}
|
||||
listState.OnBottomReached(loadMoreThreshold = 40) { onLoadMore() }
|
||||
}
|
||||
|
||||
val Currency.fullName: String
|
||||
|
|
|
|||
|
|
@ -288,7 +288,6 @@ data class WalletState(
|
|||
private fun updateTotalBalance(): WalletState {
|
||||
val walletsData = this.wallets
|
||||
.flatMap(WalletStore::walletsData)
|
||||
.filter { it.fiatRate != null }
|
||||
|
||||
return if (walletsData.isNotEmpty()) {
|
||||
this.copy(
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.tangem.tap.common.entities.FiatCurrency
|
|||
import com.tangem.tap.common.extensions.dispatchDialogShow
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.domain.TapWalletManager
|
||||
import com.tangem.tap.features.details.redux.DetailsAction
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.features.wallet.redux.WalletDialog
|
||||
import com.tangem.tap.persistence.FiatCurrenciesPrefStorage
|
||||
|
|
@ -63,6 +64,7 @@ class AppCurrencyMiddleware(
|
|||
tapWalletManager.rates.clear()
|
||||
fiatCurrenciesPrefStorage.saveAppCurrency(action.fiatCurrency)
|
||||
store.dispatch(GlobalAction.ChangeAppCurrency(action.fiatCurrency))
|
||||
store.dispatch(DetailsAction.ChangeAppCurrency(action.fiatCurrency))
|
||||
store.dispatch(WalletAction.LoadFiatRate())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,9 @@ fun List<WalletData>.calculateTotalFiatAmount(): BigDecimal {
|
|||
}
|
||||
|
||||
private fun List<WalletData>.mapToProgressState(): List<ProgressState> {
|
||||
return this.map {
|
||||
when (it.currencyData.status) {
|
||||
return this.map { wallet ->
|
||||
if (wallet.fiatRate == null) ProgressState.Error
|
||||
else when (wallet.currencyData.status) {
|
||||
BalanceStatus.Refreshing -> ProgressState.Refreshing
|
||||
BalanceStatus.VerifiedOnline,
|
||||
BalanceStatus.SameCurrencyTransactionInProgress,
|
||||
|
|
|
|||
|
|
@ -138,8 +138,7 @@ class MultiWalletView : WalletView {
|
|||
show = totalBalance.state == ProgressState.Error
|
||||
)
|
||||
|
||||
tvBalance.text = if (totalBalance.state == ProgressState.Error) "—"
|
||||
else totalBalance.fiatAmount.formatAmountAsSpannedString(
|
||||
tvBalance.text = totalBalance.fiatAmount.formatAmountAsSpannedString(
|
||||
currencySymbol = totalBalance.fiatCurrency.symbol
|
||||
)
|
||||
tvCurrencyName.text = totalBalance.fiatCurrency.code
|
||||
|
|
@ -193,7 +192,6 @@ class MultiWalletView : WalletView {
|
|||
private fun configureButtonsForEmptyWalletState(binding: FragmentWalletBinding) =
|
||||
with(binding) {
|
||||
lButtonsLong.root.show()
|
||||
lButtonsLong.btnScanLong.setOnClickListener { store.dispatch(WalletAction.Scan) }
|
||||
lButtonsLong.btnConfirmLong.setOnClickListener { store.dispatch(WalletAction.CreateWallet) }
|
||||
lButtonsLong.btnConfirmLong.text =
|
||||
fragment?.getText(R.string.wallet_button_create_wallet)
|
||||
|
|
|
|||
|
|
@ -130,20 +130,8 @@ class SingleWalletView : WalletView {
|
|||
lButtonsLong.btnConfirmLong
|
||||
}
|
||||
|
||||
val btnScan = if (state.tradeCryptoState.sellingAllowed ||
|
||||
state.tradeCryptoState.buyingAllowed
|
||||
) {
|
||||
lButtonsShort.btnScan
|
||||
} else {
|
||||
lButtonsLong.btnScanLong
|
||||
}
|
||||
|
||||
setupConfirmButton(state, btnConfirm, isTwinsWallet)
|
||||
|
||||
btnScan.setOnClickListener {
|
||||
store.dispatch(WalletAction.Scan)
|
||||
}
|
||||
|
||||
lAddress.btnCopy.setOnClickListener {
|
||||
state.walletAddresses?.selectedAddress?.address?.let { addressString ->
|
||||
store.dispatch(WalletAction.CopyAddress(addressString, fragment!!.requireContext()))
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
app:veilLayout_veiled="true"
|
||||
app:veilLayout_radius="4dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_title"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/tv_processing"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
tools:veilLayout_veiled="false">
|
||||
|
|
@ -80,7 +80,8 @@
|
|||
android:textSize="12sp"
|
||||
android:text="@string/main_processing_full_amount"
|
||||
app:layout_constraintTop_toBottomOf="@id/veil_balance"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_currency_name"
|
||||
|
|
|
|||
|
|
@ -216,8 +216,23 @@
|
|||
android:background="@color/separatorGrey2"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_settings_title" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_app_currency"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:drawablePadding="15dp"
|
||||
android:textColor="@color/darkGray1"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_angle_bracket_right"
|
||||
app:drawableTint="@color/darkGray1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_settings_title"
|
||||
tools:text="USD" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_app_currency_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="7dp"
|
||||
|
|
@ -225,8 +240,6 @@
|
|||
android:text="@string/details_row_title_currency"
|
||||
android:textColor="@color/darkGray6"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_angle_bracket_right"
|
||||
app:drawableTint="@color/darkGray1"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_settings_title" />
|
||||
|
||||
|
|
@ -243,7 +256,7 @@
|
|||
app:drawableEndCompat="@drawable/ic_angle_bracket_right"
|
||||
app:drawableTint="@color/darkGray1"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_app_currency" />
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_app_currency_title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_card_tou"
|
||||
|
|
|
|||
|
|
@ -4,22 +4,6 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_scan_long"
|
||||
style="@style/TapBlackButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginBottom="33dp"
|
||||
android:text="@string/wallet_button_scan"
|
||||
app:icon="@drawable/ic_scan"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintVertical_bias="1" />
|
||||
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline"
|
||||
|
|
@ -33,11 +17,10 @@
|
|||
android:id="@+id/btn_confirm_long"
|
||||
style="@style/TapButtonWithIcon"
|
||||
android:layout_width="0dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="33dp"
|
||||
android:text="@string/wallet_button_send"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/wallet_button_send"
|
||||
app:icon="@drawable/ic_send"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
|
@ -45,4 +28,4 @@
|
|||
app:layout_constraintVertical_bias="1" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@
|
|||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/wallet_button_trade"
|
||||
app:icon="@drawable/ic_arrows_up_down"
|
||||
app:layout_constraintBottom_toTopOf="@id/btn_scan"
|
||||
app:layout_constraintEnd_toStartOf="@id/btn_confirm"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/btn_confirm"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
|
@ -34,29 +34,10 @@
|
|||
android:text="@string/wallet_button_send"
|
||||
app:icon="@drawable/ic_send"
|
||||
app:iconGravity="textEnd"
|
||||
android:textAlignment="center"
|
||||
app:layout_constraintBottom_toTopOf="@id/btn_scan"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:textAlignment="center"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/btn_trade"
|
||||
app:layout_constraintVertical_bias="1" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_scan"
|
||||
style="@style/TapBlackButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginBottom="33dp"
|
||||
android:gravity="center"
|
||||
android:paddingTop="7dp"
|
||||
android:text="@string/wallet_button_scan"
|
||||
app:icon="@drawable/ic_scan"
|
||||
app:iconGravity="textEnd"
|
||||
android:textAlignment="center"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintVertical_bias="1" />
|
||||
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
<string name="common_custom">Пользовательский</string>
|
||||
|
||||
<string name="main_page_balance">Баланс</string>
|
||||
<string name="main_processing_full_amount">Некоторые сети недоступны</string>
|
||||
<string name="main_processing_full_amount">В сумме учтены не все монеты</string>
|
||||
<string name="main_manage_tokens">Управление токенами</string>
|
||||
<string name="token_item_no_rate">Нет цены</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
<string name="common_custom">Custom</string>
|
||||
|
||||
<string name="main_page_balance">Total balance</string>
|
||||
<string name="main_processing_full_amount">Some networks are unreachable</string>
|
||||
<string name="main_processing_full_amount">The amount does not include some of your funds</string>
|
||||
<string name="main_manage_tokens">Manage tokens</string>
|
||||
<string name="token_item_no_rate">No rate</string>
|
||||
</resources>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue